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
|
|
|
|
}
|