Skip to content

Instantly share code, notes, and snippets.

@Matthew-J-Spencer
Created October 27, 2021 13:27
Show Gist options
  • Save Matthew-J-Spencer/32b69cfc71446a9af0d697be2cee585d to your computer and use it in GitHub Desktop.
Save Matthew-J-Spencer/32b69cfc71446a9af0d697be2cee585d to your computer and use it in GitHub Desktop.
public class PlayerController : MonoBehaviour {
[SerializeField] private Rigidbody _rb;
[SerializeField] private float _speed = 5;
[SerializeField] private float _turnSpeed = 360;
private Vector3 _input;
private void Update() {
GatherInput();
Look();
}
private void FixedUpdate() {
Move();
}
private void GatherInput() {
_input = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical"));
}
private void Look() {
if (_input == Vector3.zero) return;
var rot = Quaternion.LookRotation(_input.ToIso(), Vector3.up);
transform.rotation = Quaternion.RotateTowards(transform.rotation, rot, _turnSpeed * Time.deltaTime);
}
private void Move() {
_rb.MovePosition(transform.position + transform.forward * _input.normalized.magnitude * _speed * Time.deltaTime);
}
}
public static class Helpers
{
private static Matrix4x4 _isoMatrix = Matrix4x4.Rotate(Quaternion.Euler(0, 45, 0));
public static Vector3 ToIso(this Vector3 input) => _isoMatrix.MultiplyPoint3x4(input);
}
@MrFJ
Copy link

MrFJ commented Feb 14, 2022

If you want more responsive and precise movement (Like in hades f. ex.), separate the movement and rotation between the rigidbody and a separate model.

[SerializeField] private Rigidbody _rigidBody;
[SerializeField] private Transform _model;

private void Move()
{
    _rigidBody.MovePosition(transform.position + input.ToIso() * input.normalized.magnitude * speed * Time.deltaTime);
}
private void Look()
{
    if (input == Vector3.zero) return;

    Quaternion rot = Quaternion.LookRotation(input.ToIso(), Vector3.up);
    _model.rotation = Quaternion.RotateTowards(_model.rotation, rot, turnSpeed * Time.deltaTime);
}

Oh and if you the new input system, replace Gatherinput with:

private void GatherInput()
{
    Vector2 stickValue = Gamepad.current.leftStick.ReadValue();
    _input = new Vector3(stickValue.x, 0, stickValue.y);
}

Obviously you'd need something else for keyboard input.

@Kapparow
Copy link

Kapparow commented Apr 4, 2022

You can gather keyboard or gamepad input with using input action's invoke unity events.
//name the ctx whatever you want
private void GatherInput(InputAction.CallbackContext ctx)
{
Vector2 stickValue = ctx.ReadValue();
_input = new Vector3(stickValue.x, 0, stickValue.y);
}

@kodveotesi
Copy link

If you want more responsive and precise movement (Like in hades f. ex.), separate the movement and rotation between the rigidbody and a separate model.

[SerializeField] private Rigidbody _rigidBody;
[SerializeField] private Transform _model;

private void Move()
{
    _rigidBody.MovePosition(transform.position + input.ToIso() * input.normalized.magnitude * speed * Time.deltaTime);
}
private void Look()
{
    if (input == Vector3.zero) return;

    Quaternion rot = Quaternion.LookRotation(input.ToIso(), Vector3.up);
    _model.rotation = Quaternion.RotateTowards(_model.rotation, rot, turnSpeed * Time.deltaTime);
}

Oh and if you the new input system, replace Gatherinput with:

private void GatherInput()
{
    Vector2 stickValue = Gamepad.current.leftStick.ReadValue();
    _input = new Vector3(stickValue.x, 0, stickValue.y);
}

Obviously you'd need something else for keyboard input.

You don't need to separate the GameObject and Rigidbody. It is enough simply multiply current input with the new skewed input.

@dfrl-dev
Copy link

dfrl-dev commented Jan 4, 2023

Any contact with a collider cause the object to roll around and fly off screen. Any idea why this could be occurring?

@Nikito600
Copy link

Any contact with a collider cause the object to roll around and fly off screen. Any idea why this could be occurring?

I was researching about this problem, cause i`m having it too. I think all the problem is related to the use of RigidBody to movement calculations. They recomend use another method to calc the movement...
Did you find something new about this problem?

@Edwindwin
Copy link

I was researching about this problem, cause i`m having it too. I think all the problem is related to the use of RigidBody to movement calculations. They recomend use another method to calc the movement...
Did you find something new about this problem?

I fixed this by freezing the rotation axes on the Rigidbody and the Y position

@Nikito600
Copy link

I was researching about this problem, cause i`m having it too. I think all the problem is related to the use of RigidBody to movement calculations. They recomend use another method to calc the movement...
Did you find something new about this problem?

I fixed this by freezing the rotation axes on the Rigidbody and the Y position

Thank you very much for the reply!
I'l gonna try this on my project, but in any case, using the rb.MovePosition makes the object ignore other objects with coliders... all this factors limits the possibilities on the project, like Jumping or running fast or dashing.

@t0umbo
Copy link

t0umbo commented May 10, 2023

with this code, it's impossible to control the magnitude of the movement with a joystick, is it possible to fix this?

@d-curiel
Copy link

with this code, it's impossible to control the magnitude of the movement with a joystick, is it possible to fix this?

You can normalize the vector, so if its 0, the magnitude is 0, otherwise is 1. Done that, you can simply play with the speed variable to have an "on/off" movement or add some acceleration time based.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment