Hi all. i have found some undocumented functionality in с#.
If you call the function Main() then it is performed automatically at startup. It works with the MonoBehaviour and ScriptableObject and can also automatically run Coroutine.
This feature allows you to create a very elegant code :
using UnityEngine;
using System.Collections;
public class TMain : ScriptableObject {
IEnumerator Main () {
Debug.Log ("Start");
while(true){
Debug.Log ("Update");
yield return null;
}
}
}
(Though I don’t really see much point using it to re-implement existing functionality via coroutines…)
Edit:
A little playing around of my own. A quick test shows that it’s called independently of Awake and Start, with the call order such that this code…
Results with multiple copies of the component in a scene:
Awake
Awake
Awake
Awake
Awake
Main
Start
Main
Start
Main
Start
Main
Start
Main
Start
I’m not assuming anything about which of those Mains goes with which of those Starts. You could test that easily enough by naming your objects if you wanted to find out.
It’s really odd considering the context in which the term “Main” is used in traditional programming. It’s typically the entry point to a program that kicks off one or more loops. While I’m aware that some people use Start or Awake in combination with coroutines to get similar behaviour it’s always struck me as a hack, not to mention being contrary to Unity’s intended design where Update et. al. are where we’re meant to make the guts of the magic happen.
interesting… i was thinking about using scriptable objects in rpg-like game to store buff information… and expire time, this loop can be handy for time checks.
(sorry this is unrelated but am curious since am using scriptableobjects and i was surprised that they can have corotines)
from performance perspective…
is it good idea, to have scriptableobjects have their own loops to detect when it expires so it removes it self from referenced player?? lets say if there are 100 active.
or, i should add these objects into a “status” List inside the player, and use for loop to check every object if it is expired, then remove/destroy it from list.
am currently using the second approach, which is also good if i want to clear player from all it’s current debuffs.
but i feel using lists is annoying, and not as fun as having the buff manages it self out.
Worse is that it’s undocumented and subject to change at any moment at Unity’s whim.
And also may have code that runs in an existing ‘Main’ method in the inherited class that isn’t getting ran now that you’ve shadowed it with a new ‘Main’ method.
There is another trick - Create MonoBehaviour class and attach it to GameObject. Then change inheritance to ScriptableObject. You’ll get ScriptableObject as attached Component.
I agree with you should avoid use this feature but first of all you need to know about it.
I spent a lot of time before find this bug in my code. You can imagine this frustration when i see a function worked, but i not call it anywhere. So i hope i saved somebody nerve.
I feel like using these undocumented features is a great way to booby trap your code. This is great! …if you want an unexpected surprise in Unity 5.1.7f, or some other future version.
If you assign this name to any of your methods then will get unpredictable flow of your program.
unpredictable flow == “bug” == frustration, is not it?
Better not, since if you dont know about this being called just the same as Start() or OnEnable() you might have a hard time tracking down why the game suddenly blows up.