具有2D刚体的可拉伸移动Sprite花键

时间:2019-10-18 20:51:19

标签: unity3d 2d sprite game-physics rigid-bodies

我创建了一个统一的平台,您可以使用Sprite Shape Controller进行触摸扩展。想法是,在触摸时,您可以拖动该平台并使其弯曲并像下面这样跟随鼠标: enter image description here

除了1个问题外,我还可以正常工作

我希望在其上滚动2D刚体,一个简单的球。当我快速将其向下拉伸并使其到达原始位置时,球正在经过并掉落,就会出现问题。 预期的行为是,它应该根据我为保持动量前进所付出的努力来加大力度。 这是我编写的AnchorDragger脚本,它负责拖动行为:

using UnityEngine;
using UnityEngine.U2D;

public class AnchorDragger : MonoBehaviour
{
    const int INVALLID_INSERTED_POINT_INDEX = -1;

    public float speed = 0.4f;

    public SpriteShapeController spriteShapeController;
    private Spline spline;
    private bool released = false;
    private int inseretedPointIndex = INVALLID_INSERTED_POINT_INDEX;
    private Vector3 originalPos;
    private Vector3 dropPos;
    private Ray originalToDropRay;
    private float distanceToOriginalPos;

    void Start()
    {
        spline = spriteShapeController.spline;
        int pointCount = spline.GetPointCount();
        for (var i = 0; i < pointCount; i++)
        {
            Vector3 currentPointPos = spline.GetPosition(i);
            Debug.Log("Point " + i + " position: " + currentPointPos);
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (!released && inseretedPointIndex != INVALLID_INSERTED_POINT_INDEX)
        {
            spline = spriteShapeController.spline;
            Ray r = Camera.main.ScreenPointToRay(Input.mousePosition);
            Plane p = new Plane(Vector3.forward, spriteShapeController.spline.GetPosition(0));
            float d;
            p.Raycast(r, out d);
            Vector3 pos = r.GetPoint(d);
            spline.SetPosition(inseretedPointIndex, pos);
            spriteShapeController.BakeCollider();
        }
        if (released)
        {
            Vector3 pos;
            if (distanceToOriginalPos - speed >= 0)
            {
                pos = originalToDropRay.GetPoint(distanceToOriginalPos - speed);
                spline.SetPosition(inseretedPointIndex, pos);
                distanceToOriginalPos -= speed;
            }
            else
            {
                pos = originalToDropRay.GetPoint(0);
                spline.SetPosition(inseretedPointIndex, pos);
                distanceToOriginalPos = 0;
            }
            if (pos == originalPos)
            {
                released = false;
                spline.RemovePointAt(inseretedPointIndex);
                inseretedPointIndex = INVALLID_INSERTED_POINT_INDEX;
            }
        }
    }

    void OnMouseDown()
    {
        released = false;
        Debug.Log("Mouse Down Position:" + Input.mousePosition);
        //Vector3 mouseDownPos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 1.0f));
        Ray r = Camera.main.ScreenPointToRay(Input.mousePosition);
        Plane p = new Plane(Vector3.forward, spriteShapeController.spline.GetPosition(0));
        float d;
        p.Raycast(r, out d);
        Vector3 mouseDownPos = r.GetPoint(d);
        Debug.Log("World Position: " + mouseDownPos);
        spline = spriteShapeController.spline;
        int pointCount = spline.GetPointCount();
        int closestPointIndex = int.MaxValue;
        float minDistance = int.MaxValue;
        for (var i = 0; i < pointCount; i++)
        {
            Vector3 currentPointPos = spline.GetPosition(i);
            float distance = Vector3.Distance(currentPointPos, mouseDownPos);
            if (distance < minDistance)
            {
                minDistance = distance;
                if ((-currentPointPos.x * mouseDownPos.y + currentPointPos.y * mouseDownPos.x) < 0)
                {
                    closestPointIndex = i + 1;
                } else
                {
                    closestPointIndex = i;
                }
            }
        }
        spline.InsertPointAt(closestPointIndex, mouseDownPos);
        spline.SetTangentMode(closestPointIndex, ShapeTangentMode.Continuous);
        inseretedPointIndex = closestPointIndex;
        originalPos = mouseDownPos;
        Debug.Log("Inserted point index: " + inseretedPointIndex);
    }

    void OnMouseUp()
    {
        Debug.Log("Mouse Up");
        spline = spriteShapeController.spline;
        released = true;
        dropPos = spline.GetPosition(inseretedPointIndex);
        Vector3 heading = dropPos - originalPos;
        distanceToOriginalPos = heading.magnitude;
        Vector3 direction = heading / distanceToOriginalPos;
        originalToDropRay = new Ray(originalPos, direction);
        //spline.RemovePointAt(inseretedPointIndex);
        //inseretedPointIndex = INVALLID_INSERTED_POINT_INDEX;
    }
}

以下是显示问题的gif: https://gfycat.com/badzanychimneyswift

0 个答案:

没有答案