Reputation: 51
I would like to ask if there is a way to disable diagonal movement in Unity 2D. The thing is when I press 'W' + 'D'(move key) at the same time then the character starts to move diagonally. So instead of the character moving diagonal when combining button press, I want it to go completely straight instead if I press 'd' or any other key to move even if I'm still pressing the other button at the same time. So to say prioritize the function of the last button I pressed.
Here's a short video to explain my problem further .
And here's the code for my character movement.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class keycontrol : MonoBehaviour
{
public float moveSpeed = 0f;
public Rigidbody2D rb2d;
Vector2 movement;
public Animator animator;
// Update is called once per frame
void Update()
{
movement.x = Input.GetAxisRaw("Horizontal");
movement.y = Input.GetAxisRaw("Vertical");
animator.SetFloat("walk_right", movement.x);
animator.SetFloat("walk_left", -movement.x);
animator.SetFloat("walk_down", -movement.y);
animator.SetFloat("walk_up", movement.y);
}
void FixedUpdate()
{
rb2d.MovePosition(rb2d.position + movement * moveSpeed * Time.fixedDeltaTime);
if(Input.GetKey("left shift"))
{
moveSpeed = 200 * Time.deltaTime;
animator.speed = 1.5f;
}
else
{
moveSpeed = 110 * Time.deltaTime;
animator.speed = 1f;
}
}
}
Upvotes: 1
Views: 4117
Reputation: 507
You can add condition to check if the horizontal movement is pressed.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class keycontrol : MonoBehaviour
{
public float moveSpeed = 0f;
public Rigidbody2D rb2d;
Vector2 movement;
public Animator animator;
// Update is called once per frame
void Update()
{
movement.x = Input.GetAxisRaw("Horizontal");
if(movement.x == 0){
movement.y = Input.GetAxisRaw("Vertical");
}
animator.SetFloat("walk_right", movement.x);
animator.SetFloat("walk_left", -movement.x);
animator.SetFloat("walk_down", -movement.y);
animator.SetFloat("walk_up", movement.y);
}
void FixedUpdate()
{
rb2d.MovePosition(rb2d.position + movement * moveSpeed * Time.fixedDeltaTime);
if(Input.GetKey("left shift"))
{
moveSpeed = 200 * Time.deltaTime;
animator.speed = 1.5f;
}
else
{
moveSpeed = 110 * Time.deltaTime;
animator.speed = 1f;
}
}
}
Upvotes: 0
Reputation: 4561
You can handle the movement only in one of the axis handled each chance in the code, find draft below:
bool isXMoving;
bool isYMoving;
// Update is called once per frame
void Update()
{
if (Input.GetAxisRaw("Horizontal") != 0f && !isYMoving) {
movement.x = Input.GetAxisRaw("Horizontal");
movement.y = 0;
isXMoving = true;
isYMoving = false;
}
if (Input.GetAxisRaw("Horizontal") != 0f && !isXMoving) {
movement.y = Input.GetAxisRaw("Vertical");
movement.x = 0;
isYMoving = true;
isXMoving = false;
}
Debug.Log($"X: {movement.x} Y: {movement.y}"); //check
animator.SetFloat("walk_right", movement.x);
animator.SetFloat("walk_left", -movement.x);
animator.SetFloat("walk_down", -movement.y);
animator.SetFloat("walk_up", movement.y);
}
Upvotes: 0
Reputation: 4037
A simple way to do this is to prioritize one axis over the other and just wrap the other check in a condition.
movement.x = Input.GetAxisRaw("Horizontal");
if (movement.x != 0)
{
movement.y = Input.GetAxisRaw("Vertical");
}
However, this can fail, because depending on your input, the axis might return values close to zero when using a controller. In this case, you could just get both values and check for the larger one.
movement.x = Input.GetAxisRaw("Horizontal");
movement.y = Input.GetAxisRaw("Vertical");
if (Mathf.Abs(movement.x) > Mathf.Abs(movement.y))
{
movement.y = 0;
}
else
{
movement.x = 0;
}
Upvotes: 6
Reputation: 11
Sharing as an answer since I can't comment on this post, you should check out the new input system unity released recently: https://docs.unity3d.com/Packages/[email protected]/manual/QuickStartGuide.html
It gives better control over inputs such as event systems so you can lock the movement until the first key is released.
Upvotes: 0