diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/InstantiateOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operation/InstantiateOperation.cs index b24c6a6e..f01d2d7e 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Operation/InstantiateOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/InstantiateOperation.cs @@ -7,7 +7,9 @@ namespace YooAsset private enum ESteps { None, - Clone, + LoadObject, + CloneSync, + CloneAsync, Done, } @@ -20,6 +22,10 @@ namespace YooAsset private readonly bool _actived; private ESteps _steps = ESteps.None; +#if UNITY_2022_3_OR_NEWER + private AsyncInstantiateOperation _instantiateAsync; +#endif + /// /// 实例化的游戏对象 /// @@ -39,14 +45,14 @@ namespace YooAsset } internal override void InternalOnStart() { - _steps = ESteps.Clone; + _steps = ESteps.LoadObject; } internal override void InternalOnUpdate() { if (_steps == ESteps.None || _steps == ESteps.Done) return; - if (_steps == ESteps.Clone) + if (_steps == ESteps.LoadObject) { if (_handle.IsValidWithWarning == false) { @@ -67,6 +73,15 @@ namespace YooAsset return; } +#if UNITY_2022_3_OR_NEWER + _steps = ESteps.CloneAsync; +#else + _steps = ESteps.CloneSync; +#endif + } + + if (_steps == ESteps.CloneSync) + { // 实例化游戏对象 Result = InstantiateInternal(_handle.AssetObject, _setPositionAndRotation, _position, _rotation, _parent, _worldPositionStays); if (_actived == false) @@ -75,6 +90,47 @@ namespace YooAsset _steps = ESteps.Done; Status = EOperationStatus.Succeed; } + +#if UNITY_2022_3_OR_NEWER + if (_steps == ESteps.CloneAsync) + { + if (_instantiateAsync == null) + { + _instantiateAsync = InstantiateAsyncInternal(_handle.AssetObject, _setPositionAndRotation, _position, _rotation, _parent, _worldPositionStays); + } + + if (IsWaitForAsyncComplete) + _instantiateAsync.WaitForCompletion(); + + if (_instantiateAsync.isDone == false) + return; + + if (_instantiateAsync.Result != null && _instantiateAsync.Result.Length > 0) + { + Result = _instantiateAsync.Result[0] as GameObject; + if (Result != null) + { + if (_actived == false) + Result.SetActive(false); + + _steps = ESteps.Done; + Status = EOperationStatus.Succeed; + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Instantiate game object is null !"; + } + } + else + { + _steps = ESteps.Done; + Status = EOperationStatus.Failed; + Error = $"Instantiate async results is null !"; + } + } +#endif } internal override void InternalWaitForAsyncComplete() { @@ -97,9 +153,17 @@ namespace YooAsset /// public void Cancel() { +#if UNITY_2022_3_OR_NEWER + if (_instantiateAsync != null && _instantiateAsync.isDone == false) + _instantiateAsync.Cancel(); +#endif + SetAbort(); } + /// + /// 同步实例化 + /// internal static GameObject InstantiateInternal(UnityEngine.Object assetObject, bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays) { if (assetObject == null) @@ -108,29 +172,42 @@ namespace YooAsset if (setPositionAndRotation) { if (parent != null) - { - GameObject clone = UnityEngine.Object.Instantiate(assetObject as GameObject, position, rotation, parent); - return clone; - } + return UnityEngine.Object.Instantiate(assetObject as GameObject, position, rotation, parent); else - { - GameObject clone = UnityEngine.Object.Instantiate(assetObject as GameObject, position, rotation); - return clone; - } + return UnityEngine.Object.Instantiate(assetObject as GameObject, position, rotation); } else { if (parent != null) - { - GameObject clone = UnityEngine.Object.Instantiate(assetObject as GameObject, parent, worldPositionStays); - return clone; - } + return UnityEngine.Object.Instantiate(assetObject as GameObject, parent, worldPositionStays); else - { - GameObject clone = UnityEngine.Object.Instantiate(assetObject as GameObject); - return clone; - } + return UnityEngine.Object.Instantiate(assetObject as GameObject); } } + +#if UNITY_2022_3_OR_NEWER + /// + /// 异步实例化 + /// 注意:Unity2022.3及以上版本生效 + /// https://docs.unity3d.com/2022.3/Documentation/ScriptReference/Object.InstantiateAsync.html + /// + internal static AsyncInstantiateOperation InstantiateAsyncInternal(UnityEngine.Object assetObject, bool setPositionAndRotation, Vector3 position, Quaternion rotation, Transform parent, bool worldPositionStays) + { + if (setPositionAndRotation) + { + if (parent != null) + return UnityEngine.Object.InstantiateAsync(assetObject as GameObject, parent, position, rotation); + else + return UnityEngine.Object.InstantiateAsync(assetObject as GameObject, position, rotation); + } + else + { + if (parent != null) + return UnityEngine.Object.InstantiateAsync(assetObject as GameObject, parent); + else + return UnityEngine.Object.InstantiateAsync(assetObject as GameObject); + } + } +#endif } } \ No newline at end of file