Instantiate / Destroy
Requirements
Instantiated game objects are basically the same as synchronized objects placed on the scene during development, but because they are spawned at runtime,
they have to be placed in prefabs with the ElympicsBehaviour
component attached to the root GameObject and stored inside the Resources directory.
Instantiate
ElympicsInstantiate
The only way to spawn synchronized prefab in runtime is to use ElympicsMonoBehaviour.ElympicsInstantiate
.
This method has 2 parameters:
pathInResources
: path to a prefab in Resources directory e.g."BlueBall"
player
: instantiated object will be predictable for this player (can be used for simulating ownership)ElympicsPlayer.World
- only the server can spawn with this option and it means it won't be predictable to any player - useful for random server eventsElympicsPlayer.All
- object predictable for all players, can be spawned by any player - useful for fully predictable physics objectsElympicsPlayer.FromIndex(i)
- object predictable for a specific player, can be spawned by this specific player or the server - useful for projectiles created by players
The path from pathInResources
parameter is case insensitive and must not contain a file extension.
ElympicsInstantiate
returns an object of type GameObject
and there is currently no generic override of the method available.
To get a specific component from an object spawned this way, simply use Unity's GetComponent
method, like in the example below.
// spawns "BlueBall" every 100 ticks
private readonly ElympicsInt _tick = new ElympicsInt(0);
public void ElympicsUpdate()
{
_tick.Value++;
var tickPeriod = _tick.Value % 100;
if (tickPeriod == 99)
{
GameObject prefabInstance = ElympicsInstantiate("BlueBall", ElympicsPlayer.All);
CustomScript custom = prefabInstance.GetComponent<CustomScript>();
custom.CustomMethod();
}
}
NetworkId
An object created using ElympicsInstantiate
method has its NetworkId
assigned using the following formula:
var networkId = (playerIndex + 4) * 10 000 000 + i;
where i
is the index of the instantiated object increased with every new object.
This means that all instantiated objects have the following NetworkId
ranges:
- for
All
players - [10 000 000; 19 999 999] - for
World
player - [20 000 000; 29 999 999] - for
Player 0
- [40 000 000; 49 999 999] - etc.
Number of players is limited to 196, which means the maximal possible network ID for an instantiated object is 1 999 999 999. This may change in the future releases.
ElympicsUpdate
and other callbacks are called in a deterministic order of increasing NetworkId
.
Scripts attached to objects instantiated at runtime will be executed at the end of the game loop.
Learn more.
Destroy
To destroy a game object spawned with ElympicsMonoBehaviour.ElympicsInstantiate
, simply call ElympicsMonoBehaviour.ElympicsDestroy
and pass that object as an argument.
ElympicsDestroy
can be called from any code, as long as it is a part of IUpdatable.ElympicsUpdate
or IInitializable.Initialize
.
- Self destroy
- From another object
private readonly ElympicsInt _ticksAlive = new ElympicsInt(0);
public void ElympicsUpdate()
{
_ticksAlive.Value++;
if (_ticksAlive.Value > 60)
ElympicsDestroy(gameObject);
}
private readonly ElympicsInt _tick = new ElympicsInt(0);
private readonly ElympicsGameObject _cube = new ElympicsGameObject(null);
public void ElympicsUpdate()
{
_tick.Value++;
var tickPeriod = _tick.Value % 200;
if (tickPeriod == 80)
_cube.Value = ElympicsInstantiate("Cube", ElympicsPlayer.All).GetComponent<ElympicsBehaviour>();
if (tickPeriod == 199)
{
ElympicsDestroy(_cube.Value.gameObject);
_cube.Value = null;
}
}
Prediction
Spawning and destroying objects modifies the state of the game.
This means, that those operations must follow the server authoritative approach.
As a result, both ElympicsInstantiate
and ElympicsDestroy
always has to be called on the server.
Calling those methods on a client is only possible in games with prediction enabled.
Any attempt to spawn or destory objects on a client for which they are not predictable will result in an exception.
If a call to ElympicsInstantiate
or ElympicsDestroy
for an object which is predictable for the given client does not happen in the same
tick on both client and server, reconciliation will be triggered once the client receives a snapshot for that tick.
If you want spawning and destroying objects in your game to take advantage of prediction, you can ensure it always happens in the same tick on both server and client
by using inputs. You can also send a player-to-server RPC in the same tick in which
you call ElympicsInstantiate
or ElympicsDestroy
on a client.