ユニティちゃんがデフォルトだと左右キーで回転するだけなので、キーの方向に歩くようにしてみる

ユニティちゃんが初期のバイオ◯ザードっぽい移動する件。

なんとか調整できないか、トライしていきます。

調べてみるとunitychanのモデルはこんな構造になっていました。

アニメーションUnityChanLocomotions
移動などのメイン処理UnityChanControlScriptWithRgidBody

これをそれぞれ眺めていきます。

キャラクター制御のコントローラー

UnityChanControlScriptWithRgidBodyで入力やら移動やらを処理しているのですが、すごく参考になるサンプルでした。

//
// Mecanimのアニメーションデータが、原点で移動しない場合の Rigidbody付きコントローラ
// サンプル
// 2014/03/13 N.Kobyasahi
//
using UnityEngine;
using System.Collections;

namespace UnityChan
{
// 必要なコンポーネントの列記
	[RequireComponent(typeof(Animator))]
	[RequireComponent(typeof(CapsuleCollider))]
	[RequireComponent(typeof(Rigidbody))]

	public class UnityChanControlScriptWithRgidBody : MonoBehaviour
	{

		public float animSpeed = 1.5f;				// アニメーション再生速度設定
		public float lookSmoother = 3.0f;			// a smoothing setting for camera motion
		public bool useCurves = true;				// Mecanimでカーブ調整を使うか設定する
		// このスイッチが入っていないとカーブは使われない
		public float useCurvesHeight = 0.5f;		// カーブ補正の有効高さ(地面をすり抜けやすい時には大きくする)

		// 以下キャラクターコントローラ用パラメタ
		// 前進速度
		public float forwardSpeed = 7.0f;
		// 後退速度
		public float backwardSpeed = 2.0f;
		// 旋回速度
		public float rotateSpeed = 2.0f;
		// ジャンプ威力
		public float jumpPower = 3.0f; 
		// キャラクターコントローラ(カプセルコライダ)の参照
		private CapsuleCollider col;
		private Rigidbody rb;
		// キャラクターコントローラ(カプセルコライダ)の移動量
		private Vector3 velocity;
		// CapsuleColliderで設定されているコライダのHeiht、Centerの初期値を収める変数
		private float orgColHight;
		private Vector3 orgVectColCenter;
		private Animator anim;							// キャラにアタッチされるアニメーターへの参照
		private AnimatorStateInfo currentBaseState;			// base layerで使われる、アニメーターの現在の状態の参照

		private GameObject cameraObject;	// メインカメラへの参照
		
		// アニメーター各ステートへの参照
		static int idleState = Animator.StringToHash ("Base Layer.Idle");
		static int locoState = Animator.StringToHash ("Base Layer.Locomotion");
		static int jumpState = Animator.StringToHash ("Base Layer.Jump");
		static int restState = Animator.StringToHash ("Base Layer.Rest");

