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.

 

StartPawn.png

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:

 

InventorySelect1.png

 

InventorySelect2.png

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

 

InventoryProp1.png
Listen for Space Connection and Inventory Property Updates
InventoryProp2.png
Process “inventory” String Changes and Add the Correct Static Mesh

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.

 

Candle.jpg

 

Sword.jpg

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.

 

LightSyncSetBoolean.png
Set Boolean receives updates from the Journal

 

LightSyncGetBoolean.png
Get Boolean queries the local object for changes to be sent to the Journal

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).

 

ACandle1.png
Static Mesh of the Candelabra with Components

 

ACandle2.png
Toggle Light function

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.

 

PawnSetInventory1.png
SetInventoryItem Part 1 - Object Creation
PawnSetInventory2.png
SetInventoryItem Part 2 - Container Initialization
PawnLightInput.png
Light Toggle Action on 'L' Input

And finally, the Cavrnized result:

 

CandleActorUnlit.png
So dark…

 

CandleActorLit.png
So Bright!!!

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.

CSC2.png

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.

AvatarLoader1.png
We need the Space Connection ID to listen for user properties
AvatarLoader2.png
Here we listen for the Movement property
AvatarLoader3.png
When the Movement property value is set or is updated, the remote clients switch the Pawn asset

 

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.

 

Related content