static float GetDistanceToGround(RayCastManager scene, Vector3 pos, int height) { VecInt3 g = pos; Vector3 localPos = pos - g; if (scene.isWalkable(g.x, g.y - 1, g.z, height)) { return(1 + localPos.y); } else if (scene.isWalkable(g.x, g.y, g.z, height)) { return(localPos.y); } else if (!scene.isWalkable(g.x, g.y, g.z, height)) { return(localPos.y - 1); } return(1); }
static Vector3 GetNearestWalkablePos(RayCastManager scene, Vector3 pos, int height) { float r = 0.3f; VecInt3 g = pos; Vector3 localPos = pos - g; VecInt3 step;//移动的方向,-1,0,1 step.x = localPos.x < r ? -1 : (localPos.x > (1 - r) ? 1 : 0); step.z = localPos.z < r ? -1 : (localPos.z > (1 - r) ? 1 : 0); Vector3 offset;//退回到正确的位置需要移动的量 offset.x = step.x == -1 ? r - localPos.x : (step.x == 1 ? ((1 - r) - localPos.x) : 0); offset.z = step.z == -1 ? r - localPos.z : (step.z == 1 ? ((1 - r) - localPos.z) : 0); bool bCanMoveX = step.x != 0 ? scene.isWalkable(g.x + step.x, g.y, g.z, height) : true; bool bCanMoveZ = step.z != 0 ? scene.isWalkable(g.x, g.y, g.z + step.z, height) : true; bool bCanMoveXZ = (step.x != 0 && step.z != 0) ? scene.isWalkable(g.x + step.x, g.y, g.z + step.z, height) : true; bool bCanUpX = scene.isWalkable(g.x + step.x, g.y + 1, g.z, height); bool bCanUpZ = scene.isWalkable(g.x, g.y + 1, g.z + step.z, height); bool bCanUpXZ = scene.isWalkable(g.x + step.x, g.y + 1, g.z + step.z, height); bCanMoveX |= bCanUpX; bCanMoveZ |= bCanUpZ; bCanMoveXZ |= bCanUpXZ; if (!bCanMoveXZ && bCanMoveX && bCanMoveZ) { if (Mathf.Abs(offset.x) < Mathf.Abs(offset.z)) { bCanMoveX = false; } else { bCanMoveZ = false; } } if (!bCanMoveX) { pos.x += offset.x; } if (!bCanMoveZ) { pos.z += offset.z; } //if ((!bCanMoveX) || (!bCanMoveZ)) { // bool bCanStepUp = scene.testBlock(g.x + step.x, g.y + 1, g.z + step.z, RayCastBlockType.Walkable); // if (bCanStepUp) { // pos.y = g.y + 1; // } // else { // // } //} return(pos); }
static bool IsWalkable(RayCastManager scene, Vector3 pos, int height) { VecInt3 g = pos; return(scene.isWalkable(g.x, g.y, g.z, height)); }