你误解了Lerp的作用。 Lerp本身没有动画任何东西,它只在两个值之间插入t,其中t在0到1的范围内。你可以想象t为百分比 - >如果t为0,则lerp的结果为第一个值(或者v3的情况也是第2个方向的0%),如果t为1则结果为第二个,如果t为0.5,则结果位于中间两个,所以如果它的0.25在25%(Slerp基本相同,只有该值代表一个旋转,检查维基百科的所有内容的更多信息)。
但到底这对你意味着什么呢?
您需要多次调用Lerp,并将t设置为您及时的位置。一种选择是启动协程并逐渐减少/减少 (1 / seconds) * Time.deltaTime 一旦玩家进入/退出触发器,每个帧。
(1 / seconds) * Time.deltaTime
编辑:
将其附加到可见的游戏对象并运行它。它认为它应该清理Lerp的工作原理。重要的是 的 Ť 强> 。它需要随着时间的推移而减少以获得动画效果。
using UnityEngine; public class LerpExample : MonoBehaviour { public Vector3 targetScale = new Vector3(2, 2, 2); public float duration = 2; Vector3 originalScale; float timeFactor; float t; void Start() { originalScale = transform.localScale; //since only values between 0 and 1 will do something //we need to know "how much" Time.deltaTime affects our lerping //ofc we could calculate it "on the fly", but it stays the same so better store it timeFactor = 1 / duration; t = 0; } void Update() { //this is just so it repeats over and over //if t would grow bigger than 1, it would just be interpreted as 1 by Lerp if (t > 1) t -= 1; //this is what animates it in the end. each frame (its the update method!) a fraction gets added to t. think of it as percentage. t += timeFactor * Time.deltaTime; transform.localScale = Vector3.Lerp(originalScale, targetScale, t); } }
edit2:好吧,这是以上在协程中运行的。虽然是一个小“陷阱”。我没有说明玩家在缩放结束前离开触发器的时间。如果他这样做,则持续时间不一致。例如,如果它是10s并且他在2s后离开,他将缩回到正常超过10,而不是2秒。如果你想要它修复,我会把它留给你解决。
这是触发器
using UnityEngine; public class Cake : MonoBehaviour { public Vector3 targetScale = new Vector3(2, 2, 2); public float duration = 2; void OnTriggerEnter(Collider other) { Alice alice = other.GetComponentInParent<Alice>(); if (alice == null) return; alice.Eat(this); } void OnTriggerExit(Collider other) { Alice alice = other.GetComponentInParent<Alice>(); if (alice == null) return; alice.GrowBackToNormal(this); } }
这会进入触发器的对象
using UnityEngine; using System.Collections; public class Alice : MonoBehaviour { Vector3 originalScale; Coroutine eatAllTheCakeCoroutine; void Start() { originalScale = transform.localScale; } IEnumerator ChangeScale(Vector3 targetScale, float duration) { Vector3 startScale = transform.localScale; float timeFactor = 1 / duration; float t = 0; while (t < 1) { t += timeFactor * Time.deltaTime; transform.localScale = Vector3.Lerp(startScale, targetScale, t); yield return null; } transform.localScale = targetScale; } public void Eat(Cake cake) { if (eatAllTheCakeCoroutine != null) StopCoroutine(eatAllTheCakeCoroutine); eatAllTheCakeCoroutine = StartCoroutine(ChangeScale(cake.targetScale, cake.duration)); } public void GrowBackToNormal(Cake cake) { if(eatAllTheCakeCoroutine != null) StopCoroutine(eatAllTheCakeCoroutine); eatAllTheCakeCoroutine = StartCoroutine(ChangeScale(originalScale, cake.duration)); } }