データトークン
データトークンはデータを保持するためのものです。各トークンは必ず1つの変数のみを格納します。データトークンは、Data Dictionaries や Data Lists で使用されます。
データトークンには、以下のトークンタイプを含めることができます。
- Null
- Boolean
- SByte
- Byte
- Short
- UShort
- Int
- UInt
- Long
- ULong
- Float
- Double
- String
- Data Lists (他の
DataTokensを格納) - Data Dictionaries (他の
DataTokensを格納) - Object Reference (ボクシングを通じて何でも格納できますが、シリアライズはできません)
- Data Errors (何が問題であったかを示す列挙型)
プロパティ
| Property | Result |
|---|---|
| TokenType | この DataToken が保持している変数の現在の TokenType を返します。 |
| IsNumber | DataToken が数値型を含んでいる場合に true を返します。それ以外の場合は false を返します。 |
| IsNull | DataToken 内に保持されている値がどのような形式であれ null である場合に true を返します。数値と bool は決して null にはなりません。TokenType.Null は常に null と見なされます。文字列は空文字ではなく null かどうかをチェックします。参照型については、内部で Utilities.IsValid を使用して、退出したプレイヤーや破棄されたオブジェクトを判定します。 |
| Boolean | DataToken が bool を保持している場合に bool を返します。それ以外の場合は例外をスローします。 |
| Number | DataToken が数値型を保持している場合に double を返します。それ以外の場合は例外をスローします。 |
| SByte | DataToken が sbyte を保持している場合に 8ビット符号付き sbyte を返します。それ以外の場合は例外をスローします。 |
| Byte | DataToken が byte を保持している場合に 8ビット符号なし byte を返します。それ以外の場合は例外をスローします。 |
| Short | DataToken が short、sbyte、または byte を保持している場合に 16ビット符号付き short を返します。それ以外の場合は例外をスローします。 |
| UShort | DataToken が ushort または byte を保持している場合に 16ビット符号なし ushort を返します。それ以外の場合は例外をスローします。 |
| Int | DataToken が int、sbyte、byte、short、または ushort を保持している場合に 32ビット符号付き int を返します。それ以外の場合は例外をスローします。 |
| UInt | DataToken が uint、byte、または ushort を保持している場合に 32ビット符号なし uint を返します。それ以外の場合は例外をスローします。 |
| Long | DataToken が long、sbyte、byte、short、ushort、または uint を保持している場合に 64ビット符号付き long を返します。それ以外の場合は例外をスローします。 |
| ULong | DataToken が ulong、byte、ushort、または uint を保持している場合に 64ビット符号なし ulong を返します。それ以外の場合は例外をスローします。 |
| Float | DataToken が float、sbyte、byte、short、ushort、int、uint、long、または ulong を保持している場合に 32ビット float を返します。それ以外の場合は例外をスローします。 |
| Double | DataToken が double またはその他の数値型を保持している場合に 64ビット double を返します。それ以外の場合は例外をスローします。 |
| String | DataToken が string を保持している場合に string を返します。それ以外の場合は例外をスローします。 |
| DataDictionary | DataToken が DataDictionary を保持している場合に DataDictionary を返します。それ以外の場合は例外をスローします。 |
| DataList | DataToken が DataList を保持している場合に DataList を返します。それ以外の場合は例外をスローします。 |
| Reference | DataToken がオブジェクト参照を保持している場合にオブジェクト参照を返します。それ以外の場合は例外をスローします。 |
| Error | このトークンに関連付けられているエラーを返します。それ以外の場合は DataError.None を返します。他のプロパティとは異なり、このプロパティにアクセスしても例外がスローされることはありません。エラーではないトークンから Error にアクセスしようとした場合、単に DataError.None が返されます。 |
関数
| 関数 | 結果 |
|---|---|
| Bitcast | DataToken 内の既存のデータを再利用しつつ型を変更します。C++ の reinterpret_cast や C# の BitConverter と同様です。変換先の方が型サイズが小さい場合は値が切り捨てられ、変換先の方が大きい場合はゼロ拡張されます。プリミティブ型でのみ動作し、コピーを返します。 |
| ToString | トークンの内容を文字列に変換します。String プロパティへのアクセスとは異なり、この関数は基となる値の ToString を使用するため、常に成功します。 |
| GetHashCode | トークンの内容のハッシュコードを返します。これは主に辞書のキーといった内部処理で使用されます。 |
| CompareTo | このトークンを別のトークンと比較します。比較対象の方が大きい場合は -1、等しい場合は 0、小さい場合は 1 を返します。リストや辞書といったコンテナは要素数によって比較されます。型が異なるトークン同士や数値以外を比較する場合、TokenType enum の順序が使用されます。 |
Data Token の作成
UdonSharp
UdonSharp では、DataToken を「暗黙的」に作成できます。これは、関数が DataToken を要求する際に new DataToken(value) を呼び出す必要がないことを意味します。代わりに値を直接渡すだけで、自動的に DataToken が作成されます。
// You could do this
DataToken _explicitFloat = new DataToken(5.3f);
DataToken _explicitInt = new DataToken(5);
DataToken _explicitString = new DataToken("value");
DataToken _explicitBool = new DataToken(true);
// But this is easier and simpler
DataToken _float = 5.3f;
DataToken _Int = 5;
DataToken _String = "value";
DataToken _Bool = true;
UdonSharp で DataToken を暗黙的に作成する際に nameof() を使用しないでください。エラーが発生する可能性があります。
Udon Graph
Udon Graph では、 DataToken Implicit ノードまたは DataToken Constructor ノードを使用して、値を含む DataToken を作成する必要があります。

