ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RPG 액션 연습 05. Bomb_Move
    연습 프로젝트/RPG 연습

    이번엔 Player를 따라와서 폭파되며 대미지를 입히는

    Bomb_Move의 Enemy를 만들어 보겠습니다.

    Bomb_Idle의 제작 시와 똑같이 유니티 에셋 스토어에서 무료로 다운로드하여 하여온 에셋을

    모델로 사용했습니다.

     

    Bomb_Idle과는 다르게 Bomb_Move는 모자를 쓰고 있습니다.

     

    바로 제작해 보겠습니다.

    Bomb_Move 가 가지고 있는 상태 값 입니다.

    Idle : 대기 상태

    Move : 이동 상태

    Die : 죽음 상태

     

    Bomb_Move는 특별한 목적지 입력이 필요하지 않은 상태로

    생성 시 Player를 향해 달려가므로, 3가지 상태로 구현을 했습니다.

    Bomb_Move에 선언된 변수들입니다.

     

    각 player / bombEffect / message는 Transform / GameObject / TextMeshProUGUI입니다.

    public으로 선언하여 인스펙터 창에서 쉽게 가져올 수 있게 하였고.

     

    TextMeshProUGUI를 사용하기 위해 using TMPro로 네임 스페이스를 선언해 주었습니다.

     

    isDie = false로 Bomb_Move가 죽었는지 체크할 불 변수입니다.

     

    soundStart = false로 Bomb_Move가 죽을 시 사운드 중첩 현상을 막았습니다.

     

    private로 선언해도 되지만, 인스펙터 창에서 확인하기 위해 public으로 선언해서 동작 구현 작업을 했습니다.

     

    traceRadius : 추적 후 폭발될 범위 체크용 변수입니다.

     

    atkDis : 공격 범위입니다.

     

    Speed : Bomb_Move의 스피드 값입니다.

     

    time : Bomb_Move가 Player에게 붙어있는 시간을 시각화해주기 위해

    받아올 시간입니다.

     

    nav / ani / audio는 각 컴포넌트를 받아올 변수들이며

    nav = NavMeshAgent

    ani = Animator

    audio = AudioSource입니다.

     

    여기서도 audio에 녹색 밑줄이 쳐져서 new로 해결한 모습입니다 ㅎㅎ


    근데 가만히 생각을 해 보니, Bomb_Move가 활성화될 시 바로 Player를 향해 움직이게 

    구현하려고 하기 때문에 

    상태 값에서 Idel, Move, Die 3 상태 값에서 Idle을 지워줬습니다.


    이후 Start 함수에서 상태 값을 초기에 Move로 지정을 해 주고

    각 NavMeshAgent / Animator / AudioSource를 받아오는 모습입니다.

     

    여기서  nav.speed = Speed를 이용해 인스펙터 창에서 받아온 Speed 값을 

    Bomb_Move가 갖고 있는 NavMeshAgent의 스피드를 지정해 주었습니다.

     

    Move 함수

    Bomb_Move의 Move() 함수입니다.

    nav.destination = player.position을 통해 nav의 목적지를 player.position으로 향하게 해 주었습니다.

    ani.SetTrigger("IdleToMove") : SetTrigger를 통해 애니메이터에서 지정한 IdleToMove가 On 되게 해 주었습니다.

     

    여기에서도 Distance 함수를 사용하였습니다.

    계속 설명드려서 보시는 분들이 귀찮아하실 수 있지만.. 제가 기억하기 위해.. 한번 더 설명을 이어가겠습니다.

     

     오브젝트 간의 거리를 체크하는 데 있어서

    1.Distance와 2.magnitude 그리고 3.sqrMagnitude가 있습니다.

    1번과 2번의 결과 및 계산 방식은 동일하지만 편의를 위해 편의를 위해 Distance란 함수를 제공하는 것이고

    3번의 sqrMagnitude는 제곱 값을 리턴하며 루트 연산을 하지 않아 연산속도가 더 빠르고

    작거나 같은지만 비교하고 싶을 때 사용되는 sqrMagnitude입니다.

     

    sqrMagnitude를 사용해도 되지 않을까..? 생각을 해봤는데, 자연스레 자주 사용하는 Distance 함수로 손이 갔습니다.

     

    if(Vector3.Distance(transform.position, player.position) < atkDis)

    Distance를 이용해 Bomb_Move가 플레이어와 얼마나 떨어져 있는지를 계산하여

    atkDis(공격 범위) 안에 있다면 실행되는 if 조건문입니다.

     

    print("만남") : 콘솔 창에 출력을 통해서 기록을 할 수 있습니다.

    Debug.Log("만남")으로 출력을 해도 되지만, 손에 print를 쓰는 게 더 편해서..

     

    또한 Debug.Log로 콘솔에 기록을 해서 메시지를 선택하면 콘텍스트 오브젝트에 

    대한 선이 그려지고 오류 발생 오브젝트를 발견하는데 도움이 된다고 합니다.

    쓰이는 상황이 된다면 좀 더 자세히 설명드리겠습니다.

    print로 "만남" 을 출력한 모습 입니다.

    ATK() 함수를 실행시켜 주며

    SetActive를 true로 설정해 주어 message를 활성화시켜주고

    time에 Time.deltaTime을 누적시킵니다.

     

    첫 번째 if문 if (time < 1 && time > 0)을 보겠습니다.

    time은 float 변수로 선언했기에 실수가 가능합니다.

    현재 상태를 보면 time이 1보다 작고 0보다 크다는 조건인데.

    이를 본다면 0.1f - 0.9f 값의 실수가 가능해집니다.

     

    두 번째 else if문 : else if (time < 2 && time > 1)

    time이 2보다 작고 1보다 크다는 조건입니다.

    위와 마찬가지로 1.1f - 1.9f 식의 값이 가능해집니다.

     

    이로 정확한 값은 아니지만 1초 의 상태 일시 tow - 2 의 텍스트를

    2초의 상태일시 one - 1의 텍스트를 변경해 주는 모습입니다.

    Atk 함수에서는 코 루틴을 StartCorutinew으로 실행시켜 줬습니다.

     

    IEnumerator AtkEnum의 코루틴 함수는

    yield return new WaitForSeconds(1.5f)로 1.5f초의 시간을 대기시키게 했습니다.


    yield return new WaitForSeconds과 yield return new WaitForSecondsRealtime 이 있습니다!

    둘 다 기능은 같지만 WaitForSecondsRealtime은 Time의 Scale을 안 받습니다.

     

    BombEffect : 폭발 이펙트를 SetActive의 True로 활성화를 시켜두고.

    TextMeshProGUI를 받아온 message란 변수의 텍스트의 컬러는 Color.red (레드)

    fontSize : 폰트 사이즈는 120으로 지정해 주었으며

    표시될 문구는 text = "BOOM!!!"입니다.

     

    yield return new WaitForSeconds(1.3f) 초의 시간을 대기시켜주며

    대기시켜주는 이유는, Bomb_Move의 Die 모션을 다 재생하고 사라지게 만들기 위함입니다.

     

    마지막으로 Destory를 이용해 gameObject를 파괴시켜주었습니다.

     

     

     

    마지막으로 ExpEffect 함수입니다.

    Bomb_Idle과 똑같이 Collider를 받아와 주는 OverLapSphere를 사용하였습니다.

    인자는 (OverLapSphere(중심, 범위, 비트 연산 레이어로 레이어 6)) 을 나타냅니다.

    이렇게 받아온 콜라이더를 Collider [] coll의 변수에 담아 주었고

    이 coll을 검사하여 null이 아닐 시 에는

    캐릭터가 hit 받는 구현 함수인 DamageAction으로 (공격력 5)를 주었습니다.

     

    이렇게 초기 상태 시작점인 Move함수를 Update문에서 검사를 하게 하였고.

    Bomb_Move 가 죽을 시 사운드를 재생하기 위해

    if 문에 isDie = false (죽지 않았을 시) soundStart (사운드를 시작했는지)를 검사하여

    조건에 맞는다면 PlayOnShot 함수로 사운드를 재생시켜줬고.

    audioSource의 Play 함수는 소리가 중첩됨!!!!

     

    사운드의 중복 체크를 막기 위해 soundStart는 false로 바꿔주고 

    isDie : 죽었음을 체크할 불 변수는 true로 바꿔줍니다.

     

    우선 현재까지의 동작 구현 상태를 영상으로 보겠습니다.

     

     

     

    00 : 09초

    우선 결론부터 말씀드리면 원하는 동작 구현은 완료됐습니다.

    다만.. 

    Bomb_Move가 Player에게로 시작 시 달려오면서 폭발되어 피해를 입히는 동작을 연출해 봤는데

    뭔가 긴급하면서 갑작스러운? 연출을 하고 싶은데, 아직 머릿속에서 떠오르지가 않습니다..

    생각나는 대로 즉시 구현 실행을 해 보겠습니다 


     

    아직 기초적인 문법들 뿐이지만, 코딩이라는 게 치면 칠수록 사용하면 할수록 손에 익는 것 같습니다.

    벌써부터 이런 감정을 느끼기엔 오만함이 느껴지는 부분이라고도 생각될 수 있으나.

    생각했던 구성을 코딩으로 구현하는 데에 있어, 저도 모르게 손으로 치고 있을 때가 있습니다.

    많이 연습하고 보다 더 많은 것을 보고 느끼고 경험하여, 멋진 개발자가 되고 싶습니다.

     

    김 효 겸 다짐!

    댓글

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