Unity类银河恶魔城学习记录10-11 p99 Aliment visual effects源代码

news2024/12/22 22:36:01

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

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

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

public class EntityFX : MonoBehaviour
{
    private SpriteRenderer sr;//定义SR组件来保持要用的组件
    [Header("Flash FX")]
    [SerializeField] private Material hitMat;//要改成的材料
    [SerializeField] private float flashDuration;//闪光的时间
    private Material originalMat;//原来的材料

    [Header("Aliment colors")]
    [SerializeField] private Color[] chillColor;
    [SerializeField] private Color[] igniteColor;
    [SerializeField] private Color[] shockColor;

    private void Start()
    {
        sr = GetComponentInChildren<SpriteRenderer>();//从子组件中拿到SR组件


        originalMat = sr.material;//拿到原来的材料

    }
    private IEnumerator FlashFX()//被打后该触发的函数
    {
        sr.material = hitMat;

        //修复在元素效果期间击中,颜色变红的情况
        Color currentColor = sr.color;
        sr.color = Color.white;


        yield return new WaitForSeconds(flashDuration);

        sr.color = currentColor;
        sr.material = originalMat;
    } //IEnumertor本质就是将一个函数分块执行,只有满足某些条件才能执行下一段代码,此函数有StartCoroutine调用
    //https://www.zhihu.com/tardis/bd/art/504607545?source_id=1001
    private void RedColorBlink()//使角色闪烁的函数
    {
        if (sr.color != Color.white)
        {
            sr.color = Color.white;
        }
        else
        {
            sr.color = Color.red;
        }
    }
    private void CancelColorChange()//使角色停止闪烁的函数
    {
        CancelInvoke();//取消该 MonoBehaviour 上的所有 Invoke 调用。
        //https://docs.unity3d.com/cn/current/ScriptReference/MonoBehaviour.CancelInvoke.html
        sr.color = Color.white;
    }

    public void ShockFxFor(float _second)
    {
        InvokeRepeating("ShockColorFx", 0, .3f);
        Invoke("CancelColorChange", _second);
    }

    public void ChillFxFor(float _second)
    {
        InvokeRepeating("ChillColor", 0, .3f);
        Invoke("CancelColorChange", _second);
    }



    public void IgniteFxFor(float _second)
    {
        InvokeRepeating("IgniteColorFX", 0, .3f);
        Invoke("CancelColorChange", _second);
    }

    private void IgniteColorFX()
    {
        if (sr.color != igniteColor[0])
            sr.color = igniteColor[0];
        else
            sr.color = igniteColor[1];
    }

    private void ShockColorFx()
    {
        if (sr.color != shockColor[0])
            sr.color = shockColor[0];
        else
            sr.color = shockColor[1];
    }

