对冲刺效果的学习

现在正在自制小游戏的冲刺以及残影效果,记录一下自己的学习经历

在开始学习之前,我们首先要对对象池设计模式有一个概念: 对象池(Object Pool)就是在一个池子里存放着许多的物体,当我们需要的时候就拿出来一个,将他做成我想要的样子,用完之后在存入池子里

为什么要有对象池?

因为系统中经常会出现需要频繁出现然后消失的物体,比如说我们的子弹,一个地图里出现的敌人,如果我们经常用Instantiate 和 Destroy 来生成后销毁,会比较吃内存,所以需要用对象池设计模式概念,在游戏一开始就创建若干数量的物体,先隐藏起来,在需要用到的时候再显示出来,以此循环.

我们制作残影, 是通过创建多个图像在玩家身后 然后随着时间逐渐降低它的不透明度,到达指定时间返回对象池,下面是代码.

挂在每个残影上的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();
        playerSprite = player.GetComponent();

        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 availableObjects = new Queue();

    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;
    }
}

在我们的PlayerController上需要添加一些代码,下面是添加的变量代码

[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);
                }
            }
        }

    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值