		// 初期化
		void Start ()
		{
			// Animatorコンポーネントを取得する
			anim = GetComponent<Animator> ();
			// CapsuleColliderコンポーネントを取得する(カプセル型コリジョン)
			col = GetComponent<CapsuleCollider> ();
			rb = GetComponent<Rigidbody> ();
			//メインカメラを取得する
			cameraObject = GameObject.FindWithTag ("MainCamera");
			// CapsuleColliderコンポーネントのHeight、Centerの初期値を保存する
			orgColHight = col.height;
			orgVectColCenter = col.center;
		}
	
	
		// 以下、メイン処理.リジッドボディと絡めるので、FixedUpdate内で処理を行う.
		void FixedUpdate ()
		{
			float h = Input.GetAxis ("Horizontal");				// 入力デバイスの水平軸をhで定義
			float v = Input.GetAxis ("Vertical");				// 入力デバイスの垂直軸をvで定義
			anim.SetFloat ("Speed", v);							// Animator側で設定している"Speed"パラメタにvを渡す
			anim.SetFloat ("Direction", h); 						// Animator側で設定している"Direction"パラメタにhを渡す
			anim.speed = animSpeed;								// Animatorのモーション再生速度に animSpeedを設定する
			currentBaseState = anim.GetCurrentAnimatorStateInfo (0);	// 参照用のステート変数にBase Layer (0)の現在のステートを設定する
			rb.useGravity = true;//ジャンプ中に重力を切るので、それ以外は重力の影響を受けるようにする
		
		
		
			// 以下、キャラクターの移動処理
			velocity = new Vector3 (0, 0, v);		// 上下のキー入力からZ軸方向の移動量を取得
			// キャラクターのローカル空間での方向に変換
			velocity = transform.TransformDirection (velocity);
			//以下のvの閾値は、Mecanim側のトランジションと一緒に調整する
			if (v > 0.1) {
				velocity *= forwardSpeed;		// 移動速度を掛ける
			} else if (v < -0.1) {
				velocity *= backwardSpeed;	// 移動速度を掛ける
			}
		
			if (Input.GetButtonDown ("Jump")) {	// スペースキーを入力したら

				//アニメーションのステートがLocomotionの最中のみジャンプできる
				if (currentBaseState.nameHash == locoState) {
					//ステート遷移中でなかったらジャンプできる
					if (!anim.IsInTransition (0)) {
						rb.AddForce (Vector3.up * jumpPower, ForceMode.VelocityChange);
						anim.SetBool ("Jump", true);		// Animatorにジャンプに切り替えるフラグを送る
					}
				}
			}
		

			// 上下のキー入力でキャラクターを移動させる
			transform.localPosition += velocity * Time.fixedDeltaTime;

			// 左右のキー入力でキャラクタをY軸で旋回させる
			transform.Rotate (0, h * rotateSpeed, 0);	
	

			// 以下、Animatorの各ステート中での処理
			// Locomotion中
			// 現在のベースレイヤーがlocoStateの時
			if (currentBaseState.nameHash == locoState) {
				//カーブでコライダ調整をしている時は、念のためにリセットする
				if (useCurves) {
					resetCollider ();
				}
			}
		// JUMP中の処理
		// 現在のベースレイヤーがjumpStateの時
		else if (currentBaseState.nameHash == jumpState) {
				cameraObject.SendMessage ("setCameraPositionJumpView");	// ジャンプ中のカメラに変更
				// ステートがトランジション中でない場合
				if (!anim.IsInTransition (0)) {
				
					// 以下、カーブ調整をする場合の処理
					if (useCurves) {
						// 以下JUMP00アニメーションについているカーブJumpHeightとGravityControl
						// JumpHeight:JUMP00でのジャンプの高さ(0〜1)
						// GravityControl:1⇒ジャンプ中(重力無効)、0⇒重力有効
						float jumpHeight = anim.GetFloat ("JumpHeight");
						float gravityControl = anim.GetFloat ("GravityControl"); 
						if (gravityControl > 0)
							rb.useGravity = false;	//ジャンプ中の重力の影響を切る
										
						// レイキャストをキャラクターのセンターから落とす
						Ray ray = new Ray (transform.position + Vector3.up, -Vector3.up);
						RaycastHit hitInfo = new RaycastHit ();
						// 高さが useCurvesHeight 以上ある時のみ、コライダーの高さと中心をJUMP00アニメーションについているカーブで調整する
						if (Physics.Raycast (ray, out hitInfo)) {
							if (hitInfo.distance > useCurvesHeight) {
								col.height = orgColHight - jumpHeight;			// 調整されたコライダーの高さ
								float adjCenterY = orgVectColCenter.y + jumpHeight;
								col.center = new Vector3 (0, adjCenterY, 0);	// 調整されたコライダーのセンター
							} else {
								// 閾値よりも低い時には初期値に戻す(念のため)					
								resetCollider ();
							}
						}
					}
					// Jump bool値をリセットする(ループしないようにする)				
					anim.SetBool ("Jump", false);
				}
			}
		// IDLE中の処理
		// 現在のベースレイヤーがidleStateの時
		else if (currentBaseState.nameHash == idleState) {
				//カーブでコライダ調整をしている時は、念のためにリセットする
				if (useCurves) {
					resetCollider ();
				}
				// スペースキーを入力したらRest状態になる
				if (Input.GetButtonDown ("Jump")) {
					anim.SetBool ("Rest", true);
				}
			}
		// REST中の処理
		// 現在のベースレイヤーがrestStateの時
		else if (currentBaseState.nameHash == restState) {
				//cameraObject.SendMessage("setCameraPositionFrontView");		// カメラを正面に切り替える
				// ステートが遷移中でない場合、Rest bool値をリセットする(ループしないようにする)
				if (!anim.IsInTransition (0)) {
					anim.SetBool ("Rest", false);
				}
			}
		}

