- Home /
Rotate object based on set time.
I'll try describe this as best I can.
I have a galaxy map in a space tech demo I'm working on. Currently I'm rotating the planets around in their systems by calculating an ellipse then rotating the object along that ellipse using a progress from 0.0f - 1.0f like so.
float orbitSpeed = 1f / orbitPeriod;
orbitProgress += orbitSpeed * Time.deltaTime;
orbitProgress %= 1f;
if (orbitEllipse != null) orbitPosition = orbitEllipse.Evaluate(orbitProgress);
However if I am to disable that planet when it is off screen then re enable it some time later when it is back on screen then its position will still be where it was when it was disabled.
What I want to achieve is have the planet be at the position it would if it was not disabled. I guess I'm trying to calculate its position based on a set time since the start of the game. Maybe Time.time? Dunno if I've explained this clear enough. Let me know.
Regards - Matt
Answer by RetnuhStudio · Apr 03, 2018 at 08:53 PM
Must have been having a mind blank hahah. Turned out it was as simple as changing this line here
float orbitSpeed = 1f / orbitPeriod;
orbitProgress += orbitSpeed * Time.deltaTime;
to
orbitProgress = (Time.time / orbitPeriod);
or
orbitProgress = (scriptGlobalManager.instance.tick / orbitPeriod);
I chose the second one as I wanted a independent tick rate I can control in the tech demo. It's just a float incremented by 1 every second. Like this.
tick += Time.deltatime.
Answer by remy_rm · Mar 27, 2018 at 07:26 AM
there are multiple ways you could go about this, when you disable the gameobject of your planet it will also stop all logic in the scripts on it, thus leaving it at the place of deactivation.
What you could do is make a single gameobject containing a script that manages all plantes (ofcourse this is not feasable if you got ALOT of planets) , this gameobject would always be active and keeping track of the position of all your planets. then when you disable the planet the logic behinds it rotation keeps running in the manager. then when you enable the object againt it will grab its location/rotation from the manager script and directly snap to there.
If you got a lot of planets and a manager isn't feasible you could do this with a parent/child system where the logic for its position/rotation is in the parent, (just an empty game object with the script attatched) and you just disable the child object that contains the model for the planet and everything else regaridng the planet. Though not as optimal As the parent will still keep moving constantly it still saves the haulage of having to render your planet.
Thanks for the answer. Currently I'm using object pooling to render the planets when they are on screen so I think mesh / render wise I'm about as efficient as I can get there. All the planets / moons rotations are currently handled on one script that is on the systems base (currently the host star).
foreach (scriptCelestialBody b in celestialBodies)
{
Vector2 pos = new Vector2(system.position.x, system.position.y);
if (b.orbitObject == null)
b.position = pos + b.orbit.AnimateOrbit();
else
b.position = b.orbitObject.position + b.orbit.AnimateOrbit();
}
There are about 1000 systems and around 3000 planets currently and this code here is currently at 8.4ms in the profiler.
One thing I was thinking of was maybe updating orbits that are off screen every x number of frames and just increasing their orbit speed to make up for the frames skipped?
Anyone have any other ideas?
Thanks