2D Fighter Character Controller

Last Updated by

A simple playable component created in Unity3D Game Engine to test 2D character animation and controller mechanics.

Below is a recording of 2D Fighter Character Controller inside Unity Editor and snippet of actual controller script.

using UnityEngine;
using System.Collections;
using UnityStandardAssets.CrossPlatformInput;

namespace DGS.TwoD.Proto.StreetFighter {

	public class FighterCharacterController : MonoBehaviour {

		public int fighterNumber = 1;
		public float maxSpeed = 25f;

		public float jumpForce = 20f;
		public float jumpDuration = 0.1f;

		public float attackRate = 0.3f;

		private float _jumpForce;
		private float _jumpDuration;
		private bool _isJumpButtonPressed;
		private bool _isFalling;
		private bool _isGrounded;

		private bool[] _doAttack = new bool[2];
		private float[] _attackTimer = new float[2];
		private int[] _countOfTimePressed = new int[2];

		private float _horizontal;
		private float _vertical;
		private Vector2 _movement;
		private bool _isCrouching;

		private Transform _otherFighter;
		private Rigidbody2D _body2D;
		private Animator _animator;


		// Use this for initialization
		void Start () {
			_body2D = GetComponent<Rigidbody2D>();
			_animator = GetComponentInChildren<Animator>();
		}

		void Update() {
			UpdateAnimator();

			OnGroundCheck();

			AttackInput();
		}

		void FixedUpdate () {
			_horizontal = CrossPlatformInputManager.GetAxis("Horizontal" + fighterNumber.ToString());
			_vertical = CrossPlatformInputManager.GetAxis("Vertical" + fighterNumber.ToString());

			_movement = new Vector2(_horizontal, 0);

			_isCrouching = (_vertical < -0.1f);

			if(_vertical > 0.1f) {
				if(!_isJumpButtonPressed) {
					_jumpDuration += Time.deltaTime;
					_jumpForce += Time.deltaTime;

					if(_jumpDuration < jumpDuration) {
						_body2D.velocity = new Vector2(_body2D.velocity.x, _jumpForce);
					} else {
						_isJumpButtonPressed = true;
					}
				}
			}

			if(!_isGrounded && _vertical < 0.1f) {
				_isFalling = true;
			}

			if(!_isCrouching)
				_body2D.AddForce(_movement * maxSpeed);
			else
				_body2D.velocity = Vector2.zero;
		}

		void OnCollisionEnter2D(Collision2D target) {
			if(target.collider.tag == "Ground") {
				_isGrounded = true;

				_isJumpButtonPressed = false;
				_jumpDuration = 0;
				_jumpForce = jumpForce;
				_isFalling = false;
			}
		}

		void OnCollisionExit2D(Collision2D target) {
			if(target.collider.tag == "Ground") {
				_isGrounded = false;
			}
		}

		void UpdateAnimator() {
			_animator.SetBool("IsCrouching", this._isCrouching);
			_animator.SetBool("IsGrounded", this._isGrounded);
			_animator.SetBool("IsFalling", this._isFalling);
			_animator.SetFloat("Movement", Mathf.Abs(this._horizontal));
			_animator.SetBool("DoAttackOne", this._doAttack[0]);
			_animator.SetBool("DoAttackTwo", this._doAttack[1]);
		}

		void OnGroundCheck() {
			if(!_isGrounded) {
				_body2D.gravityScale = 7f;
			} else {
				_body2D.gravityScale = 5f;
			}
		}

		void AttackInput() {
			if(CrossPlatformInputManager.GetButton("Attack1" + fighterNumber.ToString())) {
				_doAttack[0] = true;
				_attackTimer[0] = 0;
				_countOfTimePressed[0]++;
			}

			if(_doAttack[0]) {
				_attackTimer[0] += Time.deltaTime;

				if(_attackTimer[0] > attackRate || _countOfTimePressed[0] >= 4) {
					_attackTimer[0] = 0;
					_doAttack[0] = false;
					_countOfTimePressed[0] = 0;
				}
			}

			if(CrossPlatformInputManager.GetButton("Attack2" + fighterNumber.ToString())) {
				_doAttack[1] = true;
				_attackTimer[1] = 0;
				_countOfTimePressed[1]++;
			}

			if(_doAttack[1]) {
				_attackTimer[1] += Time.deltaTime;

				if(_attackTimer[1] > attackRate || _countOfTimePressed[1] >= 4) {
					_attackTimer[1] = 0;
					_doAttack[1] = false;
					_countOfTimePressed[1] = 0;
				}
			}
		}
	}
}
In-Editor recording of Game Play from Unity.
In-Editor Animation Controller Setup of Unity.