how to clone several game objects in a way that clone properties of one can be adjusted to match all others in scene view - unity3d

I asked How can I adjust shape/dimensions of one clone to affect all other clones in the scene view and the accepted answer was spot on. It could only clone one game object. I tried making some adjustments but the only solution I came up with was adding duplicate methods for additional objects. This doesn't work well when dealing with several game objects to be cloned.
How can I clone several unique game objects so that adjusting the components/properties of one clone would affect all other clones of that object in the scene view?
Please note that I don't want to achieve this at runtime and I don’t want to use prefabs. I am using this to help with creation of complex levels so the live update of clones being adjusted is very important.
Additionally, I also need a way to turn off the this repeated property/component replication on each clone, preferably with a button.

I don’t want to use prefabs
The new prefab system in Unity is exactly what you need. It fits all of your requirements:
Clone several unique game objects
The prefab system is made for cloning unique gameobjects. It even supports prefab nesting.
I don't want to achieve this at runtime
Great, prefabs only update globally when you click the override button in the editor.
I need a way to turn off the this repeated property/component replication on each clone
That's equivalent to unpacking the object (breaking the connection).
If you have a good reason to avoid using prefabs, you can always write a custom script that tracks changes in the properties you want to share, and updates all other objects immediately. You can make that script run in edit mode by adding the [ExecuteInEditMode] attribute to the class it's in, just don't forget to disable it when running the project. Again, I highly recommend using prefabs instead.

You should use a ScriptableObject as data container and attach that to the gameobject, all clones will use the same synchronized ScriptableObject.

You should use events. Unity3d tutorials has a good, simple explanation: https://unity3d.com/learn/tutorials/topics/scripting/events

Is this only for editing the objects in the editor? If so, then it sounds like prefabs are the way to go; you can directly edit the prefab and all of its 'clones' in the scene will have all changes, including all monobehaviours, transforms, and whatnot replicated to that of the prefab.
If you need this to work at runtime, then you will likely need some code to do this for you. You haven't quite provided enough clarification as to what exactly you want to do, so for the below example I'll assume that you have a gameobject with a mesh or sprite component, and want its size/scale modified alongside all of its "clones";
using UnityEngine;
using System.Collections.Generic;
public class ShapeClone : MonoBehaviour
{
//This will hold references to the other "clone" gameobjects.
public List<GameObject> otherClones = new List<GameObject>();
//All the "clones" in the list otherClones will have their scale matched to this gameobject's scale
public bool leader;
private void Update()
{
if (leader) //Only change other clones' scales if marked as leader, to avoid every single clone
//overriding each other's scale every single frame, which could be rather chaotic
{
for (int i = 0; i < otherClones.Count; i++)
{
//setting each of the other clones' scale to that of this object.
otherClones[i].transform.localScale = this.transform.localScale;
}
}
}
}
The above is a brief example to give you an idea and is by no means extensive, but you should be able to apply it to what you're trying to do; for example, if you wanted to replicate the colour of sprites across gameobjects instead, you can modify otherClones to be a list of Sprite references instead, and instead of setting the scale in update, you can set the colour of each of the Sprite components to that of this object.
If you're only needing this functionality in the editor and not during runtime, though - I highly recommend going with the first option using prefabs, as it will give you far more functionality at a fraction of the cost, performance wise.

It sounds like you have an object that has several clones. You want changing the shape or dimensions of any of those objects to affect the other ones?
For this to happen, each object needs to know about the other ones. You can do this decentralized (each object contains a reference to each other) or centralized (one object governs the rest).
The centralized approach is more simple so I'll give a simple example.
public class Shape
{
public int length;
}
public class ShapeCentral
{
public List<Shape> shapes = new List<Shape>();
public void CloneShape()
{
//instantiate new shape
shapes.Add(new Shape());
}
public void SetCloneLength(int l)
{
shapes.ForEach(x => x.length = l);
}
}
As you can see, one object can control all the clones at once. The trick is to not create clones using other methods or you will run into trouble.
If you want to tighten up your variable access (which I recommend, its a good exercise) you could use a publisher/subscriber pattern. In this, when a new clone is instantiated, it subscribes to the SetCloneLength method. When you want to change the length, the central class publishes that message and it is sent to all the subscribers.
The difference here is that in my example, the central class needs to keep track of all the clones, in publisher/subscriber, you don't.

