您的位置:首页 > 移动开发 > Unity3D

Unity3D MonoBehaviour Lifecycle

2014-09-01 16:41 585 查看







Notes

Supposing your scene starts at frame 0 (or an object gets activated, or a component gets added, or an object gets created)...
Inactive objects "don't count", think of them as basically not being on the scene at all.
Lots
more to cover...

Static Constructor

This is called by .net as your assemblies are being loaded. The
C# Reference makes very few guarantees about exactly when it will be called, but it does state that before any part of a class can be referenced its static constructor will be called.

If working from the editor, when you save a script (and thus force a recompilation), your static constructor is likely to be called immediately as Unity loads the built DLL. It will not likely be run again.

On a deployed game, this constructor will be called early in Unity's loading process.

Constructor

Unity will call the default constructor of any object but at seemingly random times. While editing a game, the constructor is likely to be called immediately after saving a script (forcing a recompilation).

Do not use a constructor to assign values to fields. Unity's
Awake() is designed specifically for that purpose.

0 : Awake

This is the one and only event that will ALWAYS fire (unless the object is inactive, see above). It will still fire if the object is active but the script is disabled.

0 : OnEnable

Not called if the behaviour is disabled.

[0 : OnLevelWasLoaded]

Not called on the first level.

Not called if the object is created once the level is loaded.

0 : Main

Not called if the behaviour is disabled.

Undocumented.

In a Javascript behaviour, this is where your inline instructions go after compilation, but it's actually usable in C# as well.

Only think of it as a pre-Start, not another round of events.

All Awakes are called, then all Main & Start are called, NOT all Awake, all Main, then all Start.

Consider components Script1 & Script2, Script1 being first in the component list, the call order will be:

Awake Script1
Awake Script2
Main Script1
Start Script1
Main Script2
Start Script2

0 : Start

Not called if the behaviour is disabled.

0 : Update (first call)

Not called if the behaviour is disabled.

0 : LateUpdate (first call)

Not called if the behaviour is disabled.

0 : OnDrawGizmos (first call)

Editor-only. Called even if the behaviour is disabled.

0 : OnDrawGizmosSelected (first call)

Editor-only, called only if the object is selected in the hierarchy view. Called even if the behaviour is disabled.

[+1 : OnNetworkLoadedLevel]

Only called if the level was network-loaded.

This event isn't actually built-in, but fired by the NetworkLevelLoad script
that lots of people are using.

The +1 delay is also introduced by this script, but I'm not sure it would be wise to try and remove it.

+x : OnApplicationQuit

+x : OnDisable

Example

Don't take my word for it, try it for yourself!

You'll notice that if you just drop this script wherever and press play, everything starts at frame 1.

I don't know if frame 0 even exists (it's called frameCount after
all), or if it's used for internal initialization...
If you load a scene from another one, you'll notice there is a one-frame delay (eg if this script is in a scene that was loaded as soon as the game starts, everything starts at frame 2).

using UnityEngine;
using System.Collections;

public class TestLifeCycle : MonoBehaviour
{
void Awake()
{
logFrame("Awake");
}
void Main()
{
logFrame("Main");
}
void Start()
{
logFrame("Start");
}

void OnLevelWasLoaded()
{
logFrame("OnLevelWasLoaded");
}
void OnNetworkLoadedLevel()
{
logFrame("OnNetworkLoadedLevel");
}

void OnEnable()
{
logFrame("OnEnable");
}
void OnDisable()
{
logFrame("OnDisable");
}
void OnApplicationQuit()
{
logFrame("OnApplicationQuit");
}

void Update()
{
logFrame("Update");
}
void LateUpdate()
{
logFrame("LateUpdate");
}
void FixedUpdate()
{
logFrame("FixedUpdate");
}
void LateFixedUpdate()
{
logFrame("LateFixedUpdate");
}

void OnDrawGizmos()
{
logFrame("OnDrawGizmos");
}
void OnDrawGizmosSelected()
{
logFrame("OnDrawGizmosSelected");
}

static void logFrame(string message)
{
Debug.Log(Time.frameCount + " - " + message);
}
}


Collisions / Physics

TODO...

explain FixedUpdate here, relation with OnCollisionXXX

GUI

TODO...

explain EventType

Network life cycle

TODO...

explain MasterServer connection, peer connection / disconnection, etc...

OnDisconnectedFromServer

If a method call Network.Disconnect(), OnDisconnectedFromServer will be called instantly (whether in the same script or any other script that subscribes to this callback).

Example:

void Disconnect()
{
logFrame("before Disconnect");
Network.Disconnect();
logFrame("after Disconnect");
}
void OnDisconnectedFromServer()
{
logFrame("OnDisconnectedFromServer");
}


will lead to the following output:

before Disconnect
OnDisconnectedFromServer
after Disconnect


This behaviour is opposed to delayed callbacks, that occur one frame later than the event that triggered them (for example OnTriggerEnter is called the frame after the collision visually occurs). Also note that Debug.Break() will not interrupt the current
call stack, merely pause the editor at the end of the current frame. TODO: reference instant/delayed callbacks.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: