所以,就像标题所说的那样,我正在制作一个多方向物理的2D平台游戏,但是我缺乏三角技术让我感到害怕。
当我的角色遇到某些东西时,它会返回一个Vector2 hitPoint。
如果这是一个单向重力平台游戏,我会做以下事情:
// considering the player's origin point in the middle
public void HitGround(Vector2 hitPoint)
{
this.position.y = hitPoint.y + height /2;
}
// considering the player's origin point in the middle
public void HitGround(Vector2 hitPoint)
{
this.position.y = hitPoint.y + height /2;
}
但由于这有多重物理学,这种简单的方法无法完成。所以我已经处理了相对位置,假设引力是(-3,-3),玩家会向西南方向移动。
// considering the player's origin point in the middle
public void HitGround(Vector2 hitPoint)
{
this.position = hitPoint + GetRelativeYPos(height / 2);
}
// returns the relative Y position based on its rotation
public Vector2 GetRelativeYPos(float offset)
{
// rotation is a Quaternion
return this.rotation * new Vector2(0, 1) * offset;
}
到目前为止,这么好。它完美地工作!但是等等......这只有在玩家的中心击中地面时才有效。事实上,玩家在坠落时会有3次射线投射。如果中心光线投射到地面,则代码在每个方向上都工作。
但当EDGE RAYCASTS击中地面时。玩家倾向于中心,因为代码不允许他向右移动。现在,我的最后一个代码想法诞生了:
// considering the player's origin point in the middle
public void HitGround(Vector2 hitPoint)
{
this.position = hitPoint + GetRelativeYPos(height / 2);
}
// returns the relative Y position based on its rotation
public Vector2 GetRelativeYPos(float offset)
{
// rotation is a Quaternion
return this.rotation * new Vector2(0, 1) * offset;
}
你去了!
当代码不起作用时,它只是因为角度的符号,由于某种原因,它被计算错误,当角度必须为正时,它返回负数,反之亦然,但它只有当“玩家的相对北位置”低于0时才会返回错误的值。
例如:
如果玩家跌倒,当Y位置高于0时,它会起作用,当它低于时,它就不起作用。
如果玩家正在下降,当Y位置低于0时,它会起作用,当它更高时,它不起作用。
如果玩家向右下方,当X位置低于0时,它就会起作用 更高,但没有。
如果玩家向左下方,当X位置大于0时,它会起作用,当它低于时,它不起作用。
再多一次:
如果玩家在东南方向下降,当Y位置高于0而X位置低于0时,它会起作用,否则,它不会
以下方法负责计算两点的“有符号距离”。我的意思是,结果向量的大小及其方向
public void HitGround(Vector2 hitPoint, Vector2 raycastOrigin)
{
// Considering that the raycastOrigin is in the same "relative X" as the player's origin
float signedDistance = SignedDistance(hitPoint, raycastOrigin);
this.position = hitPoint + GetRelativeYPos(height / 2) + GetRelativeXPos(signedDistance);
}
// returns the relative Y position based on its rotation
public Vector2 GetRelativeYPos(float offset)
{
return this.rotation * new Vector2(0, 1) * offset;
}
// returns the relative X position based on its rotation
public Vector2 GetRelativeXPos(float offset)
{
return this.rotation * new Vector2(1, 0) * offset;
}
public float SignedDistance(Vector2 p1, Vector2 p2)
{
float distance = Distance(p1, p2);
float angle = Atan2(p2.y, p2.x) + Atan2(p1.y, p1.x);
// Returns the magnitude AND direction of the vector
return distance * Sign(angle);
}
public void HitGround(Vector2 hitPoint, Vector2 raycastOrigin)
{
// Considering that the raycastOrigin is in the same "relative X" as the player's origin
float signedDistance = SignedDistance(hitPoint, raycastOrigin);
this.position = hitPoint + GetRelativeYPos(height / 2) + GetRelativeXPos(signedDistance);
}
// returns the relative Y position based on its rotation
public Vector2 GetRelativeYPos(float offset)
{
return this.rotation * new Vector2(0, 1) * offset;
}
// returns the relative X position based on its rotation
public Vector2 GetRelativeXPos(float offset)
{
return this.rotation * new Vector2(1, 0) * offset;
}
public float SignedDistance(Vector2 p1, Vector2 p2)
{
float distance = Distance(p1, p2);
float angle = Atan2(p2.y, p2.x) + Atan2(p1.y, p1.x);
// Returns the magnitude AND direction of the vector
return distance * Sign(angle);
}
这条线路有问题我无法解决。有人有点回答这个问题吗?
我希望我很清楚。再见