尋路和動畫融合
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;
}
}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.