ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • DNF 충돌 시스템
    게임 클라이언트 개발/MakeDNF 2023. 12. 3. 19:22

    Hitbox를 Collider Component를 사용하지 않고 직접 구현함에 따라 Unity의 충돌 시스템이 아닌 직접 충돌 알고리즘을 작성해야 한다.

     

     던전 앤 파이터의 월드 좌표계는 회전할 일이 없다. (차원회랑의 모로스 보스의 패턴 중 장례식 패턴에서 화면이 회전하는 경우가 존재하나 이는 카메라 회전을 통해 구현할 수 있다.)

     

    그렇다면 선택할 수 있는 충돌 알고리즘은 AABB 알고리즘과 OBB 알고리즘이 있다. 어떤 충돌 알고리즘을 사용할 지 선택하기 위해 오브젝트의 좌표계가 회전하는지에 대한 여부를 확인할 필요가 있다.

     

    대표적인 회전된 오브젝트로 런처의 양자라는 스킬이 존재한다. 양자 스킬을 사용할 경우 대각선 방향으로 미사일 오브젝트가 떨어지며 미사일 오브젝트는 45도 회전되어있다.

    양자 스킬의 미사일 오브젝트

     

    미사일 오브젝트의 히트박스가 회전되있을 경우 첫번째 애쉬코어와는 충돌이 발생하지 않아야 한다.

    OBB 알고리즘을 사용할 경우 오브젝트들의 히트박스

     

    하지만 첫번째 애쉬코어와 충돌함을 확인할 수 있다. 즉, 미사일 그래픽이 회전되있더라도 히트박스는 회전시키지 않았고, OBB 알고리즘이 아닌 AABB 알고리즘을 사용했음을 추측할 수 있다.

    양자 미사일에 피격된 첫번째 애쉬코어
    AABB 알고리즘을 사용했음을 추측할 수 있다.

     

    $XZ$ 평면에서의 충돌 시 Hitbox 모양은 Box와 Circle 총 두 가지가 있고, $XY$ 평면에서의 충돌 시 Hitbox 모양은 Box로 통일했다. 이에 따라 AABB 알고리즘을 작성했다. 

     

    Box, Box

    Box와 Box의 충돌 검사 로직은 두 Box의 각 축의 최대, 최소값을 비교하면 된다. Box의 하나의 축이라도 1번 Box의 최소값이 2번 Box의 최대값보다 크거나 1번 Box의 최대값이 2번 Box의 최소값보다 작다면, 충돌하지 않음을 의미한다.

    Box와 Box의 충돌 검사

    bool CheckBB(Hitbox b1, Hitbox b2)
        // collision do not occur in X axis
        if b1.maxX < b2.minX or b1.minX > b2.maxX
            return false 
            
        // collision do not occur in Z axis
        if b1.maxZ < b2.minZ or b1.minZ > b2.maxZ
            return false 
        
        return true // collision occur in XZ coordinates

     

    Circle, Circle

    Circle과 Circle의 충돌 검사 로직은 두 Circle의 중점 간 거리와 각 Circle의 반지름의 합을 비교하면 된다. 반지름의 합이 두 Circle의 중점 간 거리보다 작다면, 충돌하지 않음을 의미한다.

    Circle과 Circle의 충돌 검사

    bool CheckCC(Hitbox c1, Hitbox c2)
        dist = (c1.center - c2.center).sqrMagnitude
        sumRadius = c1.radius + c2.radius
        
        // collision do not occur
        if dist > sumRadius
            return false
            
        return true // collision occur

     

    Box, Circle

    Box와 Circle의 충돌 검사 로직은 Box를 기준으로 영역을 나누어 Circle의 중점의 위치에 따라 Box와 비교하면 된다.

    • 4 : Box와 Circle은 충돌함
    • 1, 7 : Circle과 Box 중점의 $Y$축 거리를 Circle의 반지름과 Box의 높이의 절반의 합과 비교한다.
    • 3, 5 : Circle과 Box 중점의 $X$축 거리를 Circle의 반지름과 Box의 넓이의 절반의 합과 비교한다.
    • 0, 2, 6, 8 : Box의 각 모서리가 Circle의 내부에 위치하는지 확인한다.

    Box와 Circle의 충돌 검사

    bool CheckBC(Hitbox b, Hitbox c)
        column = b.maxX < c.center.x ? 2 : (b.minX > c.center.x ? 0 : 1)
        row = b.maxY < c.center.y ? 2 : (b.minY > c.center.y ? 0 : 1)
        index = column + 3 * row
        
        if index = 4
            return true // collision occur
            
        elif index = 1, 7
            return Abs(b.center.y, c.center.y) < b.height * 0.5f + c.radius
            
        elif index = 3, 5
            return Abs(b.center.x, c.center.x) < b.width * 0.5f + c.radius
        
        return CheckInsideCircle(c, b.corner)

    '게임 클라이언트 개발 > MakeDNF' 카테고리의 다른 글

    Skill 시스템 구현 및 개선  (0) 2024.01.10
    DNF Input System  (0) 2023.12.11
    Hitbox with DNFTransform  (0) 2023.12.02
    2.5D 좌표계, DNFTransform  (0) 2023.12.01
    프로젝트를 시작하기 전에  (0) 2023.11.29
Designed by Tistory.