有时候我们做伤害显示飘红的时候,如果对方收到伤害的频率过高,会造成视图的混乱,也难以让玩家知道自己究竟造成了多少伤害,所以会有了伤害数字滚动显示并进行累加,比如英雄联盟中的寒冰射手开启Q时伤害累加的效果。
那么我们如何来实现这一效果呢?
1.首先解决飘红跟随问题,现在UGUI有HUD插件实现跟随,当然也可以自己写逻辑,通过相机下的转换空间的方法实现,根据需要而定;
2.然后是伤害数值的滚动,所谓的滚动,就是数值不断累加,数值显示有一个飞快的数字变化,我们可以通过Mathf中线性插值实现,最后加一些简单的动画实现强调,可以自己制作,也可以导入插件比如DoTween等;
3.最后是飘红后如果在一定时间内没有新的输出,伤害显示会飘走并且消失;
话不多说,直接上代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
public class ChangeValue : MonoBehaviour {
int value=0;//当前伤害值
int damage = 0; //伤害
int startValue = 0;//起始伤害
int endValue = 0;//结束伤害
float startTime = 0;//开始时间
public float duration = 1;//持续时间
public float normalDamageMutiple=1.5f;//普通伤害缩放倍数
public float volleyDamageMutiple=2.0f;//暴击伤害缩放倍数
bool isFollow = false;//是否跟随玩家
bool isChangeTime=false;//是否递增时间
Text damageShow;//伤害TEXT
public Canvas canvas;//画布
public Transform target;//跟随对象
Vector3 pos_InMainCamScreen=Vector3.zero;//屏幕空间坐标
Vector3 pos_InCanvasCamWorld = Vector3.zero;//UI相机世界空间下坐标
Vector3 pos_FinalInWorld = Vector3.zero;//最终坐标
// Use this for initialization
void Awake()
{
damageShow = GetComponent<Text>();
damageShow.enabled = false;
}
// Update is called once per frame
void Update () {
ScrollNum();
}
void LateUpdate()
{
Follow();
}
/// <summary>
/// 滚动数字显示
/// </summary>
void ScrollNum()
{
//普通攻击
if (Input.GetKeyDown(KeyCode.A))
{
isFollow = true;
isChangeTime = true;
damage = Random.Range(10, 200);
startTime = 0;
startValue = value;
endValue = value + damage;
damageShow.transform.DOScale(normalDamageMutiple,0.5f);
StartCoroutine(ReversePlay());
Show();
}
//暴击
if (Input.GetKeyDown(KeyCode.B))
{
isFollow = true;
isChangeTime = true;
damage = Random.Range(10, 200);
startTime = 0;
startValue = value;
endValue = value + damage;
damageShow.transform.DOScale(volleyDamageMutiple, 0.5f);
StartCoroutine(ReversePlay());
Show();
}
//时间递增
if(isChangeTime) startTime += Time.deltaTime;
if (startTime <= duration)//是否到达一秒钟
{
value = (int)Mathf.Lerp(startValue, endValue, startTime / duration);
damageShow.text = value.ToString();
}
else
{
damageShow.text = endValue.ToString();
value = 0;
isFollow = false;
isChangeTime = false;
transform.DOMoveY(1,1);
StartCoroutine(Hide());
}
}
/// <summary>
/// 反向播放放大的动画
/// </summary>
/// <returns></returns>
private IEnumerator ReversePlay()
{
yield return new WaitForSeconds(0.3f);
transform.DORewind();
}
/// <summary>
/// 延迟隐藏
/// </summary>
/// <returns></returns>
IEnumerator Hide()
{
yield return new WaitForSeconds(0.5f);
if (isFollow)
yield break;
startValue = 0;
damageShow.text = startValue.ToString();
damageShow.enabled = false;
}
/// <summary>
/// 显示
/// </summary>
void Show()
{
damageShow.enabled = true;
}
/// <summary>
/// 实现跟随
/// </summary>
void Follow()
{
if (!isFollow)
return;
pos_InMainCamScreen = Camera.main.WorldToScreenPoint(target.position);
pos_InCanvasCamWorld = canvas.worldCamera.ScreenToWorldPoint(pos_InMainCamScreen);
pos_FinalInWorld = new Vector3(pos_InCanvasCamWorld.x,pos_InCanvasCamWorld.y,canvas.GetComponent<RectTransform>().anchoredPosition3D.z);
transform.position = pos_FinalInWorld;
}
}
最后只需要将代码挂载,拖上相关的物体,设置公开的数值便可以实现了,文章中伤害是随机计算的,如有需要自行修改。