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:
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’:
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.
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);
}
}
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.
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#!
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.
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));
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.