Diagonal movement working momentarily before defaulting to up or down.

I am programming a mechanic for a 2D game where a player can press a button to grab an object. Once grabbed movement freezes and the game waits for player directional input on the right joystick. Once received the object will be launched in that direction and the player’s character will be launched in the opposite direction. This is meant to work in the 8 cardinal directions.

I have the script so it works in the 4 main directions (up, down, left, right) and the script recognizes diagonal input (confirmed by having the input assigned to an variable “angle” which is sent to console once it’s detected) but I’ve noticed 2 bugs.

1.) Input Detection is not reliable. Diagonals seem to register as Up, Down, Left or Right often. NOTE: I am using Unity’s Input System and currently have the mechanics Action Type set to Value (but have tested pass-through and button) and The Binding Parameters set to 2D Vector and Digital Normalized.

2.) When the proper input IS detected the player seems to be launched in the correct direction for a moment before being sent up or down, the diagonal momentum should continue.

Snippet of one case of the switch statement (switch statement takes player input, converts it to a variable called angle and rounds to the nearest 45 degrees (to account for the 8 directions)

Code: (Note RB = Player’s Rigidbody 2D and the “yeet” variables are serialized at the beginning of script as float values)

case -135:

// Perform action for bottom-left direction
Debug.Log(“You pressed Bottom-Left”);

//Launches player up-right
RB.AddForce(new Vector2(1f, 1f).normalized * yeetPlayerDiagSpeed * yeetPlayerDiagDistance, ForceMode2D.Impulse);
if (grabbedObject != null)
{
Rigidbody2D grabbedObjectRigidbody = grabbedObject.GetComponent () as Rigidbody2D;
if (grabbedObjectRigidbody != null)
{
//Returns physics to object
grabbedObjectRigidbody.isKinematic = false;
//Launches Object Down-Left
grabbedObjectRigidbody.AddForce(new Vector2(-1f, -1f).normalized * yeetObjectSpeed * yeetObjectDistance, ForceMode2D.Impulse);
//Removes object as child of the player
grabbedObject.transform.SetParent(null);

//(other code that is functioning properly here but unrelated to movement I’ve opted to keep this post //brief as possible)

break;

Would appreciate any ideas, I’m hitting a wall trying to figure out where this has gone wrong because the other cases all send the object in the desired direction, it is only the player that isn’t working properly.

Use code tags for your code.

They way you’re doing this is by elaborating states of a broken state machine (as evidenced by that case -135). Don’t do that. Focus on simple tasks, and make sure they work as expected.

This is what you should do first and foremost:
Construct a Vector2 from your input controls such that it reflects the state of the input.

For example:
(1, 0) would be returned when you press right,
(1, 1) when you press up-right, and
(0, -1) when you press down.

This is one possibility for the old input system

Vector2 control = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));

And here’s a simple tutorial for the new one.

So after reading all of that, i feel like you did not provide the one piece of code that’s actually relevant here: your code handling inputs and mapping it to your directions. Unity works here. The bug is almost certainly with your implementation. Do you check invidual buttons? Do you use input axis? If not the latter, why?

Also, please use code tags when posting code examples to make them more readable.

Roughly i would do the following:

  • Get both input axis
  • Map them to the closest integer, resulting in a combined 8 directions
  • Use these values as a Vector2 to launch the object
  • Make sure you dont access old values or apply them again while mid-air, depending on your setup