Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Camera Slerp and RotateAround

Discussion in 'Scripting' started by Benji23245, Aug 8, 2023.

  1. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    Hello !

    I've started working on the camera for my game and am currently facing issues :
    I'm setting the position of the camera to my player's using a Slerp, and this is called in LateUpdate.

    1st issue is, the camera is super jittery, even though I called the method to set its position in LateUpdate.
    2nd issue is, I want to rotate around the player as well, when using the right analog stick. But since I set the position, it doesn't work.

    Do you have insights on how to make it work ?

    Thank you !
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,711
  3. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    Oh so I should not build my own cam system ?

    Is that what you do yourself ?
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,711
    That is not what I said. Please read my post above again.

    I have written my own and I have used cinemachine.

    If you want to debug your own, well, then...

    Time to start debugging! Here is how you can begin your exciting new debugging adventures:

    You must find a way to get the information you need in order to reason about what the problem is.

    Once you understand what the problem is, you may begin to reason about a solution to the problem.

    What is often happening in these cases is one of the following:

    - the code you think is executing is not actually executing at all
    - the code is executing far EARLIER or LATER than you think
    - the code is executing far LESS OFTEN than you think
    - the code is executing far MORE OFTEN than you think
    - the code is executing on another GameObject than you think it is
    - you're getting an error or warning and you haven't noticed it in the console window

    To help gain more insight into your problem, I recommend liberally sprinkling
    Debug.Log()
    statements through your code to display information in realtime.

    Doing this should help you answer these types of questions:

    - is this code even running? which parts are running? how often does it run? what order does it run in?
    - what are the names of the GameObjects or Components involved?
    - what are the values of the variables involved? Are they initialized? Are the values reasonable?
    - are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

    Knowing this information will help you reason about the behavior you are seeing.

    You can also supply a second argument to Debug.Log() and when you click the message, it will highlight the object in scene, such as
    Debug.Log("Problem!",this);


    If your problem would benefit from in-scene or in-game visualization, Debug.DrawRay() or Debug.DrawLine() can help you visualize things like rays (used in raycasting) or distances.

    You can also call Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene manually, looking for all the parts, where they are, what scripts are on them, etc.

    You can also call GameObject.CreatePrimitive() to emplace debug-marker-ish objects in the scene at runtime.

    You could also just display various important quantities in UI Text elements to watch them change as you play the game.

    Visit Google for how to see console output from builds. If you are running a mobile device you can also view the console output. Google for how on your particular mobile target, such as this answer for iOS: https://forum.unity.com/threads/how-to-capturing-device-logs-on-ios.529920/ or this answer for Android: https://forum.unity.com/threads/how-to-capturing-device-logs-on-android.528680/

    If you are working in VR, it might be useful to make your on onscreen log output, or integrate one from the asset store, so you can see what is happening as you operate your software.

    Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.

    If your problem is with OnCollision-type functions, print the name of what is passed in!

    Here's an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

    https://forum.unity.com/threads/coroutine-missing-hint-and-error.1103197/#post-7100494

    "When in doubt, print it out!(tm)" - Kurt Dekker (and many others)

    Note: the
    print()
    function is an alias for Debug.Log() provided by the MonoBehaviour class.
     
  5. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    Thanks for the reply, but I’m not sure I understand why you’re telling me all this ?

    I was thinking maybe use a Rigidbody on the camera to apply velocity towards the player instead of setting it’s position directly ?

    Is it something Unity devs do ?
     
  6. ijmmai

    ijmmai

    Joined:
    Jun 9, 2023
    Posts:
    188
    I found this vid useful as a starting point. He uses a parent camera rig, you could make the player as a parent.
     
  7. faUnity

    faUnity

    Joined:
    Aug 7, 2023
    Posts:
    14
    Not sur i understood your context but this is for Not moving object.
    you need to create an empty child of your game object and place it where you want the cam to be placed.
    it's camPos in the script.
    Note that, depending on the cam position and rotation before you move it, you can have a snap due to the LookAt()
    behaviour. You can use Quaternion.LookRotation() instead.

    Code (CSharp):
    1. public class Testcamera : MonoBehaviour
    2. {
    3.     public Transform target;//the game object.
    4.     public Transform camPos;//a reference to where we want to place the camera.
    5.     private Vector3 offset; //Constant Offset : the relative position to the game object.
    6.     float y;//the angle on the Y axis.
    7.  
    8.     void Start()
    9.     {
    10.         offset = target.position - camPos.position;
    11.     }
    12.     private void LateUpdate()
    13.     {
    14.         y += Input.GetAxis("Horizontal");
    15.         Quaternion rotation = Quaternion.Euler(0, y, 0);
    16.  
    17.         //Setting the camera position/rotation.
    18.         transform.position = Vector3.MoveTowards(transform.position, target.position - (rotation * offset), 0.2f);
    19.         transform.LookAt(target);
    20.     }
    21. }
    22.  
     
  8. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,844
    Despite being the first thing many new devs jump into, coding a functioning camera system can be pretty intermediate to advanced stuff. You're very likely to make little progress and end just frustrated and give up.

    Hence the suggestion to use Cinemachine which lets you do a lot of camera stuff out of the box with zero coding work. You would prefer to be focusing on the more fun features of your game after all, wouldn't you?
     
  9. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    Well I have to say I didn't think the camera would be so tricky (but from everywhere's I've read, it appears to be though). So I have to say if even professional devs use it, I guess I'll use it too !

    I would just like to understand one thing : I've read Cinemachine covers about 99% of anyone's camera needs.
    But what is this 1% it doesn't cover ? I'm curious.

    Also, if I'm in this 1% situation at some point, will I be able to easily code what I need and plug it to the Cinemachine behavior ?
     
  10. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,844
    The only situation I've had where cinemachine wasn't enough was when dealing with variable gravity, and having to change 'up' for the camera as gravity changed.

    Though the cinemachine API is very open and resuable as well, so it's not too hard to make use of it in your own way.

    The idea is you don't get stuck indefinitely on something too difficult for a beginner, so you can continue the learning process so that you can reach a point where you can code your own camera system.

    Sometimes as a newbie you do have to admit something is too hard for the moment, and tackle something else in the meantime.

    But this depends on the type of camera system you are using in particular. You, admittedly, didn't tell us what type of game you're making. A panning isometric RPG camera is a lot easier than a full 3d orbit camera, for example.
     
    Kurt-Dekker likes this.
  11. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    Well, I'm making a fan Sonic game. With a mixed gameplay of the adventure games (SA1, SA2) and the boost game (Sonic Unleashed).

    In my head what I needed :

    - Make it follow the player with some Lerp
    - Rotate around the player when using the Right stick while still taking into account the player position
    - Rotate when the player goes sideways (so that the camera aims to go behind the player, as you would expect in a Sonic game)
    - Manage objects/walls collision so that it doesn't go through things etc

    I honestly thought it was hard but doable, like some feature I made were hard but I ended up making them work (the grind feature using Bezier splines for example, which I made from scratch, and was as hard as it was fun ^^)
     
  12. faUnity

    faUnity

    Joined:
    Aug 7, 2023
    Posts:
    14
    Not very recomended for follow cameras. Better setting the position according to the offset wich is the relative position to the game object.

    Code (CSharp):
    1. transform.position = target.position - offset;
    in a general case...
     
    Last edited: Aug 10, 2023
  13. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,844
    I would say this would be an even worse camera experience. Definitely a very basic one. Though there's lots of various ways, no one better than the other.

    The most common best-practice method used for camera is to have the camera the child of an empty, and it's the empty itself that follows the player around instead. Methods like
    Vector3.SmoothDamp
    are good choices for having a camera smoothly move towards the player with a degree of elasticity.

    Lerp can also work but you do need know some maths trickery.

    Okay a sonic game definitely has lots of out-there camera stuff, especially when we're dealing with going upside down with loop-de-loops. But that's not far off from what I'm working on - which is a puzzle platformer with some gravity elements - so I can give you some pointers.

    I opted to use the Cinemachine Free-look camera, as that handles all the smooth following and orbiting stuff out of the box, and have it follow/target an empty game object that is coded to follow the player via
    Vector3.SmoothDamp
    .

    To deal with gravity, firstly I locked the cinemachine virtual camera to the empty with the following setting: upload_2023-8-9_19-51-36.png

    Then it's a matter of rotating your empty to follow the direction of what is specifically 'up' at any given point of time. In my case it just smoothly rotates to face the current direction of gravity.
     
  14. Benji23245

    Benji23245

    Joined:
    May 7, 2020
    Posts:
    127
    Thanks for the info dude !

    I have a few questions though :

    - You talked about making the camera a child of an empty which follows the player, and then you talked about have it follow and empty which in turn follows the player. Are these 2 seperate ways of doing ?

    - Why not directly have it follow the player, why do we need an empty ?

    - Why is SmoothDamp better than Lerp/Slerp ?

    Thanks for the infos, I really appreciate it ^^
     
  15. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,844
    Cinemachine uses virtual cameras rather than an actual camera. The actual main camera then locks to whatever the current active virtual camera is.

    The free-look camera takes a target that it follows, akin to having camera the child of an empty. Because I need my camera to orient itself to 'up', it follows the empty, of which follows the player.

    It's worth mentioning in my project the player is a rolling ball. I can't lock it to the player because otherwise the camera would spin around all the time. So I need something that stands in between the two. On top of that...

    Your camera isn't always going to be looking at the player. You may want to make the camera move to points of interest, other characters, etc. Thus, having the camera follow an empty, of which is only loosely coupled to a non-specific target - often the player - is a common and flexible approach, allowing you to still have the camera move to different things as necessary.

    I mostly say this because SmoothDamp achieves the effect you want in this particular situation. It moves to a position with elasticity, as mentioned. It literally says in the docs:
    You can do the same with lerp but you need to calculate an exponential falloff... which is basically doing the same thing as
    Vector.SmoothDamp
    . So why bother?

    And also most people misuse Lerp, honestly.
     
  16. faUnity

    faUnity

    Joined:
    Aug 7, 2023
    Posts:
    14
    yeah, me too i'd like to make gran turismo 2024




     
    Last edited: Aug 10, 2023