我创建了一个统一的平台,您可以使用Sprite Shape Controller
进行触摸扩展。想法是,在触摸时,您可以拖动该平台并使其弯曲并像下面这样跟随鼠标:
除了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