unity3d 是否有任何方法可以使LineRenderer的SetPosition更平滑?

mrphzbgm  于 2022-11-15  发布在  其他
关注(0)|答案(2)|浏览(254)

有没有什么方法可以让LineRenderer的SetPosition更平滑。我在做一个2D游戏,我在做一个变色龙的舌头,它从嘴里弹出来到一个点,然后又回来,但是这会让动画非常快,有没有什么方法可以让它更慢更平滑?
我的问题是有没有一种方法可以平滑linerenderer的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);
    }

它工作正常,但我想让它更光滑,看到舌头伸出。

f87krz0w

f87krz0w1#

在Unity中平滑移动到目标点

non-physical movement

 1. Transform. Translate. For example: Transform.Translate(Vector3.zero*Time.deltaTime). Move towards (0, 0, 0) at a speed of one meter per second.

 2.Vector3.lerp Vector.Slerp, Vector3.MoveTowards.

   Vector3.lerp(transform.position,targetposition,Time.deltaTime) . //Slerp is mainly used for the interpolation operation of angle radian. MoveTowards has increased the maximum speed limit on the basis of Lerp.

 3. Vector3.SmoothDamp

   This method can smoothly move from point A to point B, and can control the speed. The most common usage is that the camera follows the target.

  physical movement:
  The Rigidbody.MovePosition method in Righdbody is used to move to the target point.
ejk8hzay

ejk8hzay2#

你可以使用各种各样的Tween库,但是我更喜欢准系统的协程。
时间跨度是设置动画所需的秒数。
[ExecuteAlways]用于编辑器中的测试。与ContextMenu(“StickTongueOut”)相同]您可以在检查器中右键单击脚本来运行动画。
在OnEnabled中初始化tongue变量,因为在程序集热重新加载后,OnEnabled被触发并重新初始化它的值,这样你就可以编写在播放时编辑脚本后仍然有效的代码。不是必须的,但是哦,多么方便啊。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[ExecuteAlways]
[RequireComponent(typeof(LineRenderer))]
public class TongueAnimator : MonoBehaviour
{
    public Transform target;
    public Transform origin;

    public float timespan = 1f;

    private LineRenderer tongue;

    private void OnEnable()
    {
        tongue = GetComponent<LineRenderer>();
    }
    private IEnumerator _tongueLoopCoroutine;

    /// <summary>
    /// This will restart tongue animation coroutine even if it is still out
    /// </summary>
    public void AnimateTongue(bool direction)
    {
        if (_tongueLoopCoroutine != null)
            StopCoroutine(_tongueLoopCoroutine);
        _tongueLoopCoroutine = TongueLoop(direction);
        StartCoroutine(_tongueLoopCoroutine);
    }

    [ContextMenu("StickTongueOut")]
    public void StickTongueOut() => AnimateTongue(true);
    [ContextMenu("RetractTongue")]
    public void RetractTongue() => AnimateTongue(false);

    public IEnumerator TongueLoop(bool direction)
    {
        var startTime = Time.time;
        while (startTime + timespan > Time.time)
        {
            float t = (Time.time - startTime) / timespan;
            if (!direction) { t = 1 - t; }
            SetPositions(t);
            yield return null;
        }
        SetPositions(direction ? 1 : 0);

        //Reusing same code. Local Methods might not be supported in older Unity versions like 2019
        void SetPositions(float t)
        {
            tongue.SetPosition(0, origin.position);
            var pos = Vector3.Lerp(origin.position, target.position, t);
            tongue.SetPosition(1, pos);
        }
    }
}

如果您需要EaseInOut,您可以在改变方向之前重新Mapt,如下所示:

using UnityEngine;

public static class Utility
{
    public static float SmoothStep(this float t) => t * t * (3f - 2f * t);
    public static float SmootherStep(this float t) => t * t * t * (t * (t * 6 - 15) + 10);
    public static float InverseSmoothStep(this float t) => .5f - Mathf.Sin(Mathf.Asin(1f - 2f * t) / 3f);
    public static float SinStep(this float t) => Mathf.Sin(Mathf.PI * (t - .5f)) / 2 + .5f;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="t"></param>
    /// <param name="p">When equals to 2 returns similar results as Smoothstep</param>
    /// <returns></returns>
    public static float SmoothStepParametric(this float t, float p = 2f)
    {
        var tp = Mathf.Pow(t, p);
        return tp / (tp + Mathf.Pow(1 - t, p));
    }
}

此实用程序允许您执行此操作

t = t.SmoothStep();
t = Utility.SmoothStep(t);

如果你的项目中有这样的没有命名空间的实用程序,你会遇到冲突。最好使用命名空间。

相关问题