本ページにはプロモーションが含まれます
Playmaker

【Unity】Playmakerが64ビット整数型のパラメータをサポートしていない

この記事は約5分で読めます。

はじめに

Playmakerは非常に便利なビジュアルスクリプトツールですが、いくつかの制限も存在します。その一例が、データ型のサポートに関するものです。Playmakerでは、FsmIntのような整数型はサポートされていますが、FsmDoubleやFsmLong、さらにはFsmUIntやFsmULongなどは対応していません。このため、これらの型を使用したい場合は、工夫が必要です。その対応メモ。

たとえば、ulong(Unsigned Long)などのデータ型をステートマシン上で扱いたい場合、Playmakerのアクションだけを使って直接やり取りすることが難しいため、以下のような工夫が求められます:

  • FsmIntを利用した変換
    ulongをFsmIntに変換して扱うことができますが、この場合は数値の範囲に注意が必要です。特に大きな値を扱う際には、オーバーフローが発生する可能性があります。
  • カスタムアクションの作成
    自分でC#スクリプトを作成して、Playmaker用のカスタムアクションとして登録することで、より柔軟にデータ型を扱えるようになります。この方法により、FsmDoubleやFsmLongを利用する機能を実装することが可能です。
  • 他のAssetとの併用
    Playmaker以外のアセットやライブラリと併用することで、必要なデータ型を扱う方法を見つけることもできます。この際、どのように統合するかが重要です。

これらの工夫を通じて、Playmakerを最大限に活用し、希望するデータ型を扱うことが可能になります。ただし、手間がかかるため、今後のアップデートでより多くのデータ型がサポートされることを期待しています。

対処方法

経緯として、よくクリッカーゲームを作るので、PlaymakerのFSM変数上でulongとかBigintとか使いたい時に使えない。要はPlaymakerで定義した変数だけではint以上の変数は使えない。別クラスやshared object経由してなら値やりとりできるけど、めんどくせー。
FsmUlong作れないかなと調査したが、PlaymakerのDLLの方にVariableTypeが定義されているのでそこで型の追加定義できない限り無理っぽい。

https://hutonggames.fogbugz.com/default.asp?W1103

目的はスマホでクリッカーゲームのように兆以上の値を使いたい、ので、多くのループ処理で64ビット変数で計算を行うとリソース消費も意外と大きいため、intとStringを使って理論的には非常に大きな数(理論上はメモリが許す限り)を扱うことができればモーマンタイな気がする。

Stringで四則演算できるクラス作ってカスタムアクションで呼び出すのが多分正解。この似非値を比較演算できるアクションや割り算できるアクションも作っておく。やりたいことは大体できた。

デメリットは、ゲーム側の定義でint,float,doubleとか計算時にtoStringで型変換して渡すのが気持ち悪い。ゲーム情報保存するストレージクラスの変数型もStringになって気持ち悪い。

追記:四則演算String->チャンク->intでやるとオーバーヘッド高いので、チャンクしたStringは適切にint,longに変換して再計算するようにしました。

存在しない理由を考察

Playmakerにdouble / decimal / bigintが存在しない理由

①UnityのゲームAPIが基本すべてfloat(単精度)だから
UnityのTransform、Physics、Animation、Time、UI…
すべてfloat前提で動いてる。だからPlayMakerもそれに合わせて

・FsmFloat(=float)
・FsmInt(=int)
しか用意してない。

DoubleやDecimalを使っても、Unity側がfloatに戻す必要があるのでメリットがない。

②ゲームではdoubleの必要性がほぼ無い
double(倍精度)は、15〜16桁の精度だけど…
ゲームでそこまでの精度を扱うケースがほぼない。

位置座標、時間、スピード、角度、スコアなど全部floatで十分。

③bigint(任意精度整数)はゲームに不要

bigintは何十桁もの巨大整数を扱えるけど…
ゲーム用途で必要になる場面:
・巨大な天文学計算
・暗号処理
・高精度の課金計算
みたいなものはPlaymakerの守備範囲外。

ゲームロジックはint / longで十分処理できるからPlayMakerは採用してない。

④PlaymakerはC#の基本型+Unityの物理型だけに絞っている

Playmakerの設計は、「ゲーム制作でよく使う型だけを扱う」という思想で作られている。
そのため標準型はこれだけ👇

・Float(float)
・Int(int)
・Bool
・String
・Vector2 / Vector3 / Rect / Quaternion / Color
・GameObject / Material / Texture / Object
・Enum
・Array

Unityで標準的に使わない型は基本入っていない。

⑤大きい数や小数精度を扱いたい場合どうする?

C#カスタムアクションでdouble / decimalを扱う → PlayMaker変数に変換して返すか、FSM側に渡す
FsmObjectとして自作クラスを扱う → FsmObjectにSystem.DecimalやSystem.Numerics.BigInteger
を入れて使うことは可能。

おわりに

PlaymakerはUnityのゲーム構造に合わせて設計されている。
要は作るゲームの精度に応じた型をしっかり使いましょうということ。
そういった意味では、表現したかったことはStringでできたので、正解だったかな、オーバーヘッド多いけど…。