Orbiting camera or rotating an object

Hi guys,
I’m learning a bit of C# and would like some help here :
I have a camera with a script to control its orbit around an object. It’s using Input.GetAxis (“Mouse X”), Input.GetAxis (“Mouse Y”) with Input.GetMouseButton(0).
And I also have a GameObject with a script to rotate (the object) on drag It’s using
void OnMouseDrag and Input.GetAxis (“Mouse X”)

My problem is when I rotate the object, the camera keeps rotating too.
I would like the camera to stop orbiting when the objects rotate.
But I don’t know how. Events Maybe ?

Here are the scripts (taken from the web) :
Camera orbit :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ThirdPersonCamera : MonoBehaviour
{
private bool isOrbiting;
private const float Y_ANGLE_MIN = -80/3.0f;
private const float Y_ANGLE_MAX = 50/3.0f;
public Transform lookat;
public Transform camTransform;
private Camera cam;
public float distance = 200.0f;
private float currentX = 0.0f;
private float currentY = 0.0f;
private float sensivityX = 4.0f;
private float sensivityY = 1.0f;
private void Start()
{
camTransform = transform;
cam = Camera.main;
}
private void Update()
{
if (Input.GetMouseButtonDown (0))
{
isOrbiting = true;
}
// Disable movements on button release
if (!Input.GetMouseButton(0)) isOrbiting=false;
if (isOrbiting)
{
currentX += Input.GetAxis ("Mouse X");
currentY += Input.GetAxis ("Mouse Y");
}
currentY = Mathf.Clamp (currentY, Y_ANGLE_MIN, Y_ANGLE_MAX);
}
private void LateUpdate()
{
Vector3 dir = new Vector3 (0, 0, -distance);
Quaternion rotation = Quaternion.Euler (-currentY*3, currentX*3, 0);
camTransform.position = lookat.position + rotation * dir;
camTransform.LookAt (lookat.position);
}
}

And the Object Rotate:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Clic_Rot_LUN_DEC : MonoBehaviour
{
float rotspeed = 6 ;
void OnMouseDrag()
{
float rotx = Input.GetAxis ("Mouse X") * rotspeed*Mathf.Deg2Rad;
transform.RotateAround (Vector3.up, -rotx);
}
}

You should set up a boolean for when you’re rotating the object.
Make the Camera check that boolean before proceeding to orbit.

Oh, great, thank you ! :slight_smile:
How do I access one script from another script (I’m going to look for a tut, but if you do have a method or a proposal, I’m all for it)

If there is only one ThirdPersonCamera you could use static variables.
(Another way would be to create references to the script you’re wanting to access by declaring a public variable and assigning the script in the unity inspector)

inside ThirdPersonCamera add this

public static bool allowedToRotate = true;

inside Clic_Rot_LUN_DEC you could do something like this

OnMouseDrag() {
    ThirdPersonCamera.allowedToRotate = false;
}

OnMouseExit() {
    ThirdPersonCamera.allowedToRotate = true;
}

This will cause issues when you have multiple rotate objects overlapping though, but there are workarounds for that.

Let me know if this helped you in any way!

