unity使用对象池实现冲锋留下的残影效果

目录

效果展示

实现思路

残影代码

对象池代码

控制冲刺产生残影

CD冷却图标


效果展示

 

实现思路

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

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

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

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

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

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

在这里插入图片描述

具体代码如下:

残影代码

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

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

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GhostImage : MonoBehaviour
{
    [Header("残影参数")]
    SpriteRenderer thisSprite;
    SpriteRenderer playerSprite;
    GameObject player;
    Color spriteColor;
    float alpha=1;
    float startAlpha;
    float alphaMultiplyRation = 0.9f;
    [SerializeField] public float activeTime=0.5f;//残影所持续的时间
    float startTime;

    //事实上,由于其是单例模式,无需用代码去unity中搜寻该物体,就可以直接从该脚本.instance的方式获取该物体
    //GhostImagePool poolInstance;

    private void OnEnable()
    {
        player = GameObject.FindGameObjectWithTag("Player");
        playerSprite = player.GetComponent<SpriteRenderer>();
        thisSprite = GetComponent<SpriteRenderer>();

        thisSprite.sprite = playerSprite.sprite;
        transform.position = player.transform.position;
        transform.rotation = player.transform.rotation;
        transform.localScale = player.transform.localScale;

        startTime = Time.time;
    }
    private void Update()
    {
        ImageDisappear();
    }
    void ImageDisappear()
    {
        thisSprite.color = new Color(0.5f, 0.5f, 1f, alpha*alphaMultiplyRation);
        if (Time.time > startTime + activeTime)
        {
            GhostImagePool.instance.ReturnPool(this.gameObject);
        }
    }
}

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

对象池代码

 对象池的代码如下:

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

其包含几个功能,

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

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

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

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

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GhostImagePool : MonoBehaviour
{
    public static GhostImagePool instance;
    int ghostImageGroupCount = 10;//对象池中的影子不够用时会多生成一组影子,这是一组影子的数量
    public GameObject ghostImagePrefab;

    void Awake()
    {
        instance = this;
    }

    Queue<GameObject> pool=new Queue<GameObject>();
    private void Start()
    {
        FillPool();
    }
    void Update()
    {
        
    }

    void FillPool()
    {
        for(int i = 0; i < ghostImageGroupCount; i++)
        {
            var ghostImage = Instantiate(ghostImagePrefab, transform);
            ReturnPool(ghostImage);
        }

    }

    public void ReturnPool(GameObject ghostImage)
    {
        pool.Enqueue(ghostImage);
        ghostImage.SetActive(false);
    }
    public GameObject GetGhostImageFromPool()
    {
        if(pool.Count <= 0)
        {
            FillPool();
        }
        GameObject ghostImage= pool.Dequeue();
        ghostImage.SetActive(true);
        return ghostImage;
    }

}

控制冲刺产生残影

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

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

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


    #region 冲刺及残影
    
    [Header("残影参数")]

    [SerializeField] public float dashContinueTime=0.5f;//冲刺持续时间
    [SerializeField] public float dashCD=2f;//冲刺技能的CD
    [SerializeField] public float dashSpeed=30;//冲刺的速度
    public Image CDImage;
    float dashLeftTime;//剩余可以用来冲刺的时间,初始为其赋值后让时间不断减少
    float lastDashTime=-10f;//上次冲刺的时间,用于设定cd(初始设定为负值是为了初始时也能调用)
    
    public bool isDashing = false;

    void CheckIfCanDash()
    {
        CDImage.fillAmount -= 1.0f / dashCD * Time.deltaTime;//实现CDImage自动减少的情况
        if (Time.time > lastDashTime + dashCD)
        {
            if (Input.GetKeyDown(KeyCode.LeftShift))
            {
                isDashing = true;
                lastDashTime = Time.time;
                dashLeftTime = dashContinueTime;
                CDImage.fillAmount = 1;//使用技能时开始计算冷却,将图标设为满填充,当图标减少时代表cd正在减少
            }
        }

    }

    void Dashing()
    {
        if (isDashing)
        {
            if(transform.localScale.x==-1)
                rigidBody.velocity = new Vector2(dashSpeed, rigidBody.velocity.y);
            else if (transform.localScale.x == 1)
                rigidBody.velocity = new Vector2(-dashSpeed, rigidBody.velocity.y);
            dashLeftTime -= Time.deltaTime;
            if(dashLeftTime <= 0)
            {
                isDashing = false;
            }
            GhostImagePool.instance.GetGhostImageFromPool();
        }
    }

    #endregion

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

CD冷却图标

实现CD图标旋转

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

 

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

 

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

dashCD即为技能冷却CD

 完整如下

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值