- Home /
The question is answered, right answer was accepted
Diagonal movement
I'm working on a 2d Game where my character can dodge via sliding... when I normalize my input I'm not able to dodge in the Up Left, Dow Left, Dow Right... but I'm able to dodge Up right... and I can also dodge on the normal 4 axis. can someone please explain this strange issue and help me correct it thank you!
public void HandleMovement()
{
input.x = Input.GetAxisRaw("Horizontal");
input.y = Input.GetAxisRaw("Vertical");
input = input.normalized;
animator.SetFloat("Speed", input.sqrMagnitude);
bool isIdle = input.x == 0 && input.y == 0;
if (isIdle)
{
animator.SetFloat("LastInputX", lastInput.x);
animator.SetFloat("LastInputY", lastInput.y);
}
else
{
playerRigidbody.MovePosition(transform.position + input * walk * Time.deltaTime);
animator.SetFloat("Horizontal", input.x);
animator.SetFloat("Vertical", input.y);
lastInput = input;
}
}
private void HandleDodging()
{
if (Input.GetKeyDown(KeyCode.Space) && input.x == 1 | input.y == 1 | input.x == -1 | input.y == -1)
{
state = State.Dodging;
isDodging = true;
}
}
private void Dodging()
{
playerRigidbody.MovePosition(transform.position + input * dodgeSpeed * Time.deltaTime);
dodgeSpeed -= dodgeSpeed * dodgeSpeedReduced * Time.deltaTime;
if (dodgeSpeed < dodgeSpeedMinimum)
{
state = State.Normal;
dodgeSpeed = dodge;
isDodging = false;
}
}
First I would advise you to put all physics related code in FixedUpdate() and to change your Time.deltaTime by Time.fixedDeltaTime.
Then I suspect you are trying to call HandleMovement() and Dodging in the same frame which means only the last playerRigidbody.MovePosition will resolve. Would you $$anonymous$$d sharing the trunk of code where you call all these methods ?
I definitely will when I wake up, not by the computer atm, I will also make those corrections and post it up for you thank you for going out of your way to help me hopefully you're on the afternoon when I awake!
I'm awake now, sorry hope you're still available.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Rigidbody2D))]
[RequireComponent(typeof(BoxCollider2D))]
public class PlayerController : MonoBehaviour
{
public Animator animator;
private Rigidbody2D playerRigidbody;
private Vector3 input;
private Vector3 lastInput;
public float walkSpeed;
float walk;
public float dodgeSpeed;
float dodge;
public float dodgeSpeedReduced;
float dodgeSpeedMinimum;
public bool isDodging;
private State state;
private enum State
{
Normal, Dodging
}
public void Awake()
{
playerRigidbody = GetComponent<Rigidbody2D>();
walk = walkSpeed;
state = State.Normal;
dodgeSpeedMinimum = walk;
dodge = dodgeSpeed;
}
private void Update()
{
HandleMovement();
}
public void FixedUpdate()
{
switch (state)
{
case State.Normal:
HandleDodging();
break;
case State.Dodging:
Dodging();
break;
}
}
public void HandleMovement()
{
input.x = Input.GetAxisRaw("Horizontal");
input.y = Input.GetAxisRaw("Vertical");
input = input.normalized;
animator.SetFloat("Speed", input.sqrMagnitude);
bool isIdle = input.x == 0 && input.y == 0;
if (isIdle)
{
animator.SetFloat("LastInputX", lastInput.x);
animator.SetFloat("LastInputY", lastInput.y);
}
else
{
playerRigidbody.MovePosition(transform.position + input * walk * Time.fixedDeltaTime);
animator.SetFloat("Horizontal", input.x);
animator.SetFloat("Vertical", input.y);
lastInput = input;
}
}
private void HandleDodging()
{
if (Input.GetKeyDown(KeyCode.Space) )
{
state = State.Dodging;
isDodging = true;
}
}
private void Dodging()
{
playerRigidbody.MovePosition(transform.position + input * dodgeSpeed * Time.fixedDeltaTime);
dodgeSpeed -= dodgeSpeed * dodgeSpeedReduced * Time.deltaTime;
if (dodgeSpeed < dodgeSpeedMinimum)
{
state = State.Normal;
dodgeSpeed = dodge;
isDodging = false;
}
}
}
In this code with out && input.x == 1..... which is after the input. get keycode space. you can move upright diagonal but no other one
Thank you. So in the code you shared you should not use playerRigidBody.Moveposition in Update(), try moving into HandleDodging like that :
private void HandleDodging()
{
bool isIdle = input.x == 0 && input.y == 0;
if (Input.GetKeyDown(KeyCode.Space) & (input.x == 1 | input.y == 1 | input.x == -1 | input.y == -1))
{
state = State.Dodging;
isDodging = true;
}
else if (!isIdle)
{
playerRigidbody.MovePosition(transform.position + input * walk * Time.fixedDeltaTime);
}
}
Get rid of input = input.normalized in HandleMovement()
Answer by iR3dyPlayZ · Mar 07, 2021 at 11:59 PM
@Drayanlia if you want to give up on me I understand but it's still not working and its not checking for space in the bool.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Rigidbody2D))]
[RequireComponent(typeof(BoxCollider2D))]
public class PlayerController : MonoBehaviour
{
public Animator animator;
private Rigidbody2D playerRigidbody;
private Vector3 input;
private Vector3 lastInput;
public float walkSpeed;
float walk;
public float dodgeSpeed;
float dodge;
public float dodgeSpeedReduced;
float dodgeSpeedMinimum;
public bool isDodging;
public bool spacePressed;
private State state;
private enum State
{
Normal, Dodging
}
public void Awake()
{
playerRigidbody = GetComponent<Rigidbody2D>();
walk = walkSpeed;
state = State.Normal;
dodgeSpeedMinimum = walk;
dodge = dodgeSpeed;
}
private void Update()
{
HandleMovement();
if (Input.GetKeyDown(KeyCode.Space))
{
spacePressed = true;
}
}
public void FixedUpdate()
{
switch (state)
{
case State.Normal:
HandleDodging();
break;
case State.Dodging:
Dodging();
break;
}
spacePressed = false;
}
public void HandleMovement()
{
input.x = Input.GetAxisRaw("Horizontal");
input.y = Input.GetAxisRaw("Vertical");
animator.SetFloat("Speed", input.sqrMagnitude);
animator.SetFloat("LastInputX", lastInput.x);
animator.SetFloat("LastInputY", lastInput.y);
animator.SetFloat("Horizontal", input.x);
animator.SetFloat("Vertical", input.y);
}
private void HandleDodging()
{
bool isIdle = input.x == 0 && input.y == 0;
if (spacePressed & (input.x == 1 | input.y == 1 | input.x == -1 | input.y == -1))
{
state = State.Dodging;
isDodging = true;
}
else if (!isIdle)
{
playerRigidbody.MovePosition(transform.position + input.normalized * walk * Time.fixedDeltaTime);
lastInput = input;
}
}
private void Dodging()
{
playerRigidbody.MovePosition(transform.position + input * dodgeSpeed * Time.fixedDeltaTime);
dodgeSpeed -= dodgeSpeed * dodgeSpeedReduced * Time.deltaTime;
if (dodgeSpeed < dodgeSpeedMinimum)
{
state = State.Normal;
dodgeSpeed = dodge;
isDodging = false;
}
}
}
Ok first let's fix checking for space ! Add this in FixedUpdate() before you set spacePressed to false
if (spacePressed)
{
Debug.Log("Space bar was pressed.");
}
Run some tests and tell me if it's printing the message in the console. Verify if it appears every time you press the key and only once by press.
all 4 directions plus upright but not the other 3 diagonals