So going off of what I learned in college studying programming in Game Design I created a StateMachine script for my character. I have tested it numerous times to make sure it works correctly, and thankfully it does. Now I’ve never done Android/mobile development before, nor have I successfully used the new GUI system that was introduced in 4.6. So I’ll leave my code below, because I don’t want to break what does work experimenting with things I’m unsure of. Please just let me know if there is a simple way to switch my key press inputs to work with individual buttons. I’m not good with vague terminology either so please try to be as detailed as possible, that way I won’t have to ask any redundant questions that may annoy you folks.
using UnityEngine;
using System.Collections;
using System;
using System.Collections.Generic;
public class NinjaStateMachine : MonoBehaviour
{
Ninja theNinja;
Animator anim;
private enum PlayerStates
{
IDLE,
RUN,
ENTER_JUMP,
IN_AIR,
THROW,
DIE,
ATTACK,
NUM_STATES
};
PlayerStates curState;
[SerializeField]
private PolygonCollider2D[] idleColliders;
private int idleColIndex = 0;
[SerializeField]
private PolygonCollider2D[] runColliders;
private int runColIndex = 0;
[SerializeField]
private PolygonCollider2D[] jumpColliders;
private int jumpColIndex = 0;
[SerializeField]
private PolygonCollider2D[] deathColliders;
private int deathColIndex = 0;
[SerializeField]
private PolygonCollider2D[] attackColliders;
private int attackColIndex = 0;
[SerializeField]
private Transform respawnPoint;
public GameObject thePlayer;
private bool canJump = true;
private bool onGround = false;
public bool playerFacingRight = false;
private bool playerDied = false;
public Rigidbody2D myNinja;
[SerializeField] private float shootTimer = 0.0f;
[SerializeField] private float jumpHoldTime = 0.5f;
[SerializeField] private float swingTime = 0.0f;
[SerializeField] private bool canSwing = true;
[SerializeField] private float throwTime = 0.0f;
[SerializeField] private bool canThrow = true;
[SerializeField] private float timeHeld = 0.0f;
[SerializeField] Transform groundCheck;
[SerializeField] LayerMask walkableLayer;
[SerializeField] private float groundCheckRadius = 0.1f;
Dictionary<PlayerStates, Action> fsm = new Dictionary<PlayerStates, Action>();
// Use this for initialization
void Start () {
theNinja = GetComponent<Ninja>();
anim = GetComponent<Animator>();
fsm.Add (PlayerStates.IDLE, StateIdle);
fsm.Add (PlayerStates.RUN, StateRun);
fsm.Add (PlayerStates.ENTER_JUMP, StateEnterJump);
fsm.Add (PlayerStates.IN_AIR, StateInAir);
fsm.Add (PlayerStates.DIE, StateDead);
fsm.Add (PlayerStates.ATTACK, StateAttack);
fsm.Add (PlayerStates.THROW, StateThrow);
SetState(PlayerStates.IDLE);
}
// Update is called once per frame
void Update ()
{
float move = Input.GetAxis ("Horizontal");
fsm[curState].Invoke();
if (move > 0 && !playerFacingRight)
Flip();
else if (move < 0 && playerFacingRight)
Flip();
if(swingTime == 0)
{
canSwing = true;
}
if(swingTime >= 0.3f)
{
canSwing = false;
}
if(throwTime == 0)
{
canThrow = true;
}
if(throwTime >= 0.3f)
{
canThrow = false;
}
shootTimer += Time.deltaTime;
}
void SetState(PlayerStates nextState)
{
if (nextState != curState)
{
timeHeld = 0;
curState = nextState;
}
}
void StateIdle()
{
DoHorizontalMove();
anim.SetBool("isIdle", true);
runColliders[runColIndex].enabled = false;
jumpColliders[jumpColIndex].enabled = false;
attackColliders[attackColIndex].enabled = false;
if(Input.GetAxis ("Horizontal") != 0f)
{
anim.SetBool("isIdle", false);
SetState (PlayerStates.RUN);
}
else if(Input.GetKeyDown (KeyCode.Space))
{
anim.SetBool("isIdle", false);
SetState(PlayerStates.ENTER_JUMP);
}
if((shootTimer >= 3f) && (Input.GetButton ("Fire1")))
{
anim.SetBool("isIdle", false);
SetState(PlayerStates.THROW);
}
if (Input.GetKeyDown (KeyCode.Z))
{
anim.SetBool("isIdle", false);
SetState(PlayerStates.ATTACK);
}
if (Input.GetKeyDown(KeyCode.X))
{
anim.SetBool("isIdle", false);
SetState(PlayerStates.DIE);
}
}
void StateRun()
{
DoHorizontalMove();
anim.SetBool("isRunning", true);
idleColliders[idleColIndex].enabled = false;
attackColliders[attackColIndex].enabled = false;
jumpColliders[jumpColIndex].enabled = false;
float direction = Input.GetAxis("Horizontal");
float magnitude = Mathf.Abs(GetComponent<Rigidbody2D>().velocity.x);
Vector2 accel = new Vector2(theNinja.Accel() * direction, 0);
if(direction != 0f)
{
GetComponent<Rigidbody2D>().velocity += accel;
}
if (Input.GetKeyDown (KeyCode.Space))
{
anim.SetBool("isRunning", false);
SetState (PlayerStates.ENTER_JUMP);
}
if (Input.GetKeyDown (KeyCode.Z))
{
anim.SetBool("isRunning", false);
SetState(PlayerStates.ATTACK);
}
if((shootTimer >= 3f) && (Input.GetButton ("Fire1")))
{
anim.SetBool("isRunning", false);
SetState(PlayerStates.THROW);
}
else if (magnitude <= 0.1f)
{
anim.SetBool("isRunning", false);
SetState (PlayerStates.IDLE);
}
else if (magnitude >= theNinja.MaxRun ())
{
GetComponent<Rigidbody2D>().velocity = new Vector2(theNinja.MaxRun() * direction, GetComponent<Rigidbody2D>().velocity.y);
}
}
void StateEnterJump()
{
GetComponent<Rigidbody2D>().velocity = new Vector2 (GetComponent<Rigidbody2D>().velocity.x, theNinja.JumpSpeed());
SetState (PlayerStates.IN_AIR);
}
void StateInAir()
{
DoHorizontalMove();
anim.SetBool("isJumping", true);
runColliders[runColIndex].enabled = false;
idleColliders[idleColIndex].enabled = false;
attackColliders[attackColIndex].enabled = false;
if (canJump == true)
{
if (timeHeld < jumpHoldTime && Input.GetKey (KeyCode.Space))
{
timeHeld += Time.deltaTime;
GetComponent<Rigidbody2D>().velocity += new Vector2 (0, theNinja.AccelJump ());
}
else
{
CheckForGround();
if(onGround)
{
HandleOnGround();
}
}
}
}
void StateAttack()
{
anim.SetBool("isAttacking", true);
swingTime += Time.deltaTime;
float magnitude = Mathf.Abs(GetComponent<Rigidbody2D>().velocity.x);
if((magnitude <= 0.1f) && (canSwing == false))
{
anim.SetBool("isAttacking", false);
swingTime = 0;
SetState (PlayerStates.IDLE);
}
if((Input.GetAxis ("Horizontal") != 0f) && (canSwing == false))
{
anim.SetBool("isAttacking", false);
swingTime = 0;
SetState (PlayerStates.RUN);
}
}
void StateThrow()
{
anim.SetBool("isThrowing", true);
shootTimer = 0f;
throwTime += Time.deltaTime;
float magnitude = Mathf.Abs(GetComponent<Rigidbody2D>().velocity.x);
if((magnitude <= 0.1f) && (canThrow == false))
{
anim.SetBool("isThrowing", false);
throwTime = 0;
SetState (PlayerStates.IDLE);
}
if((Input.GetAxis ("Horizontal") != 0f) && (canThrow == false))
{
anim.SetBool("isThrowing", false);
throwTime = 0;
SetState (PlayerStates.RUN);
}
}
void StateDead()
{
anim.SetBool("isDead", true);
runColliders[runColIndex].enabled = false;
jumpColliders[jumpColIndex].enabled = false;
attackColliders[attackColIndex].enabled = false;
idleColliders[idleColIndex].enabled = false;
}
void DoHorizontalMove()
{
float direction = Input.GetAxis ("Horizontal");
Vector2 accel = new Vector2 (theNinja.Accel () * direction, 0);
if (direction != 0f)
{
GetComponent<Rigidbody2D>().velocity += accel;
}
float magnitude = Math.Abs (GetComponent<Rigidbody2D>().velocity.x);
if (magnitude <= .01f) {
GetComponent<Rigidbody2D>().velocity = new Vector2(0, GetComponent<Rigidbody2D>().velocity.y);
}
else if (magnitude >= theNinja.MaxRun ()) {
GetComponent<Rigidbody2D>().velocity = new Vector2 (theNinja.MaxRun() * direction, GetComponent<Rigidbody2D>().velocity.y);
}
}
void CheckForGround()
{
onGround = Physics2D.OverlapCircle (groundCheck.position, groundCheckRadius, walkableLayer);
}
void HandleOnGround()
{
float direction = Input.GetAxis ("Horizontal");
canJump = true;
if (direction != 0f)
{
anim.SetBool("isJumping", false);
SetState (PlayerStates.RUN);
}
else
{
anim.SetBool("isJumping", false);
SetState(PlayerStates.IDLE);
}
}
void Flip ()
{
playerFacingRight = !playerFacingRight;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}