仅在UNITY
我正在在Unity一个简单的项目,其中有连接到SpringJoint2d component
球上成角度的斜率,像下面的图像中的球限制2D对象的运动向后:仅在UNITY
我只是希望用户能够沿着斜坡的边缘向后拖动球,换句话说,我不希望用户能够将球从斜坡上移开。
心中已经在尝试几种方法我认为可以做的工作她与我试图拖动的脚本: (这是更新版本)
public class ball : MonoBehaviour {
public Rigidbody2D rb;
public Transform spring;
public Transform calcpoint;
private Vector3 start;
private Vector3 end;
private bool isPressed = false;
RaycastHit2D[] hits = new RaycastHit2D[2];
RaycastHit2D[] hits2 = new RaycastHit2D[2];
float factor = 0;
private void OnMouseDown()
{
if (!isPressed)
{
isPressed = true;
rb.isKinematic = true;
}
}
private void OnMouseUp()
{
isPressed = false;
rb.isKinematic = false;
StartCoroutine(release());
}
/// <summary>
/// release the ball from the spring joint after a small amount of time
/// </summary>
/// <returns></returns>
IEnumerator release()
{
yield return new WaitForSeconds(0.1f);
rb.GetComponent<SpringJoint2D>().enabled = false;
}
// Update is called once per frame
void Update()
{
if (isPressed)
{
if (Vector3.Distance(spring.position, rb.position) > 3f || spring.position.x < (rb.position.x - 1)) return;//restrict the dragging of the ball to not go beyond the spring point and not too far back
float angle = 0;
if (checkGround() > 1)//if we hit the slope with the ray cast downward from the mouse/Tap position
{
angle = Mathf.Abs(Mathf.Atan2(hits[1].normal.x, hits[1].normal.y) * Mathf.Rad2Deg); //get angle
factor = (float)(((45 - angle) * 0.02) + 1) * (angle/45);//an inaccurate formula to offset the ball to be on top of the slope that works just fine with some glitches
rb.position = hits[1].point + new Vector2(0, factor * 1f);//position the ball at the point were the ray cast downward from the mouse hit
//(that puts the ball center on the line of the slope) so I offset it usinf the formula above
}
}
}
private int checkGround()
{
int h = Physics2D.RaycastNonAlloc(Camera.main.ScreenToWorldPoint(Input.mousePosition), -Vector2.up, hits); //cast downwards
return h;
}
}
这里有球的设置:
和倾斜设置:
球的拖动工作正常,有一点玩家可以将它拖到空中或进入斜坡,我设法用新代码修复它,所以现在玩家只能将它拖到边缘上,尽管我的计算仍然有点缺陷,当斜坡角度发生变化时,球会在斜坡内部倾斜一点,并在释放时导致一些问题。
用来解决问题的方法很简单,当玩家开始拖动球时,我会向下投射一个光线,并在与斜坡碰撞的点上击球,抵消它以坐在顶部它的问题是,抵消部分不够准确。
我希望我解释自己好一点这一次谢谢:)
回答:
经过大量的试验和错误我还是设法拿出一个完美的解决了问题,所以我想我也可以分享答案也许它会帮助别人。
这里更新的代码我改变了我的完全限制了运动的方法,现在我用简单的直线方程如下图所示:
private void OnMouseDown() {
if (!isPressed)
{
//cast a ray on the slope
if (checkGround() > 1)
{
angle = Mathf.Abs(Mathf.Atan2(hits[1].normal.x, hits[1].normal.y) * Mathf.Rad2Deg); //get angle
slope = Mathf.Tan(angle * Mathf.Deg2Rad);//get the slope steepiness
}
isPressed = true;
rb.isKinematic = true;
}
}
private void OnMouseUp()
{
isPressed = false;
rb.isKinematic = false;
StartCoroutine(release());
}
void Update() {
if (isPressed)
{
xMove = Camera.main.ScreenToWorldPoint(Input.mousePosition).x - spring.position.x;//get how much the mouse moved backward or forward
if (xMove < -3f) xMove = -3f; //restrict the drag range to 3 backward
if (xMove > 0.3f) xMove = 0.3f;//restrict the drag range to 0.3 forward
xpos = spring.position.x+xMove;//since the ball and the spring start at exactly the same position the new ball's x position would be the spring x + the x movement we calculated above
ypos = (xMove * slope)- spring.position.y; //the y posistion would be y=mx+b so the the x movement * the slop steepiness - the starting y position
rb.position = new Vector2(xpos, -ypos);//set the new position of the ball
}
}
private int checkGround()
{
int h = Physics2D.RaycastNonAlloc(Camera.main.ScreenToWorldPoint(Input.mousePosition), -Vector2.up, hits); //cast downwards
return h;
}
以上是 仅在UNITY 的全部内容, 来源链接: utcz.com/qa/257482.html