DataToken から値を取得する
DataToken から値を取得する前に、そのトークンがどのような型を含んでいるかを確認する必要があります。互換性のない型を取得しようとすると、UdonBehaviour が停止してしまうためです。含まれている型が目的のデータ型と互換性があることを確認するには、いくつかの方法があります。
DataToken.TokenTypeプロパティを確認することで、正確な型を取得できます。- Data List や Data Dictionary から値を取得する際、
TryGetValueを使用して TokenType を指定できます。指定した TokenType が正しくない場合、この関数は false を返します。 DataToken.IsNumberプロパティを確認することで、数値かどうかを判定できます。数値である場合、Numberプロパティから安全に値を取得できます。このプロパティは、実際の型が何であれ、それを double にキャストして返します。ただし、元の型がlongやulongであった場合、精度が失われる可能性があります。- トークンの型に関係なく、
ToStringは常に有効な選択肢であり、エラーを引き起こすことはありません。
// If we know that it's a string, we can safely pull the string out of the token
if (unknownToken.TokenType == TokenType.String)
{
Debug.Log(unknownToken.String);
}
// We can use IsNumber to see if it's some type of number, even if we don't know which.
if (unknownToken.IsNumber)
{
Debug.Log(unknownToken.Number);
}
// If we're pulling a value from a container, we can use the version that does its own type check
if (dictionary.TryGetValue("key", TokenType.String, out DataToken value))
{
Debug.Log(value.String);
}

