この記事は Cluster Creator #1 Advent Calendar 2022 の6日目の記事です。
◆前の日は Sha-la /歌詠しゃら🧸Vシンガー🌷本垢凍結で一時避難中。 さんの clusterで音楽イベントを開いてみたいアーティストの方へ。
◆次の日は さな さんの 会話ロボ in cluster です。
先日開催されたCluster GAMEJAM 2022 in AUTUMNに参加しました。三回目にして初空振りだったと思ってたのですが(毎回自主トレやにぎやかし目的で参加してるので空振りでいいんですけど)、奨励賞をいただけてました!!手広く色々な賞を用意してくださっていて参加して楽しいゲームジャムです。
GAMEJAMでは前回の春の時は「天翔ける腕輪」で空飛ぶ腕輪とクマ。
今回は「イノシシ★ダッシュ!!」で直進しかできないイノシシを作りました。
Cluster Creator Kitを使えば様々な仕掛けが作れます。公式のテンプレートワールドはどのようなことができるのかや実装テクニックを知ることができる宝の山です。 上記の乗り物もテンプレートワールドのHorseをもとに作りました。この記事ではHorseを観察しながら機能を理解して、イノシシに改造するまでをご紹介します。 Cluster Creator Kit(以降、CCK)を使えるようにするための一助になれば幸いです。
目次
動作環境
- Unity2021.3.4f1
- 2022/12/1現在のCCKとCluster
乗り物作りの環境構築
自由にいじりまわせるUnityプロジェクトを作成して、そこに公式のテンプレートワールドを読み込みます(サンプルプロジェクトではありません)。以下の公式サイトの「すぐにワールド制作したい──テンプレートワールドを導入する」を参考にテンプレートワールドをUnityで開いてください。
テンプレートワールドは、「プロジェクトに含まれるアセットは cluster にアップロードする場合には、すべてクレジット表示不要で自由に使う」ことができるとても有難いものです。活用しない手はありません。
ダウンロードしたClusterCreatorKitTemplate-master.zip
を展開して、フォルダーの名前を変更すれば(例えばNorimonoRensyu
など)複数のテンプレートワールドのプロジェクトを扱えるので便利です。
テンプレートワールドをUnityで開いたら以下のガイドに進みます。
「テンプレートワールド『乗り物』について」を参考にVehicleシーンを開きます。Playして用意されている乗り物を乗り回してみてください。ぱっと思い浮かぶ乗り物は一通り揃っていると思います。使えるようならそのまま利用してもいいですし、仕組みを観察すればCCKの活用方法を学ぶことができます。
イノシシの能力
イノシシは以下のようにします。
- スペースキーで一定速度まで加速
- スペースキーを離すと急停止
- 加減速は着地時のみ
- 左右旋回はできない
秋のゲームジャムでは上キーで等速で前進させていましたが、せっかくなのでイノシシらしく(?)加速させたいと思います。
既存の乗り物を観察する
一通り乗り物に乗ってみてイノシシに近いのはHorseなのでこれをベースにします。
Horseの階層
階層はこんな感じです。
- Horse...Character Controllerやトリガーなどの制御系のコンポーネントで構成
- Horse...ウマのモデルオブジェクト。アニメもここ。grip_Lとgrip_Rが手の位置
- Seat...腰掛ける位置を表すオブジェクト
- Exit...降りた時の位置を表すオブジェクト
- Sounds...乗り(GetOnSound)降り(GetOffSound)、着地(LandSound)を鳴らすためのオブジェクト
動きに関するコンポーネントを親オブジェクトにまとめて、モデルデータが子になっています。モデルの差し替えがしやすいUnityのオススメ構造になっていて助かります。
Horseのコンポーネント
ご覧の通りなかなかの量ですが頑張って確認していきます。
Character Controllerで動くキャラクタの設定
Character Controllerで制御するキャラクターにするためのコンポーネントです。 パラメータは殆どなく、着地位置や当たる範囲を調整したい時にCharacter Controllerをいじるぐらいです。
乗り物の設定と旋回、移動
Ridable Itemで乗り降りや腰掛ける位置、手の位置、下りる位置、乗った時のアニメを設定できます。
Steer Item Triggerは乗り物の操作入力のためのトリガーで、前後左右操作に加えて、スペースキーなどのAdditionalキーに変化があった時のシグナルと、入力値をトリガーとして送信することができます。
Set Angular Velocity Character ItemGimmickは操作入力で旋回させるギミック、Set Velocity Character Item Gimmickは同様に移動させるギミックです。
間に挟まってるItem Logicは移動を前後に制限するためのものです。入力したmoveInputをそのまま速度に設定すると左右キーでHorseが横移動してしまいます。Item Logicで上下入力だけmove.y
に設定することで左右キーの影響を除外しています。
着地とジャンプ
Horseで一番参考になったのがこの辺りでした。着地を確認するIs Grounded Character Item Triggerですが、地面のわずかなデコボコの影響で一瞬だけ空中にいると判定されることがしばしば発生します。そのまま使うとジャンプボタンを押してもジャンプしないことが頻発して操作性が落ちてしまいます。
そこで下から3番目の位置にあるItem Timerを使って、空中にいるかを表すisInAir
への着地状態の反映を0.15
秒遅らせる仕組みになっています。ジャンプできるかどうかはisInAir
がfalseかどうかで判定しているので、空中に浮いても0.15
秒間はジャンプ可能で、その間に着地すれば空中に浮いていたことはチャラになります。ジャンプ開始時にisInAir
をtrueにしているのでこの処理によって連続ジャンプすることもありません。
0.15
秒後のチェック時に運悪く空中にいる可能性もありますが、ジャンプができなかったと感じることはないので対策として十分だと思います。
イノシシでも加速は着地時にしたいのでこの処理は活用します。
その他
残りは以下のような処理です。
- 乗った時の演出のためのシグナル送信
- 降りた時の演出と操作をリセットするためのシグナル送信
- オーナーが変わった時に操作をリセットするためのシグナル送信
- 操作のリセット処理
操作や状態を一括してリセットするItem Logicは便利で、作り方の参考になりました。
イノシシへの改造
Horseの機能は一通り把握できました。改造の方針は以下の通りです。
- モデルをイノシシに差し替え
- 前後左右操作、ジャンプは不要なので削除
- Additionalキー(スペースキー)による加減速
- 加速は着地時のみ
一つずつ手順をまとめます。
モデルをイノシシに差し替え
イノシシは3月のウクライナアセットバンドルで入手したLowPoly Wild Animalsのものを利用しました。前回のシロクマもこれだったと思います。
Horseのプレハブを複製してBoarに名前を変更します。SeatとExitの位置をモデルに併せて調整して、左右の手の置き場を表すLeftHand
とRightHand
をモデルに追加しました。
アニメーション関連は、HorseのモデルからAnimatorやギミックを手作業で移植しました。Animator Controllerは Animator Override Controller を作成してHorseのAnimatorを参照して、イノシシの該当するAnimationを設定しました。Set Animator Value Gimmickは、InspectorウィンドウからHorseのコンポーネントをドラッグしてHierarchyウィンドウのBoarモデルにドロップするのを片っ端からやりました。
おおよそ以上でモデルの対応完了です。Horseを非表示にするなどして動作確認をします。
前後左右操作、ジャンプの削除
Horseの構造から不要なものを削除していきます。ここに書いてないものは後で利用予定なので手を加えないようにします。
- 上下左右キーでの操作はいらないのでSteer Item TriggerのMove Input Triggersを消します。
- 旋回動作はないのでSet Angular Velocity Character Item GimmickコンポーネントをRemoveします
- ジャンプは不要なので、Jump Character Item GimmickコンポーネントをRemoveします
以上で、乗っても移動やジャンプができなくなりました。
Additionalキー(スペースキー)での加減速
このブログの本丸である加減速を実装します。RigidbodyならAdd Force系のギミックで加速できるのですが、HorseはCharactor Controllerなので自前で実装する必要があります。
移動速度はSet Velocity Character Item Gimmickにおいてmove
キーで設定しています。Additionalキーが押されていたらmove.y
に加速値を足し、離されていたら減速させれば加減速ができます。またmove.y
に空気抵抗に見立てた値を掛ければ最高速度の制限ができます。
この処理は物理更新と似たような頻度で実行したいので、やや無理やりですがItem Timerを0.02
秒ごとに呼び出し続けて処理することにします。
関連変数の初期化
- Keyが
ResetInput
のItem Logicを探して開きます moveInput
は不要になったので削除します- ロジックを追加して、
VelocityTimer
という名前で型はSignal
にして、式は=
、Constant
,Bool
を選んでチェックします - もう一つロジックを追加して、
accel
という名前で型はFloat
にして、式は=
、Constant
,Float
を選んで値を0
にします
速度を更新するためのタイマーを設定
- 新規にItem Timerを追加します
- Targetは
This
, KeyはVelocityTimer
, Delay Time Secondsは0.02
にします - ロジックを追加して、Targetを
CheckVelocity
、ValueをSignal
にします
Additionalキーの変更時にaccelの値を設定
- 新規にItem Logicを追加します
- Targetを
This
, KeyをOnAdditionalInputChanged
にします - ロジックを追加して、Additionalキーの入力が0より大きかったらisAccelがtrueになるように設定します
- 最初の行は
This
,isAccel
,Bool
を設定します - 式は
=GreaterThan
にします - 1つ目を
RoomState
,Float
,This
,additionalInput
にします - 2つ目を
Constant
,Float
,0
にします
- 最初の行は
- さらにロジックを追加して、先に設定した
isAccel
がtrueならaccel
に加速値、falseなら減速値を設定します- 最初の行は
This
,accel
,Float
を設定します - 式は
=Condition
にします - 1つ目を
RoomState
,Bool
,This
,isAccel
にします - 2つ目を
Constant
,Float
,0.13
にします - 3つ目を
Constant
,Float
,-0.5
にします
- 最初の行は
タイマーで0.02秒ごとに呼び出される速度管理の処理
- 新規にItem Logicを追加します
- Targetを
This
, KeyをCheckVelocity
にします - ロジックを追加して、速度管理を持続させるためにタイマーを開始する
VelocityTimer
シグナルを送信します- ThisでKeyは
VelocityTimer
にして型はSignal
- 式は
=
、Constant
のBool
でチェックします
- ThisでKeyは
- ロジックを追加して、着地時のみに加減速するための設定をします
- ThisでKeyは
currentAccel
、型はFloat
にします - 式は
=Condition
にします - 1つ目の設定の条件式は
RoomState
,Bool
,This
,isInAir
として、空中かどうかで判定します - 2つ目の設定は
Constant
,Float
,0
を設定して、isInAir
がtrueの時は空中なので加速しないようにします - 3つ目の設定は
RoomState
,Float
,This
,accel
にします。これでisInAir
がfalseで着地時にはcurrentAccel
にaccel
が代入されるので加速か減速をします
- ThisでKeyは
- ロジックを追加して、currentAccelをmove.yに加算します
- ThisでKeyは
move.y
, 型はFloat
にします - 式は
=Add
にします - 1つ目の設定は
RoomState
,Float
,This
,move.y
にします - 2つ目の設定は
RoomState
,Float
,This
,currentAccel
にします
- ThisでKeyは
- ロジックを追加して、減速しすぎてバックしないようにします
- ThisでKeyは
move.y
、型はFloat
にします - 式は
=Max
にして、move.yと0のうちの大きい方をmove.yの値にすることで、値が0より小さくなることを防ぎます - 1つ目の設定は
RoomState
,Float
,This
,move.y
にします - 2つ目の設定は
Constant
,Float
,0
にします
- ThisでKeyは
- ロジックを追加して、move.yに空気抵抗がわりの定数をかけます
- ThisでKeyは
move.y
, 型はFloat
にします - 式は
=Multiply
にして掛け算をします - 1つ目の設定は
RoomState
,Float
,This
,move.y
にします - 2つ目の設定は
Constant
,Float
,0.95
にします
- ThisでKeyは
以上で完了です。スペースキーなどのAdditionalキーに該当する操作でイノシシが加速するようになりました。
成果物は以下でご確認いただけます。こちらはもう少し改造して、上キーでも加速するようにしています。
まとめ
公式テンプレートから実装したいものに近いものを探して観察し、改造することで独自の乗り物や仕掛けを作る手順をご紹介しました。Character Controllerはそのまま使うと等速移動になりますが、自前で速度計算をして加減速に対応させました。またサンプルテンプレートの着地判定を利用することで、苦労せずに着地時のみに加減速する動きが実装できました。
実装している中で機能として欲しいと思ったのは以下の2つでした。
- Set Animator Value Gimmickに別のゲームオブジェクトのアニメーターを設定したい - これによりアニメギミックを親オブジェクトなどのモデル以外のオブジェクトに構築することで、モデルの差し替えがより簡単にできるようになるのではと思います
- Is Grounded Character Item Triggerの不安定さをトリガーコンポーネント自体で吸収して欲しい
以上、Cluster Creator #1 Advent Calendar 2022 の6日目の記事でした。創作の一助になれば幸いです。
◆前の日は Sha-la /歌詠しゃら🧸Vシンガー🌷本垢凍結で一時避難中。 さんの clusterで音楽イベントを開いてみたいアーティストの方へ。
◆次の日は さな さんの 会話ロボ in cluster です。