[SOLVED] Rotate around an object based on mouse position

I’m trying to make an object, in this case a paddle, to rotate around an orb in my game. Describing it as a ‘controlled orbit’ is probably the best way to get you guys to understand what I’m trying to achieve.

Currently, I’m using a script I found online that correctly orbits the paddle automatically around the orb. I chose this because it allows me to adjust the radius of the orbit which I like. The only problem is I have no idea how to change it so that it orbits based on where my cursor/mouse is on the screen.

Here’s a GIF of the automatic orbit:
2887756--212192--ezgif.com-video-to-gif.gif

And a GIF of what I’m trying to achieve. As you can see, it’s using the automatic orbit I’m currently using but the way I’m moving my mouse around hopefully gives a picture of the ‘controlled orbit’:
2887756--212193--ezgif.com-video-to-gif (1).gif

PaddleController script:

using UnityEngine;

public class PaddleController : MonoBehaviour
{
    public GameObject orb;
    public float radius;
    public float radiusSpeed;
    public float rotationSpeed;

    private Transform centre;
    private Vector3 desiredPos;

    void Start()
    {
        centre = orb.transform;
        transform.position = (transform.position - centre.position).normalized * radius + centre.position;
    }

    void Update()
    {
        transform.RotateAround(centre.position, Vector3.forward, rotationSpeed * Time.deltaTime);
        desiredPos = (transform.position - centre.position).normalized * radius + centre.position;
        transform.position = Vector3.MoveTowards(transform.position, desiredPos, radiusSpeed * Time.deltaTime);
    }
}

UPDATE
Well, I kinda managed to get the paddle to orbit based on mouse position, but only for the ‘x’ axis and it’s not accurate. I want the paddle to look at the mouse accurately and rotate accurately too. So, if I move my mouse from left to right, the paddle should orbit and rotate left to right too.

In the GIF below, you can see my paddle orbiting when I move my mouse along the ‘x’ axis. It’s not accurate and also, if I moved my mouse in the ‘y’ axis, the paddle doesn’t orbit or move at all.
2887865--212205--ezgif.com-video-to-gif.gif

Updated script:

using UnityEngine;

public class PaddleController : MonoBehaviour
{
    public GameObject orb;
    public float radius;
    public float radiusSpeed;
    public float rotationSpeed;

    private Transform centre;
    private Vector3 desiredPos;

    void Start()
    {
        centre = orb.transform;
        transform.position = (transform.position - centre.position).normalized * radius + centre.position;
    }

    void Update()
    {
        float rotationX = Input.GetAxis("Mouse X") * -rotationSpeed;
        transform.RotateAround(centre.position, Vector3.forward, rotationX);

        desiredPos = (transform.position - centre.position).normalized * radius + centre.position;
        transform.position = Vector3.MoveTowards(transform.position, desiredPos, radiusSpeed * Time.deltaTime);
    }
}
1 Like

UPDATE
I fixed the problem after researching online for a couple of hours. I founded this script, and added one line of code to include adjustable radius.

using UnityEngine;

public class PaddleController : MonoBehaviour
{
    public Transform orb;
    public float radius;

    private Transform pivot;

    void Start()
    {
        pivot = orb.transform;
        transform.parent = pivot;
        transform.position += Vector3.up * radius;
    }

    void Update()
    {
        Vector3 orbVector = Camera.main.WorldToScreenPoint(orb.position);
        orbVector = Input.mousePosition - orbVector;
        float angle = Mathf.Atan2(orbVector.y, orbVector.x) * Mathf.Rad2Deg;

        pivot.position = orb.position;
        pivot.rotation = Quaternion.AngleAxis(angle - 90, Vector3.forward);
    }
}

This is the final outcome:
2887922--212209--ezgif.com-video-to-gif.gif

EDIT: It occurred to me during this that I didn’t have enough knowledge when it comes to maths and programming. I’m pretty good with doing maths alone but applying it with programming is pretty confusing. Time to learn how to use maths with Unity3D and C#!

9 Likes

This only works because your object you are rotating around is a circle. I tried implementing this in my own project, a 2D Platformer, where your gun rotates around you like a futuristic alien tech kinda thing. Here is a video explaining how I got this to work for me.

4 Likes

Thanks for making this video I was having exactly the same problem and was lost

how would I do this instead of the mouse it’s A and D?

Hi, here’s a simple implementation of the script using keyboard input:

   public Transform orb;
    public float radius;

    private Transform pivot;

    float curAngle;
    void Start()
    {
        pivot = orb.transform;
        transform.parent = pivot;
        transform.position += Vector3.up * radius;
        curAngle = 0;
    }

    void Update()
    {
      if(Input.GetKey(KeyCode.Q))
        {
            curAngle += 0.5f;
        }
        else if(Input.GetKey(KeyCode.E))
        {
            curAngle -= 0.5f;
        }
       pivot.rotation = Quaternion.AngleAxis(curAngle, Vector3.forward);
    }
}

I cannot read your code very well is it possible to put it in the description of your video?

I have an easier solution and it works for any gameobject. All you have to do is take the vector from between the mouse and the pivot and normalize it. That will give you the direction the object needs to be; then take that and multiply it by the radius of the circle. Then set the position of the rotating object to that vector + the position of the pivot.

Here is the code:
rotating object’s position = (Vector2)(pivot.position + (“vector between the mouse and pivot”.normalized * radius));

And here is my treatment, two ways of spinning a dial. Full package enclosed.

6201992–680924–RotateZViaDrag.unitypackage (20 KB)

Hi Kurt

i use your RotateZ, in my Project (3D) i must rotate the Y Axis with Mouse 1 and Alt Button.
How i can change this?

This is the code:

    void PerformCircularRotation()
    {
        // where is our center on screen?
        Vector3 center = Camera.main.WorldToScreenPoint(transform.position);

        // angle to previous finger
        float anglePrevious = Mathf.Atan2(center.x - lastPosition.x, lastPosition.y - center.y);

        Vector3 currPosition = Input.mousePosition;

        // angle to current finger
        float angleNow = Mathf.Atan2(center.x - currPosition.x, currPosition.y - center.y);

        lastPosition = currPosition;

        // how different are those angles?
        float angleDelta = angleNow - anglePrevious;

        // rotate by that much
        transform.Rotate(new Vector3(0, 0, angleDelta * Mathf.Rad2Deg));
    }

I’m thinking the changes would be:

  • change the angleDelta to pass in as the Y instead of the Z (line 20)

That would probably work straight up. Obviously orient the camera downwards.

It might require you inverting (negating) one or both of the input axes, OR possibly inverting the sign of the rotation… just fiddle with it.

sorry, not work

That’s not useful. I told you the necessary steps. It is up to you to do the engineering.

  • understand how the first one works (the code is provided)

  • understand what axes get swapped / inverted for your version of the problem.

  • adapt and change the code

  • test and iterate above until it works.

Great work man, you fixed the issue, good luck