Search Unity

A Free Simple Smooth Mouselook

Discussion in 'Scripting' started by FatiguedArtist, Jan 7, 2011.

Thread Status:
Not open for further replies.
  1. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,913
    It's free code.
     
  2. AdamGoodrich

    AdamGoodrich

    Joined:
    Feb 12, 2013
    Posts:
    3,783
    As it was posted here I figured this was the case and thanks :)
     
  3. Prestij2k17

    Prestij2k17

    Joined:
    Jul 8, 2017
    Posts:
    1
    when i select a character body camera doesnt turn right and left?
     
  4. indevious

    indevious

    Joined:
    Nov 29, 2017
    Posts:
    16
    Works for me as-is in latest stable Unity 2017.2.
     
  5. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,998
    The coding is a little odd. I'd say this maybe (to quote SM) "is not a good script" for someone wanting to study it to learn rotations and non-Unity coding. But that's not why you posted it. But just to answer you Q, little things:

    o targetDirection is useless in 2 ways. It converts the starting rotation to eulerAngles, but you never use eulerAngles (like 90 degrees... ) for anything. All it does is convert back into the original rotation. You could just put "Quaternion targetOrientation = transform.rotation;" in Start.

    o Notice how I changed your "var" in the declaration into "Quaternion" in the line above. When people see "var" they think "long, complex type which I won't need to know anyway." Now, I realize javascript encouraged this, and Quaternion _was_ considered a confusing type, and the script works the exact same ether way.

    o IMHO, "if(characterBody==null)" is more common. It emphases we're checking existence of a pointer. Otherwise it looks more like checking a boolean (like your use of "if(lockCursor)".)

    o Use of single ampersand(&) inside if's (not a big deal here, but you can look up how && and || are slightly better, and & is really a hack.)

    But again, the only possible reason this might matter is for someone trying to use this script to teach themselves non-Unity coding. And I'd argue we shouldn't encourage people to learn coding-by-example anyway. Otherwise it looks like a standard old-style Unity script. There's plenty of worse stuff people are copying and using.
     
    indevious likes this.
  6. flintmech

    flintmech

    Joined:
    Sep 29, 2011
    Posts:
    32
    I've been trying to implement a simple mouselook script with one particular caveat:

    I only want the camera to rotate with the mouse when a button is held down, and when the button is not held down, the mouse cursor should unlock and the user can then interact with UI without the camera rotating.

    The problem is that when toggling Cursor.lockState to Locked, the mouse pointer jumps to the center of the window and this screws with the calculations, resulting in a very jarring jump in rotation of the camera every time the button is pressed and the mouse is moved. This isn't even unique to toggling locked on/off - having the script lock the mouse cursor from the get-go causes the jump to occur as soon as the script initializes in play mode.

    Another user posted a thread describing what sounds like the same issue here and later announced that the fix for their problem had been incorporated in @FatiguedArtist's script, but it still doesn't seem to be working for me.

    I have tried OP's script in this thread, as well as others online and the MouseLook.cs from StandardAssets/Characters/FirstPersonCharacter. All of these scripts are written to track the mouse at all times. Any attempt I've made to restrict it to a condition and with the Cursor locked has failed.

    The underlying problem itself seems to be the jump of the mouse cursor to the screen center when locked. I don't know if it's a Unity bug or not, but I'm at my wit's end. Anybody have any ideas?
     
    Last edited: Jan 3, 2018
  7. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I have not paid any attention to the script from this thread, but...

    This is what I use to move my mouse (well, obviously just a tiny part of my script), but it works with the cursor locked & hidden.
    Code (csharp):
    1.  
    2. float x = Input.GetAxis("Mouse X");
    3. transform.rotation *= Quaternion.Euler(new Vector3(0, x * mouseSensitivity, 0));
    4.  
    Hope that helps.
     
  8. flintmech

    flintmech

    Joined:
    Sep 29, 2011
    Posts:
    32
    The rotation logic itself isn't the problem. The issue is that, after locking the cursor, for just one frame there is a jump in rotation that doesn't match the mouse movement, seemingly because the cursor's travel distance to the center of the window (a result of the locking) is factored into the GetAxis value.
     
  9. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Hm.. Not sure; afaik, that doesn't appear to happen with my mouse look.
     
  10. yamiyammes

    yamiyammes

    Joined:
    Dec 31, 2017
    Posts:
    1
    Wow, Your script is Amazing!
    Thank you so much, this is just what I needed for my school project.

    I'll be sure to mention your name.
     
  11. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,550
    A user was requesting help making this script have a relative UP axis so that they could rotate their character and have the camera work relative to that rotation. I have proposed a small change and a toggle for such a feature in this version of it:

    Code (csharp):
    1. using UnityEngine;
    2.  
    3. [AddComponentMenu("Camera/Simple Smooth Mouse Look ")]
    4. public class SimpleMouseLook : MonoBehaviour
    5. {
    6.     Vector2 _mouseAbsolute;
    7.     Vector2 _smoothMouse;
    8.  
    9.     public Vector2 clampInDegrees = new Vector2(360, 180);
    10.     public bool lockCursor;
    11.     public Vector2 sensitivity = new Vector2(2, 2);
    12.     public Vector2 smoothing = new Vector2(3, 3);
    13.     public Vector2 targetDirection;
    14.     public Vector2 targetCharacterDirection;
    15.     //Rotate camera relative to its parent's rotation so the camera can work in any relative orientation
    16.     //Does nothing if the camera has no parent
    17.     public bool relativeUpAxis = true;
    18.     // Assign this if there's a parent object controlling motion, such as a Character Controller.
    19.     // Yaw rotation will affect this object instead of the camera if set.
    20.     public GameObject characterBody;
    21.  
    22.     void Start()
    23.     {
    24.         // Set target direction to the camera's initial orientation.
    25.         targetDirection = transform.localRotation.eulerAngles;
    26.  
    27.         // Set target direction for the character body to its inital state.
    28.         if (characterBody)
    29.             targetCharacterDirection = characterBody.transform.localRotation.eulerAngles;
    30.     }
    31.  
    32.     void Update()
    33.     {
    34.         // Ensure the cursor is always locked when set
    35.         if (lockCursor)
    36.         {
    37.             Cursor.lockState = CursorLockMode.Locked;
    38.         }
    39.  
    40.         // Allow the script to clamp based on a desired target value.
    41.         var targetOrientation = Quaternion.Euler(targetDirection);
    42.         var targetCharacterOrientation = Quaternion.Euler(targetCharacterDirection);
    43.  
    44.         // Get raw mouse input for a cleaner reading on more sensitive mice.
    45.         var mouseDelta = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));
    46.  
    47.         // Scale input against the sensitivity setting and multiply that against the smoothing value.
    48.         mouseDelta = Vector2.Scale(mouseDelta, new Vector2(sensitivity.x * smoothing.x, sensitivity.y * smoothing.y));
    49.  
    50.         // Interpolate mouse movement over time to apply smoothing delta.
    51.         _smoothMouse.x = Mathf.Lerp(_smoothMouse.x, mouseDelta.x, 1f / smoothing.x);
    52.         _smoothMouse.y = Mathf.Lerp(_smoothMouse.y, mouseDelta.y, 1f / smoothing.y);
    53.  
    54.         // Find the absolute mouse movement value from point zero.
    55.         _mouseAbsolute += _smoothMouse;
    56.  
    57.         // Clamp and apply the local x value first, so as not to be affected by world transforms.
    58.         if (clampInDegrees.x < 360)
    59.             _mouseAbsolute.x = Mathf.Clamp(_mouseAbsolute.x, -clampInDegrees.x * 0.5f, clampInDegrees.x * 0.5f);
    60.  
    61.         // Then clamp and apply the global y value.
    62.         if (clampInDegrees.y < 360)
    63.             _mouseAbsolute.y = Mathf.Clamp(_mouseAbsolute.y, -clampInDegrees.y * 0.5f, clampInDegrees.y * 0.5f);
    64.  
    65.         transform.localRotation = Quaternion.AngleAxis(-_mouseAbsolute.y, targetOrientation * Vector3.right) * targetOrientation;
    66.  
    67.         // If there's a character body that acts as a parent to the camera
    68.         if (characterBody)
    69.         {
    70.             var yRotation = Quaternion.AngleAxis(_mouseAbsolute.x, Vector3.up);
    71.             characterBody.transform.localRotation = yRotation;
    72.         }
    73.         else
    74.         {
    75.             var upAxis = (relativeUpAxis && transform.parent != null) ? transform.parent.up : Vector3.up;
    76.             var yRotation = Quaternion.AngleAxis(_mouseAbsolute.x, transform.InverseTransformDirection(upAxis));
    77.             transform.localRotation *= yRotation;
    78.         }
    79.     }
    80. }
    81.  
    What version of Unity are you using? I am not seeing this issue in 2017.3.
     
  12. Enrico-Monese

    Enrico-Monese

    Joined:
    Dec 18, 2015
    Posts:
    77
    I also get that weird jump in rotation. Not locking the cursor doesn't fix it so I don't thunks thats the problem. It only started occurring recently. I'm on 2018.1 beta 4, maybe its a new regression if it doesn't occur in older versions.

    Edit: This has been fixed as of beta 11
     
    Last edited: Mar 24, 2018
  13. yotingo

    yotingo

    Joined:
    Jul 10, 2013
    Posts:
    44
    How would I unlock the camera from the character body at run-time, without causing the camera to jump?

    I want the ability to unlock and freely spin the camera around the character, then re-align the character to the camera direction. It's okay if the character jumps to camera rotation but not the camera jumping to character. I can't figure it out for the life of me.

    Thanks for the script! I have been using it with my character controller for months now.
     
  14. CallumEdwards

    CallumEdwards

    Joined:
    Apr 4, 2018
    Posts:
    1
  15. HonoraryBob

    HonoraryBob

    Joined:
    May 26, 2011
    Posts:
    1,214
    I've been using this script, which works fine except when I unlock the mouse to allow the user to access a menu and then lock it again to resume the game, the camera either moves upwards toward the ceiling (if the last click on a menu option was above middle of screen) or snaps back to facing backwards if I try to compensate for that. What's the proper method of setting it to the correct direction after relocking the mouse?
     
  16. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    I didn't test it but just skip the code in Update entirely as long as you are unlocked. Because this line will continue to fetch mousemovements
    Code (CSharp):
    1.  _mouseAbsolute += _smoothMouse;

    But how about a completely different script:
    It is a compressed version of the stuff i mostly use i just cobbled together for you to test. The buffer-class contained is needed for framerate independent smoothing

    Features:
    - frame rate independent smoothing
    - pitch clamping
    - smoothing-bypass
    - on/off switch
    - cursor LockState control coupled to on/off, if needed

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. //Marrt's simplest Mouselook for https://forum.unity.com/threads/a-free-simple-smooth-mouselook.73117/page-2
    4.  
    5. public class SimplestSmoothedMouseLook : MonoBehaviour {
    6.  
    7.     [Header("CameraTransform")]
    8.     public    Transform    targetTrans;
    9.     [Header("On/Off & Settings")]
    10.     public    bool        inputActive        = true;
    11.     public    bool        controlCursor    = false;
    12.     public    bool        pitchClamp        = true;
    13.     [Header("Smoothing")]
    14.     public    bool        byPassSmoothing    = false;
    15.     public    float        mLambda            = 20F;    //higher = less latency but also less smoothing
    16.     [Header("Sensitivity")]
    17.     public    float        hSens            =  4F;
    18.     public    float        vSens            =  4F;
    19.     public    BufferV2    mouseBuffer        = new BufferV2();
    20.  
    21.     void Update ()
    22.     {
    23.         if(controlCursor){    //Cursor Control
    24.             if(  inputActive && Cursor.lockState != CursorLockMode.Locked)    { Cursor.lockState = CursorLockMode.Locked;    }
    25.             if( !inputActive && Cursor.lockState != CursorLockMode.None)    { Cursor.lockState = CursorLockMode.None;    }
    26.         }
    27.         if(!inputActive){ return; }    //active?
    28.  
    29.         //Update input
    30.         UpdateMouseBuffer();
    31.         targetTrans.rotation        = Quaternion.Euler( mouseBuffer.curAbs );
    32.     }
    33.  
    34.     //consider late Update for applying the rotation if your game needs it (e.g. if camera parents are rotated in Update for some reason)
    35.     void LateUpdate() {}
    36.  
    37.     private    void UpdateMouseBuffer()
    38.     {
    39.         mouseBuffer.target    += new Vector2( vSens * -Input.GetAxisRaw("Mouse Y"), hSens * Input.GetAxisRaw("Mouse X") );//Mouse Input is inherently framerate independend!
    40.         mouseBuffer.target.x = pitchClamp?Mathf.Clamp(mouseBuffer.target.x,-80F,+80F) :mouseBuffer.target.x;
    41.         mouseBuffer.Update( mLambda, Time.deltaTime, byPassSmoothing );
    42.     }
    43. }
    44.  
    45.  
    46.  
    47. #region Helpers
    48. [System.Serializable]
    49. public class BufferV2{
    50.  
    51.     public BufferV2(){
    52.         this.target = Vector2.zero;
    53.         this.buffer = Vector2.zero;
    54.     }
    55.     public BufferV2( Vector2 targetInit, Vector2 bufferInit ) {
    56.         this.target = targetInit;
    57.         this.buffer = bufferInit;
    58.     }
    59.  
    60.     /*private*/public    Vector2    target;
    61.     /*private*/public    Vector2    buffer;
    62.  
    63.     public    Vector2    curDelta;    //Delta: apply difference from lastBuffer state to current BufferState        //get difference between last and new buffer
    64.     public    Vector2    curAbs;        //absolute
    65.  
    66.  
    67.  
    68.     /// <summary>Update Buffer By supplying new target</summary>
    69.     public    void UpdateByNewTarget( Vector2 newTarget, float dampLambda, float deltaTime ){
    70.         this.target        = newTarget;
    71.         Update(dampLambda, deltaTime);
    72.     }
    73.     /// <summary>Update Buffer By supplying the rawDelta to the last target</summary>
    74.     public    void UpdateByDelta( Vector2 rawDelta, float dampLambda, float deltaTime ){
    75.         this.target        = this.target +rawDelta;    //update Target
    76.         Update(dampLambda, deltaTime);
    77.     }
    78.  
    79.     /// <summary>Update Buffer</summary>
    80.     public    void Update( float dampLambda, float deltaTime, bool byPass = false ){
    81.         Vector2 last    = buffer;            //last state of Buffer
    82.         this.buffer        = byPass? target : DampToTargetLambda( buffer, this.target, dampLambda, deltaTime);    //damp current to target
    83.         this.curDelta    = buffer -last;
    84.         this.curAbs        = buffer;
    85.     }
    86.     public static Vector2        DampToTargetLambda( Vector2    current,        Vector2        target,        float lambda, float dt){
    87.         return Vector2.        Lerp(current, target, 1F -Mathf.Exp( -lambda *dt) );
    88.     }
    89. }
    90.  
    91.     #endregion Helpers
    if you also have the jump problem with this script, a definite fix for above script would be adding "return;" after setting the Lockstate to stop the current frame from fetching mouse deltas. "CursorLockMode.Locked; return;" But the problem didn't appear for me so i left it out for now because the Lockstate might be controlled from elsewhere.

    You can also just switch .rotation for .localRotation if you need it. It won't breaking anything.

    The only thing that might be missing is angle wrapping since this script controls via a degree angle. Floating point inaccuracies might therefore bite you at angle values of more than 100000F
     
    Last edited: Jun 20, 2018
    HonoraryBob likes this.
  17. HonoraryBob

    HonoraryBob

    Joined:
    May 26, 2011
    Posts:
    1,214
    Thank you. I just needed to make sure the above line is only run when mouse is locked, and it fixed the problem.
     
  18. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    Did you try my script too :D? The smoothing of the script you currently use is totally frame rate dependent, and that is bad.
     
  19. ngerbens

    ngerbens

    Joined:
    Nov 20, 2017
    Posts:
    33
    Thanks for this great script!
    I have one question. When in press X in my script it makes my player/camera turn towards the nearest enemy. But when I release X the player/camera turn back to the old position of this script.

    How can I make this script 'refresh/update' the position of the mouse after there has been a transform/rotation outside this script?
     
  20. Flippette

    Flippette

    Joined:
    Dec 22, 2018
    Posts:
    1
    Oh my god... I've been struggling to make the camera look at the mouse, and you made the script and allowed people to use it... You're literally my hero! :)
     
  21. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,550
    Late response, but changing Update() to LateUpdate() should solve that for most cases. But if there are also LateUpdate() scripts changing positions, then another option is to put this script very late in your Script Execution Order in Project Settings.
     
    ngerbens likes this.
  22. ngerbens

    ngerbens

    Joined:
    Nov 20, 2017
    Posts:
    33
    Thank you very much!
     
  23. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    Has anyone tested this so far?

    Features:
    - frame rate independent smoothing
    - pitch clamping
    - smoothing-bypass
    - on/off switch
    - cursor LockState control coupled to on/off, if needed
     

    Attached Files:

  24. ben_unity214

    ben_unity214

    Joined:
    May 7, 2018
    Posts:
    4
    I stumbled onto this via a Google search after recommendations I smooth out the mouse following publishing a trailer for my game. I somebody able to give me a totally idiot-proof guide into how to incorporate this into a game where I'm already using a (slightly modified) version of the standard Unity mouselook.cs script? Any attempt to copy/paste the code yields a load of compiler errors, suggesting I would have to completely re-write my first person controller, which I'd rather avoid if I can help it. Big thanks in advance.
     
  25. saltysquid

    saltysquid

    Joined:
    May 1, 2017
    Posts:
    41
    Marrt - I tested your script and it works well for what I'm doing (Thank You!). I'm playing with it now trying to get the mouse movement to control the camera so my player can look straight up or down. I still want side-to-side motion to rotate the player, but if they were to move up or down I want to "look around" :D This of course also needs to be constrained so they can't look up so far the world goes upside down.

    EDIT: It seems the script posted by Invertex does what I described. A combination of both scripts solved my issue. Thanks Marrt and Invertex
     
    Last edited: Jun 16, 2019
    Invertex and neighborlee like this.
  26. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    If i understood you correctly you need to restrict pitch? I can offer you my expert script, it allows for a special softPitchClamp.

    I need it for my gyroscope-aim games. There, the player can easily hit the clamping pitch by rotating his phone. When this happens, every additional movement will get dropped of course. This causes the normal point of aim to change. (After hitting the bottom pitch clamp, when you rotate the phone back to the original rotation you will now aim higher) . With my Soft-clamp you make hitting the clamp value much harder thereby retaining the natural pitch when returning from high or low aims.


    How does it work? The soft pitchClamp remaps the pitch after input to a broader range:
    • RED: When your pitch is below half of your pMax ( about 40° in graph), the mapping is 1:1, nothing differs from normal input
    • BLUE: When your pitch exceeds half of you pMax, the amount of pitch-change your input would create will be remapped.
    upload_2019-6-16_14-28-6.png

    Now, in order to hit the direction where the pitch gets clamped, the player needs about 50% more mousemovement. I would advice this only for games where you don't need to aim up and down a lot.
     

    Attached Files:

    csofranz likes this.
  27. neighborlee

    neighborlee

    Joined:
    Jan 26, 2016
    Posts:
    50
    Two years old I know, and I don't know ifthis is the same, as what now comes in 2019.2.17f1, but if so, and BETTER than nothing, atleast NOW I can easier create art as I go around level, wish I"d found this earlier, but unity doesn't have any TUTS that showcase this as at least a 'starting point'.

    Having said that, I can't get the movement either horizintal vertical to be 'smoother', is that the euler issue prior person was talking about ?If so I agree. ITS very hard to control mouse movement when there is no damping(?) I guess would be the operative word .

    TY , I can rest easier knowing at least I came explore my scene for testing!
    HOPe there is a way to make rotation around player (up and down) as tight and smooth ( fast but stable as well)as what ue4 gives you out of the box,,IF anyone knows what I mean,that would be very helpful
     
  28. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,550
    The euler issue generally shouldn't be an issue if the vertical rotation isn't near an extreme while doing the horizontal rotation. But if you stick to Quaternion based operations you shouldn't run into this issue at all.

    If you're talking about choppiness in your rotation, that may be a result of you not multiplying changes by Time.deltaTime where needed to ensure framerate doesn't cause speed changes which will be perceived as instability/choppiness, to put it simply.
     
  29. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    I may sound needy of appreciation, but... Just use my script already
    https://forum.unity.com/threads/a-free-simple-smooth-mouselook.73117/page-2#post-4652755
     
    FaberVi likes this.
  30. FaberVi

    FaberVi

    Joined:
    Nov 11, 2014
    Posts:
    146
  31. Marrt

    Marrt

    Joined:
    Feb 7, 2012
    Posts:
    613
    FaberVi likes this.
  32. demonpants

    demonpants

    Joined:
    Oct 3, 2008
    Posts:
    82
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.AI;
    3.  
    4. [RequireComponent(typeof(NavMeshAgent))]
    5. public class Navigator : MonoBehaviour
    6. {
    7.     [SerializeField]
    8.     [Tooltip("This is the camera we control the orientation of as we look around.")]
    9.     protected Camera lookCamera;
    10.  
    11.     [SerializeField]
    12.     [Tooltip("The sensitivity of the mouselook controls for the camera.")]
    13.     protected Vector2 lookSensitivity = new Vector2(150, 150);
    14.  
    15.     [SerializeField]
    16.     [Tooltip("We will store this many previous mouselook deltas and average them to smooth the behavior.")]
    17.     protected int lookBufferLength = 3;
    18.  
    19.     [SerializeField]
    20.     [Tooltip("Controls how the view bobs as we walk.")]
    21.     protected CameraBobProperties cameraBobProperties;
    22.  
    23.     [System.Serializable]
    24.     public struct CameraBobProperties
    25.     {
    26.         [Tooltip("When we are stopped, the view bobs this many times per second.")]
    27.         public float minFrequency;
    28.  
    29.         [Tooltip("When we are at maximum speed, the view bobs this many times per second.")]
    30.         public float maxFrequency;
    31.  
    32.         [Tooltip("At its maximum bob amplitude, the camera has travelled this far along the Y axis.")]
    33.         public float height;
    34.  
    35.         [Tooltip("We interpolate the camera to its target position at this speed.")]
    36.         public float lerpSpeed;
    37.     }
    38.  
    39.     protected NavMeshAgent agent;
    40.     protected Vector2[] lookBuffer;
    41.     protected float initialCameraYOffset;
    42.  
    43.     public void Awake()
    44.     {
    45.         agent = GetComponent<NavMeshAgent>();
    46.  
    47.         //initialize the mouselook buffer.
    48.         //there is no need to fill this - default (0,0) values are perfect
    49.         lookBuffer = new Vector2[lookBufferLength];
    50.  
    51.         initialCameraYOffset = lookCamera.transform.position.y - transform.position.y;
    52.     }
    53.  
    54.     public void Update()
    55.     {
    56.         UpdateMouseLook();
    57.         UpdateMovement();
    58.         UpdateViewBob();
    59.     }
    60.  
    61.     protected void UpdateMouseLook()
    62.     {
    63.         Vector2 delta = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
    64.         delta *= lookSensitivity.x * Time.deltaTime;
    65.         Vector2 rotAverage = delta;
    66.  
    67.         //as we average the rotations, cycle the look buffer and add in the new delta at the end
    68.         for ( int lookBufferIndex = 0; lookBufferIndex < lookBufferLength - 1; lookBufferIndex++ )
    69.         {
    70.             lookBuffer[lookBufferIndex] = lookBuffer[lookBufferIndex+1];
    71.             rotAverage += lookBuffer[lookBufferIndex];
    72.         }
    73.         lookBuffer[lookBufferLength-1] = delta;
    74.         //calculate the average
    75.         rotAverage.x /= lookBufferLength;
    76.         rotAverage.y /= lookBufferLength;
    77.         //apply the results
    78.         transform.Rotate(0f, rotAverage.x, 0f, Space.World);
    79.  
    80.         //constrain the camera so it can't flip around
    81.         Vector3 cameraRot = lookCamera.transform.eulerAngles;
    82.         cameraRot.x = NormalizeAngle( cameraRot.x - rotAverage.y );
    83.         if ( cameraRot.x < 90.0f || cameraRot.x > 270.0f )
    84.         {
    85.             lookCamera.transform.eulerAngles = cameraRot;
    86.         }
    87.     }
    88.  
    89.     protected void UpdateMovement()
    90.     {
    91.         //move relative to the look camera, but we need to remove the Y changes and normalize it
    92.         Vector3 posDelta = lookCamera.transform.forward * Input.GetAxis("Vertical") +
    93.                             lookCamera.transform.right * Input.GetAxis("Horizontal");
    94.         posDelta.y = 0.0f;
    95.         posDelta.Normalize();
    96.  
    97.         //tell the nav agent to move along the grid
    98.         Vector3 targetPos = transform.position + (Vector3) posDelta;
    99.         agent.SetDestination( targetPos );
    100.     }
    101.  
    102.     protected void UpdateViewBob()
    103.     {
    104.         float velMag = agent.velocity.magnitude;
    105.         if (velMag <= 0.0f)
    106.         {
    107.             return;
    108.         }
    109.  
    110.         float speedNormal = velMag / agent.speed;
    111.         float frequency = cameraBobProperties.minFrequency + speedNormal *
    112.                         (cameraBobProperties.maxFrequency - cameraBobProperties.minFrequency);
    113.         float t = Time.time * frequency;
    114.         float bob = Mathf.Sin(t * 2.0f * Mathf.PI) * cameraBobProperties.height;
    115.  
    116.         Vector3 cameraTargetPos = transform.position + new Vector3(0, initialCameraYOffset + bob, 0);
    117.         lookCamera.transform.position = Vector3.Lerp(lookCamera.transform.position, cameraTargetPos, cameraBobProperties.lerpSpeed);
    118.     }
    119.  
    120.     protected float NormalizeAngle( float angleDeg )
    121.     {
    122.         return  ( ( angleDeg % 360.0f ) + 360.0f ) % 360.0f;
    123.     }
    124. }
    125.  
    Here's one I whipped up that includes movement, camera orientation, and a camera bob as the character moves. Uses a NavMeshAgent to move around, but easy enough to change to whatever you want.
     
  33. ptracy

    ptracy

    Joined:
    Sep 13, 2018
    Posts:
    5
    Thank you @FatiguedArtist for sharing such an awesome FPS look script. With a little tweaking, this completely solved the subtle jittery, laggy look movements my mouse was causing my camera. You can see your script working on Newgrounds here: https://www.newgrounds.com/portal/view/808407
    Thanks again and let me know if you'd like me to add your info to the credits section, both in game and on the page.
     
    Kurt-Dekker likes this.
  34. ZeHgS

    ZeHgS

    Joined:
    Jun 20, 2015
    Posts:
    117
    Last edited: Apr 16, 2022
  35. af894464

    af894464

    Joined:
    May 5, 2022
    Posts:
    1
    it gaves me error. because the var xRotation. and it gaves me error.
     
  36. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,727
    Please don't necro-post to 12-year-old threads for your own typing mistakes.

    Just go fix your typing mistakes. Here's how:

    The complete error message contains everything you need to know to fix the error yourself.

    The important parts of the error message are:

    - the description of the error itself (google this; you are NEVER the first one!)
    - the file it occurred in (critical!)
    - the line number and character position (the two numbers in parentheses)
    - also possibly useful is the stack trace (all the lines of text in the lower console window)

    Always start with the FIRST error in the console window, as sometimes that error causes or compounds some or all of the subsequent errors. Often the error will be immediately prior to the indicated line, so make sure to check there as well.

    Look in the documentation. Every API you attempt to use is probably documented somewhere. Are you using it correctly? Are you spelling it correctly?

    All of that information is in the actual error message and you must pay attention to it. Learn how to identify it instantly so you don't have to stop your progress and fiddle around with the forum.

    Remember: NOBODY here memorizes error codes. That's not a thing. The error code is absolutely the least useful part of the error. It serves no purpose at all. Forget the error code. Put it out of your mind.

    Tutorials and example code are great, but keep this in mind to maximize your success and minimize your frustration:

    How to do tutorials properly, two (2) simple steps to success:

    Step 1. Follow the tutorial and do every single step of the tutorial 100% precisely the way it is shown. Even the slightest deviation (even a single character!) generally ends in disaster. That's how software engineering works. Every step must be taken, every single letter must be spelled, capitalized, punctuated and spaced (or not spaced) properly, literally NOTHING can be omitted or skipped.

    Fortunately this is the easiest part to get right: Be a robot. Don't make any mistakes.
    BE PERFECT IN EVERYTHING YOU DO HERE!!


    If you get any errors, learn how to read the error code and fix your error. Google is your friend here. Do NOT continue until you fix your error. Your error will probably be somewhere near the parenthesis numbers (line and character position) in the file. It is almost CERTAINLY your typo causing the error, so look again and fix it.

    Step 2. Go back and work through every part of the tutorial again, and this time explain it to your doggie. See how I am doing that in my avatar picture? If you have no dog, explain it to your house plant. If you are unable to explain any part of it, STOP. DO NOT PROCEED. Now go learn how that part works. Read the documentation on the functions involved. Go back to the tutorial and try to figure out WHY they did that. This is the part that takes a LOT of time when you are new. It might take days or weeks to work through a single 5-minute tutorial. Stick with it. You will learn.

    Step 2 is the part everybody seems to miss. Without Step 2 you are simply a code-typing monkey and outside of the specific tutorial you did, you will be completely lost. If you want to learn, you MUST do Step 2.

    Of course, all this presupposes no errors in the tutorial. For certain tutorial makers (like Unity, Brackeys, Imphenzia, Sebastian Lague) this is usually the case. For some other less-well-known content creators, this is less true. Read the comments on the video: did anyone have issues like you did? If there's an error, you will NEVER be the first guy to find it.

    Beyond that, Step 3, 4, 5 and 6 become easy because you already understand!

    Finally, when you have errors, don't post here... just go fix your errors! See above!
     
Thread Status:
Not open for further replies.