Swapping Avatars at Runtime (Unreal Engine)

Note: Before reading this, you should first make sure you understand Custom Avatars & Advanced CoPresence.

Now that you can change which remote Avatar your users will have, you may be wondering if different users can use different remote avatars, or even swap them out at runtime?

In short: no, but actually yes!

We only ever allow for you to specify one Remote User Avatar in the Cavrnus Spatial Connector. This is the “thing” that will be spawned every time a user joins. However, by using the properties system in interesting ways we can make this “avatar” do a lot of powerful stuff.

 

CSC1.png

 

CSC2.png

Swapping Sub-Parts of an Avatar

Before we dive fully into swapping out entire Avatars, let’s see how we can swap in and out objects that are a part of the avatar. In this example, let’s assume we have the standard avatar provided with the Cavrnus Connector plugin.

 

We are making a game that lets users switch out their weapon from their inventory. In this case they can choose between a light source (“candle”) and a weapon (“sword”). To synchronize this, we will use a string property that we will call “inventory”. When the avatar’s “inventory” property equals “sword” we show the sword, and when it equals “candle” we show the candelabra. For easy testing we’ll set the “candle” value when the user presses the 1 key, and the “sword” value when 2 is pressed. First, the blueprints to process the input and update the property value:

 

 

Now we need to subscribe to the property updates, and add the static mesh for the appropriate inventory item when the “inventory” property changes.

 

In the above function, “Mesh” is the Pawn’s skeletal mesh component that has been set up with a socket on the right hand bone. “Mesh Keys” is a dictionary mapping the inventory strings (i.e. “candle” and “sword”) to mesh assets representing those objects. Other potential solutions might include the inventory item being an Actor or some other object type instead.

With this users can now swap out bits of their avatars at runtime.

 

 

Giving Properties to Avatar Sub-Parts

Now that we have established how a property can be used to dynamically create/destroy objects, let’s see how those objects can, themselves, show properties!

To do this, we will have the candles from the earlier example be able to toggle its light on and off, using its own Boolean property. To facilitate this, we will switch our inventory items to be actors that contain their own components. Our new version of the candle object will need light components, a CavrnusPropertiesContainer component, and a new component that translates a boolean property value to light visibility. In order to keep different users' pawns from sharing the same inventory properties, we will manually update our CavrnusPropertiesContainer’s name to be the same as the pawn that owns it.

The LightSyncComponent created has CavrnusValueSyncBoolean as its parent class, and overrides the SetBoolean event and the GetBoolean function call. This logic is simplified to assume that all light components should be on or off in unison.

 

 

Our new inventory items are ACandleHolder and ASword. We are focusing on ACandleHolder for this example. It takes the Pawn’s input on whether to turns the lights on and off, and contains the lights, the Cavrnus Property Container, and the new LightSyncComponent. The LightSyncComponent updates the property in the journal by observing the visibility status of the light component(s).

 

 

Now the Pawn is updated from the previous example to create actors instead of static meshes, initializes the CavrnusPropertiesContainer component(s) in the actors, and has been updated to toggle the lights on and off when the user hits 'L' on the keyboard.

 

And finally, the Cavrnized result:

 

 

Swapping the “Entire” Avatar

Now that we have established how the avatar that gets spawned can create and destroy its own objects, and that those objects can have their own properties, the final step is to combine those systems to swap out the “entire” avatar.

As we have stated before, this is technically impossible, you can only specify one Remote Avatar in the Cavrnus Spatial Connector.

However, imagine if that sphere Co-Presence you see above was invisible (aka it didn’t have any renderers/geometry/etc). As far as your customers would know, their avatar was either a sword or a hammer, and they could switch between them.

Taking this a step further, let’s imagine you wanted your customers to be able to switch between a “Walking Mode” avatar, and a “Flying Mode” avatar. To achieve this, you would make an empty object called something like “Remote Avatar Loader”, with a String Synchronizer on it. This is the object you will plug into the Cavrnus Spatial Connector.

What we end up with looks essentially identical to the Item swapper above. Any additional scripts/behaviors you want these “avatars” to have can also be set up like above.

We can set up a custom property to change the pawn class in response to the user’s selected mode of movement. If the user chooses an input scheme where they can fly, other clients will see a different representation with a different asset (e.g. a flying saucer, or a mannequin with a different animation set, etc.) than they see when the user is in walk mode. Here, we’re storing their selected movement mode in a string property called Movement, under their user property container. The value of Movement would be set by an input shortcut or HUD buttons (not pictured here) and the remote avatars would update by binding to that same property.

 

Loading in Custom Content As Avatars

While the above samples involve fairly simple switches between a specified set of prefabs, you could take this concept in any direction you wish. So long as you can write the code to interpret the properties, you can do anything.

To give one example here, if you wanted to have some sort of integration with a system ReadyPlayerMe, you could allow users to set their Ready Player Me ID somewhere, and post it as a property to their container. Then, instead of switching between prefabs, you could have a SyncReadyPlayerMe script which passes the value into a loader, which would then import the avatar.