| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- ======================
- Interacting with Units
- ======================
- At some point you will probably need to reference units from the Lua scripts to
- manipulate their properties, be notified of particular events and make them do
- something interesting.
- Getting Unit handles
- --------------------
- The simplest way of getting a handle to a unit is to spawn it directly from a
- script:
- .. code::
- player = World.spawn_unit(world, "units/player/player")
- In most cases, however, units are not spawned directly but rather as a
- consequence of loading levels in a world. You can get a table with all units
- spawned in a world this way:
- .. code::
- local units = World.units(world)
- for _, u in ipairs(units) do
- -- Do something with Unit u.
- end
- To obtain a specific Unit by name (its name as set in the Level Editor, *not*
- the unit name itself):
- .. code::
- door = World.unit_by_name(world, "main_door")
- The Script component
- --------------------
- Obtaining unit handles is useful but might not be enough. With a unit handle
- alone you can modify properties but you cannot receive events.
- Creating a Unit script
- ----------------------
- Unit scripts are a particular type of scripts that can be attached to units via
- a Script Component. To create a Unit script, right click on the Project Browser
- and choose ``New (Unit) script``.
- Crown will create a new Unit script similar to the following:
- .. code::
- MyScript = MyScript or {
- data = {}
- }
- local data = MyScript.data
- -- Called after units are spawned into a world.
- function MyScript.spawned(world, units)
- if data[world] == nil then
- data[world] = {}
- end
- local world_data = data[world]
- for _, unit in pairs(units) do
- -- Store instance-specific data.
- if world_data[unit] == nil then
- world_data[unit] = {}
- end
- end
- end
- -- Called once per frame.
- function MyScript.update(world, dt)
- local world_data = data[world]
- for unit, unit_data in pairs(world_data) do
- -- Update unit.
- end
- end
- -- Called before units are unspawned from a world.
- function MyScript.unspawned(world, units)
- local world_data = data[world]
- -- Cleanup.
- for _, unit in pairs(units) do
- if world_data[unit] then
- world_data[unit] = nil
- end
- end
- end
- return MyScript
- Unit scripts work differently than similar solutions in other engines. Instead
- of getting many individual update() calls for each individual Unit, you will
- receive a single update() for *every* unit that has that particular script
- attached to it.
- This allows for efficient bulk updates, state sharing and it also make profiling
- code easier.
- Receiving collision events
- --------------------------
- To get physics collision notification events, implement any of the following
- callbacks in your script component:
- .. code::
- function MyScript.collision_begin(world, unit, other_unit, actor, other_actor, position, normal, distance)
- -- Called when unit and other_unit begin touching.
- end
- function MyScript.collision_end(world, unit, other_unit)
- -- Called when unit and other_unit end touching.
- end
- function MyScript.collision_stay(world, unit, other_unit, actor, other_actor, position, normal, distance)
- -- Called between collision_begin() and collision_end() while the units remain touching.
- end
- Triggers
- --------
- Units whose actor is configured as a trigger (actor class 'trigger') will not
- receive regular collision events, instead, they will receive trigger events:
- .. code::
- function MyScript.trigger_enter(world, trigger_unit, other_unit)
- -- Called when other_unit begins touching trigger_unit.
- end
- function MyScript.trigger_leave(world, trigger_unit, other_unit)
- -- Called when other_unit ends touching trigger_unit.
- end
|