Unity类银河战士恶魔城学习总结(P171 After image fx残影)
【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili
教程源地址:https://www.udemy.com/course/2d-rpg-alexdev/
本章节为冲刺加入了残影的效果
AfterImageFX.cs
1. 类与成员变量
sr
: 存储SpriteRenderer
组件的引用,用于控制精灵(Sprite)图像的显示。colorLooseRate
: 透明度衰减的速率。值越大,透明度消失的速度越快。
2. SetupAfterImage 方法
这个方法用于初始化后效效果。它接收两个参数:
_loosingSpeed
: 控制透明度衰减的速度。_spriteImage
: 用于设置精灵的图像。
3. Update 方法
-
每帧更新时,透明度(
alpha
)会根据衰减速率和Time.deltaTime
(每帧的时间差)逐渐减少,Time.deltaTime
确保效果在不同帧率下的一致性。alpha
表示当前精灵的透明度,它是从sr.color.a
(当前透明度)减去一个值,colorLooseRate * Time.deltaTime
。sr.color
使用新计算的透明度创建一个新的Color
对象,并更新SpriteRenderer
的颜色。
-
当透明度小于等于0时,销毁当前游戏对象,表示后效效果完全消失。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//2024.12.5 快三个月了bro
public class AfterImageFX : MonoBehaviour
{
private SpriteRenderer sr;
private float colorLooseRate;
public void SetupAfterImage(float _loosingSpeed , Sprite _spriteImage)
{
sr = GetComponent<SpriteRenderer>();//获得组件
sr.sprite = _spriteImage;
colorLooseRate= _loosingSpeed;
}
private void Update()
{
float alpha = sr.color.a - colorLooseRate * Time.deltaTime;
sr.color = new Color(sr.color.r, sr.color.g, sr.color.b, alpha);
if(sr.color.a <= 0)
Destroy(gameObject);
}
}
EntityFX.cs
修改部分!!!
[Header("残影特效")]//After image FX
[SerializeField] private float afterImageCooldown;
[SerializeField] private GameObject afterImagePrefab;
[SerializeField] private float colorLooseRate;//颜色丢失率
private float afterImageCooldownTimer;
private void Update()
{
afterImageCooldownTimer -= Time.deltaTime;
}
public void CreateAfterImage()//生成残影
{
if(afterImageCooldownTimer < 0)
return;
afterImageCooldownTimer = afterImageCooldown;//重置冷却时间
GameObject newAfterImage = Instantiate(afterImagePrefab, transform.position, transform.rotation);//生成残影实例
newAfterImage.GetComponent<AfterImageFX>().SetupAfterImage(colorLooseRate, sr.sprite);
}
完整代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EntityFX : MonoBehaviour
{
private SpriteRenderer sr;
[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>();
originalMat = sr.material;
}
private void Update()
{
afterImageCooldownTimer -= Time.deltaTime;
}
public void CreateAfterImage()//生成残影
{
if(afterImageCooldownTimer < 0)
return;
afterImageCooldownTimer = afterImageCooldown;//重置冷却时间
GameObject newAfterImage = Instantiate(afterImagePrefab, transform.position, 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);//生成特效实例
newHitFX.transform.Rotate(hitFXRotation);//设置旋转角度
Destroy(newHitFX, .3f);
}
public void PlayDustFX()
{
if (dustFx != null)
dustFx.Play();
}
}