キャラクターコントローラーで動かす一人称視点のプレイヤーをアニメーションで動かしてみます。直接Animaorコンポーネントをつけると問題があったので、アニメーションを付けた別のゲームオブジェクトに乗せて動かします。
まず乗り物になる空のゲームオブジェクトを作って、アニメーションウィンドウのCreateからアニメーターコンポーネントとアニメーターコントローラーを作ります。
アニメーションをつけるときは、FPSコントローラーを空のオブジェクトの子にして、両方とも位置と回転を0にしました。
FPSコントローラーが床の上に立っている状態にするために、乗り物のY座標を動かしています。この状態でシーンビューやゲームビューを確認しながらアニメーションが付けられす。普段は親子関係を解除しておきます。
アニメーションを付けたら、アニメーターコントローラーのEntryからまずアニメーションのないステートへ遷移するようにして、そこから今作ったアニメーションが付いたステートへ遷移して戻ってくるようにします。
トリガーパラメーターを作って、オレンジのデフォルトのステートから遷移する矢印のインスペクタでは、Has Exit Timeのチェックを切り、Transition Durationを0にして、Conditionsにトリガーパラメーターを設定します。
これでトリガーがセットされたときに遷移します。
戻るときは、Has Exit Timeのチェックを入れて、Fixed Durationのチェックを外し、Exit Timeを1、Transition Durationを0にします。Conditionsは空にします。これでモーションが一回再生されると遷移します。
スクリプト
FPSコントローラーのスクリプトでアニメーションを再生します。
// FirstPersonController
[SerializeField] Transform vehicle;
Animator vehicleAnimator;
VehicleStateMachine sm_vehicle;
// ---
// Start()
vehicleAnimator = vehicle.GetComponent<Animator>();
sm_vehicle = vehicleAnimator.GetBehaviour<VehicleStateMachine>();
sm_vehicle.sc_fps = this;
// ---
public void StopMotion()
{
m_CharacterController.enabled = true; // キャラクターコントローラーをオン
Quaternion rot = transform.rotation; // 今の回転値を保存
transform.parent = null; // 親子関係を解除
m_MouseLook.SetQuaternion(rot); // 回転値を設定
}
// ---
// Update()
if (Input.GetKeyDown(KeyCode.R))
{
m_CharacterController.enabled = false; // キャラクターコントローラーをオフ
vehicle.position = transform.position; // 位置を合わせる
vehicle.rotation = transform.rotation; // 回転を合わせる
transform.parent = vehicle; // プレイヤーを乗り物の子にする
m_MouseLook.ResetCharacterRot(); // 回転をリセット
vehicleAnimator.SetTrigger("Trigger"); // トリガーをセット
}
キー入力があるとキャラクターコントローラーをオフにして、乗り物のゲームオブジェクトの位置と回転をプレイヤーに合わせます。そして、プレイヤーその子オブジェクトにして、MouseLookの回転をリセットしてからトリガーをセットします。
回転をリセットしないと子オブジェクトにしたときにプレイヤーの向きが変わってしまいます。
トリガーがセットされるとアニメーションが始まります。アニメーションが終わってそのステートを出ると、空のオブジェクトのアニメーターコントローラーに付けたステートマシンビヘイビアから、元に戻すためのメソッドを呼びます。
// ステートマシンビヘイビア
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class VehicleStateMachine : StateMachineBehaviour
{
public UnityStandardAssets.Characters.FirstPerson.FirstPersonController1 sc_fps;
// OnStateEnter is called before OnStateEnter is called on any state inside this state machine
//override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
//{
//
//}
// OnStateUpdate is called before OnStateUpdate is called on any state inside this state machine
//override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
//{
//
//}
// OnStateExit is called before OnStateExit is called on any state inside this state machine
override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
if (stateInfo.IsName("State1"))
{
sc_fps.StopMotion();
}
}
// OnStateMove is called before OnStateMove is called on any state inside this state machine
//override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
//{
//
//}
// OnStateIK is called before OnStateIK is called on any state inside this state machine
//override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
//{
//
//}
// OnStateMachineEnter is called when entering a state machine via its Entry Node
//override public void OnStateMachineEnter(Animator animator, int stateMachinePathHash)
//{
//
//}
// OnStateMachineExit is called when exiting a state machine via its Exit Node
//override public void OnStateMachineExit(Animator animator, int stateMachinePathHash)
//{
//
//}
}
プレイヤーのスクリプトのStart()で、ステートマシンビヘイビアに自分自身を渡しています。
// FirstPersonController
[SerializeField] Transform vehicle;
Animator vehicleAnimator;
VehicleStateMachine sm_vehicle;
// ---
// Start()
vehicleAnimator = vehicle.GetComponent<Animator>();
sm_vehicle = vehicleAnimator.GetBehaviour<VehicleStateMachine>();
sm_vehicle.sc_fps = this;
このメソッドでは、キャラクターコントローラーをオンにして、親子関係を解除し、プレイヤーの回転値を設定します。
public void StopMotion()
{
m_CharacterController.enabled = true; // キャラクターコントローラーをオン
Quaternion rot = transform.rotation; // 今の回転値を保存
transform.parent = null; // 親子関係を解除
m_MouseLook.SetQuaternion(rot); // 回転値を設定
}
回転値を設定しないと0に戻ってしまいます。
そして、MouseLookクラスに上の2つのメソッドを定義します。
// MouseLook
Vector3 vector3Zero;
// 体の回転値を設定
public void SetQuaternion(Quaternion q)
{
vector3Zero.y = q.eulerAngles.y;
m_CharacterTargetRot = Quaternion.Euler(vector3Zero);
vector3Zero.y = 0f; // 0に戻す
}
// 体の回転値をリセット
public void ResetCharacterRot()
{
m_CharacterTargetRot = Quaternion.Euler(vector3Zero);
}
毎回 new Vector3()を使うと重くなるそうなので、変数に入れて使いまわしています。参考:http://tsubakit1.hateblo.jp/entry/2016/06/20/222612
これでFPSキャラクターのアニメーションができました。