uh oh
I’m a little lost. Sorry.
Is it not :
void OnMouseDrag(){
ThirdPersonCamera.allowedToRotate = false;

?

Anyway, going to try :slight_smile:

Well, without “void” it gives an error message.
And

void OnMouseDrag(){
        float rotx = Input.GetAxis ("Mouse X") * rotspeed*Mathf.Deg2Rad;
        transform.RotateAround (Vector3.up, -rotx);
        ThirdPersonCamera.allowedToRotate = false;
    }

        void OnMouseExit(){
        ThirdPersonCamera.allowedToRotate = true;
    }

inserted in the actual code of Clic_Rot_LUN_DEC does’t produce any change.
I’m certainly dumb, but please forgive me I’m barely know what I’m doing :confused:

@jeannel It is indeed with the void in front of the method names.
Also in ThirdPersonCamera you have to wrap the LookAt call within the following if-statement like this:

if (allowedToRotate) {
    camTransform.LookAt (lookat.position);
}

Preferrably you’d put the entire Update method between this if-statement.

I’ll try that tommorrow. I’ll let you know, thanks for your great support !

This worked awesomly well ! Thank’s a lot for your great help ! :slight_smile:

Here’s what’s on the camera :

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

public class ThirdPersonCamera : MonoBehaviour
{
    public static bool allowedToRotate = true;
       
    private bool isOrbiting;
    private bool isZooming;

    private const float Y_ANGLE_MIN = -80/3.0f;
    private const float Y_ANGLE_MAX = 50/3.0f;

    public Transform lookat;
    public Transform camTransform;



    private Camera cam;

    public float distance = 200.0f;
    private float currentX = 0.0f;
    private float currentY = 0.0f;
    private float sensivityX = 4.0f;
    private float sensivityY = 1.0f;

    private void Start()
    {
        camTransform = transform;
        cam = Camera.main;
    }

    private void Update()
    {
       
        if (Input.GetMouseButtonDown (0))
        {           
            isOrbiting = true;
        }

        // Disable movements on button release
        if (!Input.GetMouseButton(0)) isOrbiting=false;

        if (isOrbiting && allowedToRotate)
        {
            currentX += Input.GetAxis ("Mouse X");
            currentY += Input.GetAxis ("Mouse Y");
        }

        currentY = Mathf.Clamp (currentY, Y_ANGLE_MIN, Y_ANGLE_MAX);
    }

    private void LateUpdate()
    {
        distance += Input.GetAxis ("Mouse ScrollWheel")*5;

        Vector3 dir = new Vector3 (0, 0, -distance);
        Quaternion rotation = Quaternion.Euler (-currentY*3, currentX*3, 0);
        camTransform.position = lookat.position + rotation * dir;
        camTransform.LookAt (lookat.position);


    }
}

I changed the code a bit, added this

  if (isOrbiting && allowedToRotate)

and for the rotating object, I did as you said :

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

public class Clic_Rot_LUN_DEC : MonoBehaviour {
   
    float rotspeed = 4 ;

        // Use this for initialization
    void Start () {}
   
    // Update is called once per frame
    void Update () {}

    void OnMouseExit(){
        ThirdPersonCamera.allowedToRotate = true;
    }
    void OnMouseDrag(){
        ThirdPersonCamera.allowedToRotate = false;
        float rotx = Input.GetAxis ("Mouse X") * rotspeed*Mathf.Deg2Rad;
        transform.RotateAround (Vector3.up, -rotx);
    }

}

There’s still a litlle hiccup, nothing too important though :
If I rotate (on mouse drag) the object, and the mouse pointer goes out of the game window, it seems the OnMouseExit is not detetected and the ThirdPersonCamera.allowedToRotate stays false;
So I have to clic on the object again to “force” the OnMouseExit and be able to orbit the camera.

And I have a question : Why the public static bool allowedToRotate = true;
why does it need to be a “static” variable ?

Thank’s a lot

So finally the hiccup was something different.
When I click and drag, if the pointer while dragging got outside of the object, then the OnMouseExit was not detected. “allowedToRotate” staued false until I reclick the object.
Replacing the OnMouseExit with OnMouseUp, solved the problem !
:slight_smile:

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

public class Clic_Rot_LUN_DEC : MonoBehaviour {
   
    float rotspeed = 4.0f ;

        // Use this for initialization
    void Start () {}
   
    // Update is called once per frame
    void Update ()     {}

    void OnMouseDrag(){
        ThirdPersonCamera.allowedToRotate = false;
        float rotx = Input.GetAxis ("Mouse X") * rotspeed*Mathf.Deg2Rad;
        transform.RotateAround (Vector3.up, -rotx);
    }
    void OnMouseUp(){
        ThirdPersonCamera.allowedToRotate = true;
    }
}
1 Like

@jeannel
Good to see that you solved the dragging out of the window issue.

You don’t need the variable to be static.
You could alternatively add

public ThirdPersonCamera tpc;

to the Clic_Rot_LUN_DEC script and assign the script in the unity inspector.
then you can access the allowedToRotate variable without it having to be static.

You can access the ThirdPersonCamera script like this:

if (tpc.allowedToRotate) { //code }

Sidenote:
A static variable is the most straightforward approach, since you only have one camera that you want to be locked. Static variables are easy to access since you don’t need a reference to an existing script on a gameobject. All you need is the class name.

This is excellent, thank’s a lot for sharing your knowledge :wink:

1 Like