- Home /
Integrating unitysteer with mixamo animation scripts
I'm attempting to use UnitySteer as my pathfinding script(s) while using mixamo motion-capture animations via the scripts they've provided. Individually I can get them each to work; separately I get some weird results. It seems (sometimes) that if I have more than one instance of the animation running one of them will play through once and freeze at the end; even with the animation set to loop.
Thats a small issue and one I can probably sort out on my own. The real issue I'm having (and it could very well be because I don't entirely understand the UnitySteer autonomous vehicle script) is that the Mixamo driver script was written with the assumption that the character is player-controlled. Specifically: it looks for keystrokes to cue the animations. I've tried various forms of CharacterController.velocity to make it work, but I've been getting strange side effects such as moving sideways while walking forward or randomly flying 80ft in a random direction.
I'm posting the mixamo script below..It's rather lengthy, but seems to be fairly straight forward. It does rely on another mixamo script, but from what I've seen that one's completely devoted to regulating the animation's motion-capture side effects(mostly forward movement in the actual animation).
Is there any simple way to get unitySteer to work with this? I've done what I can think of, and I'm sure there's some simple solution I've neglected to consider.
using UnityEngine; using System.Collections;
public enum MovementMode { Human, Zombie }
[AddComponentMenu("Mixamo/Demo/Root Motion Character")] public class RootMotionCharacter : MonoBehaviour { public float turningSpeed = 90f; public RootMotionComputer computer; public CharacterController character; public MovementMode mode = MovementMode.Human;
void Start()
{
// validate component references
if (computer == null) computer = GetComponent(typeof(RootMotionComputer)) as RootMotionComputer;
if (character == null) character = GetComponent(typeof(CharacterController)) as CharacterController;
// tell the computer to just output values but not apply motion
computer.applyMotion = false;
// tell the computer that this script will manage its execution
computer.isManagedExternally = true;
// since we are using a character controller, we only want the z translation output
computer.computationMode = RootMotionComputationMode.ZTranslation;
// initialize the computer
computer.Initialize();
// set up properties for the animations
animation["idle"].layer = 0; animation["idle"].wrapMode = WrapMode.Loop;
animation["walk"].layer = 1; animation["walk"].wrapMode = WrapMode.Loop;
animation["run"].layer = 1; animation["run"].wrapMode = WrapMode.Loop;
animation["zombiewalk"].layer = 2; animation["zombiewalk"].wrapMode = WrapMode.Loop;
animation.Play("idle");
}
void Update()
{
float targetMovementWeight = 0f;
float throttle = 0f;
// turning keys
if (Input.GetKey(KeyCode.A)) transform.Rotate(Vector3.down, turningSpeed*Time.deltaTime);
if (Input.GetKey(KeyCode.D)) transform.Rotate(Vector3.up, turningSpeed*Time.deltaTime);
// forward movement keys
// ensure that the locomotion animations always blend from idle to moving at the beginning of their cycles
if (Input.GetKeyDown(KeyCode.W) &&
(animation["walk"].weight == 0f || animation["run"].weight == 0f))
{
animation["walk"].normalizedTime = 0f;
animation["run"].normalizedTime = 0f;
}
if (Input.GetKey(KeyCode.W))
{
targetMovementWeight = 1f;
}
if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) throttle = 1f;
// blend in the movement
if (mode == MovementMode.Human)
{
animation.Blend("run", targetMovementWeight*throttle, 0.5f);
animation.Blend("walk", targetMovementWeight*(1f-throttle), 0.5f);
// synchronize timing of the footsteps
animation.SyncLayer(1);
}
else
{
// ensure that the locomotion animations always blend from idle to moving at the beginning of their cycles
if (Input.GetKeyDown(KeyCode.W) &&
(animation["zombiewalk"].weight == 0f))
{
animation["zombiewalk"].normalizedTime = 0f;
}
animation.Blend("zombiewalk", targetMovementWeight, 0.5f);
}
}
void LateUpdate()
{
computer.ComputeRootMotion();
// move the character using the computer's output
character.SimpleMove(transform.TransformDirection(computer.deltaPosition)/Time.deltaTime);
}
}
As a side note, I really wouldn't use a CharacterController unless absolutely necessary - they're significantly more expensive than just using a collider: http://www.arges-systems.com/articles/47/handling-slopes-with-autonomous-vehicles
Answer by Ricardo · Jan 07, 2011 at 08:59 AM
Interesting problem.
I'm unfamiliar with Mixamo's needs, but it would seem that what it needs is to know in which direction your character is moving and if it is running. If so, you might be able to create something like VehicleLookAtOverride, which caches the Vehicle's last N forces applied. You could then judge if the vehicle is moving forward or sideways by the change in vectors, which would replace your if (Input.GetKey(KeyCode.W)). You would determine if the vehicle is moving at a running speed or not based on its Speed property, checking against whatever threshold you take to mean running, which would replace the LeftShit/RightShit comparisons.
If you don't care about sideways movement - and it appears from the code sample that A/D are only evaluated to rotate the transform - you could just get away with checking the vehicle's speed. Anything above a certain threshold (say, 0.2f) would mean forward movement and you blend into the walk/run animations (the equivalent of pressing W).
This of course depends on what computer.ComputeRootMotion() does, so you may want to review it as well.
VehicleLookAtOverride is giving me errors saying that autonomous vehicle doesnt have a LastRawForce value, but the note about a rigidbody w/ collider ins$$anonymous$$d of a character controller was a great help. I'll keep looking at VehicleLookAtOverride and autonomous vehicle and see if I can get it working. Thanks for your help.
That's because it depends on the branch b2.1 where it is. It's also meant only to give you an example of how you'd write a behavior that expands on the information from AutonomousVehicle, it's not something that'll solve your integration problem.
Your answer
Follow this Question
Related Questions
Character Animation 0 Answers
Animation not playing correctly 1 Answer
Animation precision is lost for character's blinking 1 Answer
Why are my animations not working correctly? 4 Answers
Problems with an animation 0 Answers