Hi everyone I need your help. I’m trying to create a waypoint system on a spherical world. That’s what I got. The cubes are waypoints ranging from enemy to player direction. Now I have to make sure that the cubes are placed on the spherical surface. I’m trying to use breast and cosine but missing something to make it work. Here is the code with the drawing

Here I add the various waypoints

public Transform t1, t2, node, planet;
public int division;
private List<Transform> nodes;
Vector3 direction, nodeDirection;
float dist, result;
void Start ()
{
nodes = new List<Transform>();
dist = Vector3.Distance(t1.position, t2.position);
direction = (t2.position - t1.position).normalized;
for (int i = 0; i < division; i++)
{
result = (dist / division) * i;
//
Transform t = Instantiate(node, new Vector3(GetPos(direction.x, result, t1.position.x),
GetPos(direction.y, result, t1.position.y),
GetPos(direction.z, result, t1.position.z)),
Quaternion.identity) as Transform;
nodes.Add(t);
}
float GetPos(float axis, float result, float player)
{
return (axis * result) + player;
}
}

What you just did can be accomplished with a simple Vector3.Lerp (for position) or Quaternion.Lerp (for rotation), both are the same thing. and not exactly what you want.

Store them as Quaternions and use Slerp. Use Quaternion because it takes it from the cartesian coordinate system and puts it into the Polar coordinate system which since your working on a sphere makes far more sense.

This following class takes the planet, start and endpoints, along with an optional altitude value, and then you can request points along the surface of the sphere between the two points you specified.

public class SphericalWaypoint
{
public float altitude;
private Quaternion m_start;
private Quaternion m_end;
private Transform m_planet;
public SphericalWaypoint(Transform start, Transform end, Transform planet)
{
this.m_planet = planet;
this.m_start = Quaternion.LookRotation(start.position - planet.position) * Quaternion.Inverse(planet.rotation);
this.m_end = Quaternion.LookRotation(end.position - planet.position) * Quaternion.Inverse(planet.rotation);
// radius not passed in, using best guess. half the average of the planet's scale components
var scale = planet.lossyScale;
this.altitude = (scale.x+scale.y+scale.z) / 6;
}
public SphericalWaypoint(Transform start, Transform end, Transform planet, float radius)
{
this.m_planet = planet;
this.m_start = Quaternion.LookRotation(start.position - planet.position) * Quaternion.Inverse(planet.rotation);
this.m_end = Quaternion.LookRotation(end.position - planet.position) * Quaternion.Inverse(planet.rotation);
this.altitude = radius;
}
//finds an interpolated orientation local to the planets rotation
public Quaternion LerpOrientation(float lerp)
{
lerp = Mathf.Clamp01(lerp);
return Quaternion.Slerp(this.m_start, this.m_end, lerp) * this.m_planet.rotation;
}
//finds an interpolated position local to the planet's transform
public Vector3 LerpLocalPosition(float lerp)
{
return LerpOrientation(lerp) * Vector3.Forward * this.altitude;
}
}

Mind you I’ve never had to use this solution, but this isn’t the first time a problem like the was presented to me, even for this forum. Many of my solutions come from me simply playing games and just thinking how they did it.

Take this code for example, its inspired by how I thought the planet levels in “Ratchet & Clank: Going Commando” were likely implemented. Probably not with the Quaternion Inverse though (since I think the planets themselves were likely static and didn’t move).