Search Unity

setting min and max position along a vector

Discussion in 'Scripting' started by mrmightypants, Nov 23, 2015.

  1. mrmightypants

    mrmightypants

    Joined:
    Apr 25, 2015
    Posts:
    8
    I'm working on refining the movement of the main camera in my game, looking for help with one piece of it. The LateUpdate method is below, where all the camera movement and rotation logic lives. This is a 3D, 3rd person game. As it stands, the camera follows the player character, but can be controlled independently by the player, orbiting around the player character, adjusting the view angle along the X axis, and zooming in and out. What I'd like to do is put a min and max distance from the player to limit the range of zooming.

    Currently, the distance between the camera and the player character is set with the offset variable, which is initialized to the vector between the player and camera on Start(). I was hoping I could use this with a vector equivalent of Mathf.Clamp, but Vector3.ClampMagnitude provides only a max, not a minimum. Any ideas how to do this? Thanks.

    Code (CSharp):
    1.     void LateUpdate()
    2.     {
    3.         float h = Input.GetAxis("Horizontal2");
    4.         float v = Input.GetAxis("Vertical2");
    5.  
    6.         if (h >= 0.5f || h <= -0.5f )
    7.         {
    8.             yAngle += h * orbitSpeed;
    9.             // accelerate up to top orbit speed
    10.             orbitSpeed = Mathf.Clamp(orbitSpeed * 1.075f, baseOrbitSpeed, maxOrbitSpeed);
    11.         }
    12.         else
    13.         {
    14.             // reset orbitSpeed for acceleration on next movement
    15.             orbitSpeed = baseOrbitSpeed;
    16.         }
    17.  
    18.         if (v >= 0.8f || v <= -0.8f )
    19.         {
    20.             xAngle = Mathf.Clamp(xAngle - v * rotateSpeed, minXAngle, maxXAngle);
    21.             // accelerate up to max rotation speed
    22.             rotateSpeed = Mathf.Clamp(rotateSpeed * 1.05f, baseRotateSpeed, maxRotateSpeed);
    23.  
    24.             if (xAngle >= maxXAngle || xAngle <= minXAngle)
    25.             {
    26.                 offset = offset - Vector3.forward * v / 20 ;  
    27.             }
    28.         }
    29.         else
    30.         {
    31.             // reset rotateSpeed for acceleration on next movement
    32.             rotateSpeed = baseRotateSpeed;
    33.         }
    34.  
    35.         Quaternion rotation = Quaternion.Euler(xAngle, yAngle, 0);
    36.         transform.position = target.transform.position - (rotation * offset);
    37.  
    38.         if (Input.GetButtonDown("CamReset"))
    39.         {
    40.             yAngle = target.transform.eulerAngles.y;
    41.             xAngle = defaultXAngle;
    42.             offset = defaultOffset;
    43.         }
    44.        
    45.         // aim the camera just above the target game object so that the target is not directly centered in the screen
    46.         Vector3 lookTarget = new Vector3(target.transform.position.x, target.transform.position.y + targetHeight, target.transform.position.z);
    47.         transform.LookAt(lookTarget);
    48.        
    49.         // pin the camera to the wall if it bumps into one, rather than having it go through
    50.         Ray wallLookRay = new Ray(lookTarget,this.transform.position - lookTarget);
    51.         RaycastHit wallHit;
    52.         if (Physics.Raycast(wallLookRay, out wallHit, Vector3.Distance(this.transform.position, lookTarget)))
    53.         {
    54.             transform.position = wallHit.point;
    55.         }
    56.     }
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    Normalize your vector (which keeps the same direction but makes it a magnitude of 1), and then multiply it by the desired magnitude.
     
  3. mrmightypants

    mrmightypants

    Joined:
    Apr 25, 2015
    Posts:
    8
    That makes sense, but how then, do I actually use the max and min distances to constrain the camera's movement? I can't use comparators >, >=, etc. on a Vector3, and while I can use == and !=, using those would require that the position of the camera be exactly equal to the min or max distance in order to be constrained.

    Thanks.
     
  4. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    You use >, >= etc on the magnitude of the Vector3, not the Vector3 itself.

    Code (csharp):
    1. public static Vector3 ClampMagnitude(Vector3 in, float minMagnitude, float maxMagnitude) {
    2. float inMagnitude = in.magnitude;
    3. if (inMagnitude < minMagnitude) {
    4. Vector3 inNormalized = in / inMagnitude; //equivalent to in.normalized, but slightly faster in this case
    5. return inNormalized * minMagnitude;
    6. }
    7. else if (inMagnitude > maxMagnitude) {
    8. Vector3 inNormalized = in / inMagnitude; //equivalent to in.normalized, but slightly faster in this case
    9. return inNormalized * maxMagnitude;
    10. }
    11.  
    12. // No need to clamp at all
    13. return in;
    14. }