特效会有个EffectManager用于统一管理所有特效,技能特效只是各类特效中的一种

EffectManager需要提供特效的创建,返回被封装为EffectHandle

每类特效都有各种不同的配置参数,这些配置参数会传递给EffectManager用于生成EffectHandler

为支持实现更复杂的特效表现,EffectManager应当提供接口支持根据需要动态修改配置参数

技能的特效分为三类:随身特效、表现特效、场景特效

随身特效是指跟随角色的特效,例如角色的拖尾、飘带,这些特效通常位于角色身上的某个挂载点

表现特效,指为丰富画面或技能表现而出现的特效,例如技能释放瞬间的闪光特效

场景特效,指创建出来较大的特效,创建完成后会固定在场景内基本不动

注意,这里的特效不动只是相对于挂载目标而言的,其自身可以有不同的运动形式,当挂载点运动,其也会跟着运动

【特效参数】

基础参数

  • 特效名字
  • 特效ID
  • 特效Prefab
  • 特效路径
  • 特效类型

位置参数

  • 挂载目标
    • 随身特效一般为角色自身,通常特效一直跟随角色,会在角色身上的某个点做挂载
    • 表现特效一般为角色周围的某个空间的位置
    • 场景特效一般为角色周围的场景中的某个位置,需要通过技能指向动态计算得到
  • 挂载点
  • 初始位置、偏移位置、初始朝向、初始偏移(在工程实践中,位置通常都不是单个的精确值,通常都是基础+偏移)

存活参数

  • 存活方式
    • 随身特效通常跟随技能,尤其是状态或者限时类技能,也即通常该类特效跟随技能生命周期,即进入技能时,该特效就出现,退出技能时就消失,但不是完全绝对的,可能消失有个FadeOut
    • 表现特效通常是固定时间,时间通常不长
    • 场景特效可以是跟随技能的、固定时间的,还有可能是固定范围的,即距离角色一定范围内有效,超出范围即失效
  • 渐出时间
  • 有效距离

其他各类特效相关参数

【代码实现】

    public class EffectConfigData : ScriptableObject, IData{[FoldoutGroup("基础参数")][LabelText("特效名字")]public string effectName;[FoldoutGroup("基础参数")][LabelText("特效Id"), ReadOnly]public int effectId;//todo:根据名字生成[FoldoutGroup("基础参数")][LabelText("特效Prefab")]public GameObject effectGo;[FoldoutGroup("基础参数")][LabelText("特效路径"), ReadOnly]public string effectPath;[FoldoutGroup("基础参数")][LabelText("特效类型")]public SkillEffectType type;[FoldoutGroup("初始位置参数")][LabelText("挂载目标")]public AttachTarget target;[FoldoutGroup("初始位置参数")][LabelText("挂载点")]public int slotId;[FoldoutGroup("初始位置参数")][LabelText("位置偏移")]public Vector3 offsetPos;[FoldoutGroup("初始位置参数")][LabelText("初始朝向")]public Vector3 foward;[FoldoutGroup("初始位置参数")][LabelText("朝向偏移")]public Vector3 offsetRot;[FoldoutGroup("存活参数")][LabelText("朝向偏移")]public LifeTimeType lifeTimeType;[FoldoutGroup("存活参数")][LabelText("存活时间")]public float liftTime;[FoldoutGroup("存活参数")][LabelText("渐出时间")]public float fadeOutTime;[FoldoutGroup("存活参数")][LabelText("存活距离")]public float liftDistance;public void Dispose(){}//其他特效相关参数}public enum AttachTarget{Self,Round,Scence,}public enum SkillEffectType{Role,Attack,Scene,}public enum LifeTimeType{FollowSkill = 1 << 0,FixedTime = 1 << 1,FixedDistance = 1 << 2,}public class EffectComponent:SkillLogicComponent{private GameObject prefab;private bool hasTick = false;private float curTime;protected override void OnInit(){base.OnInit();configData = EffectConfigDataSystem.Instance.GetOrCreateData(dataId);}protected override void OnStart(){base.OnStart();//根据路径在这里加载Prefab,或者传入路径,交给特效系统做加载调用//(configData as EffectConfigData).effectPath;}protected override void OnExcute(){base.OnExcute();if (prefab != null){prefab.SetActive(true);//调用prefab上的其他脚本var data = configData as EffectConfigData;if ( (data.lifeTimeType & LifeTimeType.FixedTime) != 0){GetOrReleaseTick(true);curTime = 0;}else if((data.lifeTimeType & LifeTimeType.FixedDistance) != 0 ){GetOrReleaseTick(true);}}}protected override void OnEnd(){base.OnEnd();if( ((configData as EffectConfigData).lifeTimeType & LifeTimeType.FollowSkill) != 0){DeActiceEffect();}}public override void OnDestroy() { base.OnDestroy();}private void DeActiceEffect(){GetOrReleaseTick(false);if (prefab != null){prefab.SetActive(false);//调用prefab上的其他脚本//也可以销毁}}private void GetOrReleaseTick(bool register){if(register){if(!hasTick){ComponentTick.RegisterComTick(instanceId, this, OnTick);hasTick = true;}}else{if(hasTick){ComponentTick.UnRegisterComTick(instanceId);}}}private void OnTick(float deltaTime){var data = configData as EffectConfigData;if ((data.lifeTimeType & LifeTimeType.FixedTime) != 0){curTime += deltaTime;if(curTime >= data.liftTime){DeActiceEffect();}}else if ((data.lifeTimeType & LifeTimeType.FixedDistance) != 0){//获取特效和角色的距离//var dis = (prefab.transform.position - playerPos).magnitude;var dis = 10;if(dis > data.liftDistance){DeActiceEffect();}}}}public class EffectConfigDataSystem:DataSystem<EffectConfigDataSystem, EffectConfigData>{public override string dataPath => "Assets/ConfigData/SkillEffectConfigData.asset";}public class ComponentTick//不通过层层调用做Tick,将需要Tick的Component做统一管理,可以扩展为通过优先级做先后Tick的调度{public static Dictionary<long, TickInfo> Id2Com = new Dictionary<long, TickInfo>();public struct TickInfo{public long Id;public Component com;public Action<float> cb;}public static void Tick(float deltaTime){foreach (var item in Id2Com.Values){if(item.com.Enable){item.cb?.Invoke(deltaTime);}}}public static void RegisterComTick(long instanceId,Component com,Action<float> cb){if(!Id2Com.TryGetValue(instanceId, out var info)){info = new TickInfo(){Id = instanceId,com = com,cb = cb,};Id2Com.Add(instanceId, info);}else{Debug.Log($"重复注册:{instanceId}");}}public static void UnRegisterComTick(long instanceId){if(Id2Com.TryGetValue(instanceId,out var info)){Id2Com.Remove(instanceId);}}}

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

12.OpenCV—基础入门

01读取图像 02创建空白图像 03保存图像 04更改图像亮度 05更改图像对比度 06灰度直方图均衡 07彩色直方图均衡 08五种滤波方式 09形态学操作 10仿射变换 11角度缩放仿射变换 12透视变换 13坐标映射 14模板匹配 15多模板匹配 16查找轮廓线 17轮廓线匹配 17绘制…

【Python】Python之什么是生成器?什么是迭代器?

目录 专栏导读前言什么是迭代器&#xff08;Iterator&#xff09;&#xff1f;迭代器的定义迭代器协议可迭代对象 vs 迭代器自定义迭代器迭代器的优势 什么是生成器&#xff08;Generator&#xff09;&#xff1f;生成器的定义生成器函数生成器表达式复杂的生成器示例生成器的状…

Python中实现简单爬虫并处理数据

在当今数据驱动的时代&#xff0c;能够从互联网上高效地抓取信息变得越来越重要。Python因其简洁易学的特性&#xff0c;成为了编写网络爬虫的首选语言之一。接下来&#xff0c;我将介绍如何使用Python来实现一个基础的网络爬虫&#xff0c;并对收集到的数据进行初步处理。 首先…

免费wordpress主题网

免费WordPress主题网 WP模板牛 WP模板牛是一个提供免费WordPress主题的网站&#xff0c;用户可以在这里找到大量高质量的模板&#xff0c;适用于各种网站类型。该网站致力于为用户提供简单、高效的建站体验。 官网链接&#xff1a; https://wpniu.com 建站哥模板 建站哥模板…

为什么需要MyBatis-Plus条件构造器?

目录 前言 一、传统SQL编写的痛点 二、条件构造器的核心优势 1. 防SQL注入&#xff08;安全性&#xff09; 2. 面向对象编程&#xff08;可读性&#xff09; 3. 动态条件构建&#xff08;灵活性&#xff09; 4. 数据库无关性&#xff08;可移植性&#xff09; 三、典型应…

【从零学习JVM|第九篇】常见的垃圾回收算法和垃圾回收器

前言&#xff1a; 我们知道在堆内存中&#xff0c;会有自动的垃圾回收功能&#xff0c;那今天这篇文章将会向你介绍&#xff0c;这个功能实现的方式&#xff0c;还有实现的对象&#xff0c;接下来就由我来给你们详细介绍垃圾回收的算法和实现算法的回收器。 目录 前言&#…

品牌窜货治理解决方案

在渠道网络的暗潮中&#xff0c;窜货犹如隐秘的漩涡&#xff0c;某知名白酒品牌曾因区域窜货导致终端价格体系崩溃&#xff0c;半年内损失超3亿元。窜货行为不仅破坏市场秩序&#xff0c;更会引发信任危机。随着电商平台的多元化与分销层级的复杂化&#xff0c;品牌方亟需构建一…

车载电子电器架构 --- 法律和标准对电子电气架构的影响

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…

一种通用跨平台实现SEH的解决方案

一. 前言 众所周知&#xff0c;在软件的代码中&#xff0c;处理软件本身的逻辑只要大约1/3的代码&#xff0c;另外2/3的代码实际上是在处理各种各样的异常情况。 这些异常情况一方面是因为不同用户之间不同的硬件软件环境要处理。另一方面是程序中可能出现的bug。比较典型的情…

25.6.19学习总结

什么是堆&#xff08;Heap&#xff09;&#xff1f; 堆是一种特殊的树形数据结构&#xff0c;它满足以下两个主要属性&#xff1a; 结构性&#xff08;完全二叉树&#xff09;&#xff1a; 堆总是一个完全二叉树 (Complete Binary Tree)。这意味着&#xff0c;除了最后一层&am…

【前后前】导入Excel文件闭环模型:Vue3前端上传Excel文件,【Java后端接收、解析、返回数据】,Vue3前端接收展示数据

【前后前】导入Excel文件闭环模型&#xff1a;Vue3前端上传Excel文件&#xff0c;【Java后端接收、解析、返回数据】&#xff0c;Vue3前端接收展示数据 一、Vue3前端上传&#xff08;导入&#xff09;Excel文件 ReagentInDialog.vue <script setup lang"ts" na…

网络基础入门:从OSI模型到TCP/IP协议详解

网络基础入门&#xff1a;从OSI模型到TCP/IP协议详解 一、网络基础概念与OSI七层模型 1.1 网络通信的本质 计算机网络的核心是将抽象语言转换为二进制数据进行传输与计算&#xff0c;这一过程涉及多层抽象与转换&#xff1a; 应用层&#xff1a;人机交互—抽象语言------编…

Linux致命漏洞CVE-2025-6018和CVE-2025-6019

Qualys 最近披露了两个影响主流 Linux 发行版的本地权限提升 (LPE) 漏洞&#xff0c;分别是 CVE-2025-6018 和 CVE-2025-6019。这两个漏洞可以被串联利用&#xff0c;使得非特权用户在几秒钟内获得系统的 root 权限&#xff0c;从而实现对系统的完全控制。 一、漏洞详情 这两…

【Docker基础】Docker镜像管理:docker push详解

目录 引言 1 Docker镜像推送基础概念 1.1 什么是Docker镜像推送 1.2 镜像仓库概述 1.3 镜像标签与版本控制 2 docker push命令详解 2.1 基本语法 2.2 常用参数选项 2.3 实际命令示例 2.4 推送流程 2.5 步骤描述 3 镜像推送实践示例 3.1 登录管理 3.2 标签管理 3…

FPGA基础 -- Verilog行为建模之循环语句

行为级建模&#xff08;Behavioral Modeling&#xff09;是 Verilog HDL 中最接近软件编程语言的一种描述方式&#xff0c;适用于功能建模和仿真建模的初期阶段。在行为级中&#xff0c;循环语句&#xff08;loop statements&#xff09;是常见且重要的控制结构&#xff0c;用于…

从C学C++(7)——static成员

从C学C(7)——static成员 若无特殊说明&#xff0c;本博客所执行的C标准均为C11. static成员和成员函数 对于特定类型的全体对象而言&#xff0c;有时候可能需要访问一个全局的变量。比如说统计某种类型对象已创建的数量。 通常在C中使用全局变量来实现&#xff0c;如果我们…

大模型和ollama一起打包到一个docker镜像中

如何将大模型镜像和 Ollama 镜像打包在一个 Docker 镜像中 最近工作中有个需求是将ollama和大模型一起打成一个镜像部署&#xff0c;将自己的操作步骤分享给大家。将大模型与 Ollama 服务打包在同一个 Docker 镜像中&#xff0c;可以简化部署流程并确保环境一致性。下面详细介…

2025年渗透测试面试题总结-攻防研究员(应用安全)(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 攻防研究员(应用安全) 一、基础部分 1. HTTP状态码对比 2. HTTP请求方法核心作用 3. 网络分层协议速查表…

SpringBoot新闻项目学习day3--后台权限的增删改查以及权限管理分配

新增管理员修改管理员删除管理员登录 新增管理员 1.点击新增按钮打开一个对话框 2.确定新增对话框要显示哪些内容 3.提交 4.后端处理、保存 5.响应前端 vue代码 <template><!-- 新增代码内容是比较多的,建议抽取出来,定义到一个独立的vue文件中在列表组件中导入…

算法导论第二十五章 深度学习的伦理与社会影响

第二十五章 深度学习的伦理与社会影响 技术的光芒不应掩盖伦理的阴影 随着深度学习技术在各领域的广泛应用&#xff0c;其引发的伦理和社会问题日益凸显。本章将深入探讨这些挑战&#xff0c;并提供技术解决方案和最佳实践&#xff0c;引导读者构建负责任的人工智能系统。 25.…