xulipa
xulipa10h ago

How to sync avatar animations for PC

How to sync avatar animations from animation controller the root prefab already has real-time transform
9 Replies
kapa.ai
kapa.ai10h ago
Hi @xulipa. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To synchronize avatar animations (such as those driven by an Animator or Animation Controller) across clients in Normcore, you need to explicitly synchronize the animation state, since RealtimeTransform only synchronizes position, rotation, and scale—not animation parameters or states. Here’s how you can approach this: 1. Synchronize Animation Parameters Using a RealtimeModel You should create a custom RealtimeModel to hold the parameters that drive your Animator (e.g., floats, bools, triggers). For example, if you want to sync a "walking" boolean and a "speed" float:
using Normal.Realtime;
using UnityEngine;

[RealtimeModel]
public partial class AvatarAnimationModel {
[RealtimeProperty(1, false, true)] private bool _isWalking;
[RealtimeProperty(2, false, true)] private float _speed;
}
using Normal.Realtime;
using UnityEngine;

[RealtimeModel]
public partial class AvatarAnimationModel {
[RealtimeProperty(1, false, true)] private bool _isWalking;
[RealtimeProperty(2, false, true)] private float _speed;
}
This model will synchronize the animation parameters between clients. You can add more properties as needed for your animation controller. For more details on creating and using RealtimeModels, see the Synchronizing Custom Data guide. 2. Create a RealtimeComponent to Sync Animator State Create a component that reads/writes these parameters to the Animator and the model:
using Normal.Realtime;
using UnityEngine;

public class AvatarAnimationSync : RealtimeComponent<AvatarAnimationModel> {
public Animator animator;
private void Update() {
// If this client owns the model, write to the model
if (model.isOwnedLocally) {
model.isWalking = animator.GetBool("isWalking");
model.speed = animator.GetFloat("speed");
} else {
// If not owned, update the animator from the model
animator.SetBool("isWalking", model.isWalking);
animator.SetFloat("speed", model.speed);
}
}
}
using Normal.Realtime;
using UnityEngine;

public class AvatarAnimationSync : RealtimeComponent<AvatarAnimationModel> {
public Animator animator;
private void Update() {
// If this client owns the model, write to the model
if (model.isOwnedLocally) {
model.isWalking = animator.GetBool("isWalking");
model.speed = animator.GetFloat("speed");
} else {
// If not owned, update the animator from the model
animator.SetBool("isWalking", model.isWalking);
animator.SetFloat("speed", model.speed);
}
}
}
Attach this script to your avatar prefab and assign the Animator reference. 3. Ownership Make sure the client controlling the avatar requests ownership of the model, so it can write animation state. Other clients will receive updates and apply them to their local Animator. 4. Prefab Setup - Your avatar prefab should have a RealtimeView on the root. - Add your custom RealtimeComponent (e.g., AvatarAnimationSync) to the prefab. - The prefab should be in a Resources folder and instantiated using Realtime.Instantiate(). 5. RealtimeTransform RealtimeTransform will continue to synchronize the position, rotation, and scale of the avatar root and any child objects (like head and hands), but it does not sync Animator state. You must use the approach above for animation parameters. --- Summary:
- Use a custom RealtimeModel to sync animation parameters. - Use a RealtimeComponent to read/write those parameters to the Animator. - Ensure proper ownership management. - RealtimeTransform only handles transform data, not animation state. For more details, see the Synchronizing Custom Data guide and RealtimeComponent documentation. If you need to interpolate animation parameters smoothly, you can use the [Interpolate] attribute on your model properties for smoother transitions between states, as described here. If you need more specific code examples or run into issues, let me know! ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai10h ago
<@725231244169707600> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Mechabit
Mechabit10h ago
I think there's an animator sync component coming soon tm
xulipa
xulipaOP10h ago
Nice! Like tomorrow = tm? 🙂
Mechabit
Mechabit10h ago
tm = trade mark so not soon
xulipa
xulipaOP10h ago
Ahhh 🙂 Yeah would be cool to have something to just slap onto the animator
Mechabit
Mechabit10h ago
but if you need it now you'd expose the animator variables and drive the animation from those
maxweisel
maxweisel10h ago
RealtimeAnimator ships later this year

Did you find this page helpful?