UniGame Packages Compilation
The LifeTime class is used for managing the lifetime of objects and resources in a project. It ensures proper resource cleanup and prevents memory leaks. All interactions with LifeTime should be done through the ILifeTime interface to ensure that only the owner of the resource can destroy it. This approach allows other services to depend on the specified lifetime without having the ability to prematurely release the resources.
The key concept of LifeTime is single ownership of resources, acting as the owner to simplify their release.
- Add Cleanup Actions: Register actions to be executed when the lifetime ends.
- Manage Disposable Objects: Automatically dispose of objects when the lifetime ends.
- Child Lifetimes: Manage nested lifetimes, allowing for hierarchical cleanup.
- Cancellation Tokens: Provides a cancellation token that is canceled when the lifetime ends.
- TerminatedLifetime: Property provides terminated static lifetime
To create a new LifeTime instance, use the static Create method:
varlifeTime=LifeTime.Create();You can add cleanup actions that will be executed when the lifetime ends:
lifeTime.AddCleanUpAction(()=>{Debug.Log("Cleanup action executed.");});Add disposable objects to the lifetime to ensure they are disposed of when the lifetime ends:
vardisposable=newSomeDisposableObject();lifeTime.AddDispose(disposable);You can add child lifetimes that will be terminated when the parent lifetime ends:
varchildLifeTime=LifeTime.Create();lifeTime.AddChildLifeTime(childLifeTime);The LifeTime class provides a cancellation token that is canceled when the lifetime ends:
vartoken=lifeTime.Token;token.Register(()=>{Debug.Log("Lifetime canceled.");});publicvoidDoActionAsync(){varassetLifeTime=this.GetAssetLifeTime();SomeActionAsync().AttachExternalCancellation(assetLifeTime.Token).Forget();SomeActionAsync2(assetLifeTime.Token).Forget();}publicasyncUniTaskSomeActionAsync(){}publicasyncUniTaskSomeActionAsync2(CancellationTokentoken){}You can restart a lifetime, which will reset its state and allow it to be used again:
lifeTime.Restart();To manually end a lifetime and execute all registered cleanup actions, call the Release method:
lifeTime.Release();Here is a complete example demonstrating the usage of the LifeTime class:
usingUniModules.UniCore.Runtime.DataFlow;usingUnityEngine;publicclassLifeTimeExample:MonoBehaviour{privateLifeTime_lifeTime;voidStart(){_lifeTime=LifeTime.Create();_assetLifeTime=this.GetAssetLifeTime();// you can use this.GetAssetLifeTime() extension_lifeTime.AddCleanUpAction(()=>{Debug.Log("Cleanup action executed.");});vardisposable=newSomeDisposableObject();_lifeTime.AddDispose(disposable);varchildLifeTime=LifeTime.Create();_lifeTime.AddChildLifeTime(childLifeTime);vartoken=_lifeTime.Token;token.Register(()=>{Debug.Log("Lifetime canceled.");});}voidOnDestroy(){_lifeTime.Release();}}publicclassSomeDisposableObject:IDisposable{publicvoidDispose(){Debug.Log("SomeDisposableObject disposed.");}}This example demonstrates how to create a LifeTime instance, add cleanup actions, manage disposable objects, add child lifetimes, and use the cancellation token. The OnDestroy method ensures that the lifetime is released when the MonoBehaviour is destroyed.
The AssetLifeTime provides extension utilities for managing the lifecycle of assets in Unity. It includes methods for associating assets with lifetimes and cleaning up assets when their lifetimes end.
publicclassExample:MonoBehaviour{privatevoidStart(){varscriptableAsset=ScriptableObject.Instantiate<AddressableScriptableTest>();//create lifetime for scriptable asset, lifetime will be killed when asset is destroyedvarsoLifeTime=scriptableAsset.GetAssetLifeTime();// Get or create a lifetime for this GameObjectvarlifeTime=gameObject.GetAssetLifeTime();// Get or create a lifetime for Transform component, transformLifeTime == lifeTime from the same GameObjectvartransformLifeTime=transform.GetAssetLifeTime();// Add a cleanup action to destroy the GameObject when the lifetime endslifeTime.DestroyOnCleanup(gameObject);// Add a disposable object to the lifetimevardisposable=newSomeDisposable();lifeTime.AddDispose(disposable);Object.Destroy(gameObject)//now lifetime accotiated with this object will be killed}}publicclassAddressableScriptableTest:ScriptableObject{}publicclassSomeDisposable:IDisposable{publicvoidDispose(){// Cleanup code here}}GetAssetLifeTime(Objectsource,boolterminateOnDisable=false): Retrieves or creates a lifetime for the given asset.DestroyOnCleanup(LifeTimelifeTime,GameObjectgameObject): Adds a cleanup action to destroy the GameObject when the lifetime ends.
DestroyOnCleanup(LifeTimelifeTime,Componentcomponent,boolonlyComponent=false): Adds a cleanup action to destroy the component or its GameObject when the lifetime ends.
AddDisposable(ObjectgameObject,IDisposabledisposable): Adds a disposable object to the GameObject's lifetime.
AddCleanUp(ObjectgameObject,ActioncleanupAction): Adds a cleanup action to the GameObject's lifetime.
AddDisposable(Componentcomponent,IDisposabledisposable): Adds a disposable object to the component's GameObject's lifetime.
AddCleanUp(Componentcomponent,Actionaction): Adds a cleanup action to the component's GameObject's lifetime.Provides utility methods for binding resources to the scene lifetime.
- GetActiveSceneLifeTime(): Gets the lifetime of the currently active scene.
- GetSceneLifeTime(Scene scene): Gets the lifetime of the specified scene. If scene is not loaded when return Terminated LifeTime
- AddTo(IDisposable disposable, Scene scene): Adds a disposable to the specified scene's lifetime.
- AddToActiveScene(IDisposable disposable): Adds a disposable to the active scene's lifetime.
- AddToScene(IDisposable disposable, string scenePath): Adds a disposable to the specified scene's lifetime by scene ID.
usingUnityEngine;usingUnityEngine.SceneManagement;usingUniModules.UniGame.Core.Runtime.DataFlow.Extensions;publicclassExampleUsage:MonoBehaviour{privatevoidStart(){// Initialize scene lifetime managementSceneLifeTime.Initialize();// Get the lifetime of the active scenevaractiveSceneLifeTime=SceneLifeTime.GetActiveSceneLifeTime();// Add a disposable to the active scene's lifetimevardisposable=newExampleDisposable();disposable.AddToActiveScene();activeSceneLifeTime.AddDispose(disposable);// Get the lifetime of a specific scenevarscene=SceneManager.GetSceneByName("ExampleScene");varsceneLifeTime=SceneLifeTime.GetSceneLifeTime(scene);// Add a disposable to the specific scene's lifetimesceneLifeTime.AddDispose(disposable);}}publicclassExampleDisposable:IDisposable{publicvoidDispose(){// Cleanup code here}}AddressableExtensions
/// <summary>/// Provides extension methods for working with Unity Addressables./// </summary>publicstaticclass AddressableExtensionsProvides extension methods for working with Unity Addressables. This class is used for loading and unloading resources conveniently using ILifeTime, allowing dependencies to be unloaded from memory at the appropriate time. Allow to spawn GameObject instances with object pooling and bind Addressable handle to Instance LifeTime
Methods
LoadAssetTaskAsync: Loads an asset asynchronously and bind Addressanle Handle to LifeTime
publicstaticasyncUniTask<T>LoadAssetTaskAsync<T>(thisAssetReferenceassetReference,ILifeTimelifeTime,booldownloadDependencies=false,IProgress<float>progress=null)LoadAssetsTaskAsync: Loads assets by resource location ids or asset references or GUID's
publicstaticasyncUniTask<IList<Object>>LoadAssetsTaskAsync(thisstringresource,ILifeTimelifeTime,IProgress<float>progress=null)publicstaticasyncUniTask<IList<T>>LoadAssetsTaskAsync<T>(thisIEnumerablelabels,ILifeTimelifeTime,Addressables.MergeModemode=Addressables.MergeMode.Union,IProgress<float>progress=null)Example
publicclassAddressableScriptableTest:ScriptableObject{publicAssetReferenceassetReference;publicasyncUniTaskLoadAssetAsync(){varassetLifeTime=this.GetAssetLifeTime();//load by asset referencevarloadedAsset=awaitasset1.LoadAssetTaskAsync<GameObject>(assetLifeTime);//load by guid resource locationvarloadedAssetByGUID=awaitasset1.AssetGUID.LoadAssetTaskAsync<GameObject>(assetLifeTime);}}LoadSceneTaskAsync: Loads a scene asynchronously using an AssetReference or a string reference.
publicstaticasyncUniTask<SceneInstance>LoadSceneTaskAsync(thisstringsceneReference,ILifeTimelifeTime,LoadSceneModeloadSceneMode=LoadSceneMode.Single,boolactivateOnLoad=true,intpriority=100,IProgress<float>progress=null){}publicstaticasyncUniTask<SceneInstance>LoadSceneTaskAsync(thisAssetReferencesceneReference,ILifeTimelifeTime,LoadSceneModeloadSceneMode=LoadSceneMode.Single,boolactivateOnLoad=true,intpriority=100,IProgress<float>progress=null){}Example
publicclassSceneLoader:MonoBehaviour{publicAssetReferencesceneReference;privateILifeTimelifeTime;privateasyncvoidStart(){varsceneInstance=awaitsceneReference.LoadSceneTaskAsync(lifeTime,LoadSceneMode.Single,true,100);Debug.Log("Scene loaded: "+sceneInstance.Scene.name);}}SpawnObjectAsync: Spawns an object asynchronously.
The SpawnObjectAsync method is designed to asynchronously create an instance of an object of type T from an addressable resource. It loads the resource by the specified key, creates its instance, and returns it. The method supports various parameters such as position, parent object, activation on spawn, downloading dependencies, and progress reporting. When the instance is destroyed, the addressable handle will be automatically released.
Object pooling is supported on spawn new instances
publicstaticasyncUniTask<T>SpawnObjectAsync<T>(thisstringreference,Vector3position=default,Transformparent=null,ILifeTimelifeTime=null,boolactivateOnSpawn=true,booldownloadDependencies=false,CancellationTokentoken=default,IProgress<float>progress=null)publicstaticUniTask<T>SpawnObjectAsync<T>(thisAssetReferenceT<T>reference, ...)
public staticUniTask<T>SpawnObjectAsync<T>(thisAssetReference reference, ...)SpawnObjectsAsync: Spawns multiple objects asynchronously.
The method spawns asynchronous instances and is optimized for creating multiple objects at once. It is not recommended for repeatedly spawning single objects, as an additional array will be created for the results. The method supports object pooling. Each result increments the addressable handle by one. When the instance is destroyed, the dependency counter will decrease.
publicstaticasyncUniTask<T>SpawnObjectAsync<T>(thisstringreference,Vector3position=default,Transformparent=null,ILifeTimelifeTime=null,boolactivateOnSpawn=true,booldownloadDependencies=false,CancellationTokentoken=default,IProgress<float>progress=null)publicstaticUniTask<T>SpawnObjectAsync<T>(thisAssetReferenceT<T>reference, ...)
public staticUniTask<T>SpawnObjectAsync<T>(thisAssetReference reference, ...)Exmaples
publicasyncUniTaskLoadItemsAsync(intamount){varassets=awaitasset1.SpawnObjectsAsync(amount,token:destroyCancellationToken);for(vari=0;i<assets.Length;i++){varasset=assets[i];if(asset==null)continue;asset.transform.position=Random.insideUnitSphere*radius;}}publicclassGameObjectSpawner:MonoBehaviour{publicAssetReferenceassetReference;privateILifeTimelifeTime;privateasyncvoidStart(){vargameObjectInstance=awaitassetReference.SpawnObjectAsync<GameObject>(Vector3.zero,null,lifeTime,true);Debug.Log("GameObject spawned: "+gameObjectInstance.name);}}