🐼
UdonSharpでEnumをキャストして使う時の注意点
はじめに
UdonSharpでEnum値使って計算してて実行時エラーが出たのでその時の調査とか備忘録
この時はuintにキャストして左シフト演算
(別途ulong, byteを使った場合も同じ)
環境
Unity | VRChat SDK |
---|---|
2022.3.22f1 | 3.73 |
結論
Enum値をuint, ulong, byteにして演算する場合は調査の2の書き方するとよさそう。
調査
書き方を変えてみてエラーが出るもの出ないものを調査
- エラーがでるもの1
シンプルな書き方
画像のコード
private void NG1(TestTest arg)
{
var val = ((uint)arg) << 1;
}
- OKなもの1
intキャスト入れてみる
\textcolor{blue}{これは大丈夫}
private void OK1(TestTest arg)
{
var arg_cast = (int)arg;
var val = ((uint)arg_cast) << 1;
}
- エラーがでるもの2
intキャストすればいいのかなと思ってまとめて記載
\textcolor{red}{ダメ}
private void NG2(TestTest arg)
{
var val = ((uint)((int)arg)) << 1;
}
- OKなもの2
Enumの問題かint⇒uintのキャストか切り分けたく以下のコード
普通に通る。それはそう。
private void OK2(int arg)
{
var val = ((uint)arg) << 1;
}
- エラーがでるもの3
Enum=>uintへのキャストを分けて書いてみる
\textcolor{red}{ダメ}
private void NG3(TestTest arg)
{
var arg_cast = (uint)arg;
var val = arg_cast << 1;
}
調査(それぞれのUdonAssembly)
調査した5例それぞれのUdonAssemblyを見てみる
- エラーがでるもの1
シンプルな書き方
PUSH, __0_arg__param
PUSH, __intnl_SystemUInt32_0
COPY
PUSH, __intnl_SystemUInt32_0
PUSH, __const_SystemInt32_2
PUSH, __lcl_val_SystemUInt32_0
EXTERN, "SystemUInt32.__op_LeftShift__SystemUInt32_SystemInt32__SystemUInt32"
- OKなもの1
intキャスト入れてみる
PUSH, __1_arg__param
PUSH, __lcl_command__SystemInt32_0
COPY
PUSH, __lcl_command__SystemInt32_0
PUSH, __intnl_SystemUInt32_1
EXTERN, "SystemConvert.__ToUInt32__SystemInt32__SystemUInt32"
PUSH, __intnl_SystemUInt32_1
PUSH, __const_SystemInt32_1
PUSH, __lcl_val_SystemUInt32_1
EXTERN, "SystemUInt32.__op_LeftShift__SystemUInt32_SystemInt32__SystemUInt32"
- エラーがでるもの2
intキャストまとめて記載
PUSH, __1_arg__param
PUSH, __intnl_SystemUInt32_1
COPY
PUSH, __intnl_SystemUInt32_1
PUSH, __const_SystemInt32_2
PUSH, __lcl_val_SystemUInt32_1
EXTERN, "SystemUInt32.__op_LeftShift__SystemUInt32_SystemInt32__SystemUInt32"
- OKなもの2
PUSH, __3_arg__param
PUSH, __intnl_SystemUInt32_3
EXTERN, "SystemConvert.__ToUInt32__SystemInt32__SystemUInt32"
PUSH, __intnl_SystemUInt32_3
PUSH, __const_SystemInt32_2
PUSH, __lcl_val_SystemUInt32_3
EXTERN, "SystemUInt32.__op_LeftShift__SystemUInt32_SystemInt32__SystemUInt32"
- エラーがでるもの3
Enum=>uintへのキャストを分けて書いてみる
PUSH, __4_arg__param
PUSH, __lcl_arg_cast_SystemUInt32_0
COPY
PUSH, __lcl_arg_cast_SystemUInt32_0
PUSH, __const_SystemInt32_1
PUSH, __lcl_val_SystemUInt32_4
EXTERN, "SystemUInt32.__op_LeftShift__SystemUInt32_SystemInt32__SystemUInt32"
まとめ
書き方次第でUInt32のデータにInt32の値をSystemConvertして格納するのか、Copyして格納するのか、UdonAssemblyが変わる様子。
Enumのintキャストを独立して記載することがミソかも。
(コンパイラのバグかな?)
結論:Enum値をuint, ulong, byteにして演算する場合は、ステップ数は増えるけど一度int変数に格納して使うのが良いかも。
Discussion