2020/11/09
「過去にこんなことができた」ということで、参考程度でご参照ください。
というわけで、今回はタイトル通り、CharacterMotorを使って「滑る床」を実現してみようと思います!
寒い今日、季節的にもジャストな話題ではないでしょうか。
ゲーム的にはステージギミックの1つで、特定のブロックの上では滑るような移動になります。
この手のギミックはアクが強すぎると面倒なことになったりするので、過激な設定は避けるように気を付けていきます。
また、ジャンプ中は滑る床の影響を受けません。
滑る床と判定の作成
氷の床の名目で「IceFloor」というCube状のオブジェクトを作ります。
大きさは使用箇所によって変化させ、マテリアルは水色っぽくします。
Cubeを足場として使用するためBoxColliderが設定されていますが、これでプレイヤーとの接触判定を行うのはなかなか厳しいです。
なので「足場としての判定用」と「制御用スクリプトの判定用」の2つのBoxColliderを設定します。
足場用はCubeの形状そのままで、制御用はCenterをY軸に少しずらし、isTriggerにチェックを入れておきます。
CharacterMotorのパラメータ設定
上で作ったIceFloorに制御用スクリプトを付けます。
using UnityEngine; using System.Collections; public class IceFloor : MonoBehaviour { [SerializeField] private float MaxGroundAcceleration; private float defaultMaxGroundAcceleration; public void OnTriggerEnter(Collider c) { if (TagUtility.getParentTagName(c.gameObject) == "Player") { CharacterMotor charMotor = c.gameObject.GetComponent<Player>().getCharacterMotor(); defaultMaxGroundAcceleration = charMotor.movement.maxGroundAcceleration; charMotor.movement.maxGroundAcceleration = this.MaxGroundAcceleration; } } public void OnTriggerExit(Collider c) { if (TagUtility.getParentTagName(c.gameObject) == "Player") { CharacterMotor charMotor = c.gameObject.GetComponent<Player>().getCharacterMotor(); charMotor.movement.maxGroundAcceleration = defaultMaxGroundAcceleration; } } }
予めPlayerクラスにCharacterMotorのgeterを作っておきます。
CharacterMotorの変数をpublicにしている場合は不要です。
肝となるのはCharacterMotorの「Max Ground Acceleration」です。
これはキャラクターが接地している場合の最大加速度になります。
OnTriggerEnterでPlayerクラスからCharacterMotorを取得し、その値をデフォルト値として取得した後、インスペクターから設定した値で上書きします。
これでIceFloorに接地している際にはツルツル滑ります。
どのくらいの値にすれば良いかはオブジェクトの大きさやゲームのスタイルによって変わります。
また、Exit時はしっかりデフォルト値に戻すようにします。
これが抜けているとずっと滑りっぱなしになってしまうので注意します。
まとめ
・滑る床として「IceFloor」を実装
・足場用と制御用のColliderを2つ設定する
・CharacterMotorの「Max Ground Acceleration」を変化させ、滑るような挙動にする
最近実装した要素の中ではサクっと出来た方です。
CharacterMotorもパラメータさえ理解できればいろいろと応用できます。
「敵が滑らない」という問題が残っていますが、Rigidbodyで行うのは難しそう・・・。
物理マテリアルで上手くできそうな気がしないでもないので、暇なときに検証してみます!