Unity实现残影效果

该文详细介绍了如何在Unity中实现玩家角色的冲锋效果和残影功能。PlayerMovement类处理角色移动和冲锋逻辑,ShadowSprite类用于控制残影的显示与透明度变化,而ShadowPool类则实现了对象池管理,有效复用残影预制体,提高性能。
摘要由CSDN通过智能技术生成

1、效果展示

效果展示

2、场景搭建

player
残影预制体
残影对象池

3、代码

1、PlayerMovement.cs:挂载在角色身上

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

public class PlayerMovement : MonoBehaviour
{
    [Header("人物移动速度")]
    public float moveSpeed = 5;

    private Rigidbody2D rb;

    private Vector2 moveDir;

    private Animator anim;

    [Header("冲锋时长")]
    public float dashTime = 0.5f;//冲锋时长

    private float dashTimeLeft;//冲锋剩余时间

    [Header("冲锋时的速度")]
    public float dashSpeed = 10;//冲锋时的速度

    [Header("冲锋冷却时间")]
    public float dashCoolDown = 1;//冲锋冷却时间

    private float lastDash = -10;

    private bool isDashing;//是否冲锋

    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();

        anim = GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        InputManagement();

        if (Input.GetKeyDown(KeyCode.J))
        {
            if (Time.time >= (lastDash + dashCoolDown))
            {
                ReadyToDash();
            }
        }
    }

    private void FixedUpdate()
    {
        Dash();

        if (isDashing)
        {
            return;
        }

        Move();
    }

    private void InputManagement()
    {
        float moveX = Input.GetAxisRaw("Horizontal");

        moveDir = new Vector2(moveX, 0f);

        if (moveDir.x != 0)
        {
            anim.SetBool("Run", true);
            SpriteDirectionChecker();
        }
        else
        {
            anim.SetBool("Run", false);
        }
    }

    private void Move()//人物移动
    {
        rb.velocity = new Vector2(moveDir.x * moveSpeed, 0f);
    }

    private void SpriteDirectionChecker()//人物转向
    {
        if (moveDir.x < 0)
        {
            transform.localScale = new Vector3(-1, 1, 1);
        }
        else
        {
            transform.localScale = new Vector3(1, 1, 1);
        }
    }

    private void ReadyToDash()
    {
        isDashing = true;

        dashTimeLeft = dashTime;

        lastDash = Time.time;
    }

    private void Dash()
    {
        if (isDashing)
        {
            if (dashTimeLeft > 0)
            {
                rb.velocity = new Vector2(dashSpeed * gameObject.transform.localScale.x, rb.velocity.y);

                dashTimeLeft -= Time.deltaTime;

                ShadowPool.Instance.GetFormPool();
            }
            else
            {
                isDashing = false;
            }
        }
    }
}

2、ShadowSprite.cs:挂载在残影预制体上

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

public class ShadowSprite : MonoBehaviour
{
    private Transform player;

    private SpriteRenderer thisSprite;

    private SpriteRenderer playerSprite;

    private Color color;

    [Header("残影显示时间设置")]
    public float activeTime = 2;//显示时间

    private float activeStart;//开始显示的时间

    private float alpha;

    [Header("残影透明度设置")]
    public float alphaStart = 1;//刚开始的透明度

    [Header("残影衰变指数设置")]
    public float alphaMultiplier = 0.95f;//衰变指数

    private void OnEnable()//物体每次激活时都会调用此生命周期函数
    {
        player = GameObject.FindGameObjectWithTag("Player").transform;//记得将场景中的Player的标签设置为Player

        thisSprite = GetComponent<SpriteRenderer>();

        playerSprite = player.GetComponent<SpriteRenderer>();

        alpha = alphaStart;

        thisSprite.sprite = playerSprite.sprite;

        transform.position = player.position;

        transform.localScale = player.localScale;

        transform.rotation = player.rotation;

        activeStart = Time.time;
    }

    // Update is called once per frame
    void Update()
    {
        alpha *= alphaMultiplier;

        color = new Color(0.5f, 0.5f, 1, alpha);

        thisSprite.color = color;

        if (Time.time >= activeStart + activeTime)
        {
            ShadowPool.Instance.ReturnPool(this.gameObject);
        }
    }
}

3、ShadowPool.cs:挂载在残影对象池上

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

public class ShadowPool : MonoBehaviour
{
    private static ShadowPool _instance;//单例模式

    [Header("残影预制体")]
    public GameObject shadowPrefab;

    [Header("生成预制体的数量")]
    public int shadowCount = 10;

    private Queue<GameObject> availableObjects = new Queue<GameObject>();//用队列来存储生成的预制体

    public static ShadowPool Instance
    {
        get
        {
            return _instance;
        }
    }

    private void Awake()
    {
        if (Instance == null)
        {
            _instance = this;
        }

        CreateShadow();
    }

    public void CreateShadow()//生成残影
    {
        for (int i = 0; i < shadowCount; i++)
        {
            GameObject 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)//如果队列中的预制体不够用就继续创建
        {
            CreateShadow();
        }
        GameObject outShadow = availableObjects.Dequeue();//出队

        outShadow.SetActive(true);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值