using System.Collections.Generic; using Cielonos.MainGame.Buffs.Character; using Cielonos.MainGame.UI; using Sirenix.OdinInspector; using SLSUtilities.General; using UnityEngine; using UnityEngine.Serialization; namespace Cielonos.MainGame.Characters { public partial class Player : CharacterBase { [TitleGroup("Data")] public AttributeData globalAttributeData; [TitleGroup("Data")] public PlayerViewPreset baseViewPreset; [TitleGroup("Submodules")] public AttributeSubmodule globalAttributeSm; public PlayerEventSubmodule eventSm => base.eventSm as PlayerEventSubmodule; [Required] [TitleGroup("Subcontrollers")] public PlayerInputSubcontroller inputSc; [Required] [TitleGroup("Subcontrollers")] public PlayerOperationSubcontroller operationSc; [Required] [TitleGroup("Subcontrollers")] public PlayerInteractionSubcontroller interactionSc; [Required] [TitleGroup("Subcontrollers")] public PlayerViewSubcontroller viewSc; [Required] [TitleGroup("Subcontrollers")] public PlayerLandMovementSubcontroller landMovementSc => base.movementSc as PlayerLandMovementSubcontroller; [Required] [TitleGroup("Subcontrollers")] public PlayerInventorySubcontroller inventorySc; [HideInEditorMode] public new PlayerAnimationSubcontroller animationSc => base.animationSc as PlayerAnimationSubcontroller; } public partial class Player { protected override void InitializeSubmodules() { //globalAttributeSm = new AttributeSubmodule(this, globalAttributeData); base.InitializeSubmodules(); base.eventSm = new PlayerEventSubmodule(this); eventSm.onGetHit.InsertByPriority("Feedback_GetHit", new PrioritizedAction(Feedback_GetHit)); eventSm.onAfterGetAttacked.InsertByPriority("Feedback_GetAttacked", new PrioritizedAction(Feedback_GetAttacked)); eventSm.onNormalDodgeSuccess.InsertByPriority("Feedback_NormalDodge", new PrioritizedAction(Feedback_NormalDodge)); eventSm.onPerfectDodgeSuccess.InsertByPriority("Feedback_PerfectDodge", new PrioritizedAction(Feedback_PerfectDodge)); } /// /// 注册 Player 特有的属性变更回调: /// Health/MaxHealth → HealthBar UI 更新;Energy/MaxEnergy → EnergyBar UI 更新。 /// 基类已注册 Health→onHealthChanged、Energy→onEnergyChanged 的自动触发。 /// protected override void RegisterAttributeCallbacks() { base.RegisterAttributeCallbacks(); attributeSm.RegisterValueChangedCallback(CharacterAttribute.Health, OnHealthValueChanged); attributeSm.RegisterValueChangedCallback(CharacterAttribute.MaximumHealth, OnMaxHealthValueChanged); attributeSm.RegisterValueChangedCallback(CharacterAttribute.Energy, OnEnergyValueChanged); attributeSm.RegisterValueChangedCallback(CharacterAttribute.MaximumEnergy, OnMaxEnergyValueChanged); attributeSm.RegisterValueChangedCallback(CharacterAttribute.Shield, OnShieldValueChanged); } protected override void InitializeSubcontrollers() { base.InitializeSubcontrollers(); inputSc.Initialize(); operationSc.Initialize(); interactionSc.Initialize(); viewSc.Initialize(); inventorySc.Initialize(); } protected override void Start() { base.Start(); inventorySc.equipmentSm.EquipMainWeapon(inventorySc.equipmentSm.preparedMainWeapons[0]); for (int i = 0; i < inventorySc.backpackSm.supportEquipments.Count; i++) { inventorySc.equipmentSm.EquipSupportEquipment(inventorySc.backpackSm.supportEquipments[i], i); } } protected override void Update() { base.Update(); Regeneration(); } } /// /// 属性变更 → UI 更新回调 /// public partial class Player { private void OnHealthValueChanged(float oldValue, float newValue) { PlayerCanvas.PlayerInfoUIArea.UpdateHealth(); if (newValue < oldValue) { PlayerCanvas.PlayerInfoUIArea.healthBar.GetHurtGlowBlink(); } } private void OnMaxHealthValueChanged(float oldValue, float newValue) { PlayerCanvas.PlayerInfoUIArea.UpdateHealth(); } private void OnEnergyValueChanged(float oldValue, float newValue) { PlayerCanvas.PlayerInfoUIArea.UpdateEnergy(); } private void OnMaxEnergyValueChanged(float oldValue, float newValue) { PlayerCanvas.PlayerInfoUIArea.UpdateEnergy(); } private void OnShieldValueChanged(float oldValue, float newValue) { // 护盾值变更时刷新 HealthBar(护盾通常与血条关联显示) PlayerCanvas.PlayerInfoUIArea.UpdateHealth(); } private void OnMaxShieldValueChanged(float oldValue, float newValue) { PlayerCanvas.PlayerInfoUIArea.UpdateHealth(); } } public partial class Player { private void Feedback_GetHit(AttackAreaBase attackArea) { Breakthrough.Type breakthroughType = attackArea.attackSm.attackValue.breakthroughType; if(breakthroughType == Breakthrough.Type.None) return; string feedbackName = "GetHit" + breakthroughType.ToString(); feedbackSc.PlayFeedback(feedbackName); } private void Feedback_GetAttacked(AttackAreaBase attackArea, Attack.Result attackResult) { float ratio = attackResult.finalDamage / (attributeSm["MaximumHealth"] * 0.2f); float intensity = Mathf.Lerp(0.25f, 1f, ratio); //feedbackSc.GetFeedbackData("GetAttacked") } private void Feedback_PerfectDodge(AttackAreaBase attackArea, DodgeSource dodgeSource) { feedbackSc.PlayFeedback("PerfectDodge"); } private void Feedback_NormalDodge(AttackAreaBase attackArea, DodgeSource dodgeSource) { feedbackSc.PlayFeedback("NormalDodge"); } } }