		void OnGUI ()
		{
			GUI.Box (new Rect (Screen.width - 260, 10, 250, 150), "Interaction");
			GUI.Label (new Rect (Screen.width - 245, 30, 250, 30), "Up/Down Arrow : Go Forwald/Go Back");
			GUI.Label (new Rect (Screen.width - 245, 50, 250, 30), "Left/Right Arrow : Turn Left/Turn Right");
			GUI.Label (new Rect (Screen.width - 245, 70, 250, 30), "Hit Space key while Running : Jump");
			GUI.Label (new Rect (Screen.width - 245, 90, 250, 30), "Hit Spase key while Stopping : Rest");
			GUI.Label (new Rect (Screen.width - 245, 110, 250, 30), "Left Control : Front Camera");
			GUI.Label (new Rect (Screen.width - 245, 130, 250, 30), "Alt : LookAt Camera");
		}


		// キャラクターのコライダーサイズのリセット関数
		void resetCollider ()
		{
			// コンポーネントのHeight、Centerの初期値を戻す
			col.height = orgColHight;
			col.center = orgVectColCenter;
		}
	}
}

そのまま貼り付けただけです。

すごくわかりやすいので(笑)コレをベースに調整を加えてみたいと思います。

一点だけ、フレーム単位でのアップデートではなく、一定時間単位のアップデートである、FixedUpdate にメイン処理が書かれている点が気になりました。

普通のUpdate だと環境によってフレームレートが変わってくるので、安定した挙動を求める場合にはこちらを使うようにするのかなぁ。(ちなみにこのプログラムをUpdateに切り替えると一定時間毎のフレーム数が増えるためか、むっちゃキビキビ動くようになります(笑))

前後左右に同じ速度で移動するように

			// 以下、キャラクターの移動処理
//			velocity = new Vector3 (0, 0, v);       // 上下のキー入力からZ軸方向の移動量を取得
			velocity = new Vector3 (h, 0, v);        // 上下のキー入力からZ軸とX軸方向の移動量を取得

			// キャラクターのローカル空間での方向に変換
//			velocity = transform.TransformDirection (velocity);
			//以下のvの閾値は、Mecanim側のトランジションと一緒に調整する
//			if (v > 0.1) {
//				velocity *= forwardSpeed;		// 移動速度を掛ける
//			} else if (v < -0.1) {
//				velocity *= backwardSpeed;	// 移動速度を掛ける
//			}

			velocity *= forwardSpeed;


			if (Input.GetButtonDown ("Jump")) {	// スペースキーを入力したら

				//アニメーションのステートがLocomotionの最中のみジャンプできる
				if (currentBaseState.nameHash == locoState) {
					//ステート遷移中でなかったらジャンプできる
					if (!anim.IsInTransition (0)) {
						rb.AddForce (Vector3.up * jumpPower, ForceMode.VelocityChange);
						anim.SetBool ("Jump", true);		// Animatorにジャンプに切り替えるフラグを送る
					}
				}
			}
		

			// 上下のキー入力でキャラクターを移動させる
			transform.localPosition += velocity * Time.fixedDeltaTime;

			// 左右のキー入力でキャラクタをY軸で旋回させる
//			transform.Rotate (0, h * rotateSpeed, 0);		

部分的に調整し、キャラの向きは固定ですが(笑)、どの方向にも同じ速度で移動するようになります。

