Modify rotation based on passing rigidbody's velocity and direction?

Hello!

I’ve got a fairly complex scenario where I need to update an objects rotation speed and clockwise/counter-clockwise direction. The rotation is just about the Z axis as I’ve scripted my game to be 2D in the X and Y. I’m not using gravity but have created my own custom “orbiting” gravity (it’s a slingshot physics/puzzle game in space).

Here’s a picture of the scenario I’m trying to accomplish:




The black circle represents an object who’s position doesn’t change, but is rotating via a transform.RotateAround. The blue sphere is traveling with a rigidbody and velocity throughout the game area.

I already detect when the blue circle is close enough to affect the black circle’s rotation, but how can I determine which direction the black circle needs to rotate in, and by what magnitude? I think it would relate to the blue circle’s velocity, normalized vector, and position relative to the black circle- but I can’t piece the three together logically.

Keep in mind the blue circle may come from any direction, not just from below.


What I’ve tried which sorta works but not smoothly/realistically:

I’ve been attempting to calculate which Cartesian quadrant the blue circle is in based on the black circle representing the origin. Then, I determine if the blue circle is moving faster in the X or Y direction, and spin appropriately. This doesn’t always work and doesn’t look “natural”… I’m not too good at linear algebra, so I’m unsure of any other way to achieve this? Please help!

Note: I can post scripts if needed (I’m using JavaScript), but they’re a bit lengthy- I’ll leave them out for now because I think I’m going in the wrong direction and don’t want to mess anyone else up who may be in my position.

EDIT: Sorry about the pictures not showing up, they don’t seem to want to cooperate =/

Despite the description is somewhat vague about some points, I wrote a script which can serve to your purpose - or at least can show you how to do the necessary calculation (which isn’t so easy as it may seem).

To test this script, follow these steps:

1- Create an empty object and attach the script below

2- Add a sphere colldier and set its radius to the distance the sphere can be detected

3- Create the rotor object and call it “Rotor”

4- Child the Rotor to the first object

It’s ready. Whenever a rigidbody enters the trigger, the script calculates the distance it will pass from the rotor and sets the variable rps (revolutions per second) to a suitable speed (as the sphere “pushed” the rotor):

private var rotor: Transform;
private var rps: float = 0; // revolutions per second

function Start(){
	rotor = transform.Find("Rotor");
}

function OnTriggerEnter(hit: Collider){
	if (hit.rigidbody){ // ignore non rigidbody objects
		var vel = hit.rigidbody.velocity.magnitude; // gets the sphere speed
		var dir = hit.rigidbody.velocity.normalized; // and its direction
		var start = hit.transform.position; // start is the sphere position
		var point = rotor.position; // point is the rotor center
		// find the nearest point to the rotor the sphere will pass through
		var tgPt = start + Vector3.Dot(point-start, dir)*dir;
		var radius = Vector3.Distance(tgPt, point); // distance from the rotor center
		rps = vel/(2*Mathf.PI*radius); // calculate rotations per second
		var cross = Vector3.Cross(dir, tgPt-point); // cross product will give the direction
		if (cross.z > 0) rps = -rps; // correct rotation direction if needed
	}
}

function Update(){
	rotor.Rotate(0, 0, 360*rps*Time.deltaTime); // rotate around Z axis
}