Create script CopycatManager that will hold a leader and then use dedicated setters for copying the other object properties that have the same type. If a property is a default one may need to set up either a proxy of such property within' the script or play with triggers. I would recommend proxy. Like this:
class CopycatManager {
public GameObject leader;
SomeAttributeType attributeToCopyFromLeader {get; private set}
void Start () {
// The first CopycatManager to start is the leader
List<CopycatManager> allCMs = parent.GetComponentsInChildren();
CopycatManager foundLeader = allCMs.Find(o => o.leader == o);
if (foundLeader == null) {
// There's no leader yet, set yourself a leader
leader = this;
} else {
// Found a leader, accept
leader = foundLeader;
}
}
public void SetAttribute (SomeAttributeType newVal) {
// If we're setting the attribute of the leader - we should set this attribute for all children
if (leader == gameObject) {
// Find all copycat manager scripts attached to children of current parent
// Meaning siblings
// WARNING: It will include children of siblings and the leader itself
// WARNING: It will not include parents of the Copycat Manager type, add if required
List<CopycatManager> allCMs = parent.GetComponentsInChildren();
foreach (CopycatManager manager in allCMs) {
SetAttributeFromLeader (newVal);
}
} else {
// Non-leader is attempting to change attribute - call leader
leader.SetAttribute(newVal);
}
}
// Called by leader to each child
public void SetAttributeFromLeader (SomeAttributeType newVal) {
attributeToCopyFromLeader = newVal;
}
}
Make sure to assign a new leader if the old one destroyed. Only destroy objects with CopycatManager through dedicated function.

make all items that need scaling children of an empty called WorldObjects then scale the world object, it will scale all its children accordingly. you can then either manually or through script remove the parent to make objects independent. best way without prefabs...

use a singleton class. add that script to all the objects, then you can make a call to one and it will adjust all of them.
you can also do this with a static class, but the singleton approach is cleaner, and gives you more options.
public class MySingleton
{
private static MySingleton fetch; // keep the static reference private
public bool myBool = false;
// and expose static members through properties
// this way, you have a lot more control over what is actually being sent out.
public static bool MyBool { get { return fetch ? fetch.myBool : false; } }
void Awake()
{
fetch = this;
}
}
read here for some great information on both options!

Related

How to preserve object references when loading new scene

I am trying to implement a simple racing game in Unity 2021.2 and I have a GameManager Object that holds state across different scenes (i.e. races). To achieve this I use this code in my GameManager:
public static GameManager instance;
private void Awake()
{
if (instance == null)
{
DontDestroyOnLoad(gameObject);
instance = this;
} else if (instance != this)
{
Destroy(gameObject);
}
}
This works fine as long as the fields of the GameManager are of primitive types, such as int and string. However, my GameManager also has a field of type RacerData[], where RacerData is a class that I created in a separate script, which holds data associated with a racer, such as the name, score, etc.
Using this approach I ran into the following problem: When I transition from the first race to the second, i.e. when a new scene is loaded, the GameManager keeps the values of all the fields of primitive types, but loses the references to the RacerData objects.
My first attempt to solve this was that I turned my RacerData script into a MonoBehavior. Instead of just instantiating RacerData Objects in GameManager I created a prefab with the RacerData script attached and instantiated GameObjects from this prefab in my GameManager.
GameObject myRacerDataInstance = Instantiate(myRacerDataPrefab, …, …);
DontDestroyOnLoad(myRacerDataInstance);
instead of:
RacerData myRacerData = new RacerData();
This had the desired effect fo keeping the RacerData game objects when loading a new scene, however the references of the GameManager to those game objects is still lost when a new scene is loaded. I then proceeded to write a hacky workaround to reassign the objects in the next scene which, so far, I failed to make work. However, I'm less interested in making this workaround work rather than to understand why the references to the RacerData gameObjects are lost in the first place and what better way there is to keep data across scene loads.
This appears to be a very common use case to me and I can't quite believe that a developer is supposed to rewire the references manually, especially since those could form a much more complex object graph than mine.
So: Is there a way to preserve those references across scenes? Or is DontDestroyOnLoad() not the right mechanism in the first place and in that case: what better option is there to preserve data (including object references) accross scenes?
It turns out the problem wasn't quite what I thought it to be: The references weren't set on the GameManager object at the time I tried to access them, i.e. from the Start() method of another game object called RaceManager.
A quick fix to the problem was to simply wait for the references to be recreated like so (in RaceManager):
void Start()
{
StartCoroutine(WaitForRacers());
}
private IEnumerator WaitForRacers()
{
while (racers == null)
{
yield return new WaitForSeconds(1);
gameManager = FindObjectOfType<GameManager>();
racers = gameManager.GetRacers();
}
InitializeRace(); // initialization logic that relies on racers to be != null
}

