1
votes

I currently have a setup where the player can move forward, left, right and backwards with WASD. Basic stuff.

public class Player : MonoBehaviour
{
    public InputMaster controls;
    private float playerSpeed = 4f;
    {
        controls = new InputMaster();
        controls.PlayerN.Movement.performed += ctx => Movement(ctx.ReadValue<Vector2>());
        controls.PlayerN.Movement.performed += ctx => move = ctx.ReadValue<Vector2>();
        controls.PlayerN.Movement.canceled += ctx => move = Vector2.zero;
    }

    void Update()
    {

        Vector2 inputVector = controls.PlayerN.Movement.ReadValue<Vector2>();
        inputVector = new Vector2(move.x, move.y) * Time.deltaTime * playerSpeed;

        Vector3 finalVector = new Vector3();
        finalVector.x = inputVector.x;
        finalVector.z = inputVector.y;
        transform.Translate(finalVector, Space.World);

    private void OnEnable()
       {
        controls.Enable();
       }

       private void OnDisable()
       {
        controls.Disable();
       }

    }
}

above is how I've been calling the movement. You might notice that the actionmap is called PlayerN, that's because I have 4 action maps in total, and the idea is that I want the player to switch to the next one when the camera rotates 90 degrees around the player(North, East, South, West). For example, my action map called `PlayerE' has movement left on W, movement right on S, movement down on A and movement up on D. I just reoriented the WASD keys.

I'm currently at a loss for how switch over to a different actionmap. I've looked at the documentation for the new input system and I can't find any good info for this.

I had an idea for how to fix this but I don't know if I'm on the right track or not. I have a switch loop which checks an int in another script called camDirection, and I have this part located in my void Update() function.

 switch (refScript.camDirection)
        {
            case -3:
                Debug.Log("Facing East");
                break;
            case -2:
                Debug.Log("Facing South");
                break;
            case -1:
                Debug.Log("Facing West");
                break;
            case 0:
                Debug.Log("Facing North");
                break;
            case 1:
                Debug.Log("Facing East");
                break;
            case 2:
                Debug.Log("Facing South");
                break;
            case 3:
                Debug.Log("Facing West");
                break;
        }

Anyways, I'm currently stuck with this so if anyone has any ideas how to fix this I'd really appreciate it.

1
Why did you make it so complicated? I would prefer to have one action for movement and just rotate the movement direction vector. - LaoR
short answer? because I'm noob lol. I'll try that out and report the results though. - mikaelm
Ummm...how do you actually do that? I'm struggling trying to find where and how you can alter the direction vector :( - mikaelm

1 Answers

1
votes

OK, I will post a code that calculates a player movent in 3D space as you've requested in the comments.

First, let's assume we are in the same coordinate system: X - left (-X is right) Y - up (-Y = down) Z - forward (-Z = backward). Then you need to have 3 fields (variables on class level):

//Actual position of the player in 3d space
Vector3 _playerPosition;

// The point in 3d space at which the player is looking right now
// If he can move only horizontally - the Y coordinate can be locked.
Vector3 _playerLooksAt;

// Last known mouse position
Vector2 _lastMousePosition;

Then in your Update method do the following:

void Update()
    {
        // You need to where the Player should be moved, like that:
        // Vector2 inputVector = controls.PlayerN.Movement.ReadValue<Vector2>();
        // But I do not know what did you have there, so usually I read them from
        // AWSD keys:
        float x = 0, z = 0;
        var pressedKey = Keyboard.GetPressedKey(); // depends on your platform
        if (pressedKey == "W") // move forward
        {
              z = 1;
        }
        if (pressedKey == "A") // move left
        {
              x = 1;
        }
        // and for remaining keys similar code, but assign -1 accordingly.  
        var inputVectorForMovement = new Vector3(x, 0, z);

        // Then you have to get rotation angle, again I do not know how you do it, 
        // but it is usually obtained from mouse movement:
        var currentMousePosition = Mouse.GetPosition(); // depends on your platform
        // I just did simple approximation here to rotate on the angle of 45 degrees converted to radians per 100 pixels of mouse movement:
        var horizontalRotationAngleRadians = Math.Pi/4f * (currentMousePosition.X - _lastMousePosition.X) / 100f;
        
         
        // Create rotation matrix assuming Y is up vector: 
        var rotationMatrixForPlayerDirection = Matrix.CreateRotationY(horizontalRotationAngleRadians);
       
        // Calculate player direction:
        var playerDirection = _playerLooksAt - _playerPosition;

        // Normalize it*, so the direction vector will have coefficients per each axis indicating how much the position should be moved to either side:
        playerDirection.Normalize();
        
        // and rotate it:
        var rotatedPlayerDirection = Vector3.Transfom(playerDirection, rotationMatrixForPlayerDirection);
        
        // Then you can simply move forward or backward along this vector:
        var movementOnVector = (rotatedPlayerDirection * Time.deltaTime * playerSpeed * inputVectorForMovement.Z);
        _position += movementOnVector;

        // To move left or right according to the direction vector 
        // you have to calculate a vector perpendicular 
        // to both of direction vector and up vector (which is Y)**:
        var sideDirectionVector = Vector3.Cross(rotatedPlayerDirection, Vector3.UnitY);
        // and just do the movement along that vector:
        movementOnVector = (sideDirectionVector * Time.deltaTime * playerSpeed * inputVectorForMovement.X);
        _position += movementOnVector;

        // Do not forget to update fields:
        _playerLooksAt = _position + rotatedPlayerDirection;
        _lastMousePosition = currentMousePosition;
}

*normalize vector

**cross product