Network Objects

A network object is an object that needs to be synchronized and that exists on all clients.

By default, objects in a World are local. This means that any changes made to an object are invisible to other players. To synchronize an object, you must turn it into a network object.

To do this, you can add the Para Script or Para Object Sync component to the object.

Certainly, objects that contain network feature components such as Para Portal, Para MusicPlayer, and Para VideoPlayer are all network objects. Besides, a player is also a network object, which means that their locations, Animator Controller parameters, and voices are all automatically synchronized.


The ownership of a network object determines which player can change the properties of that network object and send it to other players. The ownership of a network object must belong to a certain player at any given moment. A player can be the owner of multiple objects at the same time. If you want a player to be able to change the properties of an object, be sure to check or request the ownership of the object first.

If the owner of an object changes for some reason, the new owner will be responsible for modifying and synchronizing the network data. For example, if you pick up an object on which Para Pickup is mounted, you will become the new owner of that object. When a player leaves a room, the player no longer owns any object in that room.

Example of a Simple Network Object

If you own a 3D object that contains a renderer and a collider, you can easily turn the object into something that can be picked up and synchronized.
What you need to do is to add the Para Pickup and Para Object Sync components to the object.


The simplest network object: pickup object

The Para Pickup component allows the automatic transfer of the ownership of an object when that object is picked up. You can learn how this is implemented by viewing the source code. Since Para Pickup is a component scripted in Lua, its source code is open source.

The Para Object Sync component automatically synchronizes the location, rotation, and some physical properties of an object, ensuring that all players can see that object with no differences. If you want to synchronize other data, you must use a [synchronization variable](doc:synchronization variable).

Determine Ownership

You can use the following methods to determine the ownership of the object to which the current script belongs.
If you want a player to be able to change the properties of an object, be sure to check or request the ownership of the object first.

ParaScript.HasOwnership()Determines if you own the current object yourself.
ParaPlayer ParaScript.GetOwner()Directly gets the player object of an owner.
ParaScript.IsOwner(ParaPlayer player)Determines if a player is the owner of the current object.

Change Ownership

You can take the following steps to change the ownership of an object:

1. Request ownership

You can request the ownership of the object to which the current script belongs by calling ParaScript.RequestOwnership(Action onFinished).
Anyone can call this method.
In addition, you can directly process the logic after the request result is received in the callback of this method, as shown below:

self:RequestOwnership(function(bSucceed) -- The bSucceed parameter of the callback function indicates whether that request was successful.
	if bSucceed then
		print("request succeeded");

2. Reply to the ownership transfer request

You can reply to a request for the transfer of ownership by using the event function bool ParaScript.OnOwnershipRequest(int senderID). The owner will receive this event. If you are already the owner, you will receive this event.
If the owner returns true, it indicates consent. If the owner returns false, it indicates dissent. In the event of the former, the OnOwnershipTransferred event will be sent to all the players in the room.

Note that setting the return value to true has the same effect as not setting any return value. If you do not implement the OnOwnershipRequest event function, that has the same effect as not setting any return value. If you do not want to add a judgment logic to the ownership transfer, you can simply not set any return value.

If multiple scripts owned by an object have this event function, it indicates consent only when all the scripts return true. As long as one of the scripts returns false, the request will be rejected and the event will no longer be executed by any of the other remaining scripts. Therefore, do not implement any value assignment logic in the event function because the logic may not be executed.

function OnOwnershipRequest(senderID)
    return true;

3. Broadcast the ownership transfer

You can use the event function ParaScript.OnOwnershipTransferred to indicate that the ownership has been transferred. All players in the room will receive the event. You can also use ParaPlayer ParaScript.GetOwner() in the event function to get the new owner.

function OnOwnershipTransferred()
    print("New Owner =", self:GetOwner().playerID);

Another method: Set a new owner

The owner can directly set a player to be the new owner by calling ParaScript.SetOwner. This method also triggers the OnOwnershipTransferred event.

Dynamically Operate Network Objects

In addition to network objects that already exist when a room is created, network objects can also be dynamically generated at runtime in ParaSpace. For example, when a player triggers a trigger, new monsters appear. In this case, the monsters are dynamically generated network objects.

You can use the following methods to generate or destroy network objects:

ParaObjectService.NetSpawnGeneates a network object.
ParaObjectService.NetDestroyDestroys a network object. A network object can be destroyed only by its owner.


Upper limit on the number of network objects

Up to 10,000 network objects can coexist in a World. Generally, this number is sufficient for most creators. If you need more network objects, feel free to contact us for assistance.

Dynamically Generate Network Objects

To dynamically generate a network object, you must first configure the object in the ParaNetSpawnObjects.asset file and associate it with the ParaWorldRoot component.

  1. Create a ParaNetSpawnObjects.asset file.
  1. Associate the GameObject to be generated with the ParaNetSpawnObjects.asset file and specify a key.
    • The length of the key is not limited. However, the key must be unique.
    • You can associate the GameObject in the scene or the one in the project.
  1. Associate the ParaNetSpawnObjects.asset file with the ParaWorldRoot component.
  1. Now you can use the API in the Lua script to generate a network object when needed.
function SpawnNetObject(key, pos, rotate)
  return ParaObjectService.NetSpawn(key, pos, rotate)
  • Note: The ownership of an object belongs to the player who creates the object. The name of the generated object is the same as the configured name. A generated object will not be destroyed automatically. To ensure better performance, you need to manage the object destruction logic.