非常感谢您的帮助。我正在尝试使用角色向前播放的盒装广播来确定角色需要旋转多少才能开始围绕对象自由移动。
这里是情况的图片。角色被卡住,试图在两个红色圆柱之间移动,因为他的对撞机太宽,无法穿过。小球体代表他路径中的航点,蓝色球体是最终航点。青色球不是路径的一部分。
这是另一张图像,您可以在其中看到角色的碰撞器和其中一个圆柱体的碰撞器。两个对撞机都接触地面,在圆柱体的情况下,它恰好位于地面以下
在这个确切的点上需要解决的问题是角色必须旋转多少才能开始围绕右侧的圆柱体向右侧移动。然后,我需要确定代表该点的地面上的点以开始移动。在上面的图片中,我能做的最好的就是青色的球体,您可以看到,这显然不是开始四处走动的方法。它离圆柱体太近了。角色在其尝试移动到的任何点(它的对撞机半径)周围都需要1.75f的游隙半径,并且尝试从当前位置移到青色球体会使其与右侧的红色圆柱体接触。
这里的代码试图确定角色需要向右旋转多少,并计算沿该旋转一定距离的点。它使用的BoxCast似乎无法正常工作:
// first need to determine if the character that is moving forward collides with
// an object in the way
// the character is moving along 'path', which is a series of waypoints
dir = transform.forward;
gizmoBoxHit = Physics.BoxCast(transform.position, new Vector3(1.75f, 1.75f, 0.01f), dir, out boxHit, transform.rotation, 1.75f );
if ( gizmoBoxHit )
{
// here we've correctly determined it hit an object by doing a
// boxcast forward that is exactly as wide and forward (i think)
// as the character's collider. I believe its correct because
// as you can see from the images the character has stopped at the
// correct point, just in contact with a cylinder based on the
// boxcast.
movementPaused = true;
if (!stopTrying)
{
bool foundAround = false; // flag should turn true when way around is found
float rotateLimit = 180f; // most rotation i want to test
float rotationInterval = 3f; // increments of rotation tested
float rotationAdded = 0f; // current cumulative rotation added
Vector3 currentRotation = transform.rotation.eulerAngles;
Vector3 facingDirection = transform.forward.normalized;
float collidedWidth = boxHit.transform.GetComponent<BasicProperties>().colliderRadius * 2f;
// testLength is how far away I want to point to be in the
// correct direction, the width of the cylinder plus radius of character
testLength = basicProperties.colliderRadius + collidedWidth;
euler = Vector3.zero;
// loop a cumulative building rotation until you find the
// correct rotation
while (!foundAround && rotationAdded < rotateLimit)
{
rotationAdded += rotationInterval;
currentRotation.y += rotationInterval;
euler = new Vector3(0, rotationAdded, 0);
LayerMask wtfLayerMask = (1 << LayerMask.NameToLayer("Champions")) | (1 << LayerMask.NameToLayer("NPCs"));
// HERE LIES THE PROBLEM:
// BoxCast result should be true until a clear path is found, at which point it should become false. But its becoming false too early,
// with too small of a rotationAdded
newPathFoundHit = Physics.BoxCast(transform.position, new Vector3(1.75f, 1.7f, 0.01f), facingDirection, out newPathBoxHit, Quaternion.Euler(euler), testLength, wtfLayerMask);
if (!newPathFoundHit)
{
foundAround = true;
}
}
// based on rotation determined, figure out the point
Vector3 vector = transform.forward * testLength;
vector = Quaternion.AngleAxis(rotationAdded, Vector3.up) * vector;
Vector3 globalVector = transform.TransformPoint(vector);
// draw a cyan sphere to see where the resulint point is.
GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
sphere.GetComponent<Renderer>().material.color = Color.cyan;
sphere.transform.position = globalVector;
stopTrying = true;
}
}
else
{
movementPaused = false;
}
因此该代码不起作用。在到达角色实际上可以开始围绕圆柱体移动的点之前,旋转停止。从青色球体可以看到,它大约是60度,从角色的向前方向取或取,但它需要像110-120才能开始围绕右侧的圆柱体移动。我已经尝试解决这个问题了好几个小时,但我认为我正在正确地使用BoxCast,但一定不能。到青色圆柱体的3.5f宽的箱形广播绝对不会与红色圆柱体接触,这就是导致旋转步骤停止循环的原因。
我一定在做BoxCast错误。任何帮助将不胜感激。谢谢。