This article is written by Cartzhang, reproduced please indicate the source. All rights reserved.
Article Link: http://blog.csdn.net/cartzhang/article/details/52372611
Cartzhang
First, about Unity script Execution Sort 1 Unity script execution Sort instructions
In unity, to control the order in which Unity's scripts are executed, the unity engine itself already has a script sort. This sort can be edited and set in the editor.
It has a default in it, and the order of execution is scheduled according to the priority. If none of the sorting is performed randomly at the interval of the default time sort. In other words, the precedence in the list above the default time is always higher than the other sort.
This is a good thing for the engine itself. At least sort out your code.
Official script execution Site here: https://docs.unity3d.com/Manual/class-ScriptExecution.html
This sort of is already able to meet the basic requirements. Let's say you want to initialize the game configuration and put it in the front of all the other code. The problem is solved.
2 script Execution order is that there?
Script execution order, I always thought it would all exist in the game projectsettings in the Dynamicmanager.asset, or in other tagmanager.asset, but actually not.
See that each script has a meta file, and the meta file contains the order in which the scripts are executed.
fileFormatVersion:2guid:5715403d8bbda7e4d905d57906a392datimeCreated:1470808531licenseType: FreeMonoImporter: 2 defaultReferences: [] 0 0} userData: assetBundleName:
Executionorder:0 This is the order of execution. The smaller the priority of the execution the higher the month. By default, 0 is the case. If you want the script to execute first, you can set it to a negative value, say, 1200, and of course, in the script execution order, confirm it.
Ii. Common framework for Script execution order (singleton mode) 1 entrance
In unity, because of the fighting each other in the code, the Awake,start script, although it can handle the above mentioned problem.
However, in most games, it is necessary to comb the process of the game so that all start and awake and even update are controlled.
In such a framework, there must be a main.cs the most game of the entrance, and most of the other scripts are initialized and used from here.
Basic structure of Mai.cs:
using UnityEngine;publicclass Main : MonoBehaviour{ void Awake() { } void Start() { GameWorld.Instance.Init(this); } void Update() { GameWorld.Instance.Update(); } void OnDestroy() { GameWorld.Instance.Destroy(); } void OnApplicationQuit() { } void OnApplicationPause(bool pause) { }}
2 Singleton Mode script
What the hell is that gameworld?
This is what we call a singleton pattern.
usingSystem;usingSystem.Collections;usingSystem.Collections.Generic;usingUnityengine; Public classgameworld{ Public StaticGameworld Instance {Get{returnSingletonprovider<gameworld>. Instance; } }PrivateList<action> frameactionlist =NewList<action> (); PublicGameobject Mainobj {Get;Private Set; } PublicMain main {Get;Private Set; } Public void Init(main main) { This. main = main; This. Mainobj = Main.gameobject; NotificationManager.Instance.Init (); TimerManager.Instance.Init (); NetProcessManager.Instance.Init (); } Public void Update() {NotificationManager.Instance.Update (); TimerManager.Instance.Update (); DelayManager.Instance.Update (); NetProcessManager.Instance.Update ();//main loop for(inti =0; i < Frameactionlist.count; i++) {Action action = frameactionlist[i];if(Action! =NULL) {action (); } } } Public void Destroy() {NotificationManager.Instance.Destroy (); TimerManager.Instance.Destroy (); } Public void addframeaction(Action action) {if(!frameactionlist.contains (Action)) {Frameactionlist.add (action); } } Public void removeframeaction(Action action) {if(Frameactionlist.contains (Action)) {Frameactionlist.remove (action); } } PublicCoroutineStartcoroutine(IEnumerator routine) {return This. Main.startcoroutine (routine); } Public void Stopcoroutine(IEnumerator routine) { This. Main.stopcoroutine (routine); }}
So everything else needs to start here.
The other singleton is in this initialization, updating update, destroying destroy, and so on.
A simple analogy:
usingSystem;usingSystem.Collections.Generic;usingUnityengine; Public classxxmanager:basemanager{ Public StaticXxmanager Instance {Get{returnSingletonprovider<xxmanager>. Instance; } } Public Override void Init() { } Public Override void Update() { } Public Override void Reset() { } Public Override void Destroy() { } Public void Remove(stringClockid) {} Public void Remove(intClockid) {}}
That's basically the way it is.
But these are not what I want to say.
The advantages of these singleton patterns are quite numerous. The code is easy to manage, organize, and can easily locate bugs when there are bugs and so on.
The code is simple, clear, structured and relatively easy to meet a single responsibility principle and so on. Again, the singleton itself is a good design pattern.
However, I would like to use another try.
Third, self-study of the property definition Framework 1 What is a property
In C #, there is a attribute attribute that intends to use this property to collect all the relevant functions for uniform processing.
That's good.
First of all, this is just a personal idea. Of course, the basic implementation is complete. Good or bad, this later, as for a little, at least, the wheel is also the production of their own AH.
Besides, there are advantages.
First, the definition of the attribute:
[System.AttributeUsage(AttributeTargets.All)]internalclass SFHCall : Attribute{}
This is a property inheritance definition. Without it.
2 functions that collect the corresponding attributes
This of course needs a dictionary to store it.
Direct Code Bar:
usingUnityengine;usingSystem.Collections;usingSystem.Collections.Generic;usingSystem;usingSystem.Reflection; Public classattributeutils{ Public StaticDictionary<monobehaviour, list<methodinfo>> Monorpcmethodscache =NewDictionary<monobehaviour, list<methodinfo>> (); Public Static voidGetalldestbyproperties<t> (Object[]mono) {intLength = Mono. Length; for(inti =0; i < length; i++) {getdescbyproperties<t> (mono[i]); } }Private Static voidGetdescbyproperties<t> (Objectp) {Monobehaviour mo = (monobehaviour) p;if(!monorpcmethodscache.containskey (MO)) {cache<t> (MO); }return; }Private Static voidCache<t> (Monobehaviour p) {list<methodinfo> cachedcustommethods =NewList<methodinfo> (); Monorpcmethodscache.add (P, cachedcustommethods);varType = P.gettype ();//The method of the parent class will not be called repeatedly. varFIELDS2 = type. GetMethods (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BINDINGFLAGS.DECLAREDONLY);foreach(varFieldinchFIELDS2) {varOBJS = field. GetCustomAttributes (typeof(T),false);if(Objs. Length >0) {cachedcustommethods.add (field); } } }}
Here's a little bit:
// 不会重复调用父类的方法了。 type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
The last one only looks for the matching function in the file of course, and does not extend to the parent class. If you look in the parent class, this will result in a large number of repetitive functions, which will waste multiple times of efficiency in subsequent executions.
Although the code does not have too many comments, it is basically self-explanatory. So, not too much elaboration.
3 Execution of functions
Functions are collected. Save it in a different list, so you can do it according to your own preference!!
How do you do it? The key is invoke.
usingUnityengine;usingSystem.Collections;usingSystem;usingSystem.Collections.Generic;usingUnityeditor;class sfhlistener{StaticSfhlistener () {Initialstart (); } Public Static void CallMe() {Console.WriteLine ("Call Me"); }Private Static void Initialstart() {monobehaviour[] Testmono = getscriptassetsoftype<monobehaviour> (); Attributeutils.getalldestbyproperties<sfhcall> (Testmono);intAttributefunctioncount = AttributeUtils.monoRPCMethodsCache.Count;if(Attributefunctioncount <0) {return; }foreach(varIteminchAttributeutils.monorpcmethodscache) {Monobehaviour monob = (monobehaviour) item. Key; for(intIMethod =0; IMethod < item. Value.count; imethod++) {Objectresult = Item. Value[imethod]. Invoke ((Object) Monob,New Object[] { });if(item. Value[imethod]. ReturnType = =typeof(IEnumerator)) {Monob. Startcoroutine ((IEnumerator) result); } } } }Private StaticMonobehaviour[] Getscriptassetsoftype<t> () {//Current scripts in current scene;Monobehaviour[] monoscripts = (monobehaviour[]) gameobject.findobjectsoftype<monobehaviour> ();//Get all monobehaviours contains current scene and also all prefabs //monobehaviour[] monoscripts = (monobehaviour[]) resources.findobjectsoftypeall<monobehaviour> (); returnmonoscripts; }}
It is important to note that in the last function.
Commented out code, will find all the scene and the prefab code, so there will be a lot of overloading and duplication caused by waste.
4 The final call is
Called, this super simple.
Of course, it can be adjusted according to your needs. Put it in awake or start with your will!!
using UnityEngine;using System.Collections;using System.Collections.Generic;using UnityEditor;using System.Reflection;publicclass StartFromHere : MonoBehaviour{ // Use this for initialization void Start() { SFHListener.callme(); }}
This example is written only in start.
This is the basic explanation.
Four, of course, the source code
Github Address: Https://github.com/cartzhang/StartFromHere
Of course, you are also very welcome to submit your code.
Now the code and what it says can take parameters. This estimate look, if need to try again!!
After all, I still have to go home to sleep!!
——————, Haven ——————— –end ———————— –
If you have any questions, feel free to contact!!
Thank you so much!!!!
Unity script Execution Sequence self-research framework