RaycastHit returns 在 objects 交换位置时没有命中
RaycastHit returns no hit when objects swap positions
我正在移动一排盒子,想创造一个无限的效果。最后一个方块将与开头的克隆方块交换位置(见图)。
出于调试目的,我使用 boxcast 作为每个盒子的 raycast。它不像盒子那样移动,而是像图片中的第一行 (1.) 一样。
在我用克隆框更改第 5 个框位置并停用克隆框之前,boxcast 工作正常。我的第一个 boxcast 在交换位置后 6-10 帧没有碰撞器,即使 box 5 transform.position 正好在 boxcast 位置上。
我试过在 Boxcasting 之前更新 Physics Transform。尝试了不同的 Raycasts(Overlapbox、Ray、...)。
private void MoveRowOfBlocks(float m)
{
//debug variable set true when setting box position to clone position
bool exceed = false;
for (int i = 0; i < movingBlockRow.Length; i++)
{
GameBlock go = movingBlockRow[i].GetComponent<GameBlock>();
// Block exceeds valid area -> Swap with clone block
while (movingDir == Vector2.right && go.transformPositionCache.x + m > GameField.xFieldExtent_M - GameField.blockWidth / 2
|| movingDir == Vector2.left && go.transformPositionCache.x + m < -GameField.xFieldExtent_M + GameField.blockWidth / 2
|| movingDir == Vector2.up && go.transformPositionCache.y + m > GameField.yFieldExtent_M - GameField.blockWidth / 2
|| movingDir == Vector2.down && go.transformPositionCache.y + m < -GameField.yFieldExtent_M + GameField.blockWidth / 2)
{
exceed = true;
go.transformPositionCache -= GameField.totalWidth * movingDir;
//go.transform.position = go.transformPositionCache + (m * new Vector2(Mathf.Abs(movingDir.x), Mathf.Abs(movingDir.y)));
blockExceedCount += movingSign;
Debug.Log(go.name + " Exceeds field. Position from beginning. " + "New Position: " + go.transformPositionCache
+ " movingDir: " + movingDir + " Frame: " + debugFrameCount);
if (blockClone != null || clonedBlock != null)
{
blockClone.SetActive(false);
blockClone = null;
clonedBlock = null;
}
cachedExceededBlock = go;
debugCount++;
}
debugCount = 0;
go.transform.position = go.transformPositionCache + (m * new Vector2(Mathf.Abs(movingDir.x),Mathf.Abs(movingDir.y)));
if (exceed) Debug.LogError(go.transform.position);
}
// Move Cloned Object
if (blockClone != null)
{
Vector2 dest = (Vector2)clonedBlock.transform.position + (GameField.totalWidth * cloneMovingDir) * -1;
blockClone.transform.position = dest;
}
if (exceed)
{
Physics.SyncTransforms();
Debug.LogError(movingBlockRow[4].transform.position);
}
// Using Boxcasts foreach init box position for debugging
foreach (Vector3 v in gameField.gridPointsWorldPosition) // gridpointsworldposition is initial box position (1.)
{
RaycastHit2D rayHit = Physics2D.BoxCast(v, new Vector2(GameField.blockWidth/2, GameField.blockWidth/2), 0, Vector2.zero);
if (rayHit.collider == null)
{
Debug.LogError("NO BOX FOUND IN CELL " + v + " Box position: " + movingBlockRow[4].GetComponent<BoxCollider2D>().transform.position
+ " Frame: " + debugFrameCount); // Rayhit.collider is null even though box position = v
}
}
debugFrameCount++;
}
为每个盒子添加刚体解决了我的问题。
编辑:好吧,它只有在我没有像上面所示那样进行 Boxcast 检查时才有效。当我在下一帧调用的 movingblocks 方法之前将它放在 Update 中时,它会起作用。
所以通过使用 Rigidbodys 它仍然没有击中确切的帧,而是击中了下一帧!所以我通过调用协程并等待一帧来解决我的问题。
如果您希望对象表现得好像它没有刚体,请将刚体设置为静态。
我正在移动一排盒子,想创造一个无限的效果。最后一个方块将与开头的克隆方块交换位置(见图)。
出于调试目的,我使用 boxcast 作为每个盒子的 raycast。它不像盒子那样移动,而是像图片中的第一行 (1.) 一样。
在我用克隆框更改第 5 个框位置并停用克隆框之前,boxcast 工作正常。我的第一个 boxcast 在交换位置后 6-10 帧没有碰撞器,即使 box 5 transform.position 正好在 boxcast 位置上。
我试过在 Boxcasting 之前更新 Physics Transform。尝试了不同的 Raycasts(Overlapbox、Ray、...)。
private void MoveRowOfBlocks(float m)
{
//debug variable set true when setting box position to clone position
bool exceed = false;
for (int i = 0; i < movingBlockRow.Length; i++)
{
GameBlock go = movingBlockRow[i].GetComponent<GameBlock>();
// Block exceeds valid area -> Swap with clone block
while (movingDir == Vector2.right && go.transformPositionCache.x + m > GameField.xFieldExtent_M - GameField.blockWidth / 2
|| movingDir == Vector2.left && go.transformPositionCache.x + m < -GameField.xFieldExtent_M + GameField.blockWidth / 2
|| movingDir == Vector2.up && go.transformPositionCache.y + m > GameField.yFieldExtent_M - GameField.blockWidth / 2
|| movingDir == Vector2.down && go.transformPositionCache.y + m < -GameField.yFieldExtent_M + GameField.blockWidth / 2)
{
exceed = true;
go.transformPositionCache -= GameField.totalWidth * movingDir;
//go.transform.position = go.transformPositionCache + (m * new Vector2(Mathf.Abs(movingDir.x), Mathf.Abs(movingDir.y)));
blockExceedCount += movingSign;
Debug.Log(go.name + " Exceeds field. Position from beginning. " + "New Position: " + go.transformPositionCache
+ " movingDir: " + movingDir + " Frame: " + debugFrameCount);
if (blockClone != null || clonedBlock != null)
{
blockClone.SetActive(false);
blockClone = null;
clonedBlock = null;
}
cachedExceededBlock = go;
debugCount++;
}
debugCount = 0;
go.transform.position = go.transformPositionCache + (m * new Vector2(Mathf.Abs(movingDir.x),Mathf.Abs(movingDir.y)));
if (exceed) Debug.LogError(go.transform.position);
}
// Move Cloned Object
if (blockClone != null)
{
Vector2 dest = (Vector2)clonedBlock.transform.position + (GameField.totalWidth * cloneMovingDir) * -1;
blockClone.transform.position = dest;
}
if (exceed)
{
Physics.SyncTransforms();
Debug.LogError(movingBlockRow[4].transform.position);
}
// Using Boxcasts foreach init box position for debugging
foreach (Vector3 v in gameField.gridPointsWorldPosition) // gridpointsworldposition is initial box position (1.)
{
RaycastHit2D rayHit = Physics2D.BoxCast(v, new Vector2(GameField.blockWidth/2, GameField.blockWidth/2), 0, Vector2.zero);
if (rayHit.collider == null)
{
Debug.LogError("NO BOX FOUND IN CELL " + v + " Box position: " + movingBlockRow[4].GetComponent<BoxCollider2D>().transform.position
+ " Frame: " + debugFrameCount); // Rayhit.collider is null even though box position = v
}
}
debugFrameCount++;
}
为每个盒子添加刚体解决了我的问题。
编辑:好吧,它只有在我没有像上面所示那样进行 Boxcast 检查时才有效。当我在下一帧调用的 movingblocks 方法之前将它放在 Update 中时,它会起作用。
所以通过使用 Rigidbodys 它仍然没有击中确切的帧,而是击中了下一帧!所以我通过调用协程并等待一帧来解决我的问题。
如果您希望对象表现得好像它没有刚体,请将刚体设置为静态。