Hi guys,
I’m making a side scrolling game in 3D - the thing that the player will be doing the most is jumping, however I got a few problems with this.
First off my jump animation causes the character to pull up his legs, leaving his collider hangout beyond his feet (see the image below)
[27227-jump+collider+problem.jpg|27227]
Needless to say, this makes him collide with objects below his feet making jumping hacky and stupid.
As I use different states to control his animations I tried to change the position of the colliders center point, however that often causes the character to ignore the ground check and get stuck in the falling condition. You can see the code below:
void MovementMangemant(Vector3 targetDirection){
if(targetDirection.x != 0f || targetDirection.z != 0f && IsGrounded() && !jumping){
print ("Running");
playerCollider.center = new Vector3(0, 4, 0.5f);
playerSounds.state = PlayerSounds.States.Running;
anim.SetBool(hash.fallingBool, false);
anim.SetBool(hash.jumpingBool, false);
Rotation(targetDirection.z, targetDirection.x);
anim.SetFloat(hash.speedFloat, 5f, speedDampTime, Time.deltaTime);
anim.speed = 2.5f;
}else if(jumping){
print ("jumping");
//playerCollider.center = new Vector3(0, 5f, 0.5f);
playerSounds.state = PlayerSounds.States.Jump;
anim.SetBool(hash.jumpingBool, true);
anim.speed = 1f;
}else if(!IsGrounded() && !jumping &&!onElevator){
print ("falling");
playerCollider.center = new Vector3(0, 5f, 0.5f);
anim.SetBool(hash.jumpingBool, false);
anim.SetBool(hash.fallingBool, true);
anim.speed = 1f;
}else if(targetDirection.x == 0f || targetDirection.z == 0f && IsGrounded() && !jumping){
print ("idle");
playerCollider.center = new Vector3(0, 4, 0.5f);
playerSounds.state = PlayerSounds.States.Idle;
anim.SetFloat(hash.speedFloat, 0f);
anim.SetBool(hash.jumpingBool, false);
anim.SetBool(hash.fallingBool, false);
anim.speed = 1f;
}
Vector3 newPosition = Vector3.Lerp(rigidbody.position, rigidbody.position+targetDirection, speed * Time.deltaTime);
rigidbody.MovePosition(newPosition);
}
Again needless to say, that won’t work at all. I also tried using a mesh collider, but that won’t work at all.
Beyond that I have another (and perhaps related problem). It seems that my ground check is making some problems. Initially it seems to work, if I jump the animation change, and change correctly once I hit the ground - However, in the picture above I am able to jump again, as it apparently believes I am close enough to the ground to jump again. Strange thing however is that the animation does not change until I actually hit the ground.
Here is the code for my ground check:
private float distToGround;
distToGround = collider.bounds.extents.y;
bool IsGrounded(){
if(onElevator){
return true;
}else{
return Physics.Raycast(transform.position, -Vector3.up, distToGround + 0.1f);
}
}
And here is the entire script for the player locomotion:
using UnityEngine;
using System.Collections;
public class PlayerMotor : MonoBehaviour {
protected Animator anim;
private HashID hash;
public float DirectionDampTime = 0.25f;
public float turnSmoothing = 15f;
public float speedDampTime;
public float speed;
public float jumpForce = 5.0f;
public bool IJActive = false;
public float IJDirection;
public bool onElevator;
private bool jumping = false;
private float distToGround;
private PlayerSounds playerSounds;
private float v = 0;
private CapsuleCollider playerCollider;
void Awake(){
anim = this.GetComponent<Animator>();
playerSounds = this.GetComponent<PlayerSounds>();
hash = GameObject.Find ("Game Controller").GetComponent<HashID>();
}
void Start(){
onElevator = false;
distToGround = collider.bounds.extents.y;
playerCollider = GetComponent<CapsuleCollider>();
}
void FixedUpdate(){
float h = Input.GetAxis("Horizontal");
if(!IJActive){
v = 0;
}else if(IJActive){
v = IJDirection;
}
if(Input.GetKey(KeyCode.Space) && IsGrounded() && !jumping){
jumping = true;
StartCoroutine(Jump(jumpForce));
}
MovementMangemant(new Vector3(v, 0, h));
}
void MovementMangemant(Vector3 targetDirection){
if(targetDirection.x != 0f || targetDirection.z != 0f && IsGrounded() && !jumping){
print ("Running");
playerCollider.center = new Vector3(0, 4, 0.5f);
playerSounds.state = PlayerSounds.States.Running;
anim.SetBool(hash.fallingBool, false);
anim.SetBool(hash.jumpingBool, false);
Rotation(targetDirection.z, targetDirection.x);
anim.SetFloat(hash.speedFloat, 5f, speedDampTime, Time.deltaTime);
anim.speed = 2.5f;
}else if(jumping){
print ("jumping");
//playerCollider.center = new Vector3(0, 5f, 0.5f);
playerSounds.state = PlayerSounds.States.Jump;
anim.SetBool(hash.jumpingBool, true);
anim.speed = 1f;
}else if(!IsGrounded() && !jumping &&!onElevator){
print ("falling");
playerCollider.center = new Vector3(0, 5f, 0.5f);
anim.SetBool(hash.jumpingBool, false);
anim.SetBool(hash.fallingBool, true);
anim.speed = 1f;
}else if(targetDirection.x == 0f || targetDirection.z == 0f && IsGrounded() && !jumping){
print ("idle");
playerCollider.center = new Vector3(0, 4, 0.5f);
playerSounds.state = PlayerSounds.States.Idle;
anim.SetFloat(hash.speedFloat, 0f);
anim.SetBool(hash.jumpingBool, false);
anim.SetBool(hash.fallingBool, false);
anim.speed = 1f;
}
Vector3 newPosition = Vector3.Lerp(rigidbody.position, rigidbody.position+targetDirection, speed * Time.deltaTime);
rigidbody.MovePosition(newPosition);
}
void Rotation(float horizontal, float vertical){
Vector3 targetDirection = new Vector3(vertical, 0f, horizontal);
Quaternion targetRotation = Quaternion.LookRotation(targetDirection, Vector3.up);
Quaternion newRotation = Quaternion.Lerp(rigidbody.rotation, targetRotation, turnSmoothing * Time.deltaTime);
rigidbody.MoveRotation(newRotation);
}
IEnumerator Jump(float force){
yield return new WaitForSeconds(0.001f);
rigidbody.velocity = new Vector3(0, force, 0);
jumping = false;
}
bool IsGrounded(){
if(onElevator){
return true;
}else{
return Physics.Raycast(transform.position, -Vector3.up, distToGround + 0.1f);
}
}
Hopefully someone can help me in these problems, because I am bit at a loss here.