x


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 =/
more ▼

asked Aug 21, 2011 at 07:59 PM

Joe0418 gravatar image

Joe0418
1 3 2 3

This is too vague. I suppose that when the sphere passes within a certain distance, the black object must follow the sphere velocity - if the sphere velocity is 5 m/s and it's at 3 m from the object center, for instance, the object must rotate at 0.26 revolutions per second, which gives 5m/s at 3m.
But there are several other possibilities to consider. What should happen when:
1- The sphere passes at a large distance (nothing?)
2- The sphere hits the rotator (never happens?)
3- The object is rotating in one direction and the sphere passes in the opposite direction (follow the sphere velocity? reduces velocity?)

Aug 22, 2011 at 12:12 PM aldonaletto
(comments are locked)
10|3000 characters needed characters left

1 answer: sort voted first

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
}
more ▼

answered Aug 23, 2011 at 04:45 PM

aldonaletto gravatar image

aldonaletto
57k 31 79 292

(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x3613
x3052
x553
x498
x38

asked: Aug 21, 2011 at 07:59 PM

Seen: 1918 times

Last Updated: Aug 23, 2011 at 04:45 PM