【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
添加部分!!!
功能分解
-
生成随机位置偏移量:
- 通过
Random.Range
生成随机的偏移值,使弹出文本在一定范围内有随机性,增加视觉多样性。 randomx
:控制X轴上的随机偏移,范围在[-0.5, 0.5]
。randomy
:控制Y轴上的随机偏移,范围在[1.5, 3]
。
- 通过
-
实例化弹出文本:
- 使用
Instantiate
方法在当前物体位置加上偏移量的地方创建一个新的弹出文本对象。 Quaternion.identity
表示弹出文本没有旋转(即默认角度)。
- 使用
-
设置文本内容:
- 通过
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;elsesr.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.5public 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;}