Looked around the internet for something but I can’t find anything useful for my situation.
So when the user presses d twice or a twice in a the space of 0.5 seconds I want my program to change the players animation and increase speed 4x.
However when I run my game if i press d once for example it automatically changes to the sprint animation and doesn’t increase speed.
Thanks in advance.
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour {
public float maxSpeed = 0.5f; //new float variable called maxspeed it equals 10
public float sprintSpeed = 2f;
bool facingRight = true; //new bool variable called facingright it equals true
Animator anim;
Rigidbody2D rb;
int buttonPresses = 0;
float buttonPressTimer = 0.5f;
void Start()
{
anim = GetComponent<Animator>();
rb = GetComponent<Rigidbody2D> ();
}
void FixedUpdate()
{
float move = Input.GetAxisRaw ("Horizontal"); //how much we are moving
bool left = Input.GetKeyDown (KeyCode.A);
bool right = Input.GetKeyDown (KeyCode.D);
if(Input.GetKeyDown (KeyCode.D))
{
anim.SetFloat ("Speed", Mathf.Abs (move));
rb.velocity = new Vector2 (move * maxSpeed, rb.velocity.y);
buttonPressTimer -= Time.deltaTime;
if(Input.GetKeyDown (KeyCode.D) && buttonPressTimer > 0)
{
rb.velocity = new Vector2 (move * sprintSpeed, rb.velocity.y);
anim.SetBool ("isRunning",true);
}
}
if (move > 0 && !facingRight) //if moving left and not facing left
{
Flip (); //flip
anim.SetBool("turning",true);
anim.SetBool("turning",false);
}
else if (move < 0 && facingRight) //if moving to the right and not facing right
{
Flip (); //flip
anim.SetBool("turning",true);
anim.SetBool("turning",false);
}
}
void Flip()
{
facingRight = ! facingRight; // flips the character
Vector3 theScale = transform.localScale; //flips the local scale
theScale.x *= -1; //flip the x axis
transform.localScale = theScale; //apply all of this back to the local scale
}
}
For your situation, if you hold the D or A button down, move will always be 1 or -1 respectively. Thats what GetAxisRaw will do when you are using a keyboard. Always.
Your move variable will always be greater than or less than 0 when you are holding the button down. This means that after 2 frames of holding the button down, your character will be sprinting.
What you need to do:
a)Detect when a player initially presses down the D key (Input.GetKeyDown)
b)Begin the timer
c)Detect when a player presses down the D key again (Input.GetKeyDown)
d)Check to see if the timer has elapsed
e)If the timer has not elapsed, you are sprinting. If the timer has elapsed, you aren’t. Reset the timer to get ready to check again.
Hope this helps, if you have questions let me know.
public bool runNow = false; //Main variable to be used
public int noOfTapes = 2; //No of taps
public float tapDelay = 0.5f; //Tap delay
public float runNowTime = 5f; //Set main variable to false after this time
private int dPressed = 0; //No of times d has been pressed in tapDelay
void Update ()
{
if(Input.GetKeyDown(KeyCode.D)){
dPressed += 1;
}
if(Input.GetKeyUp(KeyCode.D)){
Invoke("SetDPressedToZero", tapDelay);
}
if(dPressed > noOfTapes - 1){
runNow = true;
Invoke("SetRunNowFalse", runNowTime);
}
}
void SetDPressedToZero ()
{
dPressed = 0;
}
void SetRunNowFalse ()
{
runNow = false;
}
What you can do is that anytime the player taps the key d, a coroutine is started, and bool A is set to true. While A is true, pressing d will not start the coroutine and once the coroutine ends, A is false. If d is pressed during the coroutine, bool B becomes true which allows sprinting. Once the key is released, bool B once again becomes false.void Update(){ if (!A) { if (Input.GetButtonDown (KeyCode.D)) { StartCoroutine (CheckSprint ()); } } else { if (Input.GetButtonDown (KeyCode.D)) { B = true; } } if (B) { //sprint } if(Input.GetButtonUp(KeyCode.D){ B = false; } } IEnumerator CheckSprint(){ A = true; yield return new WaitForSeconds(0.5f); A = false; }