modular-avatar/Packages/nadena.dev.modular-avatar/Runtime/AvatarObjectReference.cs

87 lines
2.5 KiB
C#
Raw Normal View History

using System;
using UnityEngine;
2023-07-23 13:22:25 +08:00
using VRC.SDK3.Avatars.Components;
2022-11-11 12:39:58 +08:00
namespace nadena.dev.modular_avatar.core
{
[Serializable]
2022-10-20 10:42:33 +08:00
public class AvatarObjectReference
{
public static string AVATAR_ROOT = "$$$AVATAR_ROOT$$$";
public string referencePath;
private bool _cacheValid;
private string _cachedPath;
private GameObject _cachedReference;
public GameObject Get(Component container)
{
2023-06-05 19:18:46 +08:00
if (_cacheValid && _cachedPath == referencePath && _cachedReference != null) return _cachedReference;
_cacheValid = true;
_cachedPath = referencePath;
2022-10-05 08:54:03 +08:00
if (string.IsNullOrEmpty(referencePath))
{
_cachedReference = null;
return _cachedReference;
}
RuntimeUtil.OnHierarchyChanged -= InvalidateCache;
RuntimeUtil.OnHierarchyChanged += InvalidateCache;
var avatar = RuntimeUtil.FindAvatarInParents(container.transform);
if (avatar == null) return (_cachedReference = null);
if (referencePath == AVATAR_ROOT)
{
_cachedReference = avatar.gameObject;
return _cachedReference;
}
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;
}
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);
}
}
}