How can i make a camera rotate automatically after a while around a object

Hello coders, I have a simple question.
I have been playing this game recently and i wanted to have the camera mechanics much like it, as it’s well done, useful. and looks great. The camera system i’m talking about is the garage camera in CSR 2, if you don’t know what it is i’ll explain. When you are in the garage. the camera is set to the car. and can’t move in different position then rotating around it. From up to down till the floor coliders, and the top view. and left to right around the vehicle. the camera starts roltating automatically after 30 seconds of inactivity. but you can also use the touch screen to roltate it. i wanted to do this myself. but i didn’t get the camera to work with it. Does anyone know how i can make this?

This is currently how it works.
Imgur: The magic of the Internet it rotates around the car. but i can’t use the touch screen or mouse to move the camera. and it starts to imidiately rotate.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraRotate : MonoBehaviour
{
   public float speed;
   void Update (){
       transform.Rotate(0, speed * Time.deltaTime, 0);
   }
}

In order to stop it from rotating all the time, track when the user goes idle and how much time passed since then. Then only start the idle rotation if enough time has passed since then. You also probably want to rotate around an object. All in all, the below code example should do what you want. You only need to replace the contents of isIdle() with whatever makes a player idle or not in your case. For testing purposes i added the playerIdling bool, which you can set in the inspector. You’ll see that the rotation starts timeBeforeRotate-many seconds after the bool is changed to true.

public class IdleCamRotation : MonoBehaviour
{
    [SerializeField] private float speed;
    [SerializeField] private float timeBeforeRotate = 2f;
    [SerializeField] private Transform rotateAround;
    private float lastTimeNotIdle;

    [SerializeField] private bool playerIdling = true; // testing variable only!


    // Start is called before the first frame update
    void Start()
    {
        lastTimeNotIdle = Time.realtimeSinceStartup; // initialize at "now"
    }

    // Update is called once per frame
 
    void Update()
    {
        // Check if the player is idle
        if (!isIdle())
        {
            // When we are not idling, update the time of last non-idle action
            lastTimeNotIdle = Time.realtimeSinceStartup;
        }

        // Calculate how long we are idling
        float diff = Time.realtimeSinceStartup - lastTimeNotIdle;

        // Only rotate when we waited timeBeforeRotate seconds after the last user action
        if (diff > timeBeforeRotate)
        {
            transform.RotateAround(rotateAround.position, Vector3.up, speed);
        }
    }

    private bool isIdle()
    {
        // Code for whatever makes a player idle or not idle in your situation
        return playerIdling;
    }
}

As for figuring out when the player is idling or not, it probably makes sense to make lastTimeNotIdle (or better call it lastActionTime) a global variable and update it to “now” whenever the player does something that is not idling - for example tapping the screen. Needless to say, going with this approach you can remove the whole isIdle() method and so on from the above example, since the idle status is then tracked implicitely by updating the time variable each time the player does something.

1 Like

Thanks that worked for the idle part. But the camera doesn’t allow to be moved with mouse or touch screen. (I’m making it a mobile game so best to adjust it to mobile) so all i would need more is zooming. and the camera movement with one finger.

Well, sure. Of course it doesnt, because we never made it do that :wink:
To be honest, there are a tons of tutorials on normal camera rotation, so i thought i’d focus on the idle camera part.

To move the camera via mouse, simply get the mouse inputs and use another transform.RotateAround, where the horizontal mouse input influences the speed. For the other mouse axis (up-down instead left-right) change the axis of rotation from Vector3.up to Vector3.right. Again, there are plenty of tutorials on this if you have problems. As for touch… i have not really worked with touch, but since touch without gestures is basically the same as a mouse pointer, i imagine it works pretty much the same. I’d get the mouse one to work first, so you get a feel for it. Then introducing touch shouldnt be too hard.

Hmm. It doesn’t seem to work for me. it doesn’t give errors, but it doesn’t move either. maybe i got the code wrong or the placement wrong. Could you help me out there?

I feel like you are missing some understanding. Please try to google for “Mouse Orbit Unity” or something along those lines, follow a tutorial, try to understand how it works and implement it in another script. Now you have a working script that allows you to move the camera with your mouse, and another script that allows you to automatically rotate around an object when idle. Now you can try to combine the two.

I’m really not a huge fan of just posting full solutions, but rather helping people fix a specific problem after they tried it themselves and ran into a problem they cant fix. Give a man a fish and he will return tomorrow, asking for another. Teach a man how to fish and he is well fed for the rest of his life.

1 Like

It’s not that i need a full code. but rather a solution. cause what i have is the script you gave, which rotates it after given time. and the orbit script. but the camera doesn’t move. it only works as in looking around. follows the mouse location.
I’m not an real advanced coder. i’m trying to learn, and understand which every part of a code does. But i want it to be able to rotate around the car using the mouse click as well. not the mouse cursor location. If it makes sense to you how i described it.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ManualCameraRotate : MonoBehaviour
{
    public float speedH = 2.0f;
    //public float speedV = 2.0f;

    private float yaw = 0.0f;
    private float pitch = 0.0f;



    // Use this for initialization
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {

        yaw += speedH * Input.GetAxis("Fire1");
        //pitch -= speedV * Input.GetAxis("Fire1");

        transform.eulerAngles = new Vector3(pitch, yaw, 0.0f);

    }
}

this is what i currently have setup in the script that manages the manual rotation from the player. and it’s asigned to fire1 (Mouse0) but this happens
https://i.imgur.com/fbwkFwR.mp4

it does rotate now. but at the wrong position not around the car. but at the camera point. and it’s only one sided.

If you manage to move the camera left and right with mouse input, then you are probably setting its position instead of using transform.RotateAround similar to the example above. Do it like this for example:

        Vector2 mouseInput = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));
        if (mouseInput != Vector2.zero)
        {
            lastTimeNotIdle = Time.realtimeSinceStartup;
            transform.RotateAround(rotateAround.position, Vector3.up, speed * mouseInput.x);
            // Do whatever else based on the mouse input
        }
1 Like

Yes that did it. I changed the Void Update() with that code. And added Serialized fields for RotateAround and speed not it works. it does follow my mouse x and y position. i’m not sure if that’ll cause confilicts for mobile but it works now. Much appereciated.