はじめに
移動の速度をアニメションに合わせる時、よく使われるのはroot motion。
言わば、アニメションの移動量を実際の移動量にする方法。
設定はまず
そして3Dモデルのセッティングのところでroot nodeを指定、そこはモデルデータ自体原点になるジョイントが必要。
指定した後、animationsタッグの方はこうなる:
ここで”XZ方向だけ合わせるか、回転を合わせないか”など設定できる。
(PS: この方法ではY方向の移動がうまくできない、もし誰が分かれば教えていただけると助かる)
物理(RigidBody)と併用する時
root motionを使うとRigidBody、物理の部分は変になっちゃう。いろいろ検索したけど、徹底的な解決方法が見つけなくて、自分で適当に弄って方法を発見した。それはスクリプトを使うこと。
root motionの移動はスクリプトに通じても可能、以下のように:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveControl : MonoBehaviour
{
void OnAnimatorMove()
{
transform.position = GetComponent<Animator>().rootPosition;
}
}
ナビナビゲーション(Navigation)と併用する時
root motionを使うと自分で前を進めるので、向きだけ変えればいい。なので、ナビナビゲーションの次に位置を分かれば、その位置に向かえば完成。
以下の例は左クリックの位置を目的地に設定する:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveControl : MonoBehaviour
{
private UnityEngine.AI.NavMeshAgent agent;
private void Awake()
{
//まず自動の移動をキャンセルする
agent = GetComponent<UnityEngine.AI.NavMeshAgent>();
agent.updatePosition = false;
agent.updateRotation = false;
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
Ray camRay = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(camRay, out hit, Mathf.Infinity))
{
//エージェントの目的地を設定
agent.destination = hit.point;
}
}
//向きをエージェントの次の位置に向かう
transform.LookAt(agent.steeringTarget);
//エージェントの現在の位置を更新
agent.nextPosition = transform.position;
}
void OnAnimatorMove()
{
transform.position = GetComponent<Animator>().rootPosition;
}
}