Skip to main content

Lifecycle Events

A long time ago, you were born. You are also going to die. You also poo every day. These are lifecycle events.

GameObjects are like people. They have lifecycle events.

In ModScript land, these lifecycle events are split into 2 categories:

  1. Lua functions
  2. EventsForModScript Component

The reason for this split is performance and convenience related.

Lua functions

There are 4 Lua function lifecycle events you can implement in your ModScripts:

  1. update() - called every frame (fps can vary dramatically)
  2. fixedUpdate() - called every physics step (fixed at 30fps)
  3. lateUpdate() - called every frame, after all updates have been called across all scripts
  4. cleanup() - called when exiting the level

To use one, just define it as normal Lua function in your ModScript, and it will be called automatically at the appropriate time.

function lateUpdate()
-- do stuff at the end of every frame. be very careful about performance
end

Cleanup

The cleanup function gets called when exiting the level, in the same order as the scripts were started.

function cleanup()
-- unsubscribe from all events here with <some event>.remove()
-- do all other cleaning up here
end

In this context exiting the level means:

  • Level Builder: after exiting play mode
  • Play Created Level: after leaving the scene
warning

Make sure you cleanup all events you subscribed to in your scripts, and everything else that's appropriate, or you will cause memory leaks and it will degrade performance.

EventsForModScript Component

All the other lifecycle events that you'd normally use in Unity are accessible through a separate Component in the YOMG2 codebase, called EventsForModScript.

It hooks Unity's lifecycle events up to native C# events, which which you can subscribe to in your ModScript section.

Here are all the events you can subscribe to, copied and pasted from the C# Component directly:

public event EventHandler AwakeEvent = delegate { };
public event EventHandler StartEvent = delegate { };
public event EventHandler OnDestroyEvent = delegate { };

public event EventHandler OnEnableEvent = delegate { };
public event EventHandler OnDisableEvent = delegate { };

public class CollisionEventArgs : EventArgs { public Collision2D Other { get; set; } }
public class ColliderEventArgs : EventArgs { public Collider2D Other { get; set; } }

public event EventHandler<CollisionEventArgs> OnCollisionEnterEvent = delegate { };
public event EventHandler<CollisionEventArgs> OnCollisionExitEvent = delegate { };
public event EventHandler<CollisionEventArgs> OnCollisionStayEvent = delegate { };

public event EventHandler<ColliderEventArgs> OnTriggerEnterEvent = delegate { };
public event EventHandler<ColliderEventArgs> OnTriggerExitEvent = delegate { };
public event EventHandler<ColliderEventArgs> OnTriggerStayEvent = delegate { };

public event EventHandler OnMouseUpEvent = delegate { };
public event EventHandler OnMouseDownEvent = delegate { };
public event EventHandler OnMouseDragEvent = delegate { };

You'll need to add the EventsForModScript Component to the GameObject you want these lifecycle events on, like in this example:

registerType("EventsForModScript")
registerType("EventsForModScript+CollisionEventArgs")
registerType("Collision2D")
registerType("MemeItem")
registerType("AbstractMemeItemData")

local curItem = getCurrentItem()
local events = curItem.AddComponent(getType("EventsForModScript"))

function collisionHandler(sender, eventArgs)
local otherCollider = eventArgs.Other -- look at CollisionEventArgs pasted above
print("other collider GO name: ", otherCollider.gameObject.name) -- NEVER actually rely on the root GameObject name for anything (assume it's randomly generated), it's only for demonstration purposes here
end

events.OnCollisionEnterEvent.add(collisionHandler)

function cleanup()
events.OnCollisionStayEvent.remove(collisionHandler)
end
Check out this in-depth diagram from the Unity Documentation about lifecycle events and order of execution