Created
July 3, 2018 19:10
-
-
Save juliomarcos/68b8d7922f2a11192122dd2df1215ac5 to your computer and use it in GitHub Desktop.
Character grid movement using 1 movement input buffering and input filtering delay
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public enum PlayerState { | |
Idle, | |
Moving, | |
Hit, | |
Attack, | |
AttackMove | |
} | |
public struct Move { | |
public float h, v; | |
public Move(float h, float v) | |
{ | |
this.h = h; | |
this.v = v; | |
} | |
} | |
public class PlayerController : MonoBehaviour { | |
public float speed; | |
public float pressFilterDelay; | |
private PlayerState state; | |
private float timeOfLastPress; | |
private Move? queuedMove; | |
// Use this for initialization | |
void Start () { | |
state = PlayerState.Idle; | |
queuedMove = null; | |
} | |
// Update is called once per frame | |
void Update () { | |
var hor = Input.GetAxis("Horizontal"); | |
var ver = Input.GetAxis("Vertical"); | |
if (ver < 0) transform.rotation = Quaternion.Euler(0, 0, -180); | |
else if (ver > 0) transform.rotation = Quaternion.Euler(0, 0, 0); | |
else if (hor < 0) transform.rotation = Quaternion.Euler(0, 0, 90); | |
else if (hor > 0) transform.rotation = Quaternion.Euler(0, 0, -90); | |
//transform.position += transform.up * speed * Time.deltaTime; | |
var move = MoveFromInputAxes(); | |
if (move.h == 0 && move.v == 0) return; | |
if (Time.time - timeOfLastPress < pressFilterDelay) return; | |
if (state == PlayerState.Idle) { | |
print ("from idle to move"); | |
MoveTo(move); | |
} | |
else if (state == PlayerState.Moving) { | |
// queue up to one movement | |
print ("queuing one move"); | |
queuedMove = move; | |
} | |
timeOfLastPress = Time.time; | |
} | |
private Move MoveFromInputAxes() | |
{ | |
return new Move((int)Input.GetAxisRaw("Horizontal"), (int)Input.GetAxisRaw("Vertical")); | |
} | |
void MoveTo(Move move) { | |
var xDir = move.h; | |
var yDir = move.v; | |
if (xDir == 0 && yDir == 0) return; | |
// no diagonals | |
if (yDir != 0) xDir = 0; | |
xDir *= 2; | |
yDir *= 2; | |
state = PlayerState.Moving; | |
Vector2 start = transform.position; | |
Vector2 end = start + new Vector2(xDir, yDir); | |
StartCoroutine(SmoothMove(end)); | |
} | |
IEnumerator SmoothMove(Vector3 end) { | |
print ("SmoothMove from: " + transform.position + " to: " + end); | |
float startTime = Time.time; | |
float sqrRemainingDistance; | |
do { | |
sqrRemainingDistance = (transform.position - end).sqrMagnitude; | |
float distCovered = (Time.time - startTime) * speed; // betweens [0, 1] | |
transform.position = Vector3.Lerp(transform.position, end, distCovered); | |
yield return null; | |
} while (sqrRemainingDistance > 0.01f); | |
print ("End of SmoothMove"); | |
transform.position = end; // do not accumulate error | |
print("queue " + queuedMove); | |
if (queuedMove != null) { | |
MoveTo(queuedMove.GetValueOrDefault()); | |
queuedMove = null; | |
} else { | |
state = PlayerState.Idle; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment