如何让LineRenderer的SetPosition实现平滑动画?
如何让LineRenderer控制的变色龙舌头伸缩动画更平滑?
我正在制作一款2D游戏,需要实现变色龙舌头从嘴部伸出到目标点再收回的效果。目前通过LineRenderer的SetPosition控制舌头位置,但动画速度过快,不够流畅。以下是我的相关代码,请问有什么方法能让SetPosition的动画更平滑缓慢?
EdgeCollider2D edgeCollider; LineRenderer myLine; public Transform pointOne; public Transform pointfinalZero; public Transform pointfinal; public bool isTongue; void Start() { edgeCollider = this.GetComponent<EdgeCollider2D>(); myLine = this.GetComponent<LineRenderer>(); } void Update() { SetEdgeCollider(myLine); myLine.SetPosition(0, pointOne.position); if(isTongue) { myLine.SetPosition(1, pointfinal.position); } if(!isTongue) { myLine.SetPosition(1, pointfinalZero.position); } } void SetEdgeCollider(LineRenderer lineRenderer) { List<Vector2> edges = new List<Vector2>(); for(int point = 0; point<lineRenderer.positionCount; point++) { Vector3 lineRendererPoint = lineRenderer.GetPosition(point); edges.Add(new Vector2(lineRendererPoint.x, lineRendererPoint.y)); } edgeCollider.SetPoints(edges); }
目前功能正常,但希望能让舌头伸出的动画更平滑可见。
解决方案
你当前的代码是直接让舌头从起点跳转到终点,自然会显得突兀。可以通过插值计算实现平滑过渡,这里提供两种实用方案:
方案一:线性插值配合时间增量实现基础平滑伸缩
添加变量记录舌头当前末端位置,在Update中逐步向目标位置插值,保证不同帧率下速度一致:
EdgeCollider2D edgeCollider; LineRenderer myLine; public Transform pointOne; public Transform pointfinalZero; public Transform pointfinal; public bool isTongue; // 控制伸缩速度,值越小动作越慢 public float tongueSpeed = 2f; // 记录舌头末端当前位置 private Vector3 currentTongueEndPos; void Start() { edgeCollider = GetComponent<EdgeCollider2D>(); myLine = GetComponent<LineRenderer>(); // 初始化舌头到收回状态 currentTongueEndPos = pointfinalZero.position; myLine.SetPosition(1, currentTongueEndPos); } void Update() { SetEdgeCollider(myLine); myLine.SetPosition(0, pointOne.position); // 确定当前目标位置 Vector3 targetPos = isTongue ? pointfinal.position : pointfinalZero.position; // 线性插值过渡到目标位置 currentTongueEndPos = Vector3.Lerp(currentTongueEndPos, targetPos, tongueSpeed * Time.deltaTime); // 更新LineRenderer末端位置 myLine.SetPosition(1, currentTongueEndPos); } void SetEdgeCollider(LineRenderer lineRenderer) { List<Vector2> edges = new List<Vector2>(); for(int point = 0; point < lineRenderer.positionCount; point++) { Vector3 lineRendererPoint = lineRenderer.GetPosition(point); edges.Add(new Vector2(lineRendererPoint.x, lineRendererPoint.y)); } edgeCollider.SetPoints(edges); }
方案二:协程+动画曲线实现带缓动的自然动画
如果想要更贴近真实生物的运动节奏(比如伸出加速、收回减速),可以用协程结合动画曲线自定义缓动效果:
EdgeCollider2D edgeCollider; LineRenderer myLine; public Transform pointOne; public Transform pointfinalZero; public Transform pointfinal; public bool isTongue; // 单次伸缩动画的总时长 public float animationDuration = 0.5f; // 自定义缓动曲线,可在Inspector面板调整 public AnimationCurve tongueCurve = AnimationCurve.EaseInOut(0,0,1,1); // 标记动画是否正在播放,避免重复触发 private bool isAnimating; void Start() { edgeCollider = GetComponent<EdgeCollider2D>(); myLine = GetComponent<LineRenderer>(); myLine.SetPosition(1, pointfinalZero.position); } void Update() { SetEdgeCollider(myLine); myLine.SetPosition(0, pointOne.position); if(isTongue && !isAnimating) { StartCoroutine(MoveTongueTo(pointfinal.position)); } else if(!isTongue && !isAnimating) { StartCoroutine(MoveTongueTo(pointfinalZero.position)); } } IEnumerator MoveTongueTo(Vector3 targetPos) { isAnimating = true; float elapsedTime = 0f; Vector3 startPos = myLine.GetPosition(1); while(elapsedTime < animationDuration) { elapsedTime += Time.deltaTime; // 用动画曲线计算插值比例,实现自定义缓动 float t = tongueCurve.Evaluate(elapsedTime / animationDuration); Vector3 newPos = Vector3.Lerp(startPos, targetPos, t); myLine.SetPosition(1, newPos); yield return null; } // 确保最终位置精准到达目标点 myLine.SetPosition(1, targetPos); isAnimating = false; } void SetEdgeCollider(LineRenderer lineRenderer) { List<Vector2> edges = new List<Vector2>(); for(int point = 0; point < lineRenderer.positionCount; point++) { Vector3 lineRendererPoint = lineRenderer.GetPosition(point); edges.Add(new Vector2(lineRendererPoint.x, lineRendererPoint.y)); } edgeCollider.SetPoints(edges); }
注意事项
- 两种方案都使用
Time.deltaTime,确保动画速度不受帧率波动影响。 - 方案二中的
isAnimating标记必须保留,防止动画未完成时重复触发导致动作错乱。 - 可通过调整
tongueSpeed或animationDuration参数,找到最适合的动画节奏。
内容的提问来源于stack exchange,提问作者João Carlos P.P.
相关产品推荐
相关产品推荐

