Files

163 lines
5.1 KiB
C#

using BrewMonster.Scripts;
using Cysharp.Threading.Tasks;
using UnityEngine;
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace BrewMonster
{
public class AddressableObject : MonoBehaviour
{
public string assetPath;
private GameObject _instance;
private bool _isLoading;
private bool _isLoaded;
private int _loadRequestId;
public bool IsLoaded => _isLoaded;
public bool IsLoading => _isLoading;
// some object' position is base on the center of the mesh. So we don't need to update the position at start up.
public bool NeedToUpdatePositionAtStartUp;
public Vector3 ObjectPosition;
public Vector3 ObjectPositionOxz;
void Awake()
{
if (NeedToUpdatePositionAtStartUp)
{
ObjectPosition = transform.position;
ObjectPositionOxz = new Vector3(ObjectPosition.x, 0, ObjectPosition.z);
}
}
public async UniTask LoadAsset(Action actDone = null)
{
if (string.IsNullOrEmpty(assetPath))
{
return;
}
if (_instance != null || _isLoading)
{
return;
}
_isLoading = true;
int requestId = ++_loadRequestId;
var model = await AddressableManager.Instance.LoadPrefabAsync(assetPath);
actDone?.Invoke();
// Object might have been destroyed while awaiting.
if (this == null || gameObject == null)
{
return;
}
// If we got unloaded while loading, release the cached handle to avoid keeping RAM.
if (requestId != _loadRequestId)
{
_isLoading = false;
AddressableManager.Instance.ReleaseAsset(assetPath);
return;
}
_isLoading = false;
if (model != null && _instance == null)
{
_instance = Instantiate(model);
var modelTransform = _instance.transform;
modelTransform.SetParent(transform);
modelTransform.localPosition = Vector3.zero;
modelTransform.localRotation = Quaternion.identity;
modelTransform.localScale = Vector3.one;
_instance.SetActive(true);
_isLoaded = true;
}
else
{
BMLogger.Log($"AddressableObject: LoadAsset: Object can't be load from Addressable {assetPath}");
}
}
public void UnloadAsset()
{
// make the loading request invalid.
_loadRequestId++;
_isLoading = false;
_isLoaded = false;
if (_instance != null)
{
if (Application.isPlaying)
{
Destroy(_instance);
}
else
{
DestroyImmediate(_instance);
}
_instance = null;
}
else if (transform.childCount > 0)
{
// Backward-compatible cleanup if older versions instantiated children without tracking.
for (int i = transform.childCount - 1; i >= 0; i--)
{
if (Application.isPlaying)
{
Destroy(transform.GetChild(i).gameObject);
}
else
{
DestroyImmediate(transform.GetChild(i).gameObject);
}
}
}
if (string.IsNullOrEmpty(assetPath))
{
return;
}
AddressableManager.Instance.ReleaseAsset(assetPath);
}
#if UNITY_EDITOR
public static string _modelPathPrefixToRemove = "Assets/ModelRenderer/Art/Models";
[ContextMenu("Get Asset Path")]
public void GetAssetPath()
{
var prefabObject = PrefabUtility.GetCorrespondingObjectFromSource(this.gameObject);
if (prefabObject != null)
{
var path = AssetDatabase.GetAssetPath(prefabObject);
//remove the prefix from the path
path = path.Substring(_modelPathPrefixToRemove.Length + 1);
//remove the .prefab suffix
path = path.Substring(0, path.Length - ".prefab".Length);
assetPath = path;
// now delete all the children of this object
while (transform.childCount > 0)
{
DestroyImmediate(transform.GetChild(0).gameObject);
}
//unpack completely the prefab
PrefabUtility.UnpackPrefabInstance(this.gameObject, PrefabUnpackMode.Completely, InteractionMode.UserAction);
}
else
{
Debug.LogError("No prefab object found for this object");
}
}
#endif
}
}