using System; using System.Collections.Generic; using System.Threading; using Cysharp.Threading.Tasks; using SepCore.CustomUtility; using SepCore.Definition; using SepCore.Entity; using UnityGameFramework.Runtime; using HideEntityCompleteEventArgs = UnityGameFramework.Runtime.HideEntityCompleteEventArgs; using ShowEntityFailureEventArgs = UnityGameFramework.Runtime.ShowEntityFailureEventArgs; using ShowEntitySuccessEventArgs = UnityGameFramework.Runtime.ShowEntitySuccessEventArgs; namespace SepCore.AsyncTask { /// /// Entity 异步扩展方法 /// public static class EntityAsyncExtension { private const string EntityNamespace = "SepCore.Entity."; private static readonly Dictionary _typeDict = new(); /// /// 异步显示实体 /// /// 实体组件 /// 实体编号 /// 实体逻辑类型 /// 实体资源名称 /// 实体组名称 /// 用户自定义数据 /// 超时时间(秒),0表示不超时 /// 取消令牌 /// 显示的实体 public static UniTask ShowEntityAsync(this EntityComponent entityComponent, int entityId, Type entityLogicType, string entityAssetName, string entityGroupName, object userData = null, float timeout = 30f, CancellationToken cancellationToken = default) { return ShowEntityAsync(entityComponent, entityId, entityLogicType, entityAssetName, entityGroupName, 0, userData, timeout, cancellationToken); } /// /// 异步显示实体 /// /// 实体组件 /// 实体编号 /// 实体逻辑类型 /// 实体资源名称 /// 实体组名称 /// 加载优先级 /// 用户自定义数据 /// 超时时间(秒),0表示不超时 /// 取消令牌 /// 显示的实体 public static UniTask ShowEntityAsync(this EntityComponent entityComponent, int entityId, Type entityLogicType, string entityAssetName, string entityGroupName, int priority, object userData = null, float timeout = 30f, CancellationToken cancellationToken = default) { UniTask waitTask = AsyncTaskHelper.WaitSuccessOrFailureAsync( ShowEntitySuccessEventArgs.EventId, ShowEntityFailureEventArgs.EventId, successArgs => successArgs.Entity.Id == entityId && ReferenceEquals(successArgs.UserData, userData), failureArgs => failureArgs.EntityId == entityId && ReferenceEquals(failureArgs.UserData, userData), timeout, cancellationToken ).ContinueWith(successArgs => successArgs.Entity); entityComponent.ShowEntity(entityId, entityLogicType, entityAssetName, entityGroupName, priority, userData); return waitTask; } /// /// 异步显示实体(泛型版本) /// /// 实体逻辑类型 /// 实体组件 /// 实体编号 /// 实体资源名称 /// 实体组名称 /// 用户自定义数据 /// 超时时间(秒),0表示不超时 /// 取消令牌 /// 显示的实体 public static UniTask ShowEntityAsync(this EntityComponent entityComponent, int entityId, string entityAssetName, string entityGroupName, object userData = null, float timeout = 30f, CancellationToken cancellationToken = default) where T : EntityLogic { return ShowEntityAsync(entityComponent, entityId, entityAssetName, entityGroupName, 0, userData, timeout, cancellationToken); } /// /// 异步显示实体(泛型版本) /// /// 实体逻辑类型 /// 实体组件 /// 实体编号 /// 实体资源名称 /// 实体组名称 /// 加载优先级 /// 用户自定义数据 /// 超时时间(秒),0表示不超时 /// 取消令牌 /// 显示的实体 public static UniTask ShowEntityAsync(this EntityComponent entityComponent, int entityId, string entityAssetName, string entityGroupName, int priority, object userData = null, float timeout = 30f, CancellationToken cancellationToken = default) where T : EntityLogic { UniTask waitTask = AsyncTaskHelper.WaitSuccessOrFailureAsync( ShowEntitySuccessEventArgs.EventId, ShowEntityFailureEventArgs.EventId, successArgs => successArgs.Entity.Id == entityId && ReferenceEquals(successArgs.UserData, userData), failureArgs => failureArgs.EntityId == entityId && ReferenceEquals(failureArgs.UserData, userData), timeout, cancellationToken ).ContinueWith(successArgs => (T)successArgs.Entity.Logic); entityComponent.ShowEntity(entityId, entityAssetName, entityGroupName, priority, userData); return waitTask; } /// /// 异步显示玩家实体。 /// public static UniTask ShowPlayerAsync(this EntityComponent entityComponent, PlayerData data, float timeout = 30f, CancellationToken cancellationToken = default) { return ShowEntityByDataAsync(entityComponent, typeof(Player), "Player", Constant.AssetPriority.PlayerAsset, data, timeout, cancellationToken); } /// /// 异步显示敌人实体。 /// public static UniTask ShowEnemyAsync(this EntityComponent entityComponent, EnemyData data, float timeout = 30f, CancellationToken cancellationToken = default) { Type enemyType = GetLogicType(data.LogicType); EntityConfig entityConfig = GameEntry.Luban.Get(data.AssetName); return entityComponent.ShowEntityAsync( data.Id, enemyType, AssetUtility.GetEntityAsset(entityConfig.PrefabPath), "Enemy", Constant.AssetPriority.EnemyAsset, data, timeout, cancellationToken) .ContinueWith(entity => entity?.Logic as EnemyBase); } /// /// 异步显示武器实体。 /// public static UniTask ShowWeaponAsync(this EntityComponent entityComponent, WeaponData data, float timeout = 30f, CancellationToken cancellationToken = default) { Type weaponType = GetLogicType(data.LogicType); EntityConfig entityConfig = GameEntry.Luban.Get(data.AssetName); return entityComponent.ShowEntityAsync( data.Id, weaponType, AssetUtility.GetEntityAsset(entityConfig.PrefabPath), "Weapon", Constant.AssetPriority.WeaponAsset, data, timeout, cancellationToken) .ContinueWith(entity => entity?.Logic as WeaponBase); } /// /// 异步显示特效实体。 /// public static UniTask ShowEffectAsync(this EntityComponent entityComponent, EffectData data, float timeout = 30f, CancellationToken cancellationToken = default) { return ShowEntityByDataAsync(entityComponent, typeof(Effect), "Effect", Constant.AssetPriority.EffectAsset, data, timeout, cancellationToken); } /// /// 异步显示金币掉落实体。 /// public static UniTask ShowCoinAsync(this EntityComponent entityComponent, CoinData data, float timeout = 30f, CancellationToken cancellationToken = default) { return ShowEntityByDataAsync(entityComponent, typeof(CoinEntity), "Drop", Constant.AssetPriority.EffectAsset, data, timeout, cancellationToken); } /// /// 异步显示经验掉落实体。 /// public static UniTask ShowExpAsync(this EntityComponent entityComponent, ExpData data, float timeout = 30f, CancellationToken cancellationToken = default) { return ShowEntityByDataAsync(entityComponent, typeof(ExpEntity), "Drop", Constant.AssetPriority.EffectAsset, data, timeout, cancellationToken); } /// /// 异步隐藏实体 /// /// 实体组件 /// 实体编号 /// 用户自定义数据 /// 超时时间(秒),0表示不超时 /// 取消令牌 /// 隐藏完成事件 public static UniTask HideEntityAsync(this EntityComponent entityComponent, int entityId, object userData = null, float timeout = 30f, CancellationToken cancellationToken = default) { UniTask waitTask = AsyncTaskHelper.WaitEventAsync( HideEntityCompleteEventArgs.EventId, args => args.EntityId == entityId, timeout, cancellationToken ); entityComponent.HideEntity(entityId, userData); return waitTask; } /// /// 异步隐藏实体(通过实体对象) /// /// 实体组件 /// 要隐藏的实体 /// 用户自定义数据 /// 超时时间(秒),0表示不超时 /// 取消令牌 /// 隐藏完成事件 public static UniTask HideEntityAsync(this EntityComponent entityComponent, UnityGameFramework.Runtime.Entity entity, object userData = null, float timeout = 30f, CancellationToken cancellationToken = default) { return HideEntityAsync(entityComponent, entity.Id, userData, timeout, cancellationToken); } private static UniTask ShowEntityByDataAsync(EntityComponent entityComponent, Type logicType, string entityGroupName, int priority, EntityDataBase data, float timeout, CancellationToken cancellationToken) where T : EntityLogic { EntityConfig entityConfig = GameEntry.Luban.Get(data.AssetName); return entityComponent.ShowEntityAsync(data.Id, AssetUtility.GetEntityAsset(entityConfig.PrefabPath), entityGroupName, priority, data, timeout, cancellationToken); } private static Type GetLogicType(string rawTypeName) { string typeName = EntityNamespace + rawTypeName; if (!_typeDict.TryGetValue(typeName, out Type type)) { type = Type.GetType(typeName); if (type == null) { throw new InvalidOperationException($"Can not load entity type '{typeName}'."); } _typeDict.Add(typeName, type); } return type; } } }