[Help] I want to rotate a planet around a star based on a time tick system

Right now my planets are rotating around their parent star using RotateAround. This works fine. I can randomize the speed at which they travel using a variable and it all looks good.

But now I want to make them rotate around the star based on ticks. Every tick they should move forward in their orbit by a distance that is determined by their speed.

I am still pretty new to Unity so when I try to implement something new I usually go and look how others do it first, try that out and then mix and match whatever they did to fit my own needs.

This time I’ve found a useful tutorial from CodeMonkey on Youtube showing a event based solution. This actually works but using this solution the planets are rotating insanely fast. So fast that it almost seems like they don’t move at all :sweat_smile:

The time tick system is happening in TimeManager.cs which is attach to a TimeManager game object in my hierarchy. This is how it currently looks:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TimeManager : MonoBehaviour
{
    public class OnTickEventArgs : EventArgs
    {
        public int tick;
    }
    public static event EventHandler<OnTickEventArgs> OnTick;
    private const float ROTATION_TIMER_MAX = 0.2f; // 5 ticks per second

    // Ticks for rotating orbitals
    private int currentRotationTick;
    private float RotationTickTimer;

    private void Awake()
    {
        currentRotationTick = 0;
    }

    private void Update()
    {
        RotationTimeTicks();
    }

    private void RotationTimeTicks()
    {
        RotationTickTimer += Time.deltaTime;

        if (RotationTickTimer >= ROTATION_TIMER_MAX)
        {
            RotationTickTimer -= ROTATION_TIMER_MAX;
            currentRotationTick++;
        }

        if (OnTick != null)
        {
            OnTick(this, new OnTickEventArgs { tick = currentRotationTick });
        }
    }
}

The rotation of planets happens in the RotateOrbital.cs script which get attach to each planet and moon once their respective game objects get generated on game start.

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RotateOrbital : MonoBehaviour
{
    public GameObject targetObject;
    public float rotationSpeed;

    void Start()
    {
        targetObject = transform.parent.gameObject;
    }

    void Update()
    {
        rotatePlanet();
    }

    private void rotatePlanet()
    {
        TimeManager.OnTick += TimeManager_MoveOnTick;
    }

    private void TimeManager_MoveOnTick(object sender, TimeManager.OnTickEventArgs e)
    {
        transform.RotateAround(targetObject.transform.position, Vector3.forward, rotationSpeed * Time.deltaTime);
    }
}

I don’t get why my planets/moons are rotating so damn fast now. I guess it is because I am calling the function in Update()?

In the tutorial I’ve watched the event is only triggered on a mouse click but I want the orbitals to be in constant motion all the time. So how could I go on to make this happen and have my orbitals move a certain distance based on their speed on each tick?

You’re subscribing an event in Update(). Update is called many times per second. This is almost certainly not what you want. Events are basically lists of methods. When you subscribe an event, the method is added to the list. When an event is invoked, each method in the list is called. If you add a method multiple times, it will be called multiple times. What you’re currently doing results in MoveOnTick being called many times per tick and it keeps getting more the longer the application is running.

Instead, you should probably subscribe the event in Start() or somewhere else where it only happens once.