    private void ChillColor()
    {
        if (sr.color != chillColor[0])
            sr.color = chillColor[0];
        else
            sr.color = chillColor[1];
    }

   
}
CharacterStats.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CharacterStats : MonoBehaviour
{
    private EntityFX fx;


    [Header("Major stats")]
    public Stat strength; // 力量 增伤1点 爆伤增加 1% 物抗
    public Stat agility;// 敏捷 闪避 1% 闪避几率增加 1%
    public Stat intelligence;// 1 点 魔法伤害 1点魔抗 
    public Stat vitality;//加血的

    [Header("Offensive stats")]
    public Stat damage;
    public Stat critChance;      // 暴击率
    public Stat critPower;       //150% 爆伤

    [Header("Defensive stats")]
    public Stat maxHealth;
    public Stat armor;
    public Stat evasion;//闪避值
    public Stat magicResistance;

    [Header("Magic stats")]
    public Stat fireDamage;
    public Stat iceDamage;
    public Stat lightingDamage;


    public bool isIgnited;  // 持续烧伤
    public bool isChilded;  // 削弱护甲 20%
    public bool isShocked;  // 降低敌人命中率

    [SerializeField] private float ailmentsDuration = 4;
    private float ignitedTimer;
    private float chilledTimer;
    private float shockedTimer;


    private float igniteDamageCooldown = .3f;
    private float ignitedDamageTimer;
    private int igniteDamage;

    public System.Action onHealthChanged;//使角色在Stat里调用UI层的函数

    [SerializeField] public int currentHealth;


    protected virtual void Start()
    {
        critPower.SetDefaultValue(150);//设置默认爆伤
        currentHealth = GetMaxHealthValue();

        fx = GetComponent<EntityFX>();
    }

    protected virtual void Update()
    {
        //所有的状态都设置上默认持续时间,持续过了就结束状态
        ignitedTimer -= Time.deltaTime;
        chilledTimer -= Time.deltaTime;
        shockedTimer -= Time.deltaTime;
        ignitedDamageTimer -= Time.deltaTime;

        if (ignitedTimer < 0)
            isIgnited = false;
        if (chilledTimer < 0)
            isChilded = false;
        if (shockedTimer < 0)
            isShocked = false;

        //被点燃后,出现多段伤害后点燃停止
        if (ignitedDamageTimer < 0 && isIgnited)
        {
            Debug.Log("Take Burning Damage" + igniteDamage);
            DecreaseHealthBy(igniteDamage);
            if (currentHealth < 0)
                Die();
            ignitedDamageTimer = igniteDamageCooldown;
        }
    }

    public virtual void DoDamage(CharacterStats _targetStats)//计算后造成伤害函数
    {
        if (TargetCanAvoidAttack(_targetStats))设置闪避
        {
            return;
        }



        int totleDamage = damage.GetValue() + strength.GetValue();

        //爆伤设置
        if (CanCrit())
        {
            totleDamage = CalculateCriticalDamage(totleDamage);
        }

        totleDamage = CheckTargetArmor(_targetStats, totleDamage);//设置防御

        //_targetStats.TakeDamage(totleDamage);
        DoMagicaDamage(_targetStats);
    }

    public virtual void DoMagicaDamage(CharacterStats _targetStats)//法伤计算
    {
        int _fireDamage = fireDamage.GetValue();
        int _iceDamage = iceDamage.GetValue();
        int _lightingDamage = lightingDamage.GetValue();

        int totleMagicalDamage = _fireDamage + _iceDamage + _lightingDamage + intelligence.GetValue();
        totleMagicalDamage = CheckTargetResistance(_targetStats, totleMagicalDamage);

        _targetStats.TakeDamage(totleMagicalDamage);

        //让元素效果取决与伤害
        bool canApplyIgnite = _fireDamage > _iceDamage && _fireDamage > _lightingDamage;
        bool canApplyChill = _iceDamage > _lightingDamage && _iceDamage > _fireDamage;
        bool canApplyShock = _lightingDamage > _fireDamage && _lightingDamage > _iceDamage;

        //防止循环在所有元素伤害为0时出现死循环
        if (Mathf.Max(_fireDamage, _iceDamage, _lightingDamage) <= 0)
            return;

        //为了防止出现元素伤害一致而导致无法触发元素效果
        //循环判断触发某个元素效果
        while (!canApplyIgnite && !canApplyChill && !canApplyShock)
        {
            if (Random.value < .25f)
            {
                canApplyIgnite = true;
                Debug.Log("Ignited");
                _targetStats.ApplyAilments(canApplyIgnite, canApplyChill, canApplyShock);
                return;
            }
            if (Random.value < .35f)
            {
                canApplyChill = true;
                Debug.Log("Chilled");
                _targetStats.ApplyAilments(canApplyIgnite, canApplyChill, canApplyShock);
                return;
            }
            if (Random.value < .55f)
            {
                canApplyShock = true;
                Debug.Log("Shocked");
                _targetStats.ApplyAilments(canApplyIgnite, canApplyChill, canApplyShock);
                return;
            }

        }

        //给点燃伤害赋值
        if (canApplyIgnite)
        {
            _targetStats.SetupIgniteDamage(Mathf.RoundToInt(_fireDamage * .2f));
        }

        _targetStats.ApplyAilments(canApplyIgnite, canApplyChill, canApplyShock);
    }

    private static int CheckTargetResistance(CharacterStats _targetStats, int totleMagicalDamage)//法抗计算
    {
        totleMagicalDamage -= _targetStats.magicResistance.GetValue() + (_targetStats.intelligence.GetValue() * 3);
        totleMagicalDamage = Mathf.Clamp(totleMagicalDamage, 0, int.MaxValue);
        return totleMagicalDamage;
    }

    public void ApplyAilments(bool _ignite, bool _chill, bool _shock)//判断异常状态
    {
        if (isIgnited || isChilded || isShocked)
        {
            return;
        }

        if (_ignite)
        {
            isIgnited = _ignite;
            ignitedTimer = ailmentsDuration;

            fx.IgniteFxFor(ailmentsDuration);
        }
        if (_chill)
        {
            isChilded = _chill;
            chilledTimer = ailmentsDuration;

            fx.ChillFxFor(ailmentsDuration);
        }
        if (_shock)
        {
            isShocked = _shock;
            shockedTimer = ailmentsDuration;

            fx.ShockFxFor(ailmentsDuration);
        }
    }
    public void SetupIgniteDamage(int _damage) => igniteDamage = _damage;//给点燃伤害赋值

    protected virtual void TakeDamage(int _damage)//造成伤害是出特效
    {
        DecreaseHealthBy(_damage);


        if (currentHealth < 0)
            Die();

    }
    protected virtual void DecreaseHealthBy(int _damage)//此函数用来改变当前声明值,不调用特效
    {
        currentHealth -= _damage;

        if(onHealthChanged != null)
        {
            onHealthChanged();
        }
    }
    protected virtual void Die()
    {

    }
    private static int CheckTargetArmor(CharacterStats _targetStats, int totleDamage)//设置防御
    {

        //被冰冻后,角色护甲减少
        if (_targetStats.isChilded)
            totleDamage -= Mathf.RoundToInt(_targetStats.armor.GetValue() * .8f);
        else
            totleDamage -= _targetStats.armor.GetValue();
        totleDamage = Mathf.Clamp(totleDamage, 0, int.MaxValue);
        return totleDamage;
    }

    private bool TargetCanAvoidAttack(CharacterStats _targetStats)//设置闪避
    {
        int totleEvation = _targetStats.evasion.GetValue() + _targetStats.agility.GetValue();

        //我被麻痹后
        //敌人的闪避率提升
        if (isShocked)
            totleEvation += 20;

        if (Random.Range(0, 100) < totleEvation)
        {
            return true;
        }
        return false;
    }

    private bool CanCrit()//判断是否暴击
    {
        int totleCriticalChance = critChance.GetValue() + agility.GetValue();

        if (Random.Range(0, 100) <= totleCriticalChance)
        {
            return true;
        }

        return false;
    }

    private int CalculateCriticalDamage(int _damage)//计算暴击后伤害
    {
        float totleCirticalPower = (critPower.GetValue() + strength.GetValue()) * .01f;

        float critDamage = _damage * totleCirticalPower;

        return Mathf.RoundToInt(critDamage);//返回舍入为最近整数的
    }
    public int GetMaxHealthValue()
    {

        return maxHealth.GetValue() + vitality.GetValue() * 10;

    }//统计生命值函数
}

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

