Я создал единую платформу, где вы можете растянуть ее прикосновением, используя Sprite Shape Controller
. Идея состоит в том, что при прикосновении вы можете перетащить эту платформу, изогнуть ее и следовать за своей мышью так: ![enter image description here](https://i.stack.imgur.com/n1pWl.png)
У меня это работает в значительной степени, кроме одной проблемы:
Я хочу накатить на него твердое тело 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;
}
}
Вот рисунок, показывающий проблему: https://gfycat.com/badzanychimneyswift