Unity类银河战士恶魔城学习总结(P173 Pop Up Text FX弹出文本特效)

发布于:2024-12-18 ⋅ 阅读:(71) ⋅ 点赞:(0)

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili

教程源地址:https://www.udemy.com/course/2d-rpg-alexdev/

本章节实现了冷却时间,伤害数字的弹出文本特效

PopUpTextFx.cs

1. 类成员变量

  • myText: 存储TextMeshPro组件的引用,控制文本的显示内容和颜色。
  • speed: 控制文本上升的速度。
  • disappearanceSpeed: 在文本透明度消失后,控制文本的上升速度衰减。
  • colorDisappearanceSpeed: 控制文本透明度的衰减速率。
  • lifeTime: 文本显示的总时长,超出这个时间后文本会开始消失。
  • textTimer: 用于倒计时,跟踪文本的生命周期。

2. Update() 方法

  • 文本上升:每帧通过Vector2.MoveTowards使文本沿Y轴缓慢上升。speed控制上升速度,Time.deltaTime确保上升速度与帧率无关。

  • 生命周期管理textTimer递减,当生命周期结束后(textTimer < 0),文本开始逐渐消失。

  • 透明度衰减:文本的透明度(alpha)逐渐减少,使用colorDisappearanceSpeed控制衰减速度。

  • 减慢上升速度:当透明度低于50时,减慢文本的上升速度,使其在消失时更加平滑。

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


//2024.12.6  清水河
//Author:suzh1qian
public class PopUpTextFx : MonoBehaviour
{
    private TextMeshPro myText;

    [SerializeField] private float speed;//上升速度
    [SerializeField] private float disappearanceSpeed;//文本消失时上升速度的衰减
    [SerializeField] private float colorDisappearanceSpeed;//文本消失时颜色的衰减

    [SerializeField] private float lifeTime;

    private float textTimer;//计时文本的生命周期

    void Start()
    {
        myText = GetComponent<TextMeshPro>();
        textTimer =lifeTime;
    }

    
    void Update()
    {
        transform.position = Vector2.MoveTowards(transform.position, 
            new Vector2(transform.position.x, transform.position.y + 1), speed * Time.deltaTime);// 文本沿Y轴方向上升


        textTimer -= Time.deltaTime;// 计时器递减

        if (textTimer < 0 )
        {
            float alpha = myText.color.a - colorDisappearanceSpeed * Time.deltaTime;// 文本的透明度逐渐减少
            myText.color = new Color(myText.color.r, myText.color.g, myText.color.b, alpha);

            
            if (myText.color.a < 50)// 当透明度小于50时,减慢文本的上升速度
                speed = disappearanceSpeed;

        }
    }
}

EntityFX.cs

添加部分!!!
功能分解
  1. 生成随机位置偏移量

    • 通过Random.Range生成随机的偏移值,使弹出文本在一定范围内有随机性,增加视觉多样性。
    • randomx:控制X轴上的随机偏移,范围在 [-0.5, 0.5]
    • randomy:控制Y轴上的随机偏移,范围在 [1.5, 3]
  2. 实例化弹出文本

    • 使用 Instantiate 方法在当前物体位置加上偏移量的地方创建一个新的弹出文本对象。
    • Quaternion.identity 表示弹出文本没有旋转(即默认角度)。
  3. 设置文本内容

    • 通过 newText.GetComponent<TextMeshPro>().text 将输入的 _text 参数赋值给弹出文本的内容。
    [Header("弹出文本")]//Pop Up Text
    [SerializeField] private GameObject popUpTextPrefab;

    public void CreatePopUpText(string _text)//生成弹出文本
    {
        float randomx = Random.Range(-0.5f, 0.5f);
        float randomy = Random.Range(1.5f, 3);

        Vector3 positionOffset = new Vector3(randomx, randomy, 0);

        GameObject newText = Instantiate(popUpTextPrefab, transform.position + positionOffset, Quaternion.identity);

        newText.GetComponent<TextMeshPro>().text = _text;
    }
完整代码!!!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;
using TMPro;

public class EntityFX : MonoBehaviour
{
    private Player player;  
    private SpriteRenderer sr;

    [Header("弹出文本")]//Pop Up Text
    [SerializeField] private GameObject popUpTextPrefab;


    [Header("震动特效")]//Screen shake FX
    [SerializeField] private float shakeMultiplier;
    private CinemachineImpulseSource screenShake;
    public Vector3 shakeSwordImpact;//投掷震动效果向量
    public Vector3 shakeHighDamage;//高伤害震动效果向量


    [Header("残影特效")]//After image FX
    [SerializeField] private float afterImageCooldown;
    [SerializeField] private GameObject afterImagePrefab;
    [SerializeField] private float colorLooseRate;//颜色丢失率
    private float afterImageCooldownTimer;


    [Header("闪光特效")]//Flash FX
    [SerializeField] private float flashDuration;
    [SerializeField] private Material hitMat;
    private Material originalMat;


    [Header("异常状态颜色")]//Ailment colors
    [SerializeField] private Color[] chillColor;
    [SerializeField] private Color[] igniteColor;
    [SerializeField] private Color[] shockColor;

    [Header("异常状态粒子")]//Ailment particles
    [SerializeField] private ParticleSystem igniteFx;
    [SerializeField] private ParticleSystem chillFx;
    [SerializeField] private ParticleSystem shockFx;

