XRoom_Unity/Assets/Scripts/GlbDownloader/GLBDownloader.cs

152 lines
4.7 KiB
C#

using UnityEngine;
using Fusion;
using ReadyPlayerMe.Core;
using System;
public class GLBDownloader : NetworkBehaviour
{
private GameObject currentGlbModel;
public GameObject GetCurrentGlbModel() => currentGlbModel;
private AvatarObjectLoader avatarLoader;
private AvatarLoaderSettings avatarLoaderSettings;
[Networked, OnChangedRender(nameof(OnAvatarUrlChanged))]
private NetworkString<_512> AvatarUrl { get; set; }
private string _previousUrl = null;
public override void Spawned()
{
Debug.Log($"[GLBDownloader] Spawned for {Object.InputAuthority}, local is {Runner.LocalPlayer}");
if (Object.HasInputAuthority)
{
string modelUrl = EN.instance.Me.characterUrl;
if (!string.IsNullOrEmpty(modelUrl))
{
Debug.Log($"[GLBDownloader] Setting AvatarUrl to {modelUrl} for local player");
AvatarUrl = modelUrl;
}
else
{
Debug.LogError("Character URL is empty.");
}
}
else
{
// For late joiners: handle already set avatar URL
if (!string.IsNullOrEmpty(AvatarUrl.ToString()))
{
Debug.Log($"[GLBDownloader] Late joiner loading avatar for player {Object.InputAuthority}: {AvatarUrl}");
_previousUrl = AvatarUrl.ToString();
LoadAvatar(_previousUrl);
}
}
}
private void OnAvatarUrlChanged()
{
Debug.Log($"[GLBDownloader] OnAvatarUrlChanged called on {Runner.LocalPlayer} for player {Object.InputAuthority}");
string newUrl = AvatarUrl.ToString();
if (!string.IsNullOrEmpty(newUrl) && newUrl != _previousUrl)
{
_previousUrl = newUrl;
Debug.Log($"[GLBDownloader] Loading avatar for player {Object.InputAuthority}: {newUrl}");
LoadAvatar(newUrl);
}
}
private void LoadAvatar(string url)
{
if (string.IsNullOrEmpty(url))
{
Debug.LogWarning("[GLBDownloader] LoadAvatar called with empty URL.");
return;
}
if (avatarLoaderSettings == null)
{
avatarLoaderSettings = AvatarLoaderSettings.LoadSettings();
}
avatarLoader = new AvatarObjectLoader();
avatarLoader.OnFailed += OnFailed;
avatarLoader.OnCompleted += OnCompleted;
if (avatarLoaderSettings != null)
{
avatarLoader.AvatarConfig = avatarLoaderSettings.AvatarConfig;
if (avatarLoaderSettings.GLTFDeferAgent != null)
{
avatarLoader.GLTFDeferAgent = avatarLoaderSettings.GLTFDeferAgent;
}
}
avatarLoader.LoadAvatar(url);
Debug.Log("[GLBDownloader] Avatar download started.");
}
private void OnFailed(object sender, FailureEventArgs args)
{
Debug.LogError($"[GLBDownloader] Avatar load failed: {args.Type} - {args.Message}");
}
private void OnCompleted(object sender, CompletionEventArgs args)
{
if (args.Avatar == null)
{
Debug.LogError("[GLBDownloader] Avatar loading completed but avatar is null.");
return;
}
currentGlbModel = args.Avatar;
currentGlbModel.transform.position = transform.position;
currentGlbModel.transform.rotation = transform.rotation;
currentGlbModel.transform.localScale = Vector3.one;
currentGlbModel.tag = "NetworkGLB";
GameObject avatar = this.gameObject;
if (avatar != null)
{
AttachToAvatarRig(avatar);
}
Debug.Log($"[GLBDownloader] Avatar loaded and attached for player {Object.InputAuthority}");
}
private void AttachToAvatarRig(GameObject avatar)
{
if (currentGlbModel == null) return;
Transform avatarRig = avatar.transform.Find("1");
if (avatarRig == null)
{
Debug.LogWarning("[GLBDownloader] Could not find rig root (child named '1') to attach avatar.");
return;
}
IKTargetFollowVRRig ikRig = avatarRig.GetComponent<IKTargetFollowVRRig>();
if (ikRig != null)
{
ikRig.head.ikTarget = currentGlbModel.transform;
}
currentGlbModel.transform.SetParent(avatarRig);
currentGlbModel.transform.localPosition = new Vector3(0, 0.6f, 0);
currentGlbModel.transform.localRotation = Quaternion.identity;
currentGlbModel.transform.localScale = new Vector3(1.5f,1.5f,1.5f);
}
private void OnDestroy()
{
if (avatarLoader != null)
{
avatarLoader.OnFailed -= OnFailed;
avatarLoader.OnCompleted -= OnCompleted;
}
}
}