AlicizaX/Client/Packages/com.alicizax.unity.resource/Runtime/Resource/Reference/AssetsReference.cs

195 lines
5.5 KiB
C#
Raw Normal View History

2025-07-11 21:00:00 +08:00
using System;
2025-01-23 19:06:48 +08:00
using System.Collections.Generic;
using UnityEngine;
using Object = UnityEngine.Object;
namespace AlicizaX.Resource.Runtime
{
[Serializable]
public struct AssetsRefInfo
{
public int instanceId;
public Object refAsset;
public AssetsRefInfo(Object refAsset)
{
this.refAsset = refAsset;
instanceId = this.refAsset.GetInstanceID();
}
}
2025-07-11 21:00:00 +08:00
[DisallowMultipleComponent]
2025-01-23 19:06:48 +08:00
public sealed class AssetsReference : MonoBehaviour
{
2025-04-28 19:45:45 +08:00
[SerializeField]
private GameObject sourceGameObject;
2025-01-23 19:06:48 +08:00
2025-04-28 19:45:45 +08:00
[SerializeField]
private List<AssetsRefInfo> refAssetInfoList;
2025-01-23 19:06:48 +08:00
2025-07-11 21:00:00 +08:00
private static IResourceModule _resourceModule;
2025-01-23 19:06:48 +08:00
2025-07-11 21:00:00 +08:00
private static Dictionary<GameObject, AssetsReference> _originalRefs = new();
private void CheckInit()
2025-01-23 19:06:48 +08:00
{
2025-07-11 21:00:00 +08:00
if (_resourceModule != null)
{
return;
}
else
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
_resourceModule = ModuleSystem.GetModule<IResourceModule>();
2025-01-23 19:06:48 +08:00
}
2025-04-28 19:45:45 +08:00
if (_resourceModule == null)
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
throw new GameFrameworkException($"resourceModule is null.");
2025-01-23 19:06:48 +08:00
}
2025-07-11 21:00:00 +08:00
}
2025-01-23 19:06:48 +08:00
2025-07-11 21:00:00 +08:00
private void CheckRelease()
{
2025-04-28 19:45:45 +08:00
if (sourceGameObject != null)
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
_resourceModule.UnloadAsset(sourceGameObject);
2025-01-23 19:06:48 +08:00
}
2025-07-11 21:00:00 +08:00
else
{
Log.Warning($"sourceGameObject is not invalid.");
}
}
private void Awake()
{
// If it is a clone, clear the reference records before cloning
if (!IsOriginalInstance())
{
ClearCloneReferences();
}
}
private bool IsOriginalInstance()
{
return _originalRefs.TryGetValue(gameObject, out var originalComponent) &&
originalComponent == this;
}
private void ClearCloneReferences()
{
sourceGameObject = null;
refAssetInfoList?.Clear();
}
private void OnDestroy()
{
CheckInit();
if (sourceGameObject != null)
{
CheckRelease();
}
2025-01-23 19:06:48 +08:00
ReleaseRefAssetInfoList();
}
private void ReleaseRefAssetInfoList()
{
2025-04-28 19:45:45 +08:00
if (refAssetInfoList != null)
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
foreach (var refInfo in refAssetInfoList)
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
_resourceModule.UnloadAsset(refInfo.refAsset);
2025-01-23 19:06:48 +08:00
}
2025-04-28 19:45:45 +08:00
refAssetInfoList.Clear();
2025-01-23 19:06:48 +08:00
}
}
2025-04-28 19:45:45 +08:00
public AssetsReference Ref(GameObject source, IResourceModule resourceModule = null)
2025-01-23 19:06:48 +08:00
{
if (source == null)
{
throw new GameFrameworkException($"Source gameObject is null.");
}
if (source.scene.name != null)
{
throw new GameFrameworkException($"Source gameObject is in scene.");
}
2025-04-28 19:45:45 +08:00
_resourceModule = resourceModule;
sourceGameObject = source;
2025-07-11 21:00:00 +08:00
if (!_originalRefs.ContainsKey(gameObject))
{
_originalRefs.Add(gameObject, this);
}
2025-01-23 19:06:48 +08:00
return this;
}
2025-07-11 21:00:00 +08:00
public AssetsReference Ref<T>(T source, IResourceModule resourceModule = null) where T : Object
2025-01-23 19:06:48 +08:00
{
if (source == null)
{
throw new GameFrameworkException($"Source gameObject is null.");
}
2025-04-28 19:45:45 +08:00
_resourceModule = resourceModule;
if (refAssetInfoList == null)
2025-01-23 19:06:48 +08:00
{
2025-04-28 19:45:45 +08:00
refAssetInfoList = new List<AssetsRefInfo>();
2025-01-23 19:06:48 +08:00
}
2025-04-28 19:45:45 +08:00
refAssetInfoList.Add(new AssetsRefInfo(source));
2025-01-23 19:06:48 +08:00
return this;
}
2025-07-11 21:00:00 +08:00
internal static AssetsReference Instantiate(GameObject source, Transform parent = null, IResourceModule resourceModule = null)
2025-01-23 19:06:48 +08:00
{
if (source == null)
{
throw new GameFrameworkException($"Source gameObject is null.");
}
if (source.scene.name != null)
{
throw new GameFrameworkException($"Source gameObject is in scene.");
}
GameObject instance = Object.Instantiate(source, parent);
2025-04-28 19:45:45 +08:00
return instance.AddComponent<AssetsReference>().Ref(source, resourceModule);
2025-01-23 19:06:48 +08:00
}
2025-04-28 19:45:45 +08:00
public static AssetsReference Ref(GameObject source, GameObject instance, IResourceModule resourceModule = null)
2025-01-23 19:06:48 +08:00
{
if (source == null)
{
throw new GameFrameworkException($"Source gameObject is null.");
}
if (source.scene.name != null)
{
throw new GameFrameworkException($"Source gameObject is in scene.");
}
2025-04-28 19:45:45 +08:00
var comp = instance.GetComponent<AssetsReference>();
2025-07-11 21:00:00 +08:00
return comp ? comp.Ref(source, resourceModule) : instance.AddComponent<AssetsReference>().Ref(source, resourceModule);
2025-01-23 19:06:48 +08:00
}
2025-07-11 21:00:00 +08:00
public static AssetsReference Ref<T>(T source, GameObject instance, IResourceModule resourceModule = null) where T : Object
2025-01-23 19:06:48 +08:00
{
if (source == null)
{
throw new GameFrameworkException($"Source gameObject is null.");
}
2025-04-28 19:45:45 +08:00
var comp = instance.GetComponent<AssetsReference>();
2025-07-11 21:00:00 +08:00
return comp ? comp.Ref(source, resourceModule) : instance.AddComponent<AssetsReference>().Ref(source, resourceModule);
2025-01-23 19:06:48 +08:00
}
}
2025-03-04 18:40:14 +08:00
}