【Unity】カードゲームっぽい手札を作りたかった話
こんにちは、たかせです。カードゲーム作ってます。
先日、手札のカードをこんな風に表示していたら、デザイナさんに突っ込まれました。もっと シャドバ カードゲームっぽくしたいとのこと。
UIを円状に配置できるScriptを見つけたので試してみたものの、いまいちカードゲームっぽさが出ない。
やっぱこうじゃないと...!!!
ということで、SectorLayoutGroupを作成しました。
デモ
3D対応!アニメーション可能!
使い方
スクリプトとプレファブをインポートすると使えます。UniRxというAssetに依存しているので、利用していない方はコチラからインポートしてください(無料です)。
- SectorLayoutGroup.csをインポート
- SectorTemplate.prefabをインポート
- 並べたいGameObjectをSectorTemplateの子供に子供として追加
- 完了!
パラメータの説明
Center
- 必須。扇形の中心点となるGameObjectを指定します(図中の赤点)
Start
- 必須。扇形の始点となるGameObjectを指定します(図中の青点)
End
- 必須。扇形の終点となるGameObjectを指定します(図中の緑点)
ChildrenRotateOffset
- 子供の向きを調整します。デフォルトでは
Center
を向きます
- 子供の向きを調整します。デフォルトでは
FrameCount
- アニメーションの実行時間を調整します。最終的な時間は
FrameCount * FrameInterval
により決まります
- アニメーションの実行時間を調整します。最終的な時間は
FrameInterval
- アニメーションの実行間隔を調整します。最終的な時間は
FrameCount * FrameInterval
により決まります
- アニメーションの実行間隔を調整します。最終的な時間は
useSlerp
- アニメーションにVector3.SLerpを使用します。デフォルトではVector3.Lerpを使用します
enable
- Gizmosを使ってデバッグ用の扇形と点を描画します(予めGizmosをONにしておく必要があります)
freeze
- 要素を並べる時、回転情報をリセットします
とりあえず動作確認してみたいという方へ
お試し用のプロジェクトを作成してあります。コチラからZipファイルをダウンロードして、UnityでSampleSolution
フォルダを開くと動作確認が可能です。
※git clone
でもOKです
動作の解説(と苦労話)
要素を扇状に並べる手順をざっくり言うと、次のようになります。
1. 3点(赤点、青点、緑点)をもとに扇型を定義する 2. 扇型を曲座標変換して半径、xy平面上の角度、xz平面上の角度を取得する 3. 2つの角度をn等分し、その等分線を直交座標系に戻す 4. 等分線の終点にGameObjectを配置する 5. 中心点(赤点)を向くようにGameObjectを回転させる
文字数にして149文字の短い説明ですが、ベクトルの足し算ってどうやるんだっけ...?な状態だった僕にはなかなかしんどい実装でした。
いやほんとに。高校の数学、こういう動機を持って勉強したかったなぁ。
Unityの座標系はxyzではなくxzyであることに気づかず数時間悩んだり、気まぐれにWordScopeからLocalScopeに切り替えてみたらxyz座標系に戻って悩んだ時間が吹っ飛んだり、Quaternion.LookRotation
の説明にあるspecified forward directions
がさっぱりイメージできなくて場当たり的に引数を設定してみたり...。もうさんざんでした。初めてUnityエンジニアらしい実装をした気がします。
わりと困ったのが「扇形の形が変化したら子供を並べ直す」実装で、3点(赤点、青点、緑点)のpositionの変化を検知したかったのですが、その時点で唯一知っていたOnValidate
では検知できませんでした。困った挙げ句、UniRxのObserveEveryValueChanged
を使ってtransform.position
の変化を購読することで対応しました。動作上問題は出ていないものの、誰がもっと良い実装があれば教えてください...
また、どうせUniRxを使うなら...と思いたった結果、要素数の変化もObserveEveryValueChanged
で行いました。これにより、LayoutGroupの継承をせずに済むようになり、uGUIではないLayoutGroupが完成しました。作った手前あれなんですが、非uGUIなLayoutGroupって嬉しいことあるんでしょうか...。継承を外せたのは嬉しかったんですが、使う側としても何か嬉しいことがあればぜひ教えてもらえると🙇♂️
2箇所もUniRxに依存してしまった現状、Vector3.Lerp
によるアニメーションにUniRxを使わない手はありませんでした。
こんなデータをクラスを作り、
こんなストリームを作れば、
あっと言う間にUpdateメソッドを使わないLerpアニメーションの完成です 。
Corotuineとか使ったほうがスマートかもしれません
おわりに
SectorLayoutGroupにより、こんな素敵な手札が完成しました。
GWの長い休みのおかげで開発が進み、少しずつゲーム画面を見せれるような形になってきました!
— Beyond the field 【新作TCG】2019年秋リリース (@BTF_TCG) 2019年5月6日
このようにBeyond the fieldは5×7のマスを使ったカードゲームです。
まだまだ未実装部分が多くゲーム中に何が起こっているかわかりづらいですが、後々実装完了と共にルールを説明していければと思います! pic.twitter.com/iGhL29XK1C
カードゲームを作っているみなさんが少しでも楽になりますように!
こんな風に使えるともっと便利なんだけど...みたいなご提案、お待ちしております!!!