【问题标题】:my rope stretches infinitely when i put an object on it当我在上面放一个物体时,我的绳子会无限伸展
【发布时间】:2021-10-22 08:20:37
【问题描述】:

我有一根由脚本中的纯代码生成的绳子,可以统一做一条钓鱼线,这里的问题是当我把钓鱼浮标放在绳头上时,绳子无限延伸,我想把浮标挂起来,我试过了改变绳索长度和线段尺寸,但它只是保持拉伸,我也知道铰链接头 2d 有另一种方法,但我认为它不够逼真,无法制作钓鱼线

这是我的代码:

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

public class hiloCanya : MonoBehaviour
{
    private LineRenderer lineRenderer;
    private List<HiloSegmento> hiloSegmentos = new List<HiloSegmento>();
    private float hiloSegLen = 0.25f;
    private int segmentoLength = 35;
    private float lineWidth = 0.05f;

    [SerializeField] private Transform startPoint;
    [SerializeField] private Transform endPoint;

    // Use this for initialization
    void Start()
    {
        this.lineRenderer = this.GetComponent<LineRenderer>();
        Vector3 hiloStartPoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);

        for (int i = 0; i < segmentoLength; i++)
        {
            this.hiloSegmentos.Add(new HiloSegmento(hiloStartPoint));
            hiloStartPoint.y -= hiloSegLen;
        }
    }

    // Update is called once per frame
    void Update()
    {
        this.DrawRope();
    }

    private void FixedUpdate()
    {
        this.Simulate();
    }

    private void Simulate()
    {
        // SIMULACION
        Vector2 fuerzaGravedad = new Vector2(0f, -1.5f);

        for (int i = 1; i < this.segmentoLength; i++)
        {
            HiloSegmento primerSegmento = this.hiloSegmentos[i];
            Vector2 velocidad = primerSegmento.posNow - primerSegmento.posOld;

            primerSegmento.posOld = primerSegmento.posNow;
            primerSegmento.posNow += velocidad;
            primerSegmento.posNow += fuerzaGravedad * Time.fixedDeltaTime;

            this.hiloSegmentos[i] = primerSegmento;
        }

        //CONSTRAINTS
        for (int i = 0; i < 50; i++)
        {
            this.ApplyConstraint();
        }
    }

    private void ApplyConstraint()
    {
        //Constrant to Mouse

        /* HiloSegmento primerSegmento = this.hiloSegmentos[0];
        primerSegmento.posNow = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        this.hiloSegmentos[0] = primerSegmento; */

        //objeto para el principio del hilo

        HiloSegmento primerSegmento = this.hiloSegmentos[0];
        primerSegmento.posNow = this.startPoint.position;
        this.hiloSegmentos[0] = primerSegmento;

        //objeto para el final del hilo
        HiloSegmento finalSegmento = this.hiloSegmentos[this.segmentoLength - 1];
        finalSegmento.posNow = this.endPoint.position;
        this.hiloSegmentos[this.segmentoLength - 1] = finalSegmento;

        for (int i = 0; i < this.segmentoLength - 1; i++)
        {
            HiloSegmento primerSeg = this.hiloSegmentos[i];
            HiloSegmento segundoSeg = this.hiloSegmentos[i + 1];
            float dist = (primerSeg.posNow - segundoSeg.posNow).magnitude;
            float error = Mathf.Abs(dist - this.hiloSegLen);
            Vector2 changeDir = Vector2.zero;

            if (dist > hiloSegLen)
            {
                changeDir = (primerSeg.posNow - segundoSeg.posNow).normalized;
            }
            else if (dist < hiloSegLen)
            {
                changeDir = (segundoSeg.posNow - primerSeg.posNow).normalized;
            }

            Vector2 changeAmount = changeDir * error;

            if (i != 0)
            {
                primerSeg.posNow -= changeAmount * 0.5f;
                this.hiloSegmentos[i] = primerSeg;

                segundoSeg.posNow += changeAmount * 0.5f;
                this.hiloSegmentos[i + 1] = segundoSeg;
            }
            else
            {
                segundoSeg.posNow += changeAmount;
                this.hiloSegmentos[i + 1] = segundoSeg;
            }
        }
    }

    private void DrawRope()
    {
        float lineWidth = this.lineWidth;
        lineRenderer.startWidth = lineWidth;
        lineRenderer.endWidth = lineWidth;

        Vector3[] posicionesHilo = new Vector3[this.segmentoLength];

        for (int i = 0; i < this.segmentoLength; i++)
        {
            posicionesHilo[i] = this.hiloSegmentos[i].posNow;
        }

        lineRenderer.positionCount = posicionesHilo.Length;
        lineRenderer.SetPositions(posicionesHilo);
    }

    public struct HiloSegmento
    {
        public Vector2 posNow;
        public Vector2 posOld;

        public HiloSegmento(Vector2 pos)
        {
            this.posNow = pos;
            this.posOld = pos;
        }
    }
}

【问题讨论】:

    标签: c# unity3d gravity


    【解决方案1】:

    您是否也尝试过统一使用 Spring Joint,它可能足够现实,您可以避免进行大量的硬编码。

    【讨论】:

    • 我搜索了它,你说得对,它非常简单有效,但我可以给这个属性一个绳子的皮肤吗??
    • 我建议你用一个叫做Line Renderer的东西,你可以给它两个点,然后用一个精灵把它们连接起来,它使用起来很简单,可能就是你想要的效果。如果你想使用曲线,那就有点困难了,你必须使用贝泽曲线,这是一个数学公式,可以创建你想要的任何形状的曲线。但现在对你来说可能有点困难。 (如果您仍然决定使用它们,您可以指定贝塞尔曲线上的点并用直线连接这些点,您就得到了曲线)
    • 我用上面的代码做了 LineRenderer 的事情,它也使用了一个数学公式,使 startPoint 和 Endpoint 跟随弹簧接头的 2 个对象,它可以工作!我没有得到贝泽曲线的东西,但是当我得到基本部件时我会试一试,所以非常感谢:)
    • youtube.com/watch?v=aVwxzDHniEw&t=449s 这是一个关于贝塞尔曲线的视频,可能会有所帮助
    猜你喜欢
    • 1970-01-01
    • 2013-07-11
    • 2016-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多