Presently, you might have already noticed that both our scripts, Spin and Orbit, have a gametimePerDay variable that does the same thing--defines the number of game seconds that correspond to an earth hour.
Let's refactor our code to remove this duplication and put this variable in a master GameController object instead:
- In Hierarchy, create an empty game object and name it GameController.
- Add Component, New Script (C-Sharp) and name it MasterControls, then press Create and Add.
Open it for editing, as follows:
File: MasterControls.cs using System.Collections; using System.Collections.Generic; using UnityEngine; public class MasterControls : MonoBehaviour { public float gametimePerDay = 0.05f; }
The script sets the default time to 0.05f, which will run pretty fast, but it will show the earth orbiting the sun once every 18 seconds (365 * 0.05).
Now, we will modify both Orbit.cs and Spin.cs to reference gametimePerDay of MasterControls rather than their own.
While we're at it, in preparation for adding other planets, we will also modify the Spin script so it also takes rotationRate. This is its local day in earth days. For earth, it'll be 1.0. For other planets, it can be different:
File: Spin.cs public class Spin : MonoBehaviour { public float rotationRate = 1f; // in earth days private MasterControls controls; void Start() { GameObject controller = GameObject.Find("GameController"); controls = controller.GetComponent<MasterControls>(); } void Update () { float deltaAngle = (360.0f / (rotationRate * controls.gametimePerDay)) * Time.deltaTime; transform.Rotate( 0f, deltaAngle, 0f); } }
In Spin.cs, we added two variables: rotationRate (which for the earth is 1.0) and a private controls reference to the MasterControls component. Then, we added a Start() method that will initialize controls when the app starts by finding GameController in Hierarchy and getting its MasterControls component so we can reference it in Update(). Then, in Update(), we used controls.gametimePerDay instead of a local one.
Next, we will make a similar change to Orbit.cs to use MasterControlsgametimePerDay, as follows:
File: Orbit.cs using System.Collections; using System.Collections.Generic; using UnityEngine; public class Orbit : MonoBehaviour { public Transform aroundBody; public float orbitalPeriod = 27.3f; // earth days for one complete orbit private MasterControls controls; void Start() { GameObject controller = GameObject.Find("GameController"); controls = controller.GetComponent<MasterControls>(); } void Update() { float deltaAngle = (360.0f / (orbitalPeriod * controls.gametimePerDay)) * Time.deltaTime; transform.RotateAround(aroundBody.position, Vector3.up, deltaAngle); } }
Save the scripts. Press Play. You can change the value of Gametime Per Day while it's running to see it change dynamically.