-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathAvatarSpeakerHandlerMotif.cs
123 lines (104 loc) · 3.99 KB
/
AvatarSpeakerHandlerMotif.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// Copyright (c) Meta Platforms, Inc. and affiliates.
#if FUSION2 && PHOTON_VOICE_DEFINED
using Fusion;
using System.Collections;
using System.Collections.Generic;
using Meta.XR.MultiplayerBlocks.Fusion;
using UnityEngine;
using Photon.Voice.Unity;
namespace MRMotifs.SharedActivities.Avatars
{
/// <summary>
/// Handles attaching speakers to remote avatars by matching state authority and retrying unassigned speakers after a delay.
/// </summary>
public class AvatarSpeakerHandlerMotif : NetworkBehaviour
{
private AvatarMovementHandlerMotif m_avatarMovementHandlerMotif;
private readonly List<AvatarBehaviourFusion> m_unassignedSpeakers = new();
public override void Spawned()
{
base.Spawned();
StartCoroutine(InitializeAvatarHandler());
}
private IEnumerator InitializeAvatarHandler()
{
while (!m_avatarMovementHandlerMotif)
{
m_avatarMovementHandlerMotif = FindAnyObjectByType<AvatarMovementHandlerMotif>();
yield return null;
}
m_avatarMovementHandlerMotif.OnRemoteAvatarAdded += HandleNewRemoteAvatar;
}
public override void Despawned(NetworkRunner runner, bool hasState)
{
base.Despawned(runner, hasState);
if (m_avatarMovementHandlerMotif != null)
{
m_avatarMovementHandlerMotif.OnRemoteAvatarAdded -= HandleNewRemoteAvatar;
}
}
private void HandleNewRemoteAvatar(AvatarBehaviourFusion remoteAvatar)
{
AssignSpeakerToAvatar(remoteAvatar);
}
private void AssignSpeakerToAvatar(AvatarBehaviourFusion remoteAvatar)
{
var speakers = FindObjectsByType<Speaker>(FindObjectsSortMode.None);
foreach (var speaker in speakers)
{
var networkObject = speaker.GetComponent<NetworkObject>();
if (!networkObject || networkObject.StateAuthority != remoteAvatar.Object.StateAuthority)
{
continue;
}
DisableNetworkTransform(speaker);
ParentSpeakerToAvatar(remoteAvatar, speaker.gameObject);
return;
}
m_unassignedSpeakers.Add(remoteAvatar);
}
private void DisableNetworkTransform(Speaker speaker)
{
var networkTransform = speaker.GetComponent<NetworkTransform>();
if (networkTransform)
{
networkTransform.enabled = false;
}
}
private void ParentSpeakerToAvatar(AvatarBehaviourFusion remoteAvatar, GameObject speakerObject)
{
var jointHead = remoteAvatar.transform.Find("Joint Head");
if (jointHead)
{
speakerObject.transform.SetParent(jointHead);
speakerObject.transform.localPosition = Vector3.zero;
speakerObject.transform.localRotation = Quaternion.identity;
}
else
{
var avatarCriticalJointCount = 0;
Transform fallbackJoint = null;
for (var i = 0; i < remoteAvatar.transform.childCount; i++)
{
var child = remoteAvatar.transform.GetChild(i);
if (child.name != "AvatarCriticalJoint") continue;
avatarCriticalJointCount++;
if (avatarCriticalJointCount != 4)
{
continue;
}
fallbackJoint = child;
break;
}
if (!fallbackJoint)
{
return;
}
speakerObject.transform.SetParent(fallbackJoint);
speakerObject.transform.localPosition = Vector3.zero;
speakerObject.transform.localRotation = Quaternion.identity;
}
}
}
}
#endif