diff --git a/Assets/YooAsset/Runtime/AssetSystem/AssetSystem.cs b/Assets/YooAsset/Runtime/AssetSystem/AssetSystem.cs
index 2745f6a..6259d92 100644
--- a/Assets/YooAsset/Runtime/AssetSystem/AssetSystem.cs
+++ b/Assets/YooAsset/Runtime/AssetSystem/AssetSystem.cs
@@ -68,40 +68,6 @@ namespace YooAsset
loadingCount++;
}
}
-
- // 注意:需要立刻卸载场景
- if (SimulationOnEditor)
- {
- for (int i = _providers.Count - 1; i >= 0; i--)
- {
- AssetProviderBase provider = _providers[i];
- if (provider.IsSceneProvider() && provider.CanDestroy())
- {
- provider.Destory();
- _providers.RemoveAt(i);
- }
- }
- }
- else
- {
- for (int i = _loaders.Count - 1; i >= 0; i--)
- {
- BundleFileLoader loader = _loaders[i];
- if (loader.IsSceneLoader())
- {
- loader.TryDestroyAllProviders();
- }
- }
- for (int i = _loaders.Count - 1; i >= 0; i--)
- {
- BundleFileLoader loader = _loaders[i];
- if (loader.IsSceneLoader() && loader.CanDestroy())
- {
- loader.Destroy(false);
- _loaders.RemoveAt(i);
- }
- }
- }
}
///
@@ -160,19 +126,19 @@ namespace YooAsset
Resources.UnloadUnusedAssets();
}
+
///
/// 异步加载场景
///
- /// 场景名称
- public static SceneOperationHandle LoadSceneAsync(string scenePath, LoadSceneMode mode, bool activateOnLoad)
+ public static SceneOperationHandle LoadSceneAsync(string scenePath, LoadSceneMode sceneMode, bool activateOnLoad, int priority)
{
AssetProviderBase provider = TryGetAssetProvider(scenePath);
if (provider == null)
{
if (SimulationOnEditor)
- provider = new DatabaseSceneProvider(scenePath, mode, activateOnLoad);
+ provider = new DatabaseSceneProvider(scenePath, sceneMode, activateOnLoad, priority);
else
- provider = new BundledSceneProvider(scenePath, mode, activateOnLoad);
+ provider = new BundledSceneProvider(scenePath, sceneMode, activateOnLoad, priority);
_providers.Add(provider);
}
return provider.CreateHandle() as SceneOperationHandle;
@@ -181,8 +147,6 @@ namespace YooAsset
///
/// 异步加载资源对象
///
- /// 资源路径
- /// 资源类型
public static AssetOperationHandle LoadAssetAsync(string assetPath, System.Type assetType)
{
AssetProviderBase provider = TryGetAssetProvider(assetPath);
@@ -200,9 +164,7 @@ namespace YooAsset
///
/// 异步加载所有子资源对象
///
- /// 资源路径
- /// 资源类型、
- public static AssetOperationHandle LoadSubAssetsAsync(string assetPath, System.Type assetType)
+ public static SubAssetsOperationHandle LoadSubAssetsAsync(string assetPath, System.Type assetType)
{
AssetProviderBase provider = TryGetAssetProvider(assetPath);
if (provider == null)
@@ -213,7 +175,7 @@ namespace YooAsset
provider = new BundledSubAssetsProvider(assetPath, assetType);
_providers.Add(provider);
}
- return provider.CreateHandle() as AssetOperationHandle;
+ return provider.CreateHandle() as SubAssetsOperationHandle;
}
diff --git a/Assets/YooAsset/Runtime/AssetSystem/Operations/AssetOperationHandle.cs b/Assets/YooAsset/Runtime/AssetSystem/Operations/AssetOperationHandle.cs
index a0363be..858a3cd 100644
--- a/Assets/YooAsset/Runtime/AssetSystem/Operations/AssetOperationHandle.cs
+++ b/Assets/YooAsset/Runtime/AssetSystem/Operations/AssetOperationHandle.cs
@@ -76,5 +76,13 @@ namespace YooAsset
return;
_provider.WaitForAsyncComplete();
}
+
+ ///
+ /// 释放资源句柄
+ ///
+ public void Release()
+ {
+ this.ReleaseInternal();
+ }
}
}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/AssetSystem/Operations/OperationHandleBase.cs b/Assets/YooAsset/Runtime/AssetSystem/Operations/OperationHandleBase.cs
index 1014400..c91edfb 100644
--- a/Assets/YooAsset/Runtime/AssetSystem/Operations/OperationHandleBase.cs
+++ b/Assets/YooAsset/Runtime/AssetSystem/Operations/OperationHandleBase.cs
@@ -70,7 +70,7 @@ namespace YooAsset
///
/// 释放句柄
///
- public void Release()
+ internal void ReleaseInternal()
{
if (IsValid == false)
return;
diff --git a/Assets/YooAsset/Runtime/AssetSystem/Operations/SceneOperationHandle.cs b/Assets/YooAsset/Runtime/AssetSystem/Operations/SceneOperationHandle.cs
index c2092a2..a3102c6 100644
--- a/Assets/YooAsset/Runtime/AssetSystem/Operations/SceneOperationHandle.cs
+++ b/Assets/YooAsset/Runtime/AssetSystem/Operations/SceneOperationHandle.cs
@@ -1,8 +1,114 @@
-
+using UnityEngine;
+using UnityEngine.SceneManagement;
+
namespace YooAsset
{
public class SceneOperationHandle : OperationHandleBase
{
+ ///
+ /// 场景卸载异步操作类
+ ///
+ public class UnloadSceneOperation : AsyncOperationBase
+ {
+ private enum EFlag
+ {
+ Normal,
+ Error,
+ Skip,
+ }
+ private enum ESteps
+ {
+ None,
+ UnLoad,
+ Checking,
+ Done,
+ }
+
+ private readonly EFlag _flag;
+ private ESteps _steps = ESteps.None;
+ private Scene _scene;
+ private AsyncOperation _asyncOp;
+
+ ///
+ /// 场景卸载进度
+ ///
+ public float Progress
+ {
+ get
+ {
+ if (_asyncOp == null)
+ return 0;
+ return _asyncOp.progress;
+ }
+ }
+
+ internal UnloadSceneOperation()
+ {
+ _flag = EFlag.Skip;
+ }
+ internal UnloadSceneOperation(string error)
+ {
+ _flag = EFlag.Error;
+ Error = error;
+ }
+ internal UnloadSceneOperation(Scene scene)
+ {
+ _flag = EFlag.Normal;
+ _scene = scene;
+ }
+ internal override void Start()
+ {
+ if (_flag == EFlag.Normal)
+ {
+ _steps = ESteps.UnLoad;
+ }
+ else if (_flag == EFlag.Skip)
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+ }
+ else if (_flag == EFlag.Error)
+ {
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ }
+ else
+ {
+ throw new System.NotImplementedException(_flag.ToString());
+ }
+ }
+ internal override void Update()
+ {
+ if (_steps == ESteps.None || _steps == ESteps.Done)
+ return;
+
+ if (_steps == ESteps.UnLoad)
+ {
+ if (_scene.IsValid() && _scene.isLoaded)
+ {
+ _asyncOp = SceneManager.UnloadSceneAsync(_scene);
+ _steps = ESteps.Checking;
+ }
+ else
+ {
+ Error = "Scene is invalid or is not loaded.";
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Failed;
+ }
+ }
+
+ if (_steps == ESteps.Checking)
+ {
+ if (_asyncOp.isDone == false)
+ return;
+
+ _steps = ESteps.Done;
+ Status = EOperationStatus.Succeed;
+ }
+ }
+ }
+
+
private System.Action _callback;
internal SceneOperationHandle(AssetProviderBase provider) : base(provider)
@@ -41,13 +147,13 @@ namespace YooAsset
///
/// 场景对象
///
- public UnityEngine.SceneManagement.Scene Scene
+ public Scene SceneObject
{
get
{
if (IsValid == false)
- return new UnityEngine.SceneManagement.Scene();
- return _provider.Scene;
+ return new Scene();
+ return _provider.SceneObject;
}
}
@@ -59,15 +165,79 @@ namespace YooAsset
if (IsValid == false)
return false;
- if (Scene.IsValid() && Scene.isLoaded)
+ if (SceneObject.IsValid() && SceneObject.isLoaded)
{
- return UnityEngine.SceneManagement.SceneManager.SetActiveScene(Scene);
+ return SceneManager.SetActiveScene(SceneObject);
}
else
{
- YooLogger.Warning($"Scene is invalid or not loaded : {Scene.name}");
+ YooLogger.Warning($"Scene is invalid or not loaded : {SceneObject.name}");
return false;
}
}
+
+ ///
+ /// 异步卸载场景
+ ///
+ public UnloadSceneOperation UnloadAsync()
+ {
+ if (IsValid == false)
+ {
+ string error = $"{nameof(SceneOperationHandle)} is invalid.";
+ var operation = new UnloadSceneOperation(error);
+ OperationSystem.ProcessOperaiton(operation);
+ return operation;
+ }
+
+ AssetProviderBase provider = _provider;
+
+ // 释放场景句柄
+ ReleaseInternal();
+
+ // 卸载未被使用的资源(包括场景)
+ AssetSystem.UnloadUnusedAssets();
+
+ // 返回场景卸载异步操作类
+ if (provider.IsDestroyed == false)
+ {
+ YooLogger.Warning($"Scene can not unload. The provider not destroyed : {provider.AssetPath}");
+ var operation = new UnloadSceneOperation();
+ OperationSystem.ProcessOperaiton(operation);
+ return operation;
+ }
+ else
+ {
+ if (IsAdditiveScene(provider))
+ {
+ var operation = new UnloadSceneOperation(provider.SceneObject);
+ OperationSystem.ProcessOperaiton(operation);
+ return operation;
+ }
+ else
+ {
+ var operation = new UnloadSceneOperation();
+ OperationSystem.ProcessOperaiton(operation);
+ return operation;
+ }
+ }
+ }
+
+ private bool IsAdditiveScene(AssetProviderBase provider)
+ {
+ if (provider is DatabaseSceneProvider)
+ {
+ var temp = provider as DatabaseSceneProvider;
+ return temp.SceneMode == LoadSceneMode.Additive;
+ }
+ else if (provider is BundledSceneProvider)
+ {
+ var temp = provider as BundledSceneProvider;
+ return temp.SceneMode == LoadSceneMode.Additive;
+ }
+ else
+ {
+ throw new System.NotImplementedException();
+ }
+ }
}
}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/AssetSystem/Operations/SubAssetsOperationHandle.cs b/Assets/YooAsset/Runtime/AssetSystem/Operations/SubAssetsOperationHandle.cs
new file mode 100644
index 0000000..82f30bd
--- /dev/null
+++ b/Assets/YooAsset/Runtime/AssetSystem/Operations/SubAssetsOperationHandle.cs
@@ -0,0 +1,92 @@
+
+namespace YooAsset
+{
+ public class SubAssetsOperationHandle : OperationHandleBase
+ {
+ private System.Action _callback;
+
+ internal SubAssetsOperationHandle(AssetProviderBase provider) : base(provider)
+ {
+ }
+ internal override void InvokeCallback()
+ {
+ if (IsValid)
+ {
+ _callback?.Invoke(this);
+ }
+ }
+
+ ///
+ /// 完成委托
+ ///
+ public event System.Action Completed
+ {
+ add
+ {
+ if (IsValid == false)
+ throw new System.Exception($"{nameof(SubAssetsOperationHandle)} is invalid");
+ if (_provider.IsDone)
+ value.Invoke(this);
+ else
+ _callback += value;
+ }
+ remove
+ {
+ if (IsValid == false)
+ throw new System.Exception($"{nameof(SubAssetsOperationHandle)} is invalid");
+ _callback -= value;
+ }
+ }
+
+ ///
+ /// 子资源对象集合
+ ///
+ public UnityEngine.Object[] AllAssetObjects
+ {
+ get
+ {
+ if (IsValid == false)
+ return null;
+ return _provider.AllAssets;
+ }
+ }
+
+ ///
+ /// 获取子资源对象
+ ///
+ /// 子资源对象类型
+ /// 子资源对象名称
+ public TObject GetSubAssetObject(string assetName) where TObject : UnityEngine.Object
+ {
+ if (IsValid == false)
+ return null;
+
+ foreach (var asset in _provider.AllAssets)
+ {
+ if (asset.name == assetName)
+ return asset as TObject;
+ }
+
+ YooLogger.Warning($"Not found sub asset {assetName} in {_provider.AssetPath}");
+ return null;
+ }
+
+ ///
+ /// 等待异步执行完毕
+ ///
+ public void WaitForAsyncComplete()
+ {
+ if (IsValid == false)
+ return;
+ _provider.WaitForAsyncComplete();
+ }
+
+ ///
+ /// 释放资源句柄
+ ///
+ public void Release()
+ {
+ this.ReleaseInternal();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/AssetSystem/Operations/SubAssetsOperationHandle.cs.meta b/Assets/YooAsset/Runtime/AssetSystem/Operations/SubAssetsOperationHandle.cs.meta
new file mode 100644
index 0000000..5752721
--- /dev/null
+++ b/Assets/YooAsset/Runtime/AssetSystem/Operations/SubAssetsOperationHandle.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 76b148be04a698e45a54dd85e64969dd
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/YooAsset/Runtime/AssetSystem/Provider/AssetProviderBase.cs b/Assets/YooAsset/Runtime/AssetSystem/Provider/AssetProviderBase.cs
index d0843e2..ebd2233 100644
--- a/Assets/YooAsset/Runtime/AssetSystem/Provider/AssetProviderBase.cs
+++ b/Assets/YooAsset/Runtime/AssetSystem/Provider/AssetProviderBase.cs
@@ -43,7 +43,7 @@ namespace YooAsset
///
/// 获取的场景对象
///
- public UnityEngine.SceneManagement.Scene Scene { protected set; get; }
+ public UnityEngine.SceneManagement.Scene SceneObject { protected set; get; }
///
@@ -108,6 +108,17 @@ namespace YooAsset
IsDestroyed = true;
}
+ ///
+ /// 是否可以销毁
+ ///
+ public bool CanDestroy()
+ {
+ if (IsDone == false)
+ return false;
+
+ return RefCount <= 0;
+ }
+
///
/// 创建操作句柄
///
@@ -120,6 +131,8 @@ namespace YooAsset
OperationHandleBase handle;
if (IsSceneProvider())
handle = new SceneOperationHandle(this);
+ else if (IsSubAssetsProvider())
+ handle = new SubAssetsOperationHandle(this);
else
handle = new AssetOperationHandle(this);
@@ -142,17 +155,6 @@ namespace YooAsset
RefCount--;
}
- ///
- /// 是否可以销毁
- ///
- public bool CanDestroy()
- {
- if (IsDone == false)
- return false;
-
- return RefCount <= 0;
- }
-
///
/// 是否为场景提供者
///
@@ -164,6 +166,17 @@ namespace YooAsset
return false;
}
+ ///
+ /// 是否为子资源对象提供者
+ ///
+ public bool IsSubAssetsProvider()
+ {
+ if (this is BundledSubAssetsProvider || this is DatabaseSubAssetsProvider)
+ return true;
+ else
+ return false;
+ }
+
///
/// 等待异步执行完毕
///
diff --git a/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledSceneProvider.cs b/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledSceneProvider.cs
index 2c7240f..7e8ec5e 100644
--- a/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledSceneProvider.cs
+++ b/Assets/YooAsset/Runtime/AssetSystem/Provider/BundledSceneProvider.cs
@@ -7,8 +7,9 @@ namespace YooAsset
{
internal sealed class BundledSceneProvider : BundledProvider
{
- private readonly LoadSceneMode _sceneMode;
+ public readonly LoadSceneMode SceneMode;
private readonly bool _activateOnLoad;
+ private readonly int _priority;
private AsyncOperation _asyncOp;
public override float Progress
{
@@ -20,11 +21,12 @@ namespace YooAsset
}
}
- public BundledSceneProvider(string scenePath, LoadSceneMode sceneMode, bool activateOnLoad)
+ public BundledSceneProvider(string scenePath, LoadSceneMode sceneMode, bool activateOnLoad, int priority)
: base(scenePath, null)
{
- _sceneMode = sceneMode;
+ SceneMode = sceneMode;
_activateOnLoad = activateOnLoad;
+ _priority = priority;
}
public override void Update()
{
@@ -58,10 +60,11 @@ namespace YooAsset
// 2. 加载场景
if (Status == EStatus.Loading)
{
- _asyncOp = SceneManager.LoadSceneAsync(AssetName, _sceneMode);
+ _asyncOp = SceneManager.LoadSceneAsync(AssetName, SceneMode);
if (_asyncOp != null)
{
_asyncOp.allowSceneActivation = true;
+ _asyncOp.priority = _priority;
Status = EStatus.Checking;
}
else
@@ -77,25 +80,14 @@ namespace YooAsset
{
if (_asyncOp.isDone)
{
- Scene = SceneManager.GetSceneByName(AssetName);
- if (_activateOnLoad)
- SceneManager.SetActiveScene(Scene);
+ SceneObject = SceneManager.GetSceneByName(AssetName);
+ if (SceneObject.IsValid() && _activateOnLoad)
+ SceneManager.SetActiveScene(SceneObject);
- Status = Scene.IsValid() ? EStatus.Success : EStatus.Fail;
+ Status = SceneObject.IsValid() ? EStatus.Success : EStatus.Fail;
InvokeCompletion();
}
}
}
- public override void Destory()
- {
- base.Destory();
-
- // 卸载附加场景(异步方式卸载)
- if (_sceneMode == LoadSceneMode.Additive)
- {
- if (Scene.IsValid() && Scene.isLoaded)
- SceneManager.UnloadSceneAsync(Scene);
- }
- }
}
}
\ No newline at end of file
diff --git a/Assets/YooAsset/Runtime/AssetSystem/Provider/DatabaseSceneProvider.cs b/Assets/YooAsset/Runtime/AssetSystem/Provider/DatabaseSceneProvider.cs
index 57de498..51f3007 100644
--- a/Assets/YooAsset/Runtime/AssetSystem/Provider/DatabaseSceneProvider.cs
+++ b/Assets/YooAsset/Runtime/AssetSystem/Provider/DatabaseSceneProvider.cs
@@ -5,8 +5,9 @@ namespace YooAsset
{
internal sealed class DatabaseSceneProvider : AssetProviderBase
{
- private readonly LoadSceneMode _sceneMode;
+ public readonly LoadSceneMode SceneMode;
private readonly bool _activateOnLoad;
+ private readonly int _priority;
private AsyncOperation _asyncOp;
public override float Progress
{
@@ -18,11 +19,12 @@ namespace YooAsset
}
}
- public DatabaseSceneProvider(string scenePath, LoadSceneMode sceneMode, bool activateOnLoad)
+ public DatabaseSceneProvider(string scenePath, LoadSceneMode sceneMode, bool activateOnLoad, int priority)
: base(scenePath, null)
{
- _sceneMode = sceneMode;
+ SceneMode = sceneMode;
_activateOnLoad = activateOnLoad;
+ _priority = priority;
}
public override void Update()
{
@@ -39,11 +41,12 @@ namespace YooAsset
if (Status == EStatus.Loading)
{
LoadSceneParameters loadSceneParameters = new LoadSceneParameters();
- loadSceneParameters.loadSceneMode = _sceneMode;
+ loadSceneParameters.loadSceneMode = SceneMode;
_asyncOp = UnityEditor.SceneManagement.EditorSceneManager.LoadSceneAsyncInPlayMode(AssetPath, loadSceneParameters);
if (_asyncOp != null)
{
_asyncOp.allowSceneActivation = true;
+ _asyncOp.priority = _priority;
Status = EStatus.Checking;
}
else
@@ -59,27 +62,14 @@ namespace YooAsset
{
if (_asyncOp.isDone)
{
- Scene = SceneManager.GetSceneAt(SceneManager.sceneCount - 1);
- if (_activateOnLoad)
- SceneManager.SetActiveScene(Scene);
+ SceneObject = SceneManager.GetSceneAt(SceneManager.sceneCount - 1);
+ if (SceneObject.IsValid() && _activateOnLoad)
+ SceneManager.SetActiveScene(SceneObject);
- Status = Scene.IsValid() ? EStatus.Success : EStatus.Fail;
+ Status = SceneObject.IsValid() ? EStatus.Success : EStatus.Fail;
InvokeCompletion();
}
}
-#endif
- }
- public override void Destory()
- {
-#if UNITY_EDITOR
- base.Destory();
-
- // 卸载附加场景(异步方式卸载)
- if (_sceneMode == LoadSceneMode.Additive)
- {
- if (Scene.IsValid() && Scene.isLoaded)
- SceneManager.UnloadSceneAsync(Scene);
- }
#endif
}
}
diff --git a/Assets/YooAsset/Runtime/YooAssets.cs b/Assets/YooAsset/Runtime/YooAssets.cs
index 548abb6..c83f969 100644
--- a/Assets/YooAsset/Runtime/YooAssets.cs
+++ b/Assets/YooAsset/Runtime/YooAssets.cs
@@ -289,17 +289,18 @@ namespace YooAsset
AssetSystem.GetDebugReport(report);
}
- #region 场景接口
+ #region 场景加载接口
///
/// 异步加载场景
///
/// 场景对象相对路径
- /// 场景加载模式
+ /// 场景加载模式
/// 加载完毕时是否主动激活
- public static SceneOperationHandle LoadSceneAsync(string location, LoadSceneMode mode, bool activateOnLoad)
+ /// 优先级
+ public static SceneOperationHandle LoadSceneAsync(string location, LoadSceneMode sceneMode = LoadSceneMode.Single, bool activateOnLoad = true, int priority = 100)
{
string scenePath = ConvertLocationToAssetPath(location);
- var handle = AssetSystem.LoadSceneAsync(scenePath, mode, activateOnLoad);
+ var handle = AssetSystem.LoadSceneAsync(scenePath, sceneMode, activateOnLoad, priority);
return handle;
}
#endregion
@@ -330,7 +331,7 @@ namespace YooAsset
///
/// 资源类型
/// 资源对象相对路径
- public static AssetOperationHandle LoadSubAssetsSync(string location)
+ public static SubAssetsOperationHandle LoadSubAssetsSync(string location)
{
return LoadSubAssetsInternal(location, typeof(TObject), true);
}
@@ -340,7 +341,7 @@ namespace YooAsset
///
/// 资源对象相对路径
/// 子对象类型
- public static AssetOperationHandle LoadSubAssetsSync(string location, System.Type type)
+ public static SubAssetsOperationHandle LoadSubAssetsSync(string location, System.Type type)
{
return LoadSubAssetsInternal(location, type, true);
}
@@ -371,7 +372,7 @@ namespace YooAsset
///
/// 资源类型
/// 资源对象相对路径
- public static AssetOperationHandle LoadSubAssetsAsync(string location)
+ public static SubAssetsOperationHandle LoadSubAssetsAsync(string location)
{
return LoadSubAssetsInternal(location, typeof(TObject), false);
}
@@ -381,7 +382,7 @@ namespace YooAsset
///
/// 资源对象相对路径
/// 子对象类型
- public static AssetOperationHandle LoadSubAssetsAsync(string location, System.Type type)
+ public static SubAssetsOperationHandle LoadSubAssetsAsync(string location, System.Type type)
{
return LoadSubAssetsInternal(location, type, false);
}
@@ -395,7 +396,7 @@ namespace YooAsset
handle.WaitForAsyncComplete();
return handle;
}
- private static AssetOperationHandle LoadSubAssetsInternal(string location, System.Type assetType, bool waitForAsyncComplete)
+ private static SubAssetsOperationHandle LoadSubAssetsInternal(string location, System.Type assetType, bool waitForAsyncComplete)
{
string assetPath = ConvertLocationToAssetPath(location);
var handle = AssetSystem.LoadSubAssetsAsync(assetPath, assetType);