- Home /
Quaternion Help with 3D Planetary Motion around fixed pos Earth
Hello everyone,
First off thanks for any answers you might provide!
I've looked around through unity answers, and I've found some good information that is very useful to what I am trying to do. http://answers.unity3d.com/questions/586916/rotating-an-object-around-two-axis.html Is close to what I am seeking to do but my requirements are different, such that the Earth is stagnant, it doesn't move or rotate, all the other objects rotate around the earth. I'm trying to get the sun to rotate around the earth, at first I did just a simple x/z axis rotation, not using Quaternion's, however since this is going to be realistic I need to implement a Y axis, which Quaternion's are very useful. Unfortunately, my understanding of them is very minimal outside of the past 6 hours that I've researched, scripted, and followed tutorials upon.
Nevertheless to the issue! Right now, my script causes the sun to orbit around a fixed point in space, at about -60000x, y-20000 to +20000, and -30000 to 30000z, it is not fully rotating around my earth, at 0,0,0 and its constantly speeding up, and not holding at whats supposed to be 6degrees (360deg circle around earth) per second. Below is my code, with decent comments.
using UnityEngine;
using System.Collections;
public class objectOrbit : MonoBehaviour {
public Transform target;
public float distanceFromObject = 63245f;
public float axialTiltDegrees = 23.4f;
public float orbitalPeriodDays = 365f;
public float rotationalPeriodHours = 24f;
public float minutesPerGameDay = 1f;
private float currentRotationSunX;
private float currentRotationSunY;
private float yDegreesPerSecond;
private float xDegreesPerSecond;
private float secondsinYear;
private float maxYCompenent;
private float currYComponent;
private float distBetweenObjects;
private float dayCounter = 0;
void Update()
{
Debug.Log("Current Day: " + dayCounter);
Vector3 dropYCoordinate = transform.position - target.position;
dropYCoordinate.y = 0f;
float distBetweenNoY = dropYCoordinate.magnitude;
maxYCompenent = Mathf.Tan(Mathf.Deg2Rad * axialTiltDegrees) * distBetweenNoY; //find Max Y = 66000 * Tan(23.4)
Debug.Log("Max Y Component: " + maxYCompenent);
Debug.Log("Distance between Sun-Earth, no Y: " + distBetweenNoY);
distBetweenObjects = Vector3.Distance(transform.position, target.position);
currYComponent = Mathf.Rad2Deg * Mathf.Asin(transform.position.y / distBetweenObjects); //find Current Y = ASIN ( transform.position.y(opposite) / distance(hyp) )
Debug.Log("Current Y Component in degrees: " +currYComponent);
Debug.Log("Distance between Sun-Earth: " + distBetweenObjects);
secondsinYear = orbitalPeriodDays * rotationalPeriodHours * 3600; // 365days * 24hours * 60minutes * 60seconds = ~31million seconds
xDegreesPerSecond = orbitalPeriodDays / (minutesPerGameDay * 60); // 365 / (1minute * 60seconds) to give X degrees per second. ~6deg/sec
yDegreesPerSecond = (axialTiltDegrees * 2) / (secondsinYear / (minutesPerGameDay * 60)); // 23.4 * 2 / 365 * 24 * 60 to give Y Degrees per second. ~.000089deg/sec
Debug.Log("xDegreesPerSecond: " + xDegreesPerSecond);
Debug.Log("yDegreesPerSecond: " + yDegreesPerSecond);
currentRotationSunX += xDegreesPerSecond * Time.deltaTime;
if (currYComponent > maxYCompenent) currentRotationSunY -= yDegreesPerSecond * Time.deltaTime;
if (currYComponent < -maxYCompenent) currentRotationSunY += yDegreesPerSecond * Time.deltaTime;
if ((dayCounter / orbitalPeriodDays) <= .5) currentRotationSunY += yDegreesPerSecond * Time.deltaTime;
if ((dayCounter / orbitalPeriodDays) > .5) currentRotationSunY -= yDegreesPerSecond * Time.deltaTime;
var qX = Quaternion.AngleAxis(currentRotationSunX, Vector3.right);
var qY = Quaternion.AngleAxis(currentRotationSunY, Vector3.up);
var q = qX * qY;
//Rotates about the local axis
transform.rotation = q;
//rotates the object around the axis in world axis
transform.position = q * transform.position;
if (dayCounter == orbitalPeriodDays) dayCounter = 0;
else dayCounter++;
transform.LookAt(target);
}
}
Thank you for your help!