ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RPG 듀토리얼 17. BOSS!!! 01 / 02 (Attack)
    유니티 프로젝트/RPG 듀토리얼

    안녕하세요!!!

    오늘은 튜토리얼의 클리어가 되는 조건인 

    소탕할 Boss에 대해서 작업을 하겠습니다!

     

    이렇게 생긴 녀석인데

     

    유니티 에셋 스토어에서 무료로 가져온 에셋입니다.

     

    (상당히 많은 에셋들이 듀토리얼의 Boss로 거쳐갔습니다...)

     

    이 보스의 위치는 이 병사가? 알려주었었죠 ㅎㅎ

     

    바로 스크립트로 넘어가 보겠습니다.

     


    보스를 제어하기 위해 EnemyBoss 스크립트를 만들었고

    열거형으로 boss의 상태 값을 선언해 주었습니다.

    enum은 상수의 일종으로 const대신 사용하며

    const값을 입력하지 않아도 자동으로 0,1,2.... 의 값이 대입됩니다.

    (코드가 단순해지며 가독성이 좋고, 상수 이므로 if문 swith문에서 사용이 가능합니다.)

     

    Idle : 대기

    Mve : 움직임

    Attack : 공격

    Return : 복귀

    Damaged : 대미지 받음

    Die : 죽음

     

    이며 이 열거형을 제어하기 위해 bossState의 변수를 선언해 주었습니다.

     

    나머지 선언 변수들도 한꺼번에 보겠습니다.

     

    MoveDis : 보스가 움직일 수 있는 거리

    findDis : 보스가 플레이어를 찾을 거리

    atkDis : 보스의 공격 거리

    (보스의 움직일수 있는 거리를 초과해 벗어난다면 보스는 복귀를 하게 되며

    각 범위 안에 있을 시 해당 상태 값의 동작을 실행합니다.)

     

    currentTime : 현재 시간

    attackDelay : 공격 딜레이 시간

    (현재 시간을 준 이유는 현재시간을 누적시켜 공격 딜레이 시간 이상이 된다면

    공격을 하기 위함입니다.)

     

    player : 플레이어

     

    nav : 보스의 NavMeshAgentf를 담을 변수

    ani : 보스의 Animator를 담을 변수

     

    attackPower : 보스의 공격력

    maxHp : 보스의 최대 hp

    Hp : 보스의 현재 hp

    (hp를 나눈 이유는 현재로선 복귀했을 시 최대 hp로 만들어 주기 위함입니다.)

     

    moveSpeed : 보스의 스피드입니다.

     

    hpSlider : 보스의 체력바 Slide입니다.

     

    orizinPos : 보스의 초기 위치 값입니다.

    orizinRot : 보스의 초기 회전 값입니다.

    (리턴하여 복귀 시 해당 값을 설정해 주기 위함입니다.)

     

    targetTool / targetRect

    (보스가 Die 상태 일 시 활성화돼있는 오브젝트를 비활성화해주기 위함입니다.)

     

    attackStep : 공격 스탭입니다.

    (보스의 공격 스탭 별로 각 다른 공격을 하게 됩니다)

     

    atk01 / atk02 / atk03 

    보스의 공격 콜라이더입니다.

    (콜라이더를 매 활성화해 놓지 않고 이벤트로 시간에 맞춰 활성/비활성을 하게 구현했습니다.)

     

    text / text_Clear : 보스를 소탕했을 시 띄워줄 텍스트 들입니다.

    (TextMeshProUGUI를 사용하기 위해 using TMPro를 선언해 주었습니다.)

     


    Start 함수입니다.

     

    우선 BossState의 초기 상태는 Idle로 지정해 주었으며

    각 필요한 값을 변수에 할당해 주었습니다.

     

    EbemyBoss 스크립트의 Update함수입니다.

     

    hp를 동기화해주기 위하여 현재 값 / 최댓값으로

    0.0f ~ 1.0f의 값을 갖게 해 주었습니다.

    (slide의 value 값은 0.0~1.0의 값을 갖고 있습니다.

    ex : 0.5 = 50%입니다.)

     

     

    BossState의 값이 Idle일 때 실행되는 Idle 함수입니다.

     

    간단히 거리를 측정하기 위해 Distance를 사용하였으며

    (Distance와 magnitude , sqrMagnitude의 거리 측정 방법이 있습니다.

    여기서 Distance와 magnitude는 과정 및 결과는 같지만

    편의를 위해 Distance 함수를 제공하고 있으며

    sqrMagnitude는 루트 값을 연산하지 않아 빠르다고 알고 있습니다.)

     

    즉 추적 범위 안에 플레이어가 온다면 BossState의 값을 Move로 바꿔주는 코드입니다.

    BossState의 값이 Move일 때 실행되는 Move함수입니다.

     

    이 move 함수에서는 if - else if 문을 통해 3가지 조건을 걸어 주었습니다.

    첫째.  보스가 초기위치에서의 거리가 움직일 수 있는 moveDis보다 크다면 복귀를 합니다.

    둘째. 보스에서 플레이어의 위치 거리가 공격 범위보다 크다면 플레이어를 향해 이동합니다.

    셋째. 보스에서 플레이어의 위치 거리가 공격 범위 안에 포함되어 있다면 공격을 하게 됩니다.

     

    각 복귀 / 공격 은 BossState값을 Return / Attack 값으로 조정을 해 주었고

    둘째 else If에서 네비를 멈춰 주고(isStopped = true) 목적지를 초기화 (ResetPath())

    를 해주며 경로를 다시 잡아준 이유는, 

    atkDis 안에 플레이어가 포함되어 있다가, Boss가 공격을 하는 도중 플레이어가 거리를 벗어났을 시

    미끄러지듯 움직이는 Boss를 제어하기 위함입니다.

     

    BossState의 값이 Attack일 때 실행되는Attack함수입니다.함수 입니다.

     

    BossState의 상태가 Attack 상태가 되면

    LookAt 함수를 통해 Player.position으로 회전을 하게 해 주었습니다.

     

    이후 atkDis의 범위 안에 들어왔다가 Player가 다시 벗어날 수 있기에

    Distance 함수로 보스에서 플레이어의 위치를 검사해 atkDis 안에 포함되어 있다면

    공격을 실행합니다.

     

    우선 currentTime을 +=연산자로 Time.deltaTime * 1로 +1씩 누적시켜 주었습니다.

    (여기서 *1을 해준 이유는, 안 해줘도 여기선 이상 현상이 발생하지 않았지만

    player를 작업할 때 +=연산자로 Time.deltaTime의 값을 누적시켜 주면

    잘 되다가도 한 번씩 지정 값을 넘어가는 현상이 발생해서입니다.)

    (이유를 꼭 알아오겠습니다.)

     

    이렇게 값을 누적시켜 주어 공격 딜레이 이상이 됐다면 Switch(attackStep)으로 각 case에 맞게 실행합니다.

    이 attackStep은 Random.range(0,5)로 0부터 4까지의 값을 부여받게 했습니다.

    Random.range의 값이 실수면 해당 범위 즉 0f ~ 5f까지 되지만

    Random.range의 값이 정수면 해당 범위를 제외한 0 ~ 4까지 됩니다.

     

    case는 attackStep이

    0과 1

    2와 3

    로 3가지로 나눴습니다.

     

    이렇게 나눈다면 각 40% / 40% / 20% 확률이 됩니다.

    이후 공격을 실행했으면 currentTime = 0으로 바꿔줍니다.

    (다시 값을 누적할 때 0부터 하기 위함)

     

    보스의 위치에서 플레이어의 위치가 공격 범위 안에 있지 않다면

    실행될 else문입니다.

    BossState의 값을 Move로 변경시켜 주어

    Move 함수에서 각 거리 값에 맞는 조건문을 실행해 줍니다.

    여기서도 마찬가지로 currentTime은 0으로 초기화해주었습니다.

    (공격을 실행하지 않았더라도 누적되었던 값을 초기화시켜주어 0부터 새로 누적을 하기 위함입니다.)

     

     

    Boss의 공격 부분을 영상으로 보시겠습니다.

     

     

    00 : 28초

     

    댓글

김효겸 / Tel. 010-7735-0580 / E-mail. dollzzang2@hanmail.net