首页 > 解决方案 > 在我的浮力项目中,为什么我的物体落入水中时会抖动?

问题描述

我正在研究浮力机制,并且有一个问题我已经尝试解决了几天。一切都按预期工作,除了当一个物体落入水中时,它会像疯了一样抖动。我试过弄乱拖动无济于事。我的角度阻力设置为 3。关于问题可能是什么的任何想法?这是我的代码和问题的一些 GIF(不要介意混乱):

https://gyazo.com/e6ccddc26516d6eba85cf410a20c11c0 https://gyazo.com/882d64c694296ab8cd80fb15513c1924

public class Buoyancy : MonoBehaviour
{

    // Variables
    public float buoyancy, viscosity;

    public Transform[] floatPoints;
    [HideInInspector] public List<Vector3> floatPointPositions;

    public Vector3 centerPoint;

    Rigidbody objRb;

    private void Start()
    {

        objRb = GetComponent<Rigidbody>();

    }

    private void Update()
    {

        GetUnderwaterCenter();

        // Debug
        Debug.DrawLine(new Vector3(0, 10, 0), centerPoint, Color.yellow);

    }

    private void FixedUpdate()
    {

        ObjectBuoyancy();
        
    }

    void GetUnderwaterCenter()
    {

        floatPointPositions.Clear();

        if (transform.position.y <= 0)
        {

            for (int i = 0; i < floatPoints.Length; i++)
            {

                if (floatPoints[i].position.y <= 0)
                {

                    floatPointPositions.Add(new Vector3(floatPoints[i].position.x, floatPoints[i].position.y, floatPoints[i].position.z));

                }

            }

            centerPoint = Vector3.zero;

            for (int i = 0; i < floatPointPositions.Count; i++)
            {

                centerPoint += floatPointPositions[i];

            }

            centerPoint /= floatPointPositions.Count;

        }

    }

    void ObjectBuoyancy()
    {

        if(floatPointPositions.Count > 0)
        {

            objRb.AddForceAtPosition(Vector3.up * buoyancy, centerPoint);
            objRb.AddForce(-objRb.velocity * viscosity);

        }

    }

}

标签: c#unity3d

解决方案


让我们先谈谈发生这种情况的问题/原因。因此,当我们的脚本对浮力施加力时,它会将物体发送到上方0(zero),而当物体到达上方某处时,0(zero)我们会停止对其施加力。现在因为我们有刚体,它将应用重力,从而将物体发送到下方0(zero)并循环重复。

我已经修改了您的一个功能并添加了另一个功能。

void ObjectBuoyancy()
{
    if (floatPointPositions.Count > 0)
    {
        float forceIntensity = Remap(1, 0, -0.2f, 0.2f, transform.position.y);
        objRb.AddForceAtPosition(Vector3.up * Mathf.Lerp(0, buoyancy, forceIntensity), centerPoint);
        objRb.AddForce(-objRb.velocity * Mathf.Lerp(0, viscosity, forceIntensity));
    }
}

float Remap(float remapMin, float remapMax, float valueMin, float valueMax, float value)
{
    return Mathf.Lerp (remapMin, remapMax, Mathf.InverseLerp (valueMin, valueMax, value));
}

这里Remap()函数的工作是检查 position.y 并根据它的位置返回应该添加/施加的力的强度。在这里,当物体低于 0 时,强度会增加,如果高于 0,强度会降低,如果物体低于-0.2f强度,则强度为 1,表示全力,如果高于0.2f强度,强度将为最低的 0。

注意最小值不应该0也应该总是低于零,因为这将导致与您现在类似的情况。


推荐阅读