物体残影的实现主要是根据速度或者间隔时间的生成残影物体
实现的时候主要解决2个问题
- 物体和残影的遮挡关系
- 残影和人物动作同步
物体和残影的遮挡关系,利用 stencil 蒙版实现
# 物体的shader写入模版值
# Player.shader
Stencil
{
Ref 1
Comp always
Pass replace
}
# 残影的shader读取模版值,等于1为物体颜色,不覆盖;否则绘制残影
# AfterImage.shader
Stencil
{
Ref 1
Comp NotEqual
}
残影和人物动作同步
在残影刚出现或者激活的时候,设置位置和旋转角度和目标相同
gameObject.transform.position = target.transform.position;
gameObject.transform.rotation = target.transform.rotation;
主要是设置动画的动作帧和播放时间,让残影和人物的动作一致
AnimatorStateInfo info = targetAnimator.GetCurrentAnimatorStateInfo(0);
int animationName = info.shortNameHash;
float animationTime = info.normalizedTime;
m_animator.Play(animationName, 0, animationTime);
m_animator.speed = 0;
这样残影就复制了人物的位置和动作等
使用队列保存残影,防止生成过多的残影物体
private void InitImages()
{
images = new List<AfterImage>(trailSize);
for (var i = 0; i < trailSize; i++)
{
GameObject trail = Instantiate(trailPrefab);
AfterImage afterImage = trail.GetComponent<AfterImage>();
Animator animator = GetComponent<Animator>();
afterImage.Init(thigameObject, animator, lifeTime);
images.Add(afterImage);
}
}
private void Update()
{
timer += Time.deltaTime;
if (timer > interval)
{
DrawTrail();
timer -= interval;
}
}
private void DrawTrail()
{
for (var i = 0; i < trailSize; i++)
{
AfterImage afterImage = images[i];
if (!afterImage.isActive)
{
afterImage.Active();
return;
}
}
}
添加几个控制残影的参数
public float interval = 0.1f;
public int trailSize = 10;
public float lifeTime = 0.3f;
几个最终的效果
简单的残影,颜色加深
加上透明度变化