- Home /
Issue with animation and gravity.
Hi to everyone, I have a small problem when my char idle it fly above the ground. Character snaps to the ground only when it go strait, with his anim. But when move another direction with other animation it go above the ground, The other animations I used from Mecanim Animation Tutorial https://www.youtube.com/watch?v=Xx21y9eJq1U&feature=kp≈p=desktop Only strait move animation create my self. To play this animation and move I use two scripts. The first one is rigBodyControl from Unity Wiki: http://wiki.unity3d.com/index.php/RigidbodyFPSWalker using UnityEngine; using System.Collections;
[RequireComponent(typeof(Rigidbody))] [RequireComponent(typeof(CapsuleCollider))] public class rigBodyControl : MonoBehaviour { public float speed = 10.0f; public float gravity = 10.0f; public float maxVelocityChange = 10.0f; public bool canJump = true; public float jumpHeight = 2.0f; private bool grounded = false;
void Awake()
{
rigidbody.freezeRotation = true;
rigidbody.useGravity = false;
}
void FixedUpdate()
{
GetComponent<BotControlScript>();
if (grounded)
{
// Calculate how fast we should be moving
Vector3 targetVelocity = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
targetVelocity = transform.TransformDirection(targetVelocity);
targetVelocity *= speed;
// Apply a force that attempts to reach our target velocity
Vector3 velocity = rigidbody.velocity;
Vector3 velocityChange = (targetVelocity - velocity);
velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
velocityChange.y = 0;
rigidbody.AddForce(velocityChange, ForceMode.VelocityChange);
// Jump
if (canJump && Input.GetButton("Jump"))
{
rigidbody.velocity = new Vector3(velocity.x, CalculateJumpVerticalSpeed(), velocity.z);
}
}
// We apply gravity manually for more tuning control
rigidbody.AddForce(new Vector3(0, -gravity * rigidbody.mass, 0));
grounded = false;
}
void OnCollisionStay()
{
grounded = true;
}
float CalculateJumpVerticalSpeed()
{
// From the jump height and gravity we deduce the upwards speed
// for the character to reach at the apex.
return Mathf.Sqrt(2 * jumpHeight * gravity);
}
RigBodyControl gets to the second one BotControlScript thru GetComponent
public float animSpeed = 1.5f; // a public setting for overall animator animation speed
public float lookSmoother = 3f; // a smoothing setting for camera motion
//public bool useCurves; // a setting for teaching purposes to show use of curves
private Animator anim; // a reference to the animator on the character
private AnimatorStateInfo currentBaseState; // a reference to the current state of the animator, used for base layer
private AnimatorStateInfo layer2CurrentState; // a reference to the current state of the animator, used for layer 2
//private CapsuleCollider col; // a reference to the capsule collider of the character
static int idleState = Animator.StringToHash("Base Layer.Idle");
static int locoState = Animator.StringToHash("Base Layer.Locomotion"); // these integers are references to our animator's states
static int waveState = Animator.StringToHash("Layer2.Wave");
void Start ()
{
// initialising reference variables
anim = GetComponent<Animator>();
//col = GetComponent<CapsuleCollider>();
if(anim.layerCount ==2)
anim.SetLayerWeight(1, 1);
}
void FixedUpdate ()
{
float h = Input.GetAxis("Horizontal"); // setup h variable as our horizontal input axis
float v = Input.GetAxis("Vertical"); // setup v variables as our vertical input axis
anim.SetFloat("Speed", v); // set our animator's float parameter 'Speed' equal to the vertical input axis
anim.SetFloat("Direction", h); // set our animator's float parameter 'Direction' equal to the horizontal input axis
anim.speed = animSpeed; // set the speed of our animator to the public variable 'animSpeed'
//currentBaseState = anim.GetCurrentAnimatorStateInfo(0); // set our currentState variable to the current state of the Base Layer (0) of animation
//if(anim.layerCount ==2)
//layer2CurrentState = anim.GetCurrentAnimatorStateInfo(1); // set our layer2CurrentState variable to the current state of the second Layer (1) of animation
// Raycast down from the center of the character..
//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);
//}
//}
}
}
// if we enter the waving state, reset the bool to let us wave again in future
//if(layer2CurrentState.nameHash == waveState)
//{
// anim.SetBool("Wave", false);
//}
And some pics of my problem: WalkBack
WalkForward
Answer by Harardin · Aug 10, 2015 at 10:31 AM
Just need to reset collider and to change a Root transform position to center of mass and all starts to work correctly sorry for creating a question. At animation menu.
No need to be sorry. If you've encountered such a problem, someone else probably will too. So it's good that you got a solution.