# How to play character animation when using A* pathfinding

Hi I am trying to make racing game. In which I am using mecanim animation system to animate my character. Here are the conditions for the animation to play

Speed --> 1       Run
Speed --> 0-0.5 - walk
Speed --> <-0.10   -walk back


if I set the speed to 1, my character will run i.e

anim.setFloat("Speed",1);


will run my character.

As it is a racegame I need to move the other characters from source to destination. For which I am using A* Pathfinding project of arongberg. using the above algorithm I am getting the path and I am using simpleMove of character control to move the character. Now the problems comes here

1.As the character needs to play run animation while moving, which is not happening, if I set

anim.setFloat("Speed",1); it is not moving in the direction of path instead it is moving on its own direction

1. I have tried to apply run animation directly instead of animation controller, but the same Happening.

2. if I remove all the animation character reaching to destination without any animation.

Here is the question where I have posted the code, I am asking the same question again but I was stuck with from past4 days.

• Cross-posted: stackoverflow.com/questions/17739276 – BlueRaja - Danny Pflughoeft Jul 19 '13 at 7:05
• @BlueRaja-DannyPflughoeft I don't know where to post this question, so I have posted the same in SO. It was the first time I heard this word Cross-Posted what I need to do? – Pragnani Jul 19 '13 at 7:11
• I don't believe there is an issue in cross posting to SO but doing so does cause a duplicate of a question. If in doubt you can join the GameDev Chat and ask developers directly or link to your SO post. This is very much a GameDev question so in this case I would keep your question here and remove your SO copy. – Tom 'Blue' Piddock Jul 19 '13 at 8:17

Okay this a rough copy of your code from the other question but I would create a delegate to report the next point on the path to your CharacterControl components. Please note that this is completely untested and it will require your own tinkering to make sure it works in your project - such as the delegate reference to your AIPather component instance:

First the AIPather:

using UnityEngine;
using System.Collections;
public class AIPather: MonoBehaviour {

//Delegate to pass next point out
public delegate void ReportNextPathEvent(Vector3 pos);
public event ReportNextPathEvent ReportNextPath;

// Use this for initialization
Seeker seeker;
public Transform target;
int currentWayPoint;
Pathfinding.Path path;
Animator anim;
void Start() {
seeker = GetComponent < Seeker > ();
seeker.StartPath(transform.position, target.position, onPathCompleted);
anim = GetComponent < Animator > ();
}
void onPathCompleted(Pathfinding.Path p) {
if (!p.error) {
path = p;
currentWayPoint = 0;
} else {
Debug.Log(p.error);
}
}

void FixedUpdate() {
if (path == null) {
return;
}
if (currentWayPoint >= path.vectorPath.Count) {
return;
}
Vector3 dir = (path.vectorPath[currentWayPoint] - transform.position).normalized;

//Report the path using the delegate
ReportNextPath(dir);
}
}


using UnityEngine;
using System.Collections;
public class CharacterControl: MonoBehaviour {
Animator anim;
private float swipeDistance = 0;
private bool swipeYN = false;
private Vector2 startPos;
private Vector2 endpos;
bool jumpYN = false;
static int jumpState = Animator.StringToHash("Base Layer.JumpSlide");
private float minSwipeDistance = 100;
private float maxSwipeDistance = 400;
float startTime;
float swipeDirection;
CapsuleCollider collider; // Use this for initialization
void Start() {

// <RefToPatherComponentObject += ReportNextPath;

anim = GetComponent < Animator > ();
anim.SetFloat("Speed", 1);
collider = GetComponent < CapsuleCollider > ();
}

// Update is called once per frame
void Update() {
//  anim.SetFloat("SwipeDirection",swipeDirection);
anim.SetBool("Jump", false);

// removed as now handled by delegate:
//float accelarationx = Input.acceleration.x;
//anim.SetFloat("Direction", accelarationx);

AnimatorStateInfo currentState = anim.GetCurrentAnimatorStateInfo(0);
if (Input.touchCount > 0) {
Touch start = Input.GetTouch(0);
switch (start.phase) {
case TouchPhase.Began:
startTime = Time.time;
swipeYN = true;
startPos = start.position;
break;
case TouchPhase.Moved:
if (Mathf.Abs(start.position.y - start.position.y) > maxSwipeDistance). {
swipeYN = false;
}
break;
case TouchPhase.Stationary:
swipeYN = false;
break;
case TouchPhase.Ended:
float swipeTime = Time.time;
swipeDistance = (start.position - startPos).magnitude;
if (swipeYN && (swipeDistance > minSwipeDistance)) {
swipeDirection = Mathf.Sign(start.position.y - startPos.y);
anim.SetBool("Jump", swipeYN);
jumpYN = true;
anim.SetFloat("SwipeDirection", swipeDirection);
}
break;
}
}
if (jumpYN) {
Ray ray = new Ray(transform.position + Vector3.up, -Vector3.up);
RaycastHit hitInfo = new RaycastHit();
if (Physics.Raycast(ray, out hitInfo)) {
// ..if distance to the ground is more than 1.75, use Match Target
if (hitInfo.distance > 1.75f) {
// MatchTarget allows us to take over animation and smoothly transition our character towards a location - the hit point from the ray.
// Here we're telling the Root of the character to only be influenced on the Y axis (MatchTargetWeightMask) and only occur between 0.35 and 0.5
// of the timeline of our animation clip
anim.MatchTarget(hitInfo.point, Quaternion.identity, AvatarTarget.Root, new MatchTargetWeightMask(new Vector3(0, 1, 0), 0), 0.35f, 0.5f);
}
}
}

void ReportNextPath(Vector3 pos){
Vector3 match = new Vector3(thisTransform.forward.x, 0.0f, thisTransform.forward.z).normalized;
float deltaAngle = Vector3.Angle(pos, match);
float neg = deltaAngle * Mathf.Sign(pos);
anim.SetFloat("Direction", neg, 0.25f , Time.deltaTime);
}
}

• +1 Thanks for your answer, I will try that and I will accept this if it works for me – Pragnani Jul 19 '13 at 13:23
• I have tested your code, it is not working.. But you show me the right direction... – Pragnani Jul 20 '13 at 6:19
• Well as I mentioned, it is very difficult to debug code for a project that I didn't have on my machine. Hope it works for you in the end. – Tom 'Blue' Piddock Jul 20 '13 at 12:04
• I have edited your answer..So that it will be usefull for the others. Any how Thanks for the follow up – Pragnani Jul 20 '13 at 13:54
• Your edit got reviewed by @Byte56 and he decided to keep it at its original intent. If people need to extract anything from it there is no need to reduce the content of the classes, they'll be able to take what they need from it. Thank you for accepting my answer :) – Tom 'Blue' Piddock Jul 20 '13 at 15:01