進行方向にキャラクターを向ける

		static int jumpState = Animator.StringToHash ("Base Layer.Jump");
		static int restState = Animator.StringToHash ("Base Layer.Rest");

		private Vector3 playerPosition; //プレイヤーの位置情報を格納する

		// 初期化
		void Start ()
		{
			// Animatorコンポーネントを取得する
			anim = GetComponent<Animator> ();
			// CapsuleColliderコンポーネントを取得する(カプセル型コリジョン)
			col = GetComponent<CapsuleCollider> ();
			rb = GetComponent<Rigidbody> ();
			//メインカメラを取得する
			cameraObject = GameObject.FindWithTag ("MainCamera");
			// CapsuleColliderコンポーネントのHeight、Centerの初期値を保存する
			orgColHight = col.height;
			orgVectColCenter = col.center;

			//初期状態のプレイヤー位置情報を格納
			playerPosition = GetComponent<Transform>().position;
		}

初期化時にプレイヤー位置情報を取得して

			// 上下のキー入力でキャラクターを移動させる
			transform.localPosition += velocity * Time.fixedDeltaTime;

			// 左右のキー入力でキャラクタをY軸で旋回させる
			//			transform.Rotate (0, h * rotateSpeed, 0);	

			//移動後のキャラクターが前回からどの方向に進んだか差分を取得する
			Vector3 diff = transform.position - playerPosition;

			if (diff.magnitude > 0.01f) 
			{
				//差異があった場合にのみ向きを変更する
				transform.rotation = Quaternion.LookRotation(diff);
			}

			playerPosition = transform.position; //プレイヤー位置情報を更新

			// 以下、Animatorの各ステート中での処理
			// Locomotion中
			// 現在のベースレイヤーがlocoStateの時
			if (currentBaseState.nameHash == locoState) {
				//カーブでコライダ調整をしている時は、念のためにリセットする
				if (useCurves) {
					resetCollider ();
				}
			}

キャラの移動後に向きを調整するロジックを加えてあげるとOK。

アニメーションは変ですが(笑)、ひとまず進行方向にキャラが向いて、かつどの方向にも同じ速度移動するようになりました。

アニメーションの調整

アニメーションはこちらのUnityChanLocomotions アニメーションコントローラーで処理されていました。

IdleからSpeedなどを閾値を設定し各アニメーションに遷移していきます。

Locomotionのサブアニメーション内でも速度に合わせてWalksとRunsに分岐し、さらに方向にあわせて左右の各モーションに分岐しています。

ということはidelからLocomotionへキャラがどんな方向にでも移動すれば遷移するようにしてあげれば良さそうですね。

今の設定が、Speedが0.1以上の場合に遷移なので前進中にのみこの中に突入します。
(反対にWalkBackにはSpeedが-0.1以下の場合に突入するようになっています。)

キャラの水平方向への入力値も拾って、Directionとして進む方向にあわせたアニメーションの分岐パラメーターに利用しています。

アニメーターに渡すパラメーターを調整