public class SkeletonStunnedState : EnemyState
{
    private Enemy_Skeleton enemy;
    public SkeletonStunnedState(Enemy _enemyBase, EnemyStateMachine _stateMachine, string _animBoolName,Enemy_Skeleton _enemy) : base(_enemyBase, _stateMachine, _animBoolName)
    {
        enemy = _enemy;
    }

    public override void Enter()
    {
        base.Enter();
        enemy.fx.InvokeRepeating("RedColorBlink", 0, .1f);//在 time 秒后调用 methodName 方法,然后每 repeatRate 秒调用一次。
                                                          //https://docs.unity3d.com/cn/current/ScriptReference/MonoBehaviour.InvokeRepeating.html
        stateTimer = enemy.stunnedDuration;//stunned持续时间
        rb.velocity = new Vector2(-enemy.facingDir*enemy.stunnedDirection.x, enemy.stunnedDirection.y);//stunned改变后的速度,由于SetVelocity有FlipCheck,所有这个用rb.velocity设置速度

    }

    public override void Exit()
    {
        base.Exit();
        enemy.fx.Invoke("CancelColorChange",0); //在 time 秒后调用 methodName 方法。
        //https://docs.unity3d.com/cn/current/ScriptReference/MonoBehaviour.Invoke.html
    }