Unity - Game modes as state machine?

I am making a quiz game in Unity and I've come across architectural problem.
I want the game to have few game modes, like standard, faster answer - more points, etc. Each of which will behave in its own specific way but some things will be very similar like answering questions, starting timer, etc.
Currently its structured based on this. There is a QuizSystem that holds reference to QuestionDatabase, UIReferences(buttons,score text, etc) and GameSettings (questions per game/per mode etc).
To start the game you need to call QuizSystem.Start() and it starts its current GameMode which derives from abstract StateMachine and is a monobehaviour (dont know if neccesary). I also have abstract State class from which different game states will derive from. It has a constructor with (GameMode owner) as paramenter and 3 functions: Start(), Tick(), End().
So, this way I can have Standard game mode which will instatiate lets say StandardPreparationState, which on end will call StandardAnswerState which will start the timer and wait for user input and again call StandardPreparationState. Cycle will repeat until questions per mode amount is reached and then delegate next action to QuizSystem.
The advantage of this approach is that every mode can behave in its own way like add additional steps in between but it kinda limits reusability. What I mean by that is if some OtherMode would have the same preparation functionality but different action afterwards, it wouldn't work beacause
StandardPreparationState would transition to StandardAnswerState.
I could add another parameter such as (GameMode owner, State transitionTo) to the State constructor but that somehow seems wrong I don't know why xD
What I want to know is how do you guys implement different game modes for your games? Do you make each mode as separate scene? Or maybe use States Machine pattern and have Manager class that takes care of starting/swaping modes?
I know that each game is different but are there maybe some common approaches for that?
Thanks in advance!
This question is quite open and opinion-based. However there are few "common" approaches, one of the most important is to make game "data-driven".
What? Why? How?
Imagine you are having space shooter, where you have your ship flying around and picking guns. Each time you add new gun, you will have to code its damage, kind of projectiles and how many of them you shoot, their color, in what pattern they spawn, speed, size, ...
Everytime you would want to add a new gun, you would need to enter the code and change it there, compile, ... Lot of work.
Instead people thought, "why don't we create simple class that holds all the parameters? We will make it editable from Unity, instatiate it in the project and we won't need to code that much."
This is when Unity brought Scriptable objects.
Scriptable objects
A ScriptableObject is a data container that you can use to save large amounts of data, independent of class instances. One of the main use cases for ScriptableObjects is to reduce your Project’s memory usage by avoiding copies of values.
The idea is to create scriptable object for your mode and set up multiple kinds of modifiers that will the mode use. Folder structure might look like:
> ScriptableObjects
| |--> Modes
| |-> NormalSO (instance)
| |-> HardWithLotOfExpSO (instance)
| |-> EasyWithLowerExpSO (instance)
> Script
|--> ScriptableObjects
|-> ModeSO
ScriptableObject is class that doesn't really have the logic inside, just creates "structure" for keeping data. Example of such class would be:
public class ModeSO : ScriptableObject
{
public string modeName;
public float scoreMultiplier;
public int numberOfEnemiesMaxAlive;
public int numberOfEnemiesTotal;
public Vector3[] spawnPoints;
}
In the Unity itself you would then create instance of such objects. And what about interaction with other classes? Well, they would just work as:
Game manager hold single instance of active mode
Class that would be handling score (e.g. player / scoreboard) or Enemy would ask GameManager what is current multiplier for score
WorldSpawner would ask GameManager how many enemies should he spawn, where, and when to spawn next ones
At the beginning of the game you would be able to select difficulty by its name
Example of one of the classes (Scoreboard):
public class ScoreBoard: MonoBehavior
{
GameManager manager;
private float totalScore;
OnEnemyDestroyed(float scoreForEnemy)
{
totalScore += scoreForEnemy * (manager?.activeMode?.modifier ?? 1);
}
}
And the best is, whenever you will change some data, you will just modify the existing instance in the Unity. No need to go into code. No need to recompile whole game.
I think having different scenes for each game mode, especially if the modes are very similar save for a few settings, is unnecessary. I'd have to see more of your design to know how your game logic is being handled (is it all managed in one GameManager script? Or are there multiple scripts in the scene that take values from this manager script to handle game mechanics?)
One way I've handled different game modes before is to use a public int value in the GameManager that represents the different modes (i.e 1 = easy, 2 = medium, 3 = hard). I would then use a switch statement in any scripts whose behavior/values depend on this mode and reference that public int to determine game settings.
Game Manager:
public class GameManager: MonoBehavior
{
public int gameMode = 0; //set to 1,2, or 3 by UI
[...] //rest of game manager code
}
Example Behavior Script:
public class EnemySpawn: MonoBehavior
{
public GameObject enemy;
GameManager gm;
private float spawnRate;
Start()
{
switch(gm.gameMode)
{
case 1:
spawnRate = 15f;
break;
case 2:
spawnRate = 10f;
break;
case 3:
spawnRate = 5f;
break;
default:
spawnRate = 10000f;
Debug.log("invalid mode");
break;
}
}
Awake()
{
InvokeRepeating("SpawnEnemy", spawnRate, 0f);
}
[...] //rest of EnemySpawn code, including a SpawnEnemy() function.
}
This example would reference the GameManager's gameMode int to determine what speed to spawn enemies at, assuming there is a SpawnEnemy() function somewhere down in the code. I can't verify if this example is syntactically correct, but it's just to show one way to handle game modes.

