I’m having a few issues with my character controller.
While I do have movement and jumping working, as well as aiming the weapon, the problems are with character states.
So what’s going on is I added a force in Update that just adds gravity so the character will fall down when they walk off the edge of a platform. I also have the CharacterState set up with Idle, Walk, Jump, and Fall. The problem with this is, with the gravity being added in Update, if I jump and hold down the jump key long enough then my character will be stuck in Fall, unable to do anything but look up and down. Another thing that happens is if I let go of Jump at the right moment, I will hit the ceiling in Fall and switch to Idle, and I’ll slowly float down.
Additionally, I’m using velocity to move the character and it isn’t really working as I’d want. First off, even with gravity being added at the beginning, I can’t walk off of platforms and I instead just fly over the gaps. Also, since I’m moving the player along forward, I don’t know how to rotate the character so forward is in the opposite direction when Left is being pressed.
Here is my code so far:
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour {
#region Animations
public AnimationClip[] IdleAnimations;
public AnimationClip[] WalkAnimations;
public AnimationClip[] JumpAnimations;
public AnimationClip[] FallAnimations;
#endregion
#region Variables
public float WalkSpeed;
public float Gravity;
public float JumpForce;
bool IsGrounded;
bool HasJumped;
bool HasHitCeiling;
Vector3 Forward;
CharacterController controller;
//Object LevelMesh;
//Object Player;
RaycastHit hit;
#endregion
#region Enums
enum PlayerDirection
{
Forward = 0,
Up = 1,
Down = 2
}
enum PlayerState
{
Idle = 0,
Walking = 1,
Jumping = 2,
Falling = 3,
Dead = 4
}
PlayerDirection playerDirection;
PlayerState playerState;
#endregion
// Use this for initialization
void Start () {
Forward = transform.forward;
playerState = PlayerState.Idle;
IsGrounded = true;
//LevelMesh = GameObject.FindGameObjectWithTag ("Level");
//Player = gameObject;
}
// Update is called once per frame
void Update () {
rigidbody.AddForce (Vector3.down * Gravity);
ChangeAnimation ();
AimGun ();
print ("State: " + playerState + "; Direction: " + playerDirection);
//MOVE THE PLAYER IN FORWARD AT WALKSPEED
float h = Input.GetAxis ("Horizontal");
if (h != 0)
{
if (IsGrounded)
{
playerState = PlayerState.Walking;
}
rigidbody.velocity = Forward * WalkSpeed;
//rigidbody.AddForce(Forward * WalkSpeed);
}
else if (h == 0)
{
if (IsGrounded)
{
playerState = PlayerState.Idle;
rigidbody.AddForce (new Vector3(0,0,0));
}
}
//JUMP
if (Input.GetButtonDown ("Jump") && playerState != PlayerState.Jumping && playerState != PlayerState.Falling)
{
rigidbody.AddForce (new Vector3(0, JumpForce, 0));
//print ("You are jumping.");
playerState = PlayerState.Jumping;
IsGrounded = false;
}
if (Input.GetButtonUp ("Jump") && playerState == PlayerState.Jumping)
{
playerState = PlayerState.Falling;
}
switch (playerState)
{
case PlayerState.Falling:
//rigidbody.AddForce (new Vector3(0,-Gravity,0));
IsGrounded = false;
break;
}
//FALL WHEN CEILING IS HIT
//ALSO BE ABLE TO LOOK UP WHILE GROUNDED
//AND LOOK UP & DOWN WHILE IN AIR
}
void OnCollisionEnter (Collision col)
{
if (col.gameObject.tag == "LevelMesh")
{
if (playerState == PlayerState.Falling)
{
IsGrounded = true;
playerState = PlayerState.Idle;
}
if (playerState == PlayerState.Jumping && !IsGrounded || playerState == PlayerState.Falling && !IsGrounded)
{
playerState = PlayerState.Falling;
}
}
}
void ChangeAnimation()
{
switch (playerState)
{
case PlayerState.Idle:
if (playerDirection == PlayerDirection.Forward)
{
animation.Play (IdleAnimations[0].name);
}
if (playerDirection == PlayerDirection.Up)
{
animation.Play (IdleAnimations[1].name);
}
break;
case PlayerState.Walking:
if (playerDirection == PlayerDirection.Forward)
{
animation.Play (WalkAnimations[0].name);
}
if (playerDirection == PlayerDirection.Up)
{
animation.Play (WalkAnimations[1].name);
}
break;
case PlayerState.Jumping:
if (playerDirection == PlayerDirection.Forward)
{
animation.Play (JumpAnimations[0].name);
}
if (playerDirection == PlayerDirection.Up)
{
animation.Play (JumpAnimations[1].name);
}
if (playerDirection == PlayerDirection.Down)
{
animation.Play (JumpAnimations[2].name);
}
break;
case PlayerState.Falling:
if (playerDirection == PlayerDirection.Forward)
{
animation.Play (FallAnimations[0].name);
}
if (playerDirection == PlayerDirection.Up)
{
animation.Play (FallAnimations[1].name);
}
if (playerDirection == PlayerDirection.Down)
{
animation.Play (FallAnimations[2].name);
}
break;
}
}
void AimGun()
{
if (Input.GetButton ("AimUp"))
{
playerDirection = PlayerDirection.Up;
}
if (Input.GetButton ("AimDown") && playerState == PlayerState.Jumping || Input.GetButton ("AimDown") && playerState == PlayerState.Falling)
{
playerDirection = PlayerDirection.Down;
}
if (!Input.GetButton ("AimUp") && !Input.GetButton ("AimDown"))
{
playerDirection = PlayerDirection.Forward;
}
}
}