    public override void Update()
    {
        base.Update();
        if(stateTimer < 0)
        {
            stateMachine.ChangeState(enemy.idleState);
        }
    }
}

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

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

相关文章

Mysql事务+锁测试 RR行锁升级

Mysql事务锁测试 Mysql5.7 在隔离级别RR下&#xff0c;添加写锁&#xff0c;锁住一行数据&#xff0c;写锁是排它锁&#xff0c;不允许其它的读写、 另外开启一个连接&#xff0c;进行写操作&#xff0c;发现执行没有成功&#xff0c;在等待锁 查询事务表&#xff0c;有两个事…

openssl3.2 - note - Decoders and Encoders with OpenSSL

文章目录 openssl3.2 - note - Decoders and Encoders with OpenSSL概述笔记编码器/解码器的调用链OSSL_STORE 编码器/解码器的名称和属性OSSL_FUNC_decoder_freectx_fnOSSL_FUNC_encoder_encode_fn官方文档END openssl3.2 - note - Decoders and Encoders with OpenSSL 概述 …

大数据Doris(六十八):基于Doris on ES的架构实现总结

文章目录 基于Doris on ES的架构实现总结 一、Mem Join架构遗留的核心问题 二、Doris

河南大学大数据平台技术实验报告二

大数据平台技术课程实验报告 实验二&#xff1a;HDFS操作实践 姓名&#xff1a;杨馥瑞 学号&#xff1a;2212080042 专业&#xff1a;数据科学与大数据技术 年级&#xff1a;2022级 主讲教师&#xff1a;林英豪 实验时间&#xff1a;2024年3月15日3点 至 2024年3月15日4点40 …

力扣经典题:分割平衡字符串

大佬的代码非常简洁 int balancedStringSplit(char * s){short i0,count0,sign0;while(s[i]){signs[i]L?sign1:sign-1;if(sign0) count;}return count; }

安装gpu-torch(已经成功)

### &#xff01;&#xff01;&#xff01;直接使用pip安装&#xff0c;不要使用conda安装&#xff0c;使用conda安装总是会安装成CPU版本。 1.第一次尝试 之前按照官网安装pytorch的命令进行安装&#xff0c;结果安装出来是cpu版本的&#xff0c;试过https://blog.csdn.net/…

【日常记录】【CSS】css下划线动画

文章目录 1、效果2、思路3、代码 1、效果 2、思路 整体可以用 背景来做线&#xff1a;可以用 渐变 配合 background-size 、 background-position 、background-repeat正向动画&#xff1a;可以不断追加 background-size x 轴的大小来控制&#xff0c;当鼠标移入的时候&#x…

【应急响应靶场web2】

文章目录 前言 一、应急响应 1、背景 2、webshell查杀 3、日志排查 1&#xff09;apache日志 2&#xff09;nginx日志 3&#xff09;ftp日志 4、隐藏账户 5、文件筛选 二、漏洞复现 总结 前言 靶场来源&#xff1a;知攻善防实验室 一、应急响应 1、背景 小李在某…

【算法训练营】周测1

清华大学驭风计划课程链接 学堂在线 - 精品在线课程学习平台 (xuetangx.com) 如果需要答案代码可以私聊博主 有任何疑问或者问题&#xff0c;也欢迎私信博主&#xff0c;大家可以相互讨论交流哟~~ 考题11-1 题目描述 有一个初始时为空的序列&#xff0c;你的任务是维护这个…

SpringBoot(异常处理)

