From 41ff2c6df83e79bb91afa3bdfff6593575bb6ce9 Mon Sep 17 00:00:00 2001 From: SepComet <202308010230@stu.csust.edu.cn> Date: Sat, 6 Jun 2026 14:12:05 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=81=E7=A7=BB=20Player/ProcedureGame/ShopU?= =?UTF-8?q?seCase=20=E9=87=8C=E7=9A=84=E5=AE=9E=E4=BD=93=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E8=B0=83=E7=94=A8=E9=A3=8E=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Player/ShopUseCase:调整了 Weapon 实体的打开方式 - ProcedureGame:调整初始化时的 Hud 和 Player 的初始化写法,流程更清楚 --- .../Presentation/Main/Shop/ShopController.cs | 7 +- .../Scripts/Procedure/Game/GameStateBase.cs | 11 +- .../Scripts/Procedure/Game/GameStateBattle.cs | 9 +- .../Procedure/Game/GameStateLevelUp.cs | 16 ++- .../Scripts/Procedure/Game/GameStateShop.cs | 16 +-- .../Scripts/Procedure/Game/ProcedureGame.cs | 100 +++++++----------- .../Runtime/Entity/EntityLogic/Player.cs | 50 +++++---- .../Runtime/UIBase/Main/Shop/ShopUseCase.cs | 16 ++- 8 files changed, 107 insertions(+), 118 deletions(-) diff --git a/Assets/GameMain/Scripts/Presentation/Main/Shop/ShopController.cs b/Assets/GameMain/Scripts/Presentation/Main/Shop/ShopController.cs index 7439e09..5eee229 100644 --- a/Assets/GameMain/Scripts/Presentation/Main/Shop/ShopController.cs +++ b/Assets/GameMain/Scripts/Presentation/Main/Shop/ShopController.cs @@ -448,6 +448,11 @@ namespace SepCore.UI } private void ShopPurchase(object sender, GameEventArgs e) + { + ShopPurchaseAsync(sender, e).Forget(); + } + + private async UniTaskVoid ShopPurchaseAsync(object sender, GameEventArgs e) { if (sender is not ShopForm) { @@ -459,7 +464,7 @@ namespace SepCore.UI return; } - ShopPurchaseResult result = _useCase.TryPurchase(args.GoodsIndex); + ShopPurchaseResult result = await _useCase.TryPurchaseAsync(args.GoodsIndex); if (result == null) { return; diff --git a/Assets/GameMain/Scripts/Procedure/Game/GameStateBase.cs b/Assets/GameMain/Scripts/Procedure/Game/GameStateBase.cs index fd4cfee..ae91c3b 100644 --- a/Assets/GameMain/Scripts/Procedure/Game/GameStateBase.cs +++ b/Assets/GameMain/Scripts/Procedure/Game/GameStateBase.cs @@ -10,12 +10,11 @@ namespace SepCore.Procedure { public abstract GameStateType GameStateType { get; } public abstract void OnInit(ProcedureGame master); - public abstract void OnEnter(IFsm procedureOwner); + public abstract void OnEnter(); - public abstract void OnUpdate(IFsm procedureOwner, float elapseSeconds, - float realElapseSeconds); + public abstract void OnUpdate(float elapseSeconds, float realElapseSeconds); - public abstract void OnLeave(IFsm procedureOwner); - public abstract void OnDestroy(IFsm procedureOwner); + public abstract void OnLeave(); + public abstract void OnDestroy(); } -} \ No newline at end of file +} diff --git a/Assets/GameMain/Scripts/Procedure/Game/GameStateBattle.cs b/Assets/GameMain/Scripts/Procedure/Game/GameStateBattle.cs index 4ed6f24..fe674fe 100644 --- a/Assets/GameMain/Scripts/Procedure/Game/GameStateBattle.cs +++ b/Assets/GameMain/Scripts/Procedure/Game/GameStateBattle.cs @@ -38,7 +38,7 @@ namespace SepCore.Procedure _procedureGame = master; } - public override void OnEnter(IFsm procedureOwner) + public override void OnEnter() { _currentLevel = _procedureGame.CurrentLevel; @@ -55,8 +55,7 @@ namespace SepCore.Procedure if (Player != null) Player.Enable = true; } - public override void OnUpdate(IFsm procedureOwner, float elapseSeconds, - float realElapseSeconds) + public override void OnUpdate(float elapseSeconds, float realElapseSeconds) { if (_levelTimeLeft < 0) { @@ -77,7 +76,7 @@ namespace SepCore.Procedure GameEntry.Event.Fire(this, LevelProcessEventArgs.Create((int)_levelTimeLeft)); } - public override void OnLeave(IFsm procedureOwner) + public override void OnLeave() { // 隐藏所有敌人实体 _enemyManager.OnReset(); @@ -97,7 +96,7 @@ namespace SepCore.Procedure HideEntityGroup("EnemyProjectile"); } - public override void OnDestroy(IFsm procedureOwner) + public override void OnDestroy() { _enemyManager = null; _procedureGame = null; diff --git a/Assets/GameMain/Scripts/Procedure/Game/GameStateLevelUp.cs b/Assets/GameMain/Scripts/Procedure/Game/GameStateLevelUp.cs index d8708ef..7c93ce9 100644 --- a/Assets/GameMain/Scripts/Procedure/Game/GameStateLevelUp.cs +++ b/Assets/GameMain/Scripts/Procedure/Game/GameStateLevelUp.cs @@ -12,7 +12,7 @@ namespace SepCore.Procedure public override GameStateType GameStateType => GameStateType.LevelUp; private ProcedureGame _procedureGame; - + public bool IsCompleted { get; set; } #region FSM @@ -22,22 +22,21 @@ namespace SepCore.Procedure Log.Debug("GameStateLevelUp::OnInit"); _procedureGame = master; - + var useCase = new LevelUpUseCase(_procedureGame.Player, () => IsCompleted = true); GameEntry.UIRouter.BindUIUseCase(UIFormType.LevelUpForm, useCase); } - public override void OnEnter(IFsm procedureOwner) + public override void OnEnter() { Log.Debug("GameStateLevelUp::OnEnter"); IsCompleted = false; - + GameEntry.UIRouter.OpenUIAsync(UIFormType.LevelUpForm).Forget(); } - public override void OnUpdate(IFsm procedureOwner, float elapseSeconds, - float realElapseSeconds) + public override void OnUpdate(float elapseSeconds, float realElapseSeconds) { if (IsCompleted) { @@ -45,14 +44,14 @@ namespace SepCore.Procedure } } - public override void OnLeave(IFsm procedureOwner) + public override void OnLeave() { Log.Debug("GameStateLevelUp::OnLeave"); GameEntry.UIRouter.CloseUIAsync(UIFormType.LevelUpForm).Forget(); } - public override void OnDestroy(IFsm procedureOwner) + public override void OnDestroy() { _procedureGame = null; @@ -60,6 +59,5 @@ namespace SepCore.Procedure } #endregion - } } diff --git a/Assets/GameMain/Scripts/Procedure/Game/GameStateShop.cs b/Assets/GameMain/Scripts/Procedure/Game/GameStateShop.cs index 07497fd..61a00de 100644 --- a/Assets/GameMain/Scripts/Procedure/Game/GameStateShop.cs +++ b/Assets/GameMain/Scripts/Procedure/Game/GameStateShop.cs @@ -21,12 +21,13 @@ namespace SepCore.Procedure { Log.Debug("GameStateShop::OnInit"); _procedureGame = master; - - var shopFormUseCase = new ShopUseCase(_procedureGame.Player, _procedureGame.CurrentLevel, () => ShopFinish = true); + + var shopFormUseCase = + new ShopUseCase(_procedureGame.Player, _procedureGame.CurrentLevel, () => ShopFinish = true); GameEntry.UIRouter.BindUIUseCase(UIFormType.ShopForm, shopFormUseCase); } - public override void OnEnter(IFsm procedureOwner) + public override void OnEnter() { Log.Debug("GameStateShop::OnEnter"); @@ -35,8 +36,7 @@ namespace SepCore.Procedure GameEntry.UIRouter.OpenUIAsync(UIFormType.ShopForm).Forget(); } - public override void OnUpdate(IFsm procedureOwner, float elapseSeconds, - float realElapseSeconds) + public override void OnUpdate(float elapseSeconds, float realElapseSeconds) { if (ShopFinish) { @@ -44,14 +44,14 @@ namespace SepCore.Procedure } } - public override void OnLeave(IFsm procedureOwner) + public override void OnLeave() { Log.Debug("GameStateShop::OnLeave"); GameEntry.UIRouter.CloseUIAsync(UIFormType.ShopForm).Forget(); } - public override void OnDestroy(IFsm procedureOwner) + public override void OnDestroy() { _procedureGame = null; @@ -60,4 +60,4 @@ namespace SepCore.Procedure #endregion } -} \ No newline at end of file +} diff --git a/Assets/GameMain/Scripts/Procedure/Game/ProcedureGame.cs b/Assets/GameMain/Scripts/Procedure/Game/ProcedureGame.cs index c45ccad..3061767 100644 --- a/Assets/GameMain/Scripts/Procedure/Game/ProcedureGame.cs +++ b/Assets/GameMain/Scripts/Procedure/Game/ProcedureGame.cs @@ -1,13 +1,13 @@ +using System; using System.Collections.Generic; using Cysharp.Threading.Tasks; using SepCore.DataTable; using SepCore.Definition; using SepCore.Entity; -using GameFramework.Event; using GameFramework.Fsm; using GameFramework.Procedure; using UnityGameFramework.Runtime; -using SepCore.UI; +using SepCore.AsyncTask; namespace SepCore.Procedure { @@ -23,10 +23,6 @@ namespace SepCore.Procedure { public override bool UseNativeDialog => false; - private HudForm _hudForm; - private bool _hudInitialized; - - private IFsm _procedureOwner; private PlayerData _currentPlayerData; public int CurrentLevel = 1; @@ -50,7 +46,7 @@ namespace SepCore.Procedure _gameStates[GameStateType.Shop].OnInit(this); _currentGameState = GameStateType.Battle; - _gameStates[_currentGameState].OnEnter(_procedureOwner); + _gameStates[_currentGameState].OnEnter(); } public void BattleToShopOrLevelUp() @@ -58,27 +54,27 @@ namespace SepCore.Procedure CurrentLevel++; if (_currentGameState == GameStateType.Shop || _currentGameState == GameStateType.LevelUp) return; - _gameStates[_currentGameState].OnLeave(_procedureOwner); + _gameStates[_currentGameState].OnLeave(); _currentGameState = Player.PendingLevelPoints > 0 ? GameStateType.LevelUp : GameStateType.Shop; - _gameStates[_currentGameState].OnEnter(_procedureOwner); + _gameStates[_currentGameState].OnEnter(); } public void ShopToBattle() { if (_currentGameState == GameStateType.Battle) return; - _gameStates[_currentGameState].OnLeave(_procedureOwner); + _gameStates[_currentGameState].OnLeave(); _currentGameState = GameStateType.Battle; - _gameStates[_currentGameState].OnEnter(_procedureOwner); + _gameStates[_currentGameState].OnEnter(); } public void LevelUpToShop() { if (_currentGameState == GameStateType.Shop) return; - _gameStates[_currentGameState].OnLeave(_procedureOwner); + _gameStates[_currentGameState].OnLeave(); _currentGameState = GameStateType.Shop; - _gameStates[_currentGameState].OnEnter(_procedureOwner); + _gameStates[_currentGameState].OnEnter(); } #region FSM @@ -87,87 +83,65 @@ namespace SepCore.Procedure { base.OnEnter(procedureOwner); - _procedureOwner = procedureOwner; GameEntry.SimulationWorld?.ClearSimulationState(); - GameEntry.Event.Subscribe(OpenUIFormSuccessEventArgs.EventId, OpenUIFormSuccess); - GameEntry.Event.Subscribe(ShowEntitySuccessEventArgs.EventId, ShowEntitySuccess); - CurrentLevel = 1; _currentPlayerData = new PlayerData(-1, 1001); - GameEntry.Entity.ShowPlayer(_currentPlayerData); - GameEntry.UIRouter.OpenUIAsync(UIFormType.HudForm).Forget(); + EnterAsync(procedureOwner).Forget(); } protected override void OnUpdate(IFsm procedureOwner, float elapseSeconds, float realElapseSeconds) { base.OnUpdate(procedureOwner, elapseSeconds, realElapseSeconds); - - _procedureOwner = procedureOwner; - - if (!_hudInitialized && _hudForm != null && Player != null) - { - int selectedRoleId = _procedureOwner.GetData("SelectedRoleId").Value; - var role = GameEntry.DataTable.GetDataTableRow(selectedRoleId); - Player.InitRole(role); - _hudInitialized = true; - InitGameState(); - } - - if (_hudInitialized) - _gameStates[_currentGameState].OnUpdate(procedureOwner, elapseSeconds, realElapseSeconds); + _gameStates?[_currentGameState].OnUpdate(elapseSeconds, realElapseSeconds); } protected override void OnLeave(IFsm procedureOwner, bool isShutdown) { - foreach (var state in _gameStates.Values) + if (_gameStates != null) { - state.OnDestroy(procedureOwner); - } + foreach (var state in _gameStates.Values) + { + state.OnDestroy(); + } - _gameStates.Clear(); + _gameStates.Clear(); + } GameEntry.UIRouter.CloseUIAsync(UIFormType.HudForm).Forget(); - _hudForm = null; - Player = null; - - _procedureOwner = null; GameEntry.SimulationWorld?.ClearSimulationState(); - GameEntry.Event.Unsubscribe(OpenUIFormSuccessEventArgs.EventId, OpenUIFormSuccess); - GameEntry.Event.Unsubscribe(ShowEntitySuccessEventArgs.EventId, ShowEntitySuccess); - base.OnLeave(procedureOwner, isShutdown); } #endregion - #region Event Handler - - private void OpenUIFormSuccess(object sender, GameEventArgs e) + private async UniTaskVoid EnterAsync(IFsm procedureOwner) { - if (!(e is OpenUIFormSuccessEventArgs args)) return; - - if (args.UIForm.Logic is HudForm hudForm) + try { - _hudForm = hudForm; + Player = await GameEntry.Entity.ShowPlayerAsync(_currentPlayerData); + await GameEntry.UIRouter.OpenUIAsync(UIFormType.HudForm); + + int selectedRoleId = procedureOwner.GetData("SelectedRoleId").Value; + var role = GameEntry.DataTable.GetDataTableRow(selectedRoleId); + if (role == null) + { + Log.Error("ProcedureGame.EnterAsync() can not load role '{0}'.", selectedRoleId.ToString()); + return; + } + + Player.InitRole(role); + InitGameState(); + } + catch (Exception exception) + { + Log.Error("ProcedureGame.EnterAsync() failed with exception '{0}'.", exception); } } - - private void ShowEntitySuccess(object sender, GameEventArgs e) - { - if (!(e is ShowEntitySuccessEventArgs args)) return; - - if (args.Entity.Logic is Player player) - { - Player = player; - } - } - - #endregion } } diff --git a/Assets/GameMain/Scripts/Runtime/Entity/EntityLogic/Player.cs b/Assets/GameMain/Scripts/Runtime/Entity/EntityLogic/Player.cs index 853a793..aaabea4 100644 --- a/Assets/GameMain/Scripts/Runtime/Entity/EntityLogic/Player.cs +++ b/Assets/GameMain/Scripts/Runtime/Entity/EntityLogic/Player.cs @@ -1,13 +1,13 @@ using System.Collections.Generic; +using System.Threading; +using Cysharp.Threading.Tasks; using SepCore.Components; using SepCore.Event; using SepCore.DataTable; using SepCore.Definition; -using SepCore.Entity; -using GameFramework.Event; -using UnityGameFramework.Runtime; using SepCore.Entity.Weapon; using SepCore.CustomUtility; +using SepCore.AsyncTask; namespace SepCore.Entity { @@ -92,6 +92,28 @@ namespace SepCore.Entity return _backpackComponent.AttachProp(prop); } + public async UniTask AddWeaponAsync(WeaponData weaponData, float timeout = 30f) + { + if (weaponData == null || _backpackComponent == null) + { + return null; + } + + WeaponBase weapon = await GameEntry.Entity.ShowWeaponAsync(weaponData, timeout); + if (weapon == null) + { + return null; + } + + if (!_backpackComponent.AttachWeapon(weapon)) + { + GameEntry.Entity.HideEntity(weapon); + return null; + } + + return weapon; + } + public bool RemoveWeapon(WeaponBase weapon) { if (weapon == null || _backpackComponent == null) @@ -141,8 +163,8 @@ namespace SepCore.Entity // BackpackComponent Coin = role.Coin; _backpackComponent.OnInit(this, role.WeaponCapacity); - GameEntry.Entity.ShowWeapon(EntityDataFactory.Create(GameEntry.Entity.NextId(), - WeaponType.WeaponKnife, Id, _playerData.Camp)); + AddWeaponAsync(EntityDataFactory.Create(GameEntry.Entity.NextId(), + WeaponType.WeaponKnife, Id, _playerData.Camp)).Forget(); // StatComponent foreach (var modifier in role.InitialProperties) @@ -158,8 +180,7 @@ namespace SepCore.Entity GameEntry.Event.Fire(this, PlayerExpChangeEventArgs.Create(0, 100)); - GameEntry.Event.Fire(this, - PlayerCoinChangeEventArgs.Create(Coin, Coin)); + GameEntry.Event.Fire(this, PlayerCoinChangeEventArgs.Create(Coin, Coin)); } #region FSM @@ -190,8 +211,6 @@ namespace SepCore.Entity { base.OnShow(userData); - GameEntry.Event.Subscribe(ShowEntitySuccessEventArgs.EventId, ShowEntitySuccess); - _statComponent.OnInit(); if (userData is PlayerData playerData) @@ -230,18 +249,5 @@ namespace SepCore.Entity } #endregion - - #region Event Handlers - - private void ShowEntitySuccess(object sender, GameEventArgs e) - { - if (!(e is ShowEntitySuccessEventArgs args)) return; - if (args.Entity.Logic is WeaponBase weapon) - { - _backpackComponent.AttachWeapon(weapon); - } - } - - #endregion } } diff --git a/Assets/GameMain/Scripts/Runtime/UIBase/Main/Shop/ShopUseCase.cs b/Assets/GameMain/Scripts/Runtime/UIBase/Main/Shop/ShopUseCase.cs index b983d6e..2729339 100644 --- a/Assets/GameMain/Scripts/Runtime/UIBase/Main/Shop/ShopUseCase.cs +++ b/Assets/GameMain/Scripts/Runtime/UIBase/Main/Shop/ShopUseCase.cs @@ -1,10 +1,12 @@ using System; using System.Collections.Generic; using System.Linq; +using Cysharp.Threading.Tasks; using SepCore.DataTable; using SepCore.Definition; using SepCore.Entity; using SepCore.CustomUtility; +using SepCore.Entity.Weapon; using GameFramework.DataTable; using UnityEngine; using UnityGameFramework.Runtime; @@ -107,7 +109,7 @@ namespace SepCore.UI }; } - public ShopPurchaseResult TryPurchase(int goodsIndex) + public async UniTask TryPurchaseAsync(int goodsIndex) { if (goodsIndex < 0 || goodsIndex >= _selections.Count) { @@ -128,7 +130,7 @@ namespace SepCore.UI return null; } - DisplayItemRawData displayItem = ApplyGoodsPurchase(selection); + DisplayItemRawData displayItem = await ApplyGoodsPurchaseAsync(selection); if (displayItem == null) { return null; @@ -318,7 +320,7 @@ namespace SepCore.UI return Mathf.Max(1, finalPrice); } - private DisplayItemRawData ApplyGoodsPurchase(ShopGoodsSelection goods) + private async UniTask ApplyGoodsPurchaseAsync(ShopGoodsSelection goods) { if (goods == null || Player == null) { @@ -362,7 +364,13 @@ namespace SepCore.UI return null; } - GameEntry.Entity.ShowWeapon(weaponData); + WeaponBase weapon = await Player.AddWeaponAsync(weaponData); + if (weapon == null) + { + Log.Warning( + $"ShopFormUseCase::ApplyGoodsPurchase: Show weapon failed, weapon type id = {goods.GoodsTypeId}"); + return null; + } return new DisplayItemRawData {