feat: 적과 충돌 시 미끄러짐 방지 및 8방향 양자화
- OnControllerColliderHit으로 적 충돌 감지 - 충돌 방향으로의 이동만 차단하여 튕겨나가지 않음 - 충돌 normal을 45도 간격으로 양자화하여 8각형 충돌 느낌 구현 - Enemy 레이어 추가 Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -31,6 +31,10 @@ namespace Colosseum.Player
|
||||
private bool isJumping;
|
||||
private bool wasGrounded;
|
||||
|
||||
// 적 충돌 방향 (이동 차단용)
|
||||
private Vector3 blockedDirection;
|
||||
private int enemyLayerMask;
|
||||
|
||||
/// <summary>
|
||||
/// 현재 이동 속도 (애니메이션용)
|
||||
/// </summary>
|
||||
@@ -79,6 +83,9 @@ namespace Colosseum.Player
|
||||
|
||||
// 카메라 설정
|
||||
SetupCamera();
|
||||
|
||||
// 적 레이어 마스크 초기화
|
||||
enemyLayerMask = LayerMask.GetMask("Enemy");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -233,10 +240,24 @@ namespace Colosseum.Player
|
||||
moveDirection = TransformDirectionByCamera(moveDirection);
|
||||
moveDirection.Normalize();
|
||||
|
||||
// 충돌 방향으로의 이동 차단 (미끄러짐 방지)
|
||||
if (blockedDirection != Vector3.zero)
|
||||
{
|
||||
float blockedAmount = Vector3.Dot(moveDirection, blockedDirection);
|
||||
if (blockedAmount > 0f)
|
||||
{
|
||||
moveDirection -= blockedDirection * blockedAmount;
|
||||
moveDirection.Normalize();
|
||||
}
|
||||
}
|
||||
|
||||
// 이동 적용
|
||||
Vector3 moveVector = moveDirection * moveSpeed * Time.deltaTime;
|
||||
characterController.Move(moveVector + velocity * Time.deltaTime);
|
||||
|
||||
// 충돌 방향 리셋
|
||||
blockedDirection = Vector3.zero;
|
||||
|
||||
// 회전 (이동 중일 때만)
|
||||
if (moveDirection != Vector3.zero)
|
||||
{
|
||||
@@ -330,5 +351,43 @@ namespace Colosseum.Player
|
||||
|
||||
wasGrounded = characterController.isGrounded;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CharacterController 충돌 처리. 적과 충돌 시 해당 방향 이동을 차단합니다.
|
||||
/// 충돌 normal을 8방향으로 양자화하여 각진 충돌 느낌을 줍니다.
|
||||
/// </summary>
|
||||
private void OnControllerColliderHit(ControllerColliderHit hit)
|
||||
{
|
||||
// 적과의 충돌인지 확인
|
||||
if ((enemyLayerMask & (1 << hit.gameObject.layer)) != 0)
|
||||
{
|
||||
// 충돌 방향 저장 (이동 차단용)
|
||||
blockedDirection = hit.normal;
|
||||
blockedDirection.y = 0f;
|
||||
blockedDirection.Normalize();
|
||||
|
||||
// 8방향으로 양자화 (45도 간격)
|
||||
blockedDirection = QuantizeToOctagon(blockedDirection);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 방향을 8각형(45도 간격) 방향으로 양자화합니다.
|
||||
/// </summary>
|
||||
private Vector3 QuantizeToOctagon(Vector3 direction)
|
||||
{
|
||||
if (direction == Vector3.zero)
|
||||
return direction;
|
||||
|
||||
// 각도 계산
|
||||
float angle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg;
|
||||
|
||||
// 45도 단위로 반올림
|
||||
float snappedAngle = Mathf.Round(angle / 45f) * 45f;
|
||||
|
||||
// 다시 벡터로 변환
|
||||
float radians = snappedAngle * Mathf.Deg2Rad;
|
||||
return new Vector3(Mathf.Sin(radians), 0f, Mathf.Cos(radians));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user