適切な型であることを確認したら、DataToken.Float や DataToken.Boolean といった値プロパティにアクセスすることで、DataToken から値を取得できます。各型には、その特定の型を取り出すために使用できる独自のプロパティが用意されています。
取り扱うデータを完全に制御できている場合は、すべての TokenType チェックをスキップして、トークンから直接値を取得しても構いません。これによりコード量を減らすことができますが、外部ソースからデータが来る場合や、他の型である可能性がある場合は、この方法をとらないようにしてください。
dictionary["A"] = 5;
dictionary["B"] = 10;
// This makes the assumption that A and B will always contain integers.
// This is a safe assumption to make since we set them just above in a controlled environment.
// If the data is coming from an external source, we shouldn't make these assumptions!
int sum = dictionary["A"].Int + dictionary["B"].Int;
エラー
Data List または Data Dictionary に対する操作が失敗し、DataToken が返された場合、エラートークンが生成されます。エラートークンには、エラーの種類を分類する列挙型(enum)と、エラーの詳細を説明する文字列が含まれます。詳細な説明が不要な場合など、すべてのエラーに文字列が含まれるわけではありません。
エラートークンを取得した場合、DataToken.Error を使用してエラーの列挙型を、DataToken.String を使用してメッセージを取得できます。また、DataToken.ToString() を使用すれば、列挙型と文字列を自動的に結合して完全なメッセージを作成できるため、単純に Debug.Log(token) を呼び出す際に便利です。
エラートークンには、主に以下の種類があります。
| 値 | 意味 |
|---|---|
| KeyDoesNotExist | Data Dictionary 内のキーにアクセスしようとしましたが、そのキーが存在しません。 |
| IndexOutOfRange | Data Array 内のインデックスにアクセスしようとしましたが、そのインデックスが 0 未満、あるいは配列の要素数以上でした。 |
| TypeMismatch | 値にアクセスしようとしましたが、期待した型ではありませんでした。注:これは型を指定するバージョンの TryGetValue を使用している場合にのみ発生します。 |
| TypeUnsupported | データコンテナに、使用しようとしたシリアライズ形式でサポートされていない型が含まれていました。これは、Data Container に参照トークンを入れ、それを JSON にシリアライズしようとした場合などに発生します。 |
| ValueUnsupported | データコンテナに、使用しようとしたシリアライズ形式でサポートされていない値が含まれていました。これは、Data Container に NaN や Infinity の浮動小数点数を入れた状態で、JSON にシリアライズしようとした場合などに発生します。 |
| UnableToParse | シリアライズされた形式を解析できませんでした。これは、元の JSON が無効な場合に発生します。 |
if (dictionary.TryGetValue("key", TokenType.Float out DataToken value)) {
// If TryGetValue succeeds, we can do things with the token
Debug.Log($"Successfully retrieved value {token.Float}");
} else {
// If TryGetValue fails, the token will instead be an error
Debug.Log($"Failed to retrieve value with error {token.Error}");
}

FAQ
String と ToString の違いは何ですか?
DataToken.String と DataToken.ToString() は似ていますが、全く同じものではありません。DataToken.String は DataToken 内にある文字列の値に直接アクセスするのに対し、DataToken.ToString() は存在するあらゆるデータを文字列に変換するためです。
結果として、ToString は DataToken の中身に関わらず常に有効であり、UdonBehaviour が停止することはありません。中身が bool であれば true または false を返し、数値であれば ToString("G", CultureInfo.InvariantCulture) を用いてその数値を表す文字列を作成します。
その一方で、DataToken.String へのアクセスは、DataToken に文字列が含まれている場合にのみ有効です。DataToken に float が含まれている状態で DataToken.String にアクセスしようとすると、例外が発生し、UdonBehaviour は停止します。
DataErrors は、Error enum と文字列の両方を含んでいるという点で特殊です。DataErrors に対しては ToString() を使用することをお勧めします。これは、ToString() を使うと enum と文字列が結合され、エラーの内容と理由の両方を含む単一のメッセージとして取得できるためです。
トークンを介さず、直接値を取得する TryGetValue はないのですか?
トークンを介さずに直接値を取得できる TryGetValue メソッドがあれば便利でしょう。コンテナから毎回トークンを取得し、その中からさらに値を取り出すという手間を考えると、この質問はもっともです。このプロセスを簡略化するためにいくつかの選択肢が検討されており、その解決策の一つとして、TryGetValue に型チェック機能を組み込むという実装が行われました。
また別の検討案として、T 引数を使用してシステム型を指定するジェネリック版の TryGetValue を作成することも考えられました。UdonSharp は(少なくとも静的メソッド内であれば)このアプローチをサポートしていますが、Udon 自体は対応していません。さらに、この方法には利点がある一方で、エラー発生時に DataToken を介して DataError を返すことができなくなり、代わりにデフォルト値が返されてしまうという問題があります。最終的に、ユーザーからエラーが隠蔽され、問題の特定が困難になるという理由から、この実装は採用しませんでした。幸いなことに、UdonSharp であれば Generics、Statics、および拡張メソッドが利用できるため、ユーザー自身でジェネリックな値取得のためのソリューションを作成することが可能です。
最終更新: