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

news2024/11/26 0:53:30

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);
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1604539.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python多态

1.多态 多态定义&#xff1a;多态&#xff08;polymorphism&#xff09;是指同一个方法调用由于对象不同可能会产生不同的行为 注意以下2点&#xff1a; 1.多态是方法的多态&#xff0c;属性没有多态。 2.多态的存在有2个必要条件&#xff1a;继承、方法重写 class Animal:de…

LearnOpenGl练习题-着色器

LearnOpenGl练习题-着色器 题目地址&#xff1a;着色器 - LearnOpenGL CN 题目一&#xff1a;修改顶点着色器让三角形上下颠倒&#xff1a; #version 330 core layout (location 0) in vec3 aPos; layout (location 1) in vec3 aColor; out vec3 ourColor; void main() {gl…

openEuler 22.03 LTS SP3源码编译部署OpenStack-Bobcat(Neutron使用OVN)

openEuler 22.03 LTS SP3部署OpenStack-Bobcat 说明机器详情安装操作系统注意事项基础准备Controller节点 && Compute节点 && Block节点关闭防火墙关闭selinux设置静态IP更新安装前准备Controller节点 && Compute节点 && Block节点设置主机名配…

简单认识Git(dirsearch、githack下载),git泄露(ctfhub)

目录 dirsearch下载地址: githack下载&#xff08;一次不成功可多试几次&#xff09; 一、什么是Git 1.git结构 2.git常用命令及示例 3.Git泄露原理 二、Git泄露 1.Log 2.Stash 3.Index 工具准备&#xff1a;dirsearch、githack dirsearch下载地址: GitHub - mauroso…

配置流策略实现不同网段间限制互访

在创建了 vlanif 接口并配置 IP 地址后,不同 vlan 间就可以互通了。 如果我们想要限制vlan 之间的通信,就可以通过配置流策略实现。 配置步骤(以华为交换机为例) 1、ACL 定义拒绝通过的数据流 2、定义流分类,按照ACL 对报文进行分类 3、配置流行为,动作为deny 4、配置流…

计算机不联网是否有IP地址

计算机不联网是否会有IP地址&#xff0c;这个问题涉及到计算机网络的基础知识。要深入探讨这个问题&#xff0c;我们需要从IP地址的定义、作用&#xff0c;以及计算机在不联网状态下的网络配置等多个方面进行分析。 首先&#xff0c;IP地址&#xff08;Internet Protocol Addre…

深度学习——常用激活函数解析与对比

1、 简介 在神经网络中&#xff0c;激活函数扮演着至关重要的角色。它们的主要目的是引入非线性因素&#xff0c;使得网络能够学习和表示更加复杂的函数映射。以下是激活函数应具备的特点&#xff0c;以及这些特点为何重要的详细解释&#xff1a; 引入非线性有助于优化网络&am…

求奖金(if)(C语言)

一、N-S流程图&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>int main() {//初始化变量值&#xff1b;int I 0;float bonus 0;//提示用户&#xff1b;printf("请输入利润I&#xff1a;");//获取用户值&#xf…

怎么给一个字典进行按值或key来排序?

字典是具有指定数字或键的特定数据集或组。在 Python 以外的编程语言中&#xff0c;它们也被称为哈希映射或关联数组。 一般来说&#xff0c;它是键值对的形式&#xff0c;就像现实世界的字典一样。 要创建字典&#xff0c;请从左括号开始&#xff0c;添加键并键入一个冒号。…

SpringBoot 项目Docker部署三种方式

一种&#xff1a;直接拷贝jar到服务器部署 1.增加docker配置文件 新建Dockerfile文件&#xff0c;负责Docker的配置 FROM openjdk:21#ENV timezone RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \&& echo Asia/Shanghai >/etc/timezone# WORKD…

[2021最新]Java时间戳和日期时间互转换

代码&#xff1a; import java.text.ParseException; import java.text.SimpleDateFormat;public class MainProcess {public static void main(String[] args) throws ParseException {// 1.set formatSimpleDateFormat timeSmat new SimpleDateFormat("yyyy-MM-dd HH:…

【Jupyter Notebook】快捷键

在命令模式下&#xff0c;单元格边框是灰色&#xff08;缺省&#xff09;的。这些快捷键主要用于操作单元格。 Enter&#xff1a;进入编辑模式Shift Enter&#xff1a;运行当前单元格并选中下一个单元格Ctrl Enter&#xff1a;运行当前单元格Alt Enter&#xff1a;运行当前单…

高效生产管理:选择顺通网络ERP系统派单的理由

显然&#xff0c;传统的生产管理模式已经难以满足现代企业的需求&#xff0c;因此选择一款适合自身业务特点的生产管理软件成为了企业的当务之急。顺通鞋业ERP系统作为一款功能强大的生产管理软件&#xff0c;凭借其出色的派单功能&#xff0c;正逐渐成为众多企业的首选。通过系…

DBA-现在应该刚刚入门吧

说来话长 在2023年以前&#xff0c;我的DBA生涯都是“孤独的”。成长路径除了毕业前的实习期有人带&#xff0c;后续几乎都是靠自学。如何自学&#xff0c;看视频、看文档、网上查阅资料、项目实战。 可能是学疏才浅 &#xff0c;一直都是在中小公司混&#xff0c;在中小公司通…

MYSQL09_行格式概述、变长字段、NULL值、记录头信息、真实数据、内部结构

文章目录 ①. InnoDB - 行格式概述②. 变长字段长度列表 ③. NULL值列表④. 记录头信息5字节⑤. 记录的真实数据⑥. Compact行记录的内部结构⑦. Dynamic和Compressed行格式 ①. InnoDB - 行格式概述 ①. 我们平时的数据以行为单位来向表中插入数据,这些记录在磁盘上的存放方式…

PostgreSQL的学习心得和知识总结(一百三十八)|深入理解PostgreSQL数据库之Protocol message构造和解析逻辑

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《PostgreSQL数据库内核分析》 2、参考书籍&#xff1a;《数据库事务处理的艺术&#xff1a;事务管理与并发控制》 3、PostgreSQL数据库仓库…

09-ESP32-IDF中的日志系统

ESP32-IDF中的日志系统 在ESP32-IDF中&#xff0c;日志系统是一个重要的组成部分&#xff0c;它可以帮助开发者调试代码和理解系统的运行状态。 1. 日志系统的作用 日志系统在ESP32-IDF中扮演着非常重要的角色。它可以记录系统的运行信息&#xff0c;包括系统启动、运行、错…

OSPF笔记+大实验

OSPF综合大实验---实验报告 配置IP地址 R1&#xff1a; [R1]int g0/0/0 [R1-GigabitEthernet0/0/0]ip add 172.16.33.1 24 [R1-GigabitEthernet0/0/0]int l0 [R1-LoopBack0]ip add 172.168.34.1 24 R2: [R2]int g0/0/0 [R2-GigabitEthernet0/0/0]ip add 172.16.33.2 24…

电脑怎么创建加密磁盘?方法很简单!

在电脑中创建加密磁盘&#xff0c;可以有效地保护电脑数据&#xff0c;避免数据泄露。那么&#xff0c;电脑怎么创建加密磁盘呢&#xff1f;下面我们就一起来了解一下吧。 密盘创建方法 创建密盘建议使用超级秘密磁盘3000&#xff0c;软件界面简约&#xff0c;操作简单&#x…

Linux上比top更直观和美观的监控软件htop

2024年4月18日&#xff0c;周四上午 htop 是一个交互式的系统监控工具&#xff0c;类似于 Linux 系统中的 top 命令&#xff0c;但提供了更加友好的界面和功能。它允许用户以直观的方式查看系统的进程、CPU、内存、交换空间以及各种系统指标的使用情况。 一些 htop 的特点包括…