using UnityEngine;
using System.Collections;
[DisallowMultipleComponent]
[RequireComponent(typeof(Animator))]
public class SoldierMovement : MonoBehaviour {
Animator anim;
bool isCrouch = false;
bool isWalk = false;
bool isRun = false;
bool isJump = false;
void Awake()
{
anim = GetComponent<Animator> ();
}
void Update()
{
Walking ();
Strafing ();
Crouch ();
Run ();
Jump ();
}
void Walking()
{
anim.SetFloat ("Walking", Input.GetAxis ("Horizontal"));
}
void Strafing()
{
anim.SetFloat ("Strafing", Input.GetAxis ("Vertical"));
}
void Turning()
{
anim.SetFloat ("Turning", Input.GetAxis ("Mouse X"));
}
void Crouch ()
{
if (Input.GetKeyDown (KeyCode.LeftControl)) {
isCrouch = !isCrouch;
isRun = false;
anim.SetBool ("Crouch", isCrouch);
anim.SetBool ("Run", isRun);
}
}
void Jump ()
{
if (Input.GetKeyDown (KeyCode.LeftControl)) {
isJump = !isJump;
anim.SetBool ("Jump", isJump);
}
}
void Run ()
{
if (Input.GetKeyDown (KeyCode.LeftShift)) {
isRun = true;
anim.SetBool ("run", isRun);
} else {
isRun = false;
anim.SetBool ("run", isRun);
}
}
}
Using a Raycast alone is a bad way to check if the player is on the ground or in the air.
Consider a scenario where there is some space directly below your character, but not wide enough to fall through - the raycast doesn’t hit anything but the collider is too wide to fully fall through (like for example some rock crevice or some chairs or tables in the scene). You’ll get stuck in infinite falling loop.
I would suggesting using both a raycast and a collision point normals to check if you are actually standing on something.
Here’s my code for character collision (it uses one capsule collider for character). Adjust for your own needs:
public void OnCollisionStay(Collision other)
{
float highestDotProduct = float.MinValue;
ContactPoint[] points = other.contacts;
for (int i = 0; i < points.Length; i++)
{
float dotProduct = Vector3.Dot(points*.normal, Vector3.up);*
if (dotProduct > highestDotProduct)
{
highestDotProduct = dotProduct;
}
}
if (highestDotProduct > 0.7f)
{
EndJump();
isGroundedByCollision = true;
//print(“Correction via hit normal!”);
}
else
{
isGroundedByCollision = false;
}
}
public void OnCollisionExit(Collision other)
{
if (other.contacts.Length == 0)
isGroundedByCollision = false;
}
Then finally at main check:
bool IsGrounded()
- {*
if (!isGroundedByCollision)
{
Vector3 cColliderBottomLocation = transform.position +
((cCollider.center - new Vector3(0, (cCollider.height) / 2 - 0.05f, 0)) * transform.localScale.y);
float rayLength = 0.25f;
Debug.DrawRay(cColliderBottomLocation, -Vector3.up * rayLength);
return Physics.Raycast(cColliderBottomLocation, -Vector3.up, rayLength);
}
else
return true;
- }*
cCollider is a collider component fetched at the start.