Notifications
Article
Unity教程:利用对象池设计制作Dash冲锋残影效果!
Updated 8 months ago
2.4 K
29
学习对象池的设计模式,并在实战中应用出来!(2D&3D通用哦!)强烈建议收藏

本篇文章中包含超级干货的内容,为了更好的学习,强烈建议您收藏此文章!😜

教程内容:
  • 对象池设计模式介绍
  • 残影效果制作的code代码部分
  • 利用UI小技巧制作技能冷却CD动画

对象池设计模式概念(已残影生成为例):

对象池(Object Pool)但从字面理解就是一池子的物体,在我们需要使用的时候就拿出来一个,然后包装成我想用的样子。用完之后清空放回到池子里。
为什么要有对象池呢?
因为有系统通常会有需要频繁出现然后消失的物体,如果我们频繁使用 Instantiate 和 Destroy 来生成后销毁,那么会占用大量的系统内存,甚至导致系统崩溃。所以我们可以利用对象池的设计模式概念,在游戏的一开始就制作若干个数量的物体,将他们设置 SetActive(false) 当我们需要它们的时候,只要把它们设置成 SetActive(true) 就好了,用完了再次设置为false。以此方法来循环使用,以达到优化系统的作用。
以冲锋残影的案例来说的话,我们只需要制作每一个残影的 Prefab 让它可以获得玩家的坐标位置和 Sprite 图像资源,然后随着时间推移降低不透明度,到达指定时间就返回对象池当中就可以了:

代码部分来了!此代码仅在 Connect 上分享了哦~所以赶紧收藏起来吧~

ShadowPrefab 上面挂在的脚本:
using UnityEngine; public class ShadowSprite : MonoBehaviour { private Transform player; private SpriteRenderer thisSprite; private SpriteRenderer playerSprite; private Color color; [Header("时间控制参数")] public float activeTime;//显示时间 public float activeStart;//开始显示的时间点 [Header("不透明度控制")] private float alpha; public float alphaSet;//初始值 public float alphaMultiplier; private void OnEnable() { player = GameObject.FindGameObjectWithTag("Player").transform; thisSprite = GetComponent<SpriteRenderer>(); playerSprite = player.GetComponent<SpriteRenderer>(); alpha = alphaSet; thisSprite.sprite = playerSprite.sprite; transform.position = player.position; transform.localScale = player.localScale; transform.rotation = player.rotation; activeStart = Time.time; } void Update() { alpha *= alphaMultiplier; color = new Color(0.5f, 0.5f, 1, alpha);//Color(1,1,1,1)代表100%显示各通道颜色,请查看Api手册 thisSprite.color = color; if (Time.time >= activeStart + activeTime) { //返回对象池 ShadowPool.instance.ReturnPool(this.gameObject); } } }
ShadowPool 上面挂在的脚本:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ShadowPool : MonoBehaviour { public static ShadowPool instance; public GameObject shadowPrefab; public int shadowCount; private Queue<GameObject> availableObjects = new Queue<GameObject>(); void Awake() { instance = this; //初始化对象池 FillPool(); } public void FillPool() { for (int i = 0; i < shadowCount; i++) { var newShadow = Instantiate(shadowPrefab); newShadow.transform.SetParent(transform); //取消启用,返回对象池 ReturnPool(newShadow); } } public void ReturnPool(GameObject gameObject) { gameObject.SetActive(false); availableObjects.Enqueue(gameObject); } public GameObject GetFormPool() { if (availableObjects.Count == 0) { FillPool(); } var outShadow = availableObjects.Dequeue(); outShadow.SetActive(true); return outShadow; } }
接下来就是调整 Player 相关控制的脚本了,这里根据之前 2D平台完美手感操作 项目的脚本来修改的。
下载地址:https://github.com/M-Studio-M/2D-Controller
这里只介绍调整的部分:
变量方面添加的内容:
[Header("CD的UI组件")] public Image cdImage; [Header("Dash参数")] public float dashTime;//dash时长 private float dashTimeLeft;//冲锋剩余时间 private float lastDash = -10f;//上一次dash时间点 public float dashCoolDown; public float dashSpeed; public bool isGround, isJump, isDashing;
Update 中获得按键反馈的方法
void Update() { if (Input.GetKeyDown(KeyCode.J)) { if (Time.time >= (lastDash + dashCoolDown)) { //可以执行dash ReadyToDash(); } } }
void ReadyToDash() { isDashing = true; dashTimeLeft = dashTime; lastDash = Time.time; }
最后真正执行冲锋的动作、冲锋的力的方法如下,记得要放在 FixedUpdate 中去执行哦!!!
void Dash() { if (isDashing) { if (dashTimeLeft > 0) { if (rb.velocity.y > 0 && !isGround) { rb.velocity = new Vector2(dashSpeed * horizontalMove, jumpForce);//在空中Dash向上 } rb.velocity = new Vector2(dashSpeed * horizontalMove, rb.velocity.y);//地面Dash dashTimeLeft -= Time.deltaTime; ShadowPool.instance.GetFormPool(); } if (dashTimeLeft <= 0) { isDashing = false; if (!isGround) { //目的为了在空中结束 Dash 的时候可以接一个小跳跃。根据自己需要随意删减调整 rb.velocity = new Vector2(dashSpeed * horizontalMove, jumpForce); } } } }

技能图标冷却CD的动画制作窍门

将遮盖的图片修改颜色,关键是:调整 Image Type Filled (填充),然后我们使用360˚填充方法,最后我们调整 Fill Amount 这个参数的数值就实现了填充效果了!
至于如何让 Fill Amount 的数值从1变成0的过程刚好跟我的CD冷却时间一致?官方手册里搜索 Fill Amount 你会发现惊喜哦!!

你学会了吗?千万别忘记给我点赞和收藏文章哦~如果喜欢看视频讲解,记得来我的B站观看哦~地址如下:

https://www.bilibili.com/video/av83771678
感谢大家的支持!!我是 Michael ~ 加油哦~!
Michael Wang
Trainer - Programmer
18
Comments
XiaoDao
10 days ago
剑仙
麦扣老师,我发现一个bug,当方向左键,跳跃和冲刺同时按下时,冲刺无效了。但是方向右键,跳跃和冲刺同时按下时,冲刺又有效。这是为什么呢?
0
王德兴
7 months ago
学生
已收藏,感谢麦扣哥!
0
花阳
7 months ago
萌新
支持麦扣
0
Michael Wang
8 months ago
Trainer
AGP从教程过来的,感谢分享!!!
感谢支持!谢谢
0
AGP
8 months ago
从教程过来的,感谢分享!!!
0