需求:当玩家受到攻击时,屏幕边缘出现一层红色的平滑闪烁效果。
实现思路很简单——给一个覆盖全屏边缘的 Raw Image 绑定脚本,通过在协程里持续改变它 color 的 alpha 值,做出先淡入再淡出的闪烁动画。
脚本实现
下面的 Blink 脚本挂在带 RawImage 组件的 GameObject 上。它暴露了一个静态单例 ins,外部只需要调用 DoBlik() 就能触发一次完整的闪烁。
public class Blink : MonoBehaviour {
static public Blink ins;
void Awake()
{
ins = this;
}
// Use this for initialization
void Start () {
StartCoroutine(doBlink());
}
// Update is called once per frame
void Update () {
}
// externl interface to blink
public void DoBlik()
{
StopCoroutine(doBlink());
StartCoroutine(doBlink());
}
IEnumerator doBlink()
{
GetComponent<RawImage>().enabled = true;
float delta=0.1f;
//fade in
for (float i = 0; i < 1; i += delta)
{
yield return new WaitForSeconds(0);
GetComponent<RawImage>().color = new Color(1, 1, 1, i);
}
delta /= 2.0f;
//fade out
for (float i = 1; i > 0; i -= delta)
{
yield return new WaitForSeconds(0);
GetComponent<RawImage>().color = new Color(1, 1, 1, i);
}
// for (float i = 0; i < 1; i += delta)
// {
// yield return new WaitForSeconds(0);
// GetComponent<RawImage>().color = new Color(1, 1, 1, i);
// }
//
//
// for (float i = 1; i > 0; i -= delta)
// {
// yield return new WaitForSeconds(0);
// GetComponent<RawImage>().color = new Color(1, 1, 1, i);
// }
GetComponent<RawImage>().enabled = false;
}
}
要点说明
- 协程
doBlink()分两段:第一段以步长0.1把 alpha 从 0 逐步加到 1 完成淡入,随后把步长折半再从 1 递减到 0 完成淡出,使得"出现快、消退慢"的观感更接近受击反馈。 - 每次循环用
yield return new WaitForSeconds(0)让出一帧,避免一口气在同一帧里跑完整个循环。 - 进入协程前先把
RawImage的enabled打开,协程结束再关闭,避免非闪烁状态下图像还残留在屏幕上。 - 对外暴露的
DoBlik()在重新启动协程前先调用StopCoroutine(doBlink()),防止短时间内多次触发造成叠加。