best practice to show possible positions and put object on one of them Unity

I have a lot of Game Objects I need to Instantiate and put on scene on possible positions.
I have a list of rules where GameObject can be put by player (e.g. small box only at big box, sphere only on small box etc.)
I know I can put every rule into an "if", but I think it's not the most efficienty way. How should I keep a list of rules where can user put GameObjects? How my scripts should check and show possible positions? I will be thankful for any ideas how to start, to make it elegant and efficient.
There are many ways to do this.
What i would prefer is to keep everything organized and configurable per object (looking at the object oriënted programming structure).
I suggest defining per object where it can be placed. Here an example.
public yourClass
{
public GameObject ObjectToPlace;
public List<GameObject> ObjectToPlaceOnList;
public bool CanObjectBePlaced(GameObject targetObjectToPlaceUpon)
{
if (ObjectToPlaceOnList.Contains(targetObjectToPlaceUpon))
{
return true;
}
return false;
}
}
Your script may look different ofcourse, based on your current scripts.

Duplicating Unity's mystic Interface power

Unity3D has an interface like this, for any Component on a MonoBehavior you just do this:
public class LaraCroft:MonoBehaviour,IPointerDownHandler
{
public void OnPointerDown(PointerEventData data)
{
Debug.Log("With no other effort, this function is called
for you, by the Unity engine, every time someone touches
the glass of your iPhone or Android.");
}
You do not have to register, set a delegate or anything else. OnPointerDown (the only item in IPointerDownHandler) gets called for you every single time someone touches the screen.
Amazing!
Here's a similar interface I wrote ...
public interface ISingleFingerDownHandler
{
void OnSingleFingerDown();
}
Now, I want consumers to be able to do this...
public class LaraCroft:MonoBehaviour,ISingleFingerDownHandler
{
public void OnSingleFingerDown(PointerEventData data)
{
Debug.Log("this will get called every time
the screen is touched...");
}
Just to recap, using Unity's interface, the function gets called automatically with no further effort - the consumer does not have to register or anything else.
Sadly, I can achieve that only like this:
I write a "daemon" ..
public class ISingleFingerDaemon:MonoBehaviour
{
private ISingleFingerDownHandler needsUs = null;
// of course that would be a List,
// just one shown for simplicity in this example code
void Awake()
{
needsUs = GetComponent(typeof(ISingleFingerDownHandler))
as ISingleFingerDownHandler;
// of course, this could search the whole scene,
// just the local gameobject shown here for simplicity
}
... when something happens ...
if (needsUs != null) needsUs.OnSingleFingerDown(data);
}
And I get that daemon running somewhere.
If you're not a Unity user - what it does is looks around for and finds any of the ISingleFingerDownHandler consumers, keeps a list of them, and then appropriately calls OnPointerDown as needed. This works fine BUT
the consumer-programmer has to remember to "put the daemon somewhere" and get it running etc.
there are obvious anti-elegancies whenever you do something like this (in Unity or elsewhere), re efficiency, placement, etc etc
• this approach fails of course if a consumer comes in to existence at a time when the daemon is not searching for them (Unity's magic interfaces don't suffer this problem - they have more magic to deal with that)
(PS, I know how to write an automatic helper that places the daemon and so on: please do not reply in that vein, thanks!)
Indeed, obviously the developers at Unity have some system going on behind the scenes, which does all that beautifully because "their" interfaces are perfectly able to call all the needed calls, regardless of even items being created on the fly etc.
What's the best solution? Am I stuck with needing a daemon? And perhaps having to register?
(It would surely suck - indeed generally not be usable in typical Unity projects - to just make it a class to inherit from; that type of facility is naturally an interface.)
So to recap, Unity has this:
public class LaraCroft:MonoBehaviour,IPointerDownHandler
Surely there's a way for me to make a replacement, extension, for that...
public class LaraCroft:MonoBehaviour,ISuperiorPointerDownHandler
which can then be used the same way / which shares the magic qualities of that interface? I can do it fine, but only my making a daemon.
Update
Full solution for "ISingleFingerHandler" "IPinchHandler" and similar concepts in Unity is here: https://stackoverflow.com/a/40591301/294884
You say you don't want to do a daemon but that is exactly what Unity is doing. The StandaloneInputModule class that is automatically added when you add a UI component is that daemon.
What you can do is create a new class derived from one of the classes derived from BaseInputModule (likey PointerInputModule for your case) that can handle listening to trigger and raising your extra events then add that new class to the EventSystem object.
See the Unity manual section on the Event System for notes on how to create your custom events and more details on what the input module does.
I hate to answer my own questions, but the answer here is really:
You cannot. You do have to add a daemon.
But then, it's very much worth noting that
Indeed, Unity add a daemon - they just hide it a little.
The final absolutely critical point to understand is that:
Unity screwed-up: you cannot in fact inherit from their lovely StandAloneInputModule. This is a big mistake.
Unity's StandAloneInputModule and IPointerDownHandler family - are brilliant. But you can't inherit from them properly.
The fact is, you just have to inherit sideways from IPointerDownHandler. That's all there is to it.
The fact is you have to make your own daemon ("as if" it inherits from StandAloneInputModule) which actually just goes sideways from IPointerDownHandler family.
So the actual answer is (A) you have this
public interface ISingleFingerHandler
{
void OnSingleFingerDown (Vector2 position);
void OnSingleFingerUp (Vector2 position);
void OnSingleFingerDrag (Vector2 delta);
}
public class SingleFingerInputModule:MonoBehaviour,
IPointerDownHandler,IPointerUpHandler,IDragHandler
and (B) you do have to put that on a game object (it's a daemon), and then (C) it's just stupidly easy to finally handle pinches, etc.
public class YourFingerClass:MonoBehaviour, IPinchHandler
{
public void OnPinchZoom (float delta)
{
_processPinch(delta);
}
That's it!
Full production code for PinchInputModule ...
https://stackoverflow.com/a/40591301/294884
...which indeed inherits sideways from ("uses") IPointerDownHandler family.
My assumption is that MonoBehaviour runs a type check in ctor. Which is why you cannot use the ctor on those to avoid overriding that process. The common solution is that your interface would also require to implement a registering method (Vuforia does that for instance) so any new instance registers itself.
You could also extend MB class with your own MB system:
public class JoeMonoBehaviour : MonoBehaviour
{
protected virtual void Awake(){
Init();
}
private void Init(){
if(this is ISuperiorPointerDownHandler)
{
if(ISuperiorHandler.Instance != null){
ISuperiorHandlerInstance.RegisterPointerDownHandler(this as ISuperiorPointerDownHandler);
}
}
}
}
It does not have the magic of Unity but you cannot achieve the magic of Unity with MonoBehaviour. It require the sub class to make sure it calls the base.Awake() if overriding it.
You'd have to come up with your own side engine system to run your own engine logic. Not sure that'd be worth it.
Another solution is to create your own Instantiate:
namespace JoeBlowEngine{
public static GameObject Instantiate(GameObject prefab, Vector3 position, Quaternion rotation){
GameObject obj = (GameObject)Instantiate(prefab, position, rotation);
MonoBehaviour [] mbs = obj.GetComponentsInChildren<MonoBehaviour>(true); // I think it should also get all components on the parent object
foreach(MonoBehaviour mb in mbs){
CheckForSuperior(mb);
CheckForInferior(mb);
// so on...
}
return obj;
}
internal static CheckForSuperior(MonoBehaviour mb)
{
if(mb is SomeType) { SomeTypeHandler.Instance.Register(mb as SomeType); }
}
}
Now it look like you are doing some magic only with :
JoeBlowEngine.Instantiate(prefab, Vector3.zero, Quaternion.identity);

Correct way to connect an instance of a class to a GameObject mesh

I have a model with an animator; and a controller script to make it move, then I created a simple class called "TheEntity", which hold a name, and an int for the energy. When the time goes by, the energy goes down, so the mesh walk around or perform animations at random.
public class TheEntity()
{
public string name;
public int energy;
public TheEntity()
{
// make a random name
name = "joe"+ rnd.next(1,1000).toString();
energy = rnd.next(20, 100);
}
}
When the energy value goes to 0, the mesh "goes to sleep", and regenerate again in a certain amount of time.
If I have a list of TheEntity instances, as it would be if I have a list of NPC, what would be the correct way to assign a mesh to each entity class in the list?
Should I have a script on the mesh, that has a reference to a TheEntity class. and assign it at runtime when I load the mesh prefab?
Or should I put the whole "TheEntity" class script on the mesh, and save it as prefab, so every time that I load the prefab, I will have a mesh with a related TheEntity instance directly?
"Things" in the Unity scene are GameObject , that's all there is to it.
Your class must be a MonoBehaviour to be on a game object.
In Unity, everything is a MonoBehaviour (a Component). There is, quite literally, nothing else whatsoever in Unity.
(Of course, you may have some "raw" non-Unity classes for things like say math calculations, but that's irrelevant.)
It's just that simple.
public Class Entity:Monobehaviour
{
}
attach that to an empty game object. Add the models (meshes) .. or whatever you want. Add sound effects, add anything.
Regarding "changing the mesh", no problem.
Do that in a routine in Entity, if you like.
public Class Entity:Monobehaviour
{
public void ChooseRandomMesh()
{
}
public void ChooseRandomColorPattern()
{
}
public void RunForTheHills()
{
}
public void AttackHero()
{
}
}
If you prefer, write a Component which does nothing other than randomly change the mesh.
public Class Entity:Monobehaviour
{
public void RandomizeEntity()
{
}
public void ChooseRandomColorPattern()
{
}
}
.. and attach that script to the game object, also.
In Unity, everything is a MonoBehaviour (a Component), it's that simple.
Regarding making it a prefab, if you want to, sure do that. Read any of thousands of tutorials on prefabs.
There's a critical comment you made in your comments below:
"Also the entity class is not MonoBehaviour..."
Here's an incredibly critical point in understanding Unity:
1) You're quite right that your "model" or "AI" or "database connection" sort of has "nothing to do" with unity game objects. (They of course don't have a "position" or "mass!" or anything, right?!)
HOWEVER HOWEVER HOWEVER HOWEVER HOWEVER HOWEVER HOWEVER HOWEVER HOWEVER
2) In Unity unless a class is a MonoBehaviour: you can't do anything with it/ You can't even access the run loop, it's a total nonstarter.
THUS THUS THUS THUS THUS THUS THUS THUS THUS THUS THUS THUS THUS THUS
3) In Unity all the stuff like that, IS IN FACT a MonoBehaviour AND YOU SIMPLY sit it on an empty game object. (Usually the name in the Heirarchy starts with underscore, say, so you know it's "not really" a conventional game object.)
The simple bottom line is in your preload scene (you must have one in 100% of projects) you have all your "AI" and "model" and "database" stuff, just sitting on one or more "pretend" markers (marker == otherwise empty game object).
Bottom line, when you say below "your model is not a MonoBehaviour" that is wrong. It will have to be a MonoBehaviour (if you think about it, it's absolutely inevitable you'll need to access the runloop, if nothing else) ... just make it a MonoBehaviour and put it on a marker, almost certainly in your preload.
I hope it makes sense. Essay on the topic.