    [Header("攻击特效")]//Hit FX
    [SerializeField] private GameObject hitFX;
    [SerializeField] private GameObject criticalHitFx;

    [Space]
    [SerializeField] private ParticleSystem dustFx;


    private void Start()
    {
        sr = GetComponentInChildren<SpriteRenderer>();
        player = PlayerManager.instance.player;
        screenShake = GetComponent<CinemachineImpulseSource>();
        originalMat = sr.material;
    }

    private void Update()
    {
        afterImageCooldownTimer -= Time.deltaTime;

    }

    public void CreatePopUpText(string _text)//生成弹出文本
    {
        float randomx = Random.Range(-0.5f, 0.5f);
        float randomy = Random.Range(1.5f, 3);

        Vector3 positionOffset = new Vector3(randomx, randomy, 0);

        GameObject newText = Instantiate(popUpTextPrefab, transform.position + positionOffset, Quaternion.identity);

        newText.GetComponent<TextMeshPro>().text = _text;
    }


    public void ScreenShake(Vector3 _shakePower)
    {
        screenShake.m_DefaultVelocity = new Vector3(_shakePower.x * player.facingDir , _shakePower.y ) * shakeMultiplier;
        screenShake.GenerateImpulse();

    }



    public void CreateAfterImage()//生成残影
    {
        if(afterImageCooldownTimer < 0)
        {
            afterImageCooldownTimer = afterImageCooldown;//重置冷却时间

            GameObject newAfterImage = Instantiate(afterImagePrefab, transform.position + new Vector3(0, .25f, 0), transform.rotation);//生成残影实例

            newAfterImage.GetComponent<AfterImageFX>().SetupAfterImage(colorLooseRate, sr.sprite);

        }    
    }




    public void MakeTransprent(bool _transparent)//攻击命中时候的透明特效
    {
        if (_transparent)
            sr.color = Color.clear;
        else
            sr.color = Color.white;
    }


    private IEnumerator FlashFX()//定义了一个私有的协程 FlashFX,用于在一段时间内改变 SpriteRenderer 的材质,然后恢复原始材质。
    {
        sr.material = hitMat;
        Color currentColor = sr.color;//保存最开始的颜色,闪光之后变回去

        sr.color = Color.white;
        yield return new WaitForSeconds(flashDuration);

        sr.color = currentColor;
        sr.material = originalMat;

    }

    //P59,骷髅战士的血条闪烁
    private void RedColorBlink()
    {
        if (sr.color != Color.white)
            sr.color = Color.white;
        else
        {
            sr.color = Color.red;
        }
    }

    private void CancelColorChange()
    {
        CancelInvoke();//调用 CancelInvoke 方法取消所有与当前游戏对象关联的 Invoke 调用。
        sr.color = Color.white;

        igniteFx.Stop();
        chillFx.Stop();
        shockFx.Stop();
    }


    //10月30日
    //三个状态的携程
    public void ShockFxFor(float _seconds)
    {
        shockFx.Play();

        InvokeRepeating("ShockColorFx", 0, .3f);
        Invoke("CancelColorChange", _seconds);
    }



    public void IgniteFxFor(float _seconds)
    {
        igniteFx.Play();

        InvokeRepeating("IgniteColorFx", 0, .3f);
        Invoke("CancelColorChange", _seconds);
    }


    public void ChillFxFor(float _seconds)
    {
        chillFx.Play();

        InvokeRepeating("ChillColorFx", 0, .3f);
        Invoke("CancelColorChange", _seconds);
    }



    private void ShockColorFx()
    {
        if (sr.color != shockColor[0])
            sr.color = shockColor[0];
        else
        {
            sr.color = shockColor[1];
        }
    }


    private void IgniteColorFx()//燃烧状态颜色
    {
        if (sr.color != igniteColor[0])
            sr.color = igniteColor[0];
        else
        {
            sr.color = igniteColor[1];
        }
    }

    private void ChillColorFx()//燃烧状态颜色
    {
        if (sr.color != chillColor[0])
            sr.color = chillColor[0];
        else
        {
            sr.color = chillColor[1];
        }
    }

    //2024.12.5
    public void CreateHitFX(Transform _target, bool _critical)//攻击特效
    {

        float zRotation = Random.Range(-90, 90);
        float xPosition = Random.Range(-.5f, .5f);
        float yPosition = Random.Range(-.5f, .5f);

        Vector3 hitFXRotation = new Vector3(0, 0, zRotation);//生成的旋转向量

        GameObject hitPrefab = hitFX;

        if (_critical)//如果暴击
        {
            hitPrefab = criticalHitFx;

            float yRotation = 0;
            zRotation = Random.Range(-45, 45);

            if (GetComponent<Entity>().facingDir == -1)//如果玩家朝向左边
                yRotation = 180;

            hitFXRotation = new Vector3(0, yRotation, zRotation);

        }

        GameObject newHitFX = Instantiate(hitPrefab, _target.position + new Vector3(xPosition, yPosition), Quaternion.identity);//,_target);

        newHitFX.transform.Rotate(hitFXRotation);//设置旋转角度

        Destroy(newHitFX, .3f);

    }

    public void PlayDustFX()
    {
        if (dustFx != null)
            dustFx.Play();
    }

}
   

PlayerGroundedState.cs

设置冷却显示

            if(player.skill.blackhole.cooldownTimer>0)
            {
                player.fx.CreatePopUpText("冷却中");
                return;
            }

网站公告

今日签到

点亮在社区的每一天
去签到