I was connected in a multiplayer session in a room. My player A is looking at player B who is sitting on a chair whose current animation is āsitDownā. When I switch to some other browser tab and player B moved away from the chair and standing idle now in space. Now when I come back to my current tab and I see that player B is at new position where he was standing idle but I see player B animation as āSitDownā only.
Its updates for me only when player B move again after I came back to my current screen.
I saw the logs from ādebuganimatorcontrollerā, I found that I didnāt received the log ātransition changed to 0(idle)ā only got the log Set Trigger to āidleā.
Iāve used āconnection.sendā and client gets update from ābeginListenā callback. Please find the code snippet for logic Iāve used for my custom SyncedAnimator. Let me know if there is any issue in it. If this didnt work, I will used the sample logic of SyncedAnimator.
onEnable(): void {
this.animator = this.gameObject.getComponent(Animator) as Animator;
this.context.connection.beginListen("animCall", this.onAnimationUpdated);
}
onDisable(): void {
this.context.connection.stopListen("animCall", this.onAnimationUpdated);
}
onAnimationUpdated = (response: AnimModel) => {
if (!this.animator) return;
if (response.id === this.syncedTransformGuid) {
this.ResetAllTriggers();
this.animator.setTrigger(response.transitionTo);
}
}
public SetTrigger(transitionTo: string) {
if (!this.animator) return;
this.ResetAllTriggers();
this.animator.setTrigger(transitionTo);
this.animModel = new AnimModel(this.syncedTransformGuid, transitionTo);
this.context.connection.send("animCall", this.animModel);
}
private ResetAllTriggers() {
if (!this.animator) return;
this.animator.resetTrigger("idle");
this.animator.resetTrigger("walking");
this.animator.resetTrigger("running");
this.animator.resetTrigger("dance");
this.animator.resetTrigger("sitDown");
this.animator.resetTrigger("sitIdle");
this.animator.resetTrigger("standUp");
}
this.syncedTransformGuid Iām getting this from another class where Iām downloading model and assigning SyncTransform at runtime. So its like that
// my Character loading class...
:
:
@serializable(SyncedTransform)
currentSyncedTransform!: SyncedTransform;
:
:
async downloadAndApply(url: string) {
:
// downloading model from url and instantiating it as a GameObject
:
:
//
let syncAnimatorInstance = GameObject.addNewComponent(go, SyncAnimator);
if (syncAnimatorInstance) {
syncAnimatorInstance.awake();
syncAnimatorInstance.enabled = true;
if (this.currentSyncedTransform) {
syncAnimatorInstance.syncedTransformGuid = this.currentSyncedTransform.guid;
}
}
:
:
do not use the same guid for your animation and position.
The guid is an ID for the storage on the server, so under a single guid a single message is stored. And the usecase here is to store the last message for whoever connects to get it.
This way you could be randomly āloosing dataā, since it is sharing a single ID for 2 unique information.
While it is called guid, it is rather just a unique string. So to make it deterministic i would advice to add a prefix and set that to the sync animator.
like⦠anim_${syncTransform.guid} and see if that solves the issue of loosing state on āreconnectā.