I'm attempting to rework some code that I wrote early on and I'm not the best at math, so what I ended up doing to avoid figuring out a math problem that puzzled me for several days was as follows:
Problem: figure out how to get the correct angle of the players direction of travel relative to the "north pole" on my 3d planet... for generating a stinking simple compass display.
Honestly, I think I spent almost a full week trying to get this to work.. I looked up nearly every math heavy google result I could to try and make it work but I just couldn't wrap my head around enough of it to get it going without some trickery. So, even though I've learned a LOT since then, I really don't want to spend hours and hours trying to look up the same problem that I really wasn't effective at solving on my own the first time.. haha
My Trickery:
1) I was having trouble figuring out how to implement the correct math for half of the problem(maybe the only real math part...). So, instead, I created a child object of the player character and gave it this code:
(the code was not actually doing anything at all, so I've removed it..., see below example where the gymbal object rotation is set, the code here was doing similarly)..
My goal, and the effect, was to define a constant source of angle information so I didn't have to do the math. It works, quite effectively.. I just feel like there's a much much much easier(more efficient) way to do it that I can't sort out (mathematically IN c#)...
2) the second part of the trickery is using the data from the "gymbal" object instead of calculating the math directly.
//Code to determine player direction of travel NSEW, on a spheroid planet.
Vector3 point2origin = transform.position - planet.transform.position; //origin is center of planet
Vector3 point2closestPointOnLine = point2origin - Vector3.Dot(point2origin, planet.transform.up) * planet.transform.up;
//(playerGymbal) == Generic game object parented to player character object(keeps it moving with the pc).
playerGymbal.transform.rotation = Quaternion.FromToRotation(-transform.up, point2closestPointOnLine) * transform.rotation;
//Here's the number I actually need.
float angle = SignedAngle(playerGymbal.transform.forward, planet.transform.up, playerGymbal.transform.position);
String nsew = "";
if (angle < -5 && angle > -85)
{nsew = "SE";}
if (angle <= 5 && angle >= -5)
{nsew = "S";}
if (angle > 5 && angle < 85)
{nsew = "SW";}
if (angle >= 85 && angle <= 95)
{nsew = "W";}
if (angle > 95 && angle < 175)
{nsew = "NW";}
if (angle >= 175 || angle <= -175)
{nsew = "N";}
if (angle > -175 && angle < -95)
{nsew = "NE";}
if (angle >= -95 && angle <= -85)
{nsew = "E";}
Dir.text = nsew;
So, ignoring the pile of ifs and I'm sure a few other nasty code smells, does anybody see my solution clearly? I just want to simplify this process and get rid of the extra gymbal object and its Update loop.
If I wasn't worried about optimization, or could use it as a helpful visual aid, I would just keep it because I think I clevered my way out of that problem pretty creatively.. But nope, it's just an invisible object using resources..
Anyhow, thanks for checking it out, any help would be greatly appreciated!
To summarize, I've got:
Planet's position in 3d space.
Player's position/rotation in 3d space.
North Pole's position in 3d space.
How do I calculate the resulting angles as above(or similar), simply, without all the extra trickery?
An important point:
The player character's "gymbal" object, always points towards the line running from the north pole to the south pole, and it rotates relative to the player's rotation, so that's how the extra object saved me from figuring out the math...
I failed to mention that anywhere above.. sorry.