Search Unity

Move using different speeds (front/back/lateral) while oriented independently of camera.

Discussion in 'Scripting' started by kellsey, Mar 20, 2019.

  1. kellsey

    kellsey

    Joined:
    Apr 5, 2012
    Posts:
    11
    Hi, I'm trying to make a player move with different speeds (forward, backwards, lateral), while facing a target, independently of the actual camera angle. The inputs are based on a Xbox360 pad.

    To do so, i have a _moveInputVector witch is then reoriented to be relative to the camera in world space, and used later as a velocity.
    I calculate the difference between the desired movement direction (_moveInputVector) , and the actual character facing direction with Vector3.Dot() on both the forward and right axis.
    It gives me a number between -1 and 1 that represents how much the desired direction axis matches the character facing direction axis.
    Finally i use those numbers to calculate a final speed by adding the vertical speed and horizontal speed.

    However, when i Debug.Log the Vector3.Dot results and add them, they go sightly beyond 1 sometimes (like 1.3f), which makes no sense for me since we can't be full forward speed (1.0f) AND a bit left/right (0.3f) at same time due to the use of a directional joystick.

    Do anyone has an idea how to fix this ?

    I'm aware there might be some better ways to achieve what i want but it's the only solution i found, so i'm also opened to different approaches.

    Here is the code where speed is calculated :

    Code (CSharp):
    1. if(targetMode) // calculate speed when in target mode
    2. {
    3.     // the forward vector the player faces ( normalized before in the code )
    4.     Vector3 targetDirForward = _lookInputVector;
    5.     // the right of this facing direction
    6.     Vector3 targetDirRight = new Vector3(targetDirForward.z, 0, -targetDirForward.x);
    7.    
    8.     // difference between the inputs direction and character facing direction    
    9.     float dotForward = Vector3.Dot(targetDirForward, _moveInputVector);
    10.     // same but with the right vector
    11.     float dotRight = Vector3.Dot(targetDirRight, _moveInputVector);
    12.  
    13.     // if we move forward according to facing direction, add forward speed proportional to the "amount of forward" we are trying to move
    14.     if (dotForward > 0) finalSpeed += Mathf.Abs(dotForward) * currSpeedSet.fwdMaxSpeed;
    15.     // same for if move backwards
    16.     else finalSpeed += Mathf.Abs(dotForward) * currSpeedSet.backMaxSpeed;
    17.  
    18.     // add the lateral speed (always proportional to how much we try to move on the left/right of the player facing direction)
    19.     finalSpeed += Mathf.Abs(dotRight) * currSpeedSet.lateralMaxSpeed;
    20. }
    21.                  
    22. // make the velocity proportionnal to finalSpeed and apply velocity
    23. targetMovementVelocity = reorientedInput * finalSpeed;
    24. currentVelocity = targetMovementVelocity;
     
  2. kellsey

    kellsey

    Joined:
    Apr 5, 2012
    Posts:
    11
    Nevermind i found a solution for this. If anyone has the same problem, it came from the fact the joystick inputs were squared (so 45° on the pad would not mean 0.5 + 0.5 but a little more).

    With this function it fixes it so when i'm full Top Down Left or Right, value will be 1 but if i go 45°, those 1 will be shared between the 2 axis (like 0.7 top 0.3 right).

    Code (CSharp):
    1. public static Vector3 ClampDiamond(Vector3 vector, float maxLength) // Diamond inputs instead of squared (for pad)
    2.     {
    3.         float diamondSize = Mathf.Abs(vector.x) + Mathf.Abs(vector.z);
    4.         if (diamondSize > maxLength)
    5.         {
    6.             return vector / diamondSize * maxLength;
    7.         }
    8.         else
    9.         {
    10.             return vector;
    11.         }
    12.     }
    I made it in a Vector3 but can be made as Vector2 aswell.