117 lines
2.2 KiB
C#
117 lines
2.2 KiB
C#
namespace ClientTester.DummyService;
|
|
|
|
public class MapBounds
|
|
{
|
|
public float MinX
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
public float MaxX
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
public float MinZ
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
public float MaxZ
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
public MapBounds(float minX, float maxX, float minZ, float maxZ)
|
|
{
|
|
MinX = minX;
|
|
MaxX = maxX;
|
|
MinZ = minZ;
|
|
MaxZ = maxZ;
|
|
}
|
|
|
|
// 위치가 경계 안에 있는지 체크
|
|
public bool IsInside(float x, float z)
|
|
{
|
|
return x >= MinX && x <= MaxX && z >= MinZ && z <= MaxZ;
|
|
}
|
|
|
|
// 경계 초과 시 clamp, 벽에 부딪혔으면 true 반환
|
|
public bool Clamp(ref float x, ref float z)
|
|
{
|
|
bool hit = false;
|
|
|
|
if (x < MinX)
|
|
{
|
|
x = MinX;
|
|
hit = true;
|
|
}
|
|
else if (x > MaxX)
|
|
{
|
|
x = MaxX;
|
|
hit = true;
|
|
}
|
|
|
|
if (z < MinZ)
|
|
{
|
|
z = MinZ;
|
|
hit = true;
|
|
}
|
|
else if (z > MaxZ)
|
|
{
|
|
z = MaxZ;
|
|
hit = true;
|
|
}
|
|
|
|
return hit;
|
|
}
|
|
|
|
// 현재 위치 기준으로 벽 반대 방향 rotY 계산 (벽 없으면 -1)
|
|
public int GetRotYAwayFromWall(float x, float z, float margin = 0.5f)
|
|
{
|
|
bool atLeft = x <= MinX + margin;
|
|
bool atRight = x >= MaxX - margin;
|
|
bool atBottom = z <= MinZ + margin;
|
|
bool atTop = z >= MaxZ - margin;
|
|
|
|
if (!atLeft && !atRight && !atBottom && !atTop)
|
|
{
|
|
return -1; // 벽 근처 아님
|
|
}
|
|
|
|
// 벽 반대 방향 벡터 합산
|
|
float awayX = 0f, awayZ = 0f;
|
|
if (atLeft)
|
|
{
|
|
awayX += 1f;
|
|
}
|
|
|
|
if (atRight)
|
|
{
|
|
awayX -= 1f;
|
|
}
|
|
|
|
if (atBottom)
|
|
{
|
|
awayZ += 1f;
|
|
}
|
|
|
|
if (atTop)
|
|
{
|
|
awayZ -= 1f;
|
|
}
|
|
|
|
// 정규화
|
|
float len = MathF.Sqrt(awayX * awayX + awayZ * awayZ);
|
|
awayX /= len;
|
|
awayZ /= len;
|
|
|
|
// 방향 벡터 → rotY (degree)
|
|
return ((int)(MathF.Atan2(awayX, awayZ) * 180f / MathF.PI) + 360) % 360;
|
|
}
|
|
}
|