Skip to content

Instantly share code, notes, and snippets.

@haramakoto
Created January 28, 2013 14:14
Show Gist options
  • Save haramakoto/4655816 to your computer and use it in GitHub Desktop.
Save haramakoto/4655816 to your computer and use it in GitHub Desktop.
NavMeshのサンプルコードagentLocomotionのCS化
using UnityEngine;
using System.Collections;
[RequireComponent (typeof (NavMeshAgent))]
public class agentLocomotion : MonoBehaviour {
private string locoState_ = "Locomotion_Stand";
private NavMeshAgent agent_;
private Animation anim_;
private Vector3 linkStart_;
private Vector3 linkEnd_;
private Quaternion linkRot_;
// Use this for initialization
IEnumerator Start () {
agent_ = GetComponent<NavMeshAgent>();
agent_.autoTraverseOffMeshLink=false;
AnimationSetup();
while(Application.isPlaying){
yield return StartCoroutine(locoState_);
}
}
IEnumerator Locomotion_Stand(){
do{
UpdateAnimationBlend();
yield return null;
} while(agent_.remainingDistance==0);
locoState_="Locomotion_Move";
yield return null;
}
IEnumerator Locomotion_Move(){
do{
UpdateAnimationBlend();
yield return null;
if(agent_.isOnOffMeshLink){
locoState_=SelectLinkAnimation();
yield return null;
}
}while(agent_.remainingDistance!=0);
locoState_="Locomotion_Stand";
yield return null;
}
void UpdateAnimationBlend(){
float walkAnimationSpeed = 1.5f;
float runAnimationSpeed = 4.0f;
float speedThreshold = 0.1f;
Vector3 velocityXZ = new Vector3(agent_.velocity.x, 0.0f, agent_.velocity.z);
float speed = velocityXZ.magnitude;
anim_["Run"].speed = speed / runAnimationSpeed;
anim_["Walk"].speed = speed / walkAnimationSpeed;
if(speed > (walkAnimationSpeed+runAnimationSpeed)/2.0f) {
anim_.CrossFade("Run");
}
else if(speed > speedThreshold) {
anim_.CrossFade("Walk");
} else {
anim_.CrossFade("Idle", 0.1f, PlayMode.StopAll);
}
}
void AnimationSetup(){
anim_=GetComponent<Animation>();
anim_["Walk"].layer = 1;
anim_["Run"].layer = 1;
anim_.SyncLayer(1);
anim_["RunJump"].wrapMode = WrapMode.ClampForever;
anim_["RunJump"].speed = 2;
anim_["Ladder Up"].wrapMode = WrapMode.ClampForever;
anim_["Ladder Up"].speed = 2;
anim_["Ladder Down"].wrapMode = WrapMode.ClampForever;
anim_["Ladder Down"].speed = 2;
anim_.CrossFade("Idle", 0.1f, PlayMode.StopAll);
}
IEnumerator Locomotion_JumpAnimation(){
string linkAnimationName = "RunJump";
agent_.Stop(true);
anim_.CrossFade(linkAnimationName, 0.1f, PlayMode.StopAll);
transform.rotation=linkRot_;
Vector3 posStartAnim = transform.position;
do{
float tlerp = anim_[linkAnimationName].normalizedTime;
Vector3 newPos = Vector3.Lerp(posStartAnim, linkEnd_, tlerp);
newPos.y += 0.4f*Mathf.Sin(3.14159f*tlerp);
transform.position = newPos;
yield return null;
}while(anim_[linkAnimationName].normalizedTime < 1);
anim_.Play("Idle");
agent_.CompleteOffMeshLink();
agent_.Resume();
transform.position = linkEnd_;
locoState_ = "Locomotion_Stand";
yield return null;
}
IEnumerator Locomotion_LadderAnimation(){
Vector3 linkCenter = 0.5f*(linkEnd_ + linkStart_);
string linkAnimationName;
if(transform.position.y > linkCenter.y) {
linkAnimationName = "Ladder Down";
} else {
linkAnimationName = "Ladder Up";
}
agent_.Stop(true);
Quaternion startRot = transform.rotation;
Vector3 startPos = transform.position;
float blendTime = 0.2f;
float tblend = 0;
do{
transform.position = Vector3.Lerp(startPos, linkStart_, tblend/blendTime);
transform.rotation = Quaternion.Slerp(startRot, linkRot_, tblend/blendTime);
yield return null;
tblend += Time.deltaTime;
}while(tblend < blendTime);
transform.position = linkStart_;
anim_.CrossFade(linkAnimationName, 0.1f, PlayMode.StopAll);
agent_.ActivateCurrentOffMeshLink(false);
do {
yield return null;
} while(anim_[linkAnimationName].normalizedTime < 1);
agent_.ActivateCurrentOffMeshLink(true);
anim_.Play("Idle");
transform.position = linkEnd_;
agent_.CompleteOffMeshLink();
agent_.Resume();
locoState_ = "Locomotion_Stand";
yield return null;
}
string SelectLinkAnimation(){
OffMeshLinkData link = agent_.currentOffMeshLinkData;
float distS = (transform.position - link.startPos).magnitude;
float distE = (transform.position - link.endPos).magnitude;
if(distS < distE) {
linkStart_ = link.startPos;
linkEnd_ = link.endPos;
} else {
linkStart_ = link.endPos;
linkEnd_ = link.startPos;
}
Vector3 alignDir = linkEnd_ - linkStart_;
alignDir.y = 0;
linkRot_ = Quaternion.LookRotation(alignDir);
if(link.linkType == OffMeshLinkType.LinkTypeManual) {
return "Locomotion_LadderAnimation";
} else {
return "Locomotion_JumpAnimation";
}
}
// Update is called once per frame
void Update () {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment