当前位置:   article > 正文

unity使用对象池实现冲锋留下的残影效果_u3d残影怎么做到的

u3d残影怎么做到的

目录

效果展示

实现思路

残影代码

对象池代码

控制冲刺产生残影

CD冷却图标


效果展示

 

实现思路

对象池,有想要用的物体时可以从池子里取,用完再放回去。
因为在生成残影再销毁,这个过程中创建和销毁都需要耗费大量资源,因此尽量避免这样的浪费资源。

实现残影的思路如下:其实很简单

当人物按下冲刺键时,让此时人物突然加速,在加速的过程中并且每隔X帧就生成一个sprite,这个sprite的图像、位置、旋转角度和当前玩家所处位置一样,这样就相当于一个影分身。

在冲刺的过程中就会留下分身,然后让这些生成的分身在隔一段时间后自动销毁即可。

那使用对象池的思路用图来表示如下:

当需要使用残影时,便从对象池中取出,然后将该物体的位置设定为玩家当前位置,当时间到后自动将该物体放回池中。

在这里插入图片描述

具体代码如下:

残影代码

先写残影预制体的代码,它包含如下功能:

当它被启用时,设定它的位置为玩家的位置,并且过了一段时间后会消失,就是将其返回对象池

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class GhostImage : MonoBehaviour
  5. {
  6. [Header("残影参数")]
  7. SpriteRenderer thisSprite;
  8. SpriteRenderer playerSprite;
  9. GameObject player;
  10. Color spriteColor;
  11. float alpha=1;
  12. float startAlpha;
  13. float alphaMultiplyRation = 0.9f;
  14. [SerializeField] public float activeTime=0.5f;//残影所持续的时间
  15. float startTime;
  16. //事实上,由于其是单例模式,无需用代码去unity中搜寻该物体,就可以直接从该脚本.instance的方式获取该物体
  17. //GhostImagePool poolInstance;
  18. private void OnEnable()
  19. {
  20. player = GameObject.FindGameObjectWithTag("Player");
  21. playerSprite = player.GetComponent<SpriteRenderer>();
  22. thisSprite = GetComponent<SpriteRenderer>();
  23. thisSprite.sprite = playerSprite.sprite;
  24. transform.position = player.transform.position;
  25. transform.rotation = player.transform.rotation;
  26. transform.localScale = player.transform.localScale;
  27. startTime = Time.time;
  28. }
  29. private void Update()
  30. {
  31. ImageDisappear();
  32. }
  33. void ImageDisappear()
  34. {
  35. thisSprite.color = new Color(0.5f, 0.5f, 1f, alpha*alphaMultiplyRation);
  36. if (Time.time > startTime + activeTime)
  37. {
  38. GhostImagePool.instance.ReturnPool(this.gameObject);
  39. }
  40. }
  41. }

该物体被激活后,在该物体的OnEnable函数中会自动设定该物体的位置。时间一到后该物体会自动将自己放回对象池。

对象池代码

 对象池的代码如下:

为了场景中只有一个残影对象池,我们使用单例模式

其包含几个功能,

接收与存储对象的方式通过Queue<GameObject>来存储

1.初始时便生成残影预制体并作为该对象池的子物体

2.某个对象不用时,对象池可以接受该物体。(将该对象加入Queue,并取消激活,即setActive(false)

3.需要使用物体时,便从该对象池中取出物体(通过在Queue中取,并激活,即setActive(true)

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class GhostImagePool : MonoBehaviour
  5. {
  6. public static GhostImagePool instance;
  7. int ghostImageGroupCount = 10;//对象池中的影子不够用时会多生成一组影子,这是一组影子的数量
  8. public GameObject ghostImagePrefab;
  9. void Awake()
  10. {
  11. instance = this;
  12. }
  13. Queue<GameObject> pool=new Queue<GameObject>();
  14. private void Start()
  15. {
  16. FillPool();
  17. }
  18. void Update()
  19. {
  20. }
  21. void FillPool()
  22. {
  23. for(int i = 0; i < ghostImageGroupCount; i++)
  24. {
  25. var ghostImage = Instantiate(ghostImagePrefab, transform);
  26. ReturnPool(ghostImage);
  27. }
  28. }
  29. public void ReturnPool(GameObject ghostImage)
  30. {
  31. pool.Enqueue(ghostImage);
  32. ghostImage.SetActive(false);
  33. }
  34. public GameObject GetGhostImageFromPool()
  35. {
  36. if(pool.Count <= 0)
  37. {
  38. FillPool();
  39. }
  40. GameObject ghostImage= pool.Dequeue();
  41. ghostImage.SetActive(true);
  42. return ghostImage;
  43. }
  44. }

控制冲刺产生残影

然后在playerController中加入以下代码:

注意人物使用技能是有CD的

通过冲刺时来激活对象池中的物体,

  1. #region 冲刺及残影
  2. [Header("残影参数")]
  3. [SerializeField] public float dashContinueTime=0.5f;//冲刺持续时间
  4. [SerializeField] public float dashCD=2f;//冲刺技能的CD
  5. [SerializeField] public float dashSpeed=30;//冲刺的速度
  6. public Image CDImage;
  7. float dashLeftTime;//剩余可以用来冲刺的时间,初始为其赋值后让时间不断减少
  8. float lastDashTime=-10f;//上次冲刺的时间,用于设定cd(初始设定为负值是为了初始时也能调用)
  9. public bool isDashing = false;
  10. void CheckIfCanDash()
  11. {
  12. CDImage.fillAmount -= 1.0f / dashCD * Time.deltaTime;//实现CDImage自动减少的情况
  13. if (Time.time > lastDashTime + dashCD)
  14. {
  15. if (Input.GetKeyDown(KeyCode.LeftShift))
  16. {
  17. isDashing = true;
  18. lastDashTime = Time.time;
  19. dashLeftTime = dashContinueTime;
  20. CDImage.fillAmount = 1;//使用技能时开始计算冷却,将图标设为满填充,当图标减少时代表cd正在减少
  21. }
  22. }
  23. }
  24. void Dashing()
  25. {
  26. if (isDashing)
  27. {
  28. if(transform.localScale.x==-1)
  29. rigidBody.velocity = new Vector2(dashSpeed, rigidBody.velocity.y);
  30. else if (transform.localScale.x == 1)
  31. rigidBody.velocity = new Vector2(-dashSpeed, rigidBody.velocity.y);
  32. dashLeftTime -= Time.deltaTime;
  33. if(dashLeftTime <= 0)
  34. {
  35. isDashing = false;
  36. }
  37. GhostImagePool.instance.GetGhostImageFromPool();
  38. }
  39. }
  40. #endregion

其中CheckIfCanDash()和Dashing()函数在update中调用

CD冷却图标

实现CD图标旋转

unity中FillAmount自动代表了填充效果,我们只需要在代码中随着时间流动调整这个填充的FillAmount即可

 

开始使用技能时设定CD图标的填充为1,

 

之后让其随时间自动削减。按照如下的公式即可

dashCD即为技能冷却CD

 完整如下

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/114602?site
推荐阅读
相关标签
  

闽ICP备14008679号