Unity类银河恶魔城学习记录12-11 P133 Merge Skill Tree with Parry skill源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释,可供学习Alex教程的人参考
此代码仅为较上一P有所改变的代码

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili

 Parry_Skill.cs
using UnityEngine;
using UnityEngine.UI;

public class Parry_Skill : Skill
{
    [Header("Perry")]
    [SerializeField] private UI_SkillTreeSlot parryUnlockButton;
    public bool parryUnlocked { get; private set; }
    [Header("Restore Health")]
    [SerializeField] private UI_SkillTreeSlot restoreUnlockButton;
    [Range(0f, 1f)]
    [SerializeField] private float restoreHealthPerentage;
    public bool restoreUnlocked{ get; private set; }
    [Header("Parry Mirage")]
    [SerializeField] private UI_SkillTreeSlot parryWithUnlockButton;
    public bool parryWithMirageUnlocked { get; private set; }



    public override void UseSkill()
    {
        base.UseSkill();

        if (restoreUnlocked)
        {
            int restoreAmount = Mathf.RoundToInt(player.stats.GetMaxHealthValue() * restoreHealthPerentage);
            player.stats.IncreaseHealthBy(restoreAmount);
        }
    }

    protected override void Start()
    {
        base.Start();
        parryUnlockButton.GetComponent<Button>().onClick.AddListener(UnlockParry);
        restoreUnlockButton.GetComponent<Button>().onClick.AddListener(UnlockParryRestore);
        parryWithUnlockButton.GetComponent<Button>().onClick.AddListener(UnlockParryWithMirage);
    }

    private void UnlockParry()
    {
        Debug.Log(2);
        if (parryUnlockButton.unlocked)
        {
            parryUnlocked = true;
        }
    }
    private void UnlockParryRestore()
    {
        if (restoreUnlockButton.unlocked)
        {
            restoreUnlocked = true;
        }
    }
    private void UnlockParryWithMirage()
    {
        if (parryWithUnlockButton.unlocked)
        {
            parryWithMirageUnlocked = true;
        }
    }

    public void MakeMirageOnParry(Transform _transform)
    {
        if (parryWithMirageUnlocked)
            player.skill.clone.CanCreateCloneWithDelay(_transform);
    }
}
Clone_Skill.cs
using System.Collections;
using UnityEngine;

public class Clone_Skill : Skill
{
    [Header("Clone Info")]
    [SerializeField] private GameObject clonePrefab;//克隆原型
    [SerializeField] private float cloneDuration;//克隆持续时间

    [SerializeField] private bool canAttack;// 判断是否可以攻击


    [Header("Clone can duplicate")]
    [SerializeField] private bool canDuplicateClone;
    [SerializeField] private float chanceToDuplicate;

    [Header("Crystal instead of clone")]
    public bool crystalInsteadOfClone;


    public void CreateClone(Transform _clonePosition, Vector3 _offset)//传入克隆位置
    {
        if (crystalInsteadOfClone)
        {
            SkillManager.instance.crystal.CreateCrystal();

            return;
        }//让所有的生成克隆的技能都变成生成水晶


        GameObject newClone = Instantiate(clonePrefab);//创建新的克隆//克隆 original 对象并返回克隆对象。
        //https://docs.unity3d.com/cn/current/ScriptReference/Object.Instantiate.html

        newClone.GetComponent<Clone_Skill_Controller>().SetupClone(_clonePosition, cloneDuration, canAttack, _offset, FindClosestEnemy(newClone.transform), canDuplicateClone, chanceToDuplicate, player);//调试clone的位置,同时调试克隆持续时间                                                                                            //Controller绑在克隆原型上的,所以用GetComponent                                                                                        
    }



    //反击后产生一个克隆背刺敌人
    public void CanCreateCloneWithDelay(Transform _enemyTransform)
    {

        StartCoroutine(CreateDelayCoroutine(_enemyTransform, new Vector3(1 * player.facingDir, 0, 0)));
    }
    //整个延迟生成
    private IEnumerator CreateDelayCoroutine(Transform _enemyTransform, Vector3 _offset)
    {
        yield return new WaitForSeconds(.4f);
        CreateClone(_enemyTransform, _offset);

    }
}

SkillManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SkillManager : MonoBehaviour
{
    public static SkillManager instance;

    public Dash_Skill dash { get; private set; }
    public Clone_Skill clone { get; private set; }
    public Sword_Skill sword { get; private set; }
    public Blackhole_Skill blackhole { get; private set; }
    public Crystal_Skill crystal { get; private set; }
    public Parry_Skill parry { get; private set; }
    private void Awake()
    {
        if (instance != null)
        {
           // Destroy(instance.gameObject);
        }
        else
            instance = this;
    }
    private void Start()
    {
        dash = GetComponent<Dash_Skill>();
        clone = GetComponent<Clone_Skill>();
        sword = GetComponent<Sword_Skill>();
        blackhole = GetComponent<Blackhole_Skill>();
        crystal = GetComponent<Crystal_Skill>();
        parry = GetComponent<Parry_Skill>();
    }
}
PlayerGroundState.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//GroundState用于保证只有在Idle和Move这两个地面状态下才能调用某些函数,并且稍微减少一点代码量
public class PlayerGroundState : PlayerState
{
    public PlayerGroundState(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())//点击右键进入瞄准状态,当sword存在时,不能进入aim状态
        {
            stateMachine.ChangeState(player.aimSword);
        }
        if(Input.GetKeyDown(KeyCode.Q) && player.skill.parry.parryUnlocked)//摁Q进入反击状态
        {
            stateMachine.ChangeState(player.counterAttack);
        }
        if(Input.GetKeyDown(KeyCode.Mouse0))//p38 2.从ground进入攻击状态
        {
            stateMachine.ChangeState(player.primaryAttack);
        }
        if(player.IsGroundDetected()==false)
        {
            stateMachine.ChangeState(player.airState);
        }// 写这个是为了防止在空中直接切换为moveState了。

        if (Input.GetKeyDown(KeyCode.Space) && player.IsGroundDetected())
        {
            stateMachine.ChangeState(player.jumpState);
        }//空格切换为跳跃状态


    }
    private bool HasNoSword()//用这个函数同时控制了是否能进入aimSword和如果sword存在便使他回归player的功能
    {
        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;
//从Ground里摁Q进入
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;//设置Counter在没有成功的情况下可以保持的时间
        player.anim.SetBool("SuccessfulCounterAttack", false);//默认失败
    }

    public override void Exit()
    {
        base.Exit();
    }

    public override void Update()
    {
        base.Update();
        player.SetZeroVelocity();// 修复在Counter时还能移动的问题

        Collider2D[] colliders = Physics2D.OverlapCircleAll(player.attackCheck.position, player.attackCheckRadius);//创建一个碰撞器组,保存所有圈所碰到的碰撞器
        //https://docs.unity3d.com/2022.3/Documentation/ScriptReference/Physics2D.OverlapCircleAll.html
        foreach (var hit in colliders)//https://blog.csdn.net/m0_52358030/article/details/121722077
        {
            if (hit.GetComponent<Enemy>() != null)
            {
                if(hit.GetComponent<Enemy>().CanBeStunned())
                {
                    stateTimer = 10;//只要比1大就行,防止成功反击的动画还没完就进入idleState了
                    player.anim.SetBool("SuccessfulCounterAttack", true);//使进入成功反击动画

                    player.skill.parry.UseSkill();//设置反击回血

                    if (canCreateClone)
                    {
                        canCreateClone = false;//每次反击只产生一个clone
                        
                        player.skill.parry.MakeMirageOnParry(hit.transform);
                    }
                    
                }
            }
        }

        if(stateTimer<0||triggerCalled)//当反击动画结束或反击可以持续的时间结束后回到idleState
        {
            stateMachine.ChangeState(player.idleState);
        }
    }
}

  • 10
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值