Alright, so I need get an object from point a, which is located at one location on a sphere, to point b, which is located at another position on a sphere. How would I go about doing that? Currently, I have it moving around to the points by essentially doing a smooth look at, however the problem I am facing is that this isn’t the most direct path, the object is going in more of a circular path to get to point b instead of the direct path. Any suggestions?
Give this a go
var Target : Transform;
private var Axis : Vector3;
var Centre : Vector3 = Vector3.zero;
var Seconds = 1.0; //if set to 0, speed will be used instead
private var SecSpeed : float;
var Speed = 20.0;
private var CrossProd : Vector3;
private var Theta : float;
var snapDist = 0.01;
function Start() {
CrossProd = (Vector3.Cross((transform.position - Centre), (Target.position - Centre))).normalized;
if(CrossProd == Vector3.zero){
Theta = Mathf.PI;
CrossProd = Vector3.Cross(Vector3.forward, transform.position);
}else{
Theta = Mathf.Acos(Vector3.Dot(transform.position - Centre, Target.position - Centre));
}
if(Seconds != 0){
SecSpeed = ((Theta/Mathf.PI)*180.0)/Seconds;
}
}
function Update () {
if(Mathf.Abs(Vector3.Distance(transform.position, Target.position)) > snapDist){
if(Seconds != 0){
transform.RotateAround(Centre, CrossProd, SecSpeed * Time.deltaTime);
}else{
transform.RotateAround(Centre, CrossProd, Speed * Time.deltaTime);
}
}else{
transform.position = Target.position;
}
}
Hope that helps, If your object doesn’t stop when it reaches the target you might need to increase the snapping distance (snapDist).
Scribe
I assume your object is like a grounded vehicle and your sphere is like a Super Mario Galaxy style planetoid, right?
What I woulddo, off the top of my head, is have an empty object centered on the sphere with its forward axis pointing at your current location and another empty object as its child, and Quaternion.Slerp the central object to face the new location, and then have the object which you’re actually moving match its world space position to empty child object. Then if necessary, adjust its distance from the sphere center based on terrain height at that point.
Use Vector3.Slerp in a coroutine:
function MoveOnSphereSurface (thisTransform : Transform, startPos : Vector3, endPos : Vector3, radius : float, speed : float) {
var distance = Mathf.Acos (Vector3.Dot (startPos, endPos) / Mathf.Pow (radius, 2)) * radius;
var rate = 1.0 / distance * speed;
var t = 0.0;
while (t < 1.0) {
t += Time.deltaTime * rate;
thisTransform.position = Vector3.Slerp (startPos, endPos, t);
yield;
}
}
Then use it like this:
var sphereRadius = 10.0;
var moveSpeed = 20.0;
function Start () {
var startPos = Random.onUnitSphere * sphereRadius;
var endPos = Random.onUnitSphere * sphereRadius;
MoveOnSphereSurface (transform, startPos, endPos, sphereRadius, moveSpeed);
}
Note that this code only works right if the sphere is at the origin.