SpringBoot&#xff08;异常处理&#xff09; 1.基本介绍 2.debug异常处理机制 1.找到 DefaultErrorViewResolver 2.下断点 3.debug启动&#xff0c;浏览器输出一个不存在的页面 4.第一次查找 error/404 1.查看目前要找的视图名 2.准备去查找资源 3.准备从四个默认存放静态资…

使用 FastAPI APIRouter 构建高效的 API

FastAPI 是一个现代的、高性能的 Python Web 框架&#xff0c;它提供了 APIRouter 来帮助组织和管理路由。APIRouter 是一个可用于组织和分组路由的类&#xff0c;使得代码结构更加清晰和可维护。本文将介绍 FastAPI APIRouter 的用法&#xff0c;包括实践案例以及在 IDE 编辑器…

【商业|数据科学主题会议推荐】2024年商业分析与数据科学国际学术会议(ICBADS 2024)

【商业|数据科学主题会议推荐】2024年商业分析与数据科学国际学术会议&#xff08;ICBADS 2024) 征稿主题 &#xff08;以下主题包括但不限于&#xff09; 多媒体决策 决策理论与决策科学 数字市场设计与运营 降维 电子商务 道德决策 财务分析 群体决策与软件 医疗保…

podman proxy 【podman 代理】

文章目录 方法1: 为当前用户设置环境变量方法2&#xff1a;为 Podman 服务设置配置文件方法3: 为单个 Podman 命令设置代理方法四: 配置 http-proxy.conf 方法1: 为当前用户设置环境变量 您可以为当前用户设置 HTTP_PROXY 和 HTTPS_PROXY 环境变量,Podman 将自动读取这些环境变…

C语言从入门到熟悉------第四阶段

指针 地址和指针的概念 要明白什么是指针&#xff0c;必须先要弄清楚数据在内存中是如何存储的&#xff0c;又是如何被读取的。如果在程序中定义了一个变量&#xff0c;在对程序进行编译时&#xff0c;系统就会为这个变量分配内存单元。编译系统根据程序中定义的变量类型分配…

【项目笔记】java微服务:黑马头条(day04)

文章目录 自媒体文章-自动审核1)自媒体文章自动审核流程2)内容安全第三方接口2.1)概述2.2)准备工作2.3)文本内容审核接口2.4)图片审核接口2.5)项目集成 3)app端文章保存接口3.1)表结构说明3.2)分布式id3.3)思路分析3.4)feign接口 4)自媒体文章自动审核功能实现4.1)表结构说明4.…

linux ffmpeg编译

下载源码 https://ffmpeg.org/ csdn下载源码包 不想编译可以直接下载使用静态版本 https://ffmpeg.org/download.html https://johnvansickle.com/ffmpeg/ 根据cpu类型&#xff0c;下载解压后就可以直接使用了。 linux编译 安装底层依赖 yum install gcc yum isntall …

mysql用存储过程更新表

打开workbench,点击下面的按钮 编写存储过程 CREATE DEFINERrootlocalhost PROCEDURE new_procedure10(IN myId int,IN myTitle varchar(20),IN myContent varchar(20)) BEGIN if myTitle is NULL then select title into myTitle from blog where idmyId; end if; if myC…

学习通刷视频刷题脚本及安装使用过程

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、安装插件二、复制脚本文件链接三、启动脚本四、登录学习通&#xff08;切记一倍速就行不然被封哦&#xff09;五、最好先把答题关掉先刷视频 前言 解决学习…

C++中的多值返回:解锁函数返回值的神奇力量

C中的多值返回&#xff1a;解锁函数返回值的神奇力量 在C编程中&#xff0c;有时候我们需要从函数中返回多个值。虽然C中的函数通常只能返回一个值&#xff0c;但有几种技术和惯用法可以实现返回多个值的效果。本文将介绍C中实现多值返回的几种常用方法&#xff0c;包括引用、指…

JavaWeb(p116-p134)

#驱动类名称 spring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver #数据库连接的ur1 spring.datasource.urljdbc:mysql://localhost:3306/mybatis #连接数据库的用户名 spring.datasource.usernameroot #连接数据库的密码 spring.datasource.password**********2.1 数…