尋路和動畫融合

1.融合動畫和使用動畫的位移。同步尋路代理和角色的位置。
2.ik頭部旋轉。
3.鼠標點擊移動到對應位置。
using UnityEngine;
[RequireComponent (typeof (NavMeshAgent))]
[RequireComponent (typeof (Animator))]
public class LocomotionSimpleAgent : MonoBehaviour {
       Animator anim;
       NavMeshAgent agent;
       Vector2 smoothDeltaPosition = Vector2.zero;
       Vector2 velocity = Vector2.zero;
       void Start () {
              anim = GetComponent<Animator> ();
              agent = GetComponent<NavMeshAgent> ();
              agent.updatePosition = false;
       }
       
       void Update () {
              Vector3 worldDeltaPosition = agent.nextPosition - transform.position;
              // Map 'worldDeltaPosition' to local space
              float dx = Vector3.Dot (transform.right, worldDeltaPosition);
              float dy = Vector3.Dot (transform.forward, worldDeltaPosition);
              Vector2 deltaPosition = new Vector2 (dx, dy);
              // Low-pass filter the deltaMove
              float smooth = Mathf.Min(1.0f, Time.deltaTime/0.15f);
              smoothDeltaPosition = Vector2.Lerp (smoothDeltaPosition, deltaPosition, smooth);
              // Update velocity if delta time is safe
              if (Time.deltaTime > 1e-5f)
                     velocity = smoothDeltaPosition / Time.deltaTime;
              bool shouldMove = velocity.magnitude > 0.5f && agent.remainingDistance > agent.radius;
              // Update animation parameters
              anim.SetBool("move", shouldMove);
              anim.SetFloat ("velx", velocity.x);
              anim.SetFloat ("vely", velocity.y);
              LookAt lookAt = GetComponent<LookAt> ();
              if (lookAt)
                     lookAt.lookAtTargetPosition = agent.steeringTarget + transform.forward;
//            // Pull character towards agent
//            if (worldDeltaPosition.magnitude > agent.radius)
//                   transform.position = agent.nextPosition - 0.9f*worldDeltaPosition;
//            // Pull agent towards character
//            if (worldDeltaPosition.magnitude > agent.radius)
//                   agent.nextPosition = transform.position + 0.9f*worldDeltaPosition;
       }
       void OnAnimatorMove () {
              // Update postion to agent position
//            transform.position = agent.nextPosition;
              // Update position based on animation movement using navigation surface height
              Vector3 position = anim.rootPosition;
              position.y = agent.nextPosition.y;
              transform.position = position;
       }
}

// LookAt.cs
using UnityEngine;
using System.Collections;
[RequireComponent (typeof (Animator))]
public class LookAt : MonoBehaviour {
       public Transform head = null;
       public Vector3 lookAtTargetPosition;
       public float lookAtCoolTime = 0.2f;
       public float lookAtHeatTime = 0.2f;
       public bool looking = true;
    public Transform m_lookAtTargetPosition;
    public Transform m_lookAtPosition;
       private Vector3 lookAtPosition;
       private Animator anim;
       private float lookAtWeight = 0.0f;
       void Start ()
       {
              if (!head)
              {
                     Debug.LogError("No head transform - LookAt disabled");
                     enabled = false;
                     return;
              }
              anim = GetComponent<Animator> ();
              lookAtTargetPosition = head.position + transform.forward;
              lookAtPosition = lookAtTargetPosition;
       }
    private void SetLookAtPosition() {
        if (m_lookAtTargetPosition != null) {
            m_lookAtTargetPosition.position = lookAtTargetPosition;
        }
        if (m_lookAtPosition != null) {
            m_lookAtPosition.position = lookAtPosition;
        }
    }
       void OnAnimatorIK ()
       {
              lookAtTargetPosition.y = head.position.y;
              float lookAtTargetWeight = looking ? 1.0f : 0.0f;
              Vector3 curDir = lookAtPosition - head.position;
              Vector3 futDir = lookAtTargetPosition - head.position;
              curDir = Vector3.RotateTowards(curDir, futDir, 6.28f*Time.deltaTime, float.PositiveInfinity);
              lookAtPosition = head.position + curDir;
        SetLookAtPosition();
        float blendTime = lookAtTargetWeight > lookAtWeight ? lookAtHeatTime : lookAtCoolTime;
              lookAtWeight = Mathf.MoveTowards (lookAtWeight, lookAtTargetWeight, Time.deltaTime/blendTime);
              anim.SetLookAtWeight (lookAtWeight, 0.2f, 0.5f, 0.7f, 0.5f);
              anim.SetLookAtPosition (lookAtPosition);
       }
}


// ClickToMove.cs
using UnityEngine;
[RequireComponent (typeof (NavMeshAgent))]
public class ClickToMove : MonoBehaviour {
       RaycastHit hitInfo = new RaycastHit();
       NavMeshAgent agent;
       void Start () {
              agent = GetComponent<NavMeshAgent> ();
       }
       void Update () {
              if(Input.GetMouseButtonDown(0)) {
                     Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                     if (Physics.Raycast(ray.origin, ray.direction, out hitInfo))
                           agent.destination = hitInfo.point;
              }
       }
}


發佈了60 篇原創文章 · 獲贊 31 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章