スクリプト部で、

		// 以下、メイン処理.リジッドボディと絡めるので、FixedUpdate内で処理を行う.
		void FixedUpdate ()
		{
			float h = Input.GetAxis ("Horizontal");				// 入力デバイスの水平軸をhで定義
			float v = Input.GetAxis ("Vertical");				// 入力デバイスの垂直軸をvで定義
//			anim.SetFloat ("Speed", v);							// Animator側で設定している"Speed"パラメタにvを渡す
//			anim.SetFloat ("Direction", h);                         // Animator側で設定している"Direction"パラメタにhを渡す

			//入力値を移動量とするため、マイナス値の場合のみプラスに補正
			float move_h = h;
			if( move_h < 0 )
			{
				move_h = move_h * -1;
			}

			float move_v = v;
			if (move_v < 0)
			{
				move_v = move_v * -1;
			}
			anim.SetFloat("Speed", move_h + move_v );           // Animator側で設定している"Speed"パラメタに移動量を渡す

			anim.speed = animSpeed;								// Animatorのモーション再生速度に animSpeedを設定する
			currentBaseState = anim.GetCurrentAnimatorStateInfo (0);	// 参照用のステート変数にBase Layer (0)の現在のステートを設定する
			rb.useGravity = true;//ジャンプ中に重力を切るので、それ以外は重力の影響を受けるようにする

Animator側にSpeedとDirectionを渡している箇所をこのように修正するだけ。

どんな方向に対してもプラスの移動量として、Speedだけ渡すイメージです。

すると……

出来ました♪

不要なアニメーション設定の削除

ですが、このままだとアニメーターに使われないアニメーションが残ったままになりますので、不要箇所を削除してあげた方がスッキリするかもしれません。

こんな感じになりますかね。

Directionパラメーターも不要なので削除してもいいかも。

このあたりはお好みで。

発見される不具合

ジャンプキー(スペースキー)を押した際にアニメーションもしくはキャラの向きがおかしくなるみたい。

なんでだろと原因を探していると、

col.height = orgColHight - jumpHeight;			// 調整されたコライダーの高さ
float adjCenterY = orgVectColCenter.y + jumpHeight;
col.center = new Vector3 (0, adjCenterY, 0);	// 調整されたコライダーのセンター

このコライダーをいじっている箇所でこのような感じになっていました。

レイキャストで地面からの高さを判別して、キャラクターのコライダーをイジっているっぽいので、段にジャンプで飛び乗れるようにしている処理なんだろうか……今ひとつ理解は追いついてないですが、これをコメントアウトするとこの表示不具合が治るということはわかりました。

あと、

rb.AddForce (Vector3.up * jumpPower, ForceMode.VelocityChange);

この箇所でリグボディーオブジェクトを若干上方に移動させているのですが、これもコメントアウトしたほうがアニメーションのカクつきが減ってきれいになりました。なにかしら理由があってはいっていのだと思いますが、今はここも理解が及びませんでした^^

nameHashは古いらしい

何箇所か出てくる、currentBaseState.nameHashは古いそうでワーニングが出ていました。

currentBaseState.fullPathHash

に置き換えるといいみたい。

Substateの扱いがかわるみたいなんですが、今回のコードだとSubstateを使っていないので単純に置換だけでOKです。

改変後のソースコード

最終的に諸々を変更した、UnityChanControlScriptWithRgidBodyの改変後ソースコードも載せておきます。

今回の変更でコライダーをいじらなくなったのでリセット処理なんかも不要そうだったりと、突き詰めていけばもっとスッキリかけそうです。

//
// Mecanimのアニメーションデータが、原点で移動しない場合の Rigidbody付きコントローラ
// サンプル
// 2014/03/13 N.Kobyasahi
//
using UnityEngine;
using System.Collections;

namespace UnityChan
{
// 必要なコンポーネントの列記
	[RequireComponent(typeof(Animator))]
	[RequireComponent(typeof(CapsuleCollider))]
	[RequireComponent(typeof(Rigidbody))]

	public class UnityChanControlScriptWithRgidBody : MonoBehaviour
	{

		public float animSpeed = 1.5f;				// アニメーション再生速度設定
		public float lookSmoother = 3.0f;			// a smoothing setting for camera motion
		public bool useCurves = true;				// Mecanimでカーブ調整を使うか設定する
		// このスイッチが入っていないとカーブは使われない
		public float useCurvesHeight = 0.5f;		// カーブ補正の有効高さ(地面をすり抜けやすい時には大きくする)

		// 以下キャラクターコントローラ用パラメタ
		// 前進速度
		public float forwardSpeed = 7.0f;
		// 後退速度
		public float backwardSpeed = 2.0f;
		// 旋回速度
		public float rotateSpeed = 2.0f;
		// ジャンプ威力
		public float jumpPower = 3.0f; 
		// キャラクターコントローラ(カプセルコライダ)の参照
		private CapsuleCollider col;
		private Rigidbody rb;
		// キャラクターコントローラ(カプセルコライダ)の移動量
		private Vector3 velocity;
		// CapsuleColliderで設定されているコライダのHeiht、Centerの初期値を収める変数
		private float orgColHight;
		private Vector3 orgVectColCenter;
		private Animator anim;							// キャラにアタッチされるアニメーターへの参照
		private AnimatorStateInfo currentBaseState;			// base layerで使われる、アニメーターの現在の状態の参照

		private GameObject cameraObject;	// メインカメラへの参照
		
		// アニメーター各ステートへの参照
		static int idleState = Animator.StringToHash ("Base Layer.Idle");
		static int locoState = Animator.StringToHash ("Base Layer.Locomotion");
		static int jumpState = Animator.StringToHash ("Base Layer.Jump");
		static int restState = Animator.StringToHash ("Base Layer.Rest");

		private Vector3 playerPosition; //プレイヤーの位置情報を格納する

		// 初期化
		void Start ()
		{
			// Animatorコンポーネントを取得する
			anim = GetComponent<Animator> ();
			// CapsuleColliderコンポーネントを取得する(カプセル型コリジョン)
			col = GetComponent<CapsuleCollider> ();
			rb = GetComponent<Rigidbody> ();
			//メインカメラを取得する
			cameraObject = GameObject.FindWithTag ("MainCamera");
			// CapsuleColliderコンポーネントのHeight、Centerの初期値を保存する
			orgColHight = col.height;
			orgVectColCenter = col.center;

			//初期状態のプレイヤー位置情報を格納
			playerPosition = GetComponent<Transform>().position;
		}
	
	
		// 以下、メイン処理.リジッドボディと絡めるので、FixedUpdate内で処理を行う.
		void FixedUpdate ()
		{
			float h = Input.GetAxis ("Horizontal");				// 入力デバイスの水平軸をhで定義
			float v = Input.GetAxis ("Vertical");				// 入力デバイスの垂直軸をvで定義
//			anim.SetFloat ("Speed", v);							// Animator側で設定している"Speed"パラメタにvを渡す
//			anim.SetFloat ("Direction", h);                         // Animator側で設定している"Direction"パラメタにhを渡す

			//入力値を移動量とするため、マイナス値の場合のみプラスに補正
			float move_h = h;
			if( move_h < 0 )
			{
				move_h = move_h * -1;
			}

			float move_v = v;
			if (move_v < 0)
			{
				move_v = move_v * -1;
			}
			anim.SetFloat("Speed", move_h + move_v );           // Animator側で設定している"Speed"パラメタに移動量を渡す

			anim.speed = animSpeed;								// Animatorのモーション再生速度に animSpeedを設定する
			currentBaseState = anim.GetCurrentAnimatorStateInfo (0);	// 参照用のステート変数にBase Layer (0)の現在のステートを設定する
			rb.useGravity = true;//ジャンプ中に重力を切るので、それ以外は重力の影響を受けるようにする
		
		
		
			// 以下、キャラクターの移動処理
//			velocity = new Vector3 (0, 0, v);       // 上下のキー入力からZ軸方向の移動量を取得
			velocity = new Vector3 (h, 0, v);        // 上下のキー入力からZ軸とX軸方向の移動量を取得

			// キャラクターのローカル空間での方向に変換
//			velocity = transform.TransformDirection (velocity);
			//以下のvの閾値は、Mecanim側のトランジションと一緒に調整する
//			if (v > 0.1) {
//				velocity *= forwardSpeed;		// 移動速度を掛ける
//			} else if (v < -0.1) {
//				velocity *= backwardSpeed;	// 移動速度を掛ける
//			}

			velocity *= forwardSpeed;


			if (Input.GetButtonDown ("Jump")) {	// スペースキーを入力したら

				//アニメーションのステートがLocomotionの最中のみジャンプできる
				if (currentBaseState.fullPathHash == locoState) {
					//ステート遷移中でなかったらジャンプできる
					if (!anim.IsInTransition (0)) {
//						rb.AddForce (Vector3.up * jumpPower, ForceMode.VelocityChange);
						anim.SetBool ("Jump", true);		// Animatorにジャンプに切り替えるフラグを送る
					}
				}
			}
		

			// 上下のキー入力でキャラクターを移動させる
			transform.localPosition += velocity * Time.fixedDeltaTime;

			// 左右のキー入力でキャラクタをY軸で旋回させる
			//			transform.Rotate (0, h * rotateSpeed, 0);	

			//移動後のキャラクターが前回からどの方向に進んだか差分を取得する
			Vector3 diff = transform.position - playerPosition;

			if (diff.magnitude > 0.01f) 
			{
				//差異があった場合にのみ向きを変更する
				transform.rotation = Quaternion.LookRotation(diff);
			}

			playerPosition = transform.position; //プレイヤー位置情報を更新


			// 以下、Animatorの各ステート中での処理
			// Locomotion中
			// 現在のベースレイヤーがlocoStateの時
			if (currentBaseState.fullPathHash == locoState) {
				//カーブでコライダ調整をしている時は、念のためにリセットする
				if (useCurves) {
					resetCollider ();
				}
			}
		// JUMP中の処理
		// 現在のベースレイヤーがjumpStateの時
		else if (currentBaseState.fullPathHash == jumpState) {
				cameraObject.SendMessage ("setCameraPositionJumpView");	// ジャンプ中のカメラに変更
				// ステートがトランジション中でない場合
				if (!anim.IsInTransition (0)) {
				
					// 以下、カーブ調整をする場合の処理
					if (useCurves) {
						// 以下JUMP00アニメーションについているカーブJumpHeightとGravityControl
						// JumpHeight:JUMP00でのジャンプの高さ(0〜1)
						// GravityControl:1⇒ジャンプ中(重力無効)、0⇒重力有効
						float jumpHeight = anim.GetFloat ("JumpHeight");
						float gravityControl = anim.GetFloat ("GravityControl"); 
						if (gravityControl > 0)
							rb.useGravity = false;	//ジャンプ中の重力の影響を切る
										
						// レイキャストをキャラクターのセンターから落とす
						Ray ray = new Ray (transform.position + Vector3.up, -Vector3.up);
						RaycastHit hitInfo = new RaycastHit ();
						// 高さが useCurvesHeight 以上ある時のみ、コライダーの高さと中心をJUMP00アニメーションについているカーブで調整する
						if (Physics.Raycast (ray, out hitInfo)) {
							if (hitInfo.distance > useCurvesHeight) {
//								col.height = orgColHight - jumpHeight;			// 調整されたコライダーの高さ
//								float adjCenterY = orgVectColCenter.y + jumpHeight;
//								col.center = new Vector3 (0, adjCenterY, 0);	// 調整されたコライダーのセンター
							} else {
								// 閾値よりも低い時には初期値に戻す(念のため)					
								resetCollider ();
							}
						}
					}
					// Jump bool値をリセットする(ループしないようにする)				
					anim.SetBool ("Jump", false);
				}
			}
		// IDLE中の処理
		// 現在のベースレイヤーがidleStateの時
		else if (currentBaseState.fullPathHash == idleState) {
				//カーブでコライダ調整をしている時は、念のためにリセットする
				if (useCurves) {
					resetCollider ();
				}
				// スペースキーを入力したらRest状態になる
				if (Input.GetButtonDown ("Jump")) {
					anim.SetBool ("Rest", true);
				}
			}
		// REST中の処理
		// 現在のベースレイヤーがrestStateの時
		else if (currentBaseState.fullPathHash == restState) {
				//cameraObject.SendMessage("setCameraPositionFrontView");		// カメラを正面に切り替える
				// ステートが遷移中でない場合、Rest bool値をリセットする(ループしないようにする)
				if (!anim.IsInTransition (0)) {
					anim.SetBool ("Rest", false);
				}
			}
		}

		void OnGUI ()
		{
			GUI.Box (new Rect (Screen.width - 260, 10, 250, 150), "Interaction");
			GUI.Label (new Rect (Screen.width - 245, 30, 250, 30), "Up/Down Arrow : Go Forwald/Go Back");
			GUI.Label (new Rect (Screen.width - 245, 50, 250, 30), "Left/Right Arrow : Turn Left/Turn Right");
			GUI.Label (new Rect (Screen.width - 245, 70, 250, 30), "Hit Space key while Running : Jump");
			GUI.Label (new Rect (Screen.width - 245, 90, 250, 30), "Hit Spase key while Stopping : Rest");
			GUI.Label (new Rect (Screen.width - 245, 110, 250, 30), "Left Control : Front Camera");
			GUI.Label (new Rect (Screen.width - 245, 130, 250, 30), "Alt : LookAt Camera");
		}


		// キャラクターのコライダーサイズのリセット関数
		void resetCollider ()
		{
			// コンポーネントのHeight、Centerの初期値を戻す
			col.height = orgColHight;
			col.center = orgVectColCenter;
		}
	}
}

ここまででキャラクターの移動とアニメーションとの関係性の理解が大きく進みました。

次は、新しいモーションをアセットストアから取り込んでみたいです。

この記事はユニティちゃんライセンス条項の元に提供されています。
© Unity Technologies Japan/UCL