【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili
教程源地址:https://www.udemy.com/course/2d-rpg-alexdev/
完成了技能树上的格挡技能的UI逻辑
Parry_SKill.cs
核心功能
代码主要围绕以下功能展开:
(1)技能解锁
- 通过绑定解锁按钮的点击事件(
onClick
),来解锁技能。 - 每个技能都依赖一个
UI_SKillTreeSlot
(可能是一个技能树的 UI 元素),通过检测其unlocked
属性判断技能是否解锁成功。
(2)技能效果
a. 使用技能 (UseSkill
)
- 在技能使用时,检查特定效果是否已解锁,并执行对应功能。
- 恢复生命值的功能:
b. 格挡幻影 (MakeMirageOnParry
)
- 如果
parrtWithMirageUnlocked
解锁,生成一个幻影(类似分身):
UI逻辑:
UI_SKillTreeSlot
是解锁按钮的一个组件,应该包括:
- 一个布尔变量
unlocked
表示当前技能是否解锁。 - 一个
Button
组件用作解锁触发点。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class Parry_SKill : Skill
{[Header("反击")]//parry[SerializeField] private UI_SKillTreeSlot parryUnlockButton;public bool parryUnlocked{ get; private set; }[Header("反击恢复")]//Parry restor[SerializeField] private UI_SKillTreeSlot restorUnlockButton;[Range(0f,1f)][SerializeField] private float restoreHealthPercentage;public bool restorUnlocked{ get; private set; }[Header("格挡幻影")]//Parry mirrage[SerializeField] private UI_SKillTreeSlot parrtWithMirageUnlockButton;public bool parrtWithMirageUnlocked { get; private set; }public override void UseSkill(){base.UseSkill();if(restorUnlocked){int restoreAmount = Mathf.RoundToInt(player.stats.GetMaxHealthValue() * restoreHealthPercentage);player.stats.IncreaseHealthBy(restoreAmount);}}protected override void Start(){base.Start();parryUnlockButton.GetComponent<Button>().onClick.AddListener(UnlockParry);restorUnlockButton.GetComponent<Button>().onClick.AddListener(UnlockParryRestor);parrtWithMirageUnlockButton.GetComponent<Button>().onClick.AddListener(UnlockParrtWithMirage);}private void UnlockParry(){if (parryUnlockButton.unlocked)parryUnlocked = true;}private void UnlockParryRestor(){if (restorUnlockButton.unlocked)restorUnlocked = true;}private void UnlockParrtWithMirage(){if (parrtWithMirageUnlockButton.unlocked)parrtWithMirageUnlocked = true;}public void MakeMirageOnParry(Transform _respawnTransform){if (parrtWithMirageUnlocked)SkillManager.instance.clone.CreateCloneWithDelay(_respawnTransform);}
}
PlayerGroundedState.cs
修改了格挡技能Q的逻辑判断
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class PlayerGroundedState : PlayerState
{public PlayerGroundedState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) : base(_player, _stateMachine, _animBoolName){}public override void Enter(){base.Enter();}public override void Exit(){base.Exit();}public override void Update(){base.Update();if (Input.GetKeyDown(KeyCode.R))stateMachine.ChangeState(player.blackHole);if (Input.GetKeyDown(KeyCode.Mouse1) && HasNoSword())stateMachine.ChangeState(player.aimSword);if (Input.GetKeyDown(KeyCode.Q) && player.skill.parry.parryUnlocked)stateMachine.ChangeState(player.counterAttack);if (Input.GetKeyDown(KeyCode.Mouse0))//GetKeyDown改成GetKey按住就可以攻击了stateMachine.ChangeState(player.primaryAttack);if (!player.IsGroundDetected())stateMachine.ChangeState(player.airState);if (Input.GetKeyDown(KeyCode.Space) && player.IsGroundDetected())stateMachine.ChangeState(player.jumpState);}private bool HasNoSword(){if (!player.sword){return true;}player.sword.GetComponent<Sword_Skill_Controller>().ReturnSword();return false;}
}
PlayerCounterAttackState.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class PlayerCounterAttackState : PlayerState
{private bool canCreateClone;public PlayerCounterAttackState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) : base(_player, _stateMachine, _animBoolName){}public override void Enter(){base.Enter();canCreateClone = true;stateTimer = player.counterAttackDuration;player.anim.SetBool("SuccessfulCounterAttack", false);}public override void Exit(){base.Exit();}public override void Update(){base.Update();player.SetZeroVelocity();Collider2D[] colliders = Physics2D.OverlapCircleAll(player.attackCheck.position, player.attackCheckRadius);//这行代码在 Unity 中用于检测一个圆形区域内的所有碰撞体,并返回它们的数组。foreach (var hit in colliders)//foreach循环是一个迭代器,它可以遍历数组、集合、列表、字典等数据结构。攻击到敌人后,调用伤害函数{if (hit.GetComponent<Enemy>() != null){if (hit.GetComponent<Enemy>().CanBeStunned()){stateTimer = 10;//大于1的数,保证不会进入idle状态player.anim.SetBool("SuccessfulCounterAttack", true);player.skill.parry.UseSkill();if (canCreateClone){canCreateClone = false; player.skill.parry.MakeMirageOnParry(hit.transform);}}}}if (stateTimer < 0 || triggerCalled)stateMachine.ChangeState(player.idleState);}
}
Dash_Skill.cs
修改了一些变量
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;//2024年11月19日添加解锁技能逻辑
public class Dash_Skill : Skill
{[Header("Dash")][SerializeField] private UI_SKillTreeSlot dashUnlockButton;public bool dashUnlocked { get; private set; }[Header("Clone on dash")][SerializeField] private UI_SKillTreeSlot cloneOnDashUnlockButton;public bool cloneOmDashUnlocked { get; private set; }[Header("Clone on arrival")][SerializeField] private UI_SKillTreeSlot cloneOnArrivalUnlockButton;public bool cloneOnArrivalUnlocked { get; private set; }public override void UseSkill(){base.UseSkill();}protected override void Start(){base.Start();dashUnlockButton.GetComponent<Button>().onClick.AddListener(UnlockDash);cloneOnDashUnlockButton.GetComponent<Button>().onClick.AddListener(UnlockCloneOnDash);cloneOnArrivalUnlockButton.GetComponent<Button>().onClick.AddListener(UnlockCloneOnArrival);}private void UnlockDash(){if (dashUnlockButton.unlocked) dashUnlocked = true;}private void UnlockCloneOnDash(){if (cloneOnDashUnlockButton.unlocked)cloneOmDashUnlocked = true;}private void UnlockCloneOnArrival(){if (cloneOnArrivalUnlockButton.unlocked)cloneOnArrivalUnlocked = true;}public void CloneOnDash(){if (cloneOmDashUnlocked)SkillManager.instance.clone.CreateClone(player.transform, Vector3.zero);}public void CloneOnArrival(){if (cloneOnArrivalUnlocked)SkillManager.instance.clone.CreateClone(player.transform, Vector3.zero);}}