2022-10-03 08:37:50 +08:00
|
|
|
|
using System;
|
|
|
|
|
using UnityEngine;
|
2023-07-23 13:22:25 +08:00
|
|
|
|
using VRC.SDK3.Avatars.Components;
|
2022-10-03 08:37:50 +08:00
|
|
|
|
|
2022-11-11 12:39:58 +08:00
|
|
|
|
namespace nadena.dev.modular_avatar.core
|
2022-10-03 08:37:50 +08:00
|
|
|
|
{
|
|
|
|
|
[Serializable]
|
2022-10-20 10:42:33 +08:00
|
|
|
|
public class AvatarObjectReference
|
2022-10-03 08:37:50 +08:00
|
|
|
|
{
|
2022-10-03 11:34:39 +08:00
|
|
|
|
public static string AVATAR_ROOT = "$$$AVATAR_ROOT$$$";
|
2022-10-03 09:16:58 +08:00
|
|
|
|
public string referencePath;
|
2022-10-03 08:37:50 +08:00
|
|
|
|
|
2022-10-03 09:16:58 +08:00
|
|
|
|
private bool _cacheValid;
|
|
|
|
|
private string _cachedPath;
|
2022-10-03 08:37:50 +08:00
|
|
|
|
private GameObject _cachedReference;
|
|
|
|
|
|
|
|
|
|
public GameObject Get(Component container)
|
|
|
|
|
{
|
2023-06-05 19:18:46 +08:00
|
|
|
|
if (_cacheValid && _cachedPath == referencePath && _cachedReference != null) return _cachedReference;
|
2022-10-03 08:37:50 +08:00
|
|
|
|
|
|
|
|
|
_cacheValid = true;
|
|
|
|
|
_cachedPath = referencePath;
|
|
|
|
|
|
2022-10-05 08:54:03 +08:00
|
|
|
|
if (string.IsNullOrEmpty(referencePath))
|
2022-10-03 08:37:50 +08:00
|
|
|
|
{
|
|
|
|
|
_cachedReference = null;
|
|
|
|
|
return _cachedReference;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RuntimeUtil.OnHierarchyChanged -= InvalidateCache;
|
|
|
|
|
RuntimeUtil.OnHierarchyChanged += InvalidateCache;
|
|
|
|
|
|
|
|
|
|
var avatar = RuntimeUtil.FindAvatarInParents(container.transform);
|
|
|
|
|
if (avatar == null) return (_cachedReference = null);
|
|
|
|
|
|
2022-10-03 11:34:39 +08:00
|
|
|
|
if (referencePath == AVATAR_ROOT)
|
|
|
|
|
{
|
|
|
|
|
_cachedReference = avatar.gameObject;
|
|
|
|
|
return _cachedReference;
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-03 08:37:50 +08:00
|
|
|
|
return (_cachedReference = avatar.transform.Find(referencePath)?.gameObject);
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-23 13:22:25 +08:00
|
|
|
|
public void Set(GameObject target)
|
|
|
|
|
{
|
|
|
|
|
if (target == null)
|
|
|
|
|
{
|
|
|
|
|
referencePath = "";
|
|
|
|
|
}
|
|
|
|
|
else if (target.GetComponent<VRCAvatarDescriptor>() != null)
|
|
|
|
|
{
|
|
|
|
|
referencePath = AVATAR_ROOT;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
referencePath = RuntimeUtil.AvatarRootPath(target);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_cacheValid = false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-03 08:37:50 +08:00
|
|
|
|
private void InvalidateCache()
|
|
|
|
|
{
|
|
|
|
|
RuntimeUtil.OnHierarchyChanged -= InvalidateCache;
|
|
|
|
|
_cacheValid = false;
|
|
|
|
|
}
|
2022-10-20 10:42:33 +08:00
|
|
|
|
|
|
|
|
|
protected bool Equals(AvatarObjectReference other)
|
|
|
|
|
{
|
|
|
|
|
return referencePath == other.referencePath;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool Equals(object obj)
|
|
|
|
|
{
|
|
|
|
|
if (ReferenceEquals(null, obj)) return false;
|
|
|
|
|
if (ReferenceEquals(this, obj)) return true;
|
|
|
|
|
if (obj.GetType() != this.GetType()) return false;
|
|
|
|
|
return Equals((AvatarObjectReference) obj);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override int GetHashCode()
|
|
|
|
|
{
|
|
|
|
|
return (referencePath != null ? referencePath.GetHashCode() : 0);
|
|
|
|
|
}
|
2022-10-03 08:37:50 +08:00
|
|
|
|
}
|
|
|
|
|
}
|