ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RPG 듀토리얼 10. Player Skill (Casting)
    유니티 프로젝트/RPG 듀토리얼

    안녕하세요!!

    지난 시간에 UI의 버튼을 누르면 지정된 시간에 맞게 쿨타임이 생기며

     

    시각적인 효과를 버튼의 Fill Amount로 봤었는데요.

    player가 힐을 쓰는 모습 (현재 hp가 max치 이기에 +0으로 떴습니다.)

    오늘은 각 스킬 사용 시 캐스팅과 동작 구현을 볼 것입니다.

     

    지난 시간에 SkillBtn 스크립트에서 Casting() 함수를 실행시키는 코드를 봤었습니다.

     

    이 Casting 함수는 PlayerController에 구현을 했는데요.

     

    Casting 함수를 구현하는데 필요한 target이나 각 변수들의 편리함도 있었지만

     

    이 스킬은 스킬 버튼이 아닌 player가 사용을 하는 것 이기에

     

    관리적인 측면에서 PlayerController에 담았습니다.

     


     

    우선 캐스팅 함수를 실행하기 위해 선언 변수들부터 보겠습니다.

     

    PlayerController 스크립트

    onCasting : 캐스팅 중인지 확인할 불 변수입니다.

    이 캐스팅이 진행 중에는 다른 동작을 못하게 조건을 걸어주기 위함입니다.

     

    castingBar : 캐스팅 바 이미지입니다.

    캐릭터의 하단에 시각적인 UI 효과를 주기 위함입니다.

     

    castingTime : 캐스팅 시간입니다.

    skillBtn에서 받아온 time을 대입하여 제어를 할 변수입니다.

     

    atkTarget : 공격할 대상입니다.

     

    nothingAtkTarget : 공격할 대상 이 없을 때 atkTarget을 대신해 줄 오브젝트입니다.

     

    skillObj : skillBtn에서 인자로 준 Obj를 받을 스킬 이펙트 오브젝트입니다.

     

    skillObjectCasting : 스킬 캐스팅 이미지입니다.

    스킬을 발사할 때 이펙트랑 스킬을 발사하기 전 캐스팅 때의 이펙트 동작을 나눠 봤습니다.

     

    slideTarget : 슬라이드 할 대상입니다.

     

    waitScond : 스킬을 쓰고 난 후 Invoke 함수에 인자로 들어갈 시간입니다.


    자 그럼 이제 Casting 함수를 들어가 보겠습니다.

     

     Casting 함수에는 인자를 인스펙터에서 지정해줄 castingTime과 skillObj를 넣어 주었었습니다.

    playerController에 있는 casting 함수입니다.

    castingTime 받을 float time과 / skillObj을

     

    castingTime = time; 받아온 시간을 castingTime으로 지정해 줬습니다.

     

    atkTrget = target : atkTarget(공격할 타깃) = target(터치 / 클릭 한 오브젝트입니다)

    OnPointerDown에서 터치가 이루어져 transform이 있고, 그 오브젝트의 tag가 "Enemy"면 타기팅 함수가 실행됐었죠.

    (반대로 target이 null 일 시도 있습니다. 이는 아래 코 루틴 함수에서 구현을 했습니다.)

     

    skillObjCasting : 캐스팅 시전 시 발생할 이펙트입니다.

    player.transform.position + new Vector3(0, 1, 0)으로 위치를 잡아주고

    SetActive(true)를 이용해 활성화를 해주는 모습입니다.


    StartCoroutine으로 실행을 시켜주는 코 루틴 함수 "OnCasting"을 보겠습니다.

    OnCasting 코루틴 함수입니다.

    이 OnCasting 함수는 캐스팅 바의 fillAmount를 이용해 캐스팅 바를 조절하는 역할을 해줍니다.

     

    casting이 실행 중이니 onCasting은 true로 바꿔 주어 중복 실행이 안되게 합니다.

     

    스킬은 타깃을 지정 했을 시 타겟을 바라보며 공격을 하지만

    타깃이 없을 때도 생각해서 nothingAtkTarget의 오브젝트를 만들었습니다.

    nothingAtkTarget 빈 오브젝트

    if (target!= null) : 타깃이 비어있지 않을 시 에는

    LookAt 함수로 atkTarget을 바라보게 회전을 시켜 주며

     

    if (target == null) : 타겟이 비어 있을 시 에는

    LookAt 함수로 target을 바라보게 회전을 시켜줍니다.

     

    playerAni.Play("Casting") : Player 함수로 인해 Animator에서 Casting애니메이션을 실 해잇 켜 줍니다.

     

    아무런 동작을 하지 않을 것이기에 Nav의 enabled = false로 비활성화해 주고

     

    castingBar.transform.parent.gameObject.SetActive(true)

    캐스팅 바의 부모인 오브젝트를 활성화시켜주는 코드입니다.

     

    캐스팅 바의 fillAmount를 조절하는 동작은 while문에서 진행됩니다.

     

    time += Time.deltaTime * 1 : time에 Time.deltaTime의 값을 += 연산자로 인해 누적시켜주며

    이 누적시킨 time 값으로 

    castingBar의 fillAmount를 time / castingTime으로 설정해 주어

    0f ~ 1.0f의 값을 맞춰 줍니다.

    fillAmount의 값은 최소 0 ~ 최대 1의 값을 받습니다.

     

    if (time >= castingTime) : time이 캐스팅 타임보다 크거나 같다면

    즉, 캐스팅 시전이 완료됐다면 코 루틴 함수를 종료시켜 줍니다.

    StopCoroutine("OnCasting")

     

     castingBar.transform.parent.gameObject.SetActive(false);

    이후 활성화됐던 캐스팅 바는 다시 비활성화해줍니다.

    캐스팅 함수가 시작되면서 발생한 skillObjCasting는

    //

    지정한 시간으로 비활성화되는 스크립트인 DisableObj에서 비활성화를 시켜줬습니다.

    DisableObj 스크립트는 한번 만들어 놓으니 상당히 많은 곳에 쓰이고 있습니다.

    //

    playerAni.Play("Attack")

    발사 완료 후 애니메이션 재생

     

    Manager.instance.managerSE.seAudio.PlayOneShot(Manager.instance.managerSE.SkillAttack00)

    오디오 효과 재생

     

    그리고 skillBtn에서 받아온 skillObj을 위치를 잡아 주고 

    활성화시켜주는 코드입니다.

     

     

    Invoke("CastingInvoke", waitScond)

    이 Invoke 함수는 자신이 설정한 시간만큼 지연을 시킨 뒤 실행시켜 주는 중요한 함수였죠?

    waitScond(인스펙터 창에서 지정한 시간)을 기다려 준 뒤

     

    CastingInvoke를 실행해 줍니다.

     

    waitScond은 스킬 캐스팅 후 스킬 시전 시 

    애니메이션의 대기 시간이었습니다.

    스킬 발사는 애니메이션 시작과 동시에 나가니

    애니메이션이 끝났다면, 다시 플레이어는 움직 일 수 있게 됩니다.

     

    지정된 시간이 끝난 후 nav는 enabled로 true

    onCasting = false로

    캐스팅 ~ 스킬 이 끝났다는 것을 알려줍니다

    즉 다시 스킬을 시전 할 수 있는 상태가 된 것입니다.


     

    나머지 스킬도 지정된 시간 값이 다를 뿐 비슷합니다!!

     

    다만 스킬 3번의 힐 스킬과  / 슬라이드 기능에서는 조금 다른 부분이 있는데요.

     

    다른 부분만 짚어서 보도록 하겠습니다.

     

    우선 스킬 3번인 힐이 적용되는 부분부터 보시겠습니다.

    if(player.GetComponent <PlayerStats>(). hp_Cur!= 0)의 조건문을 통해

    현재 체력이 0이 아니라면 실행되는 조건문을 걸어 주었습니다.

     

    gainTextResilt : 힐 적용 시 시각화를 더 해줄 텍스트입니다. 

    (애니메이션을 적용해 주어 시각 효과를 더 해 주었습니다)

     

    gainTextResult = (int)(player.GetComponent <PlayerStats>(). hp_Max - player.GetComponent <PlayerStats>(). hp_Cur)

    를 이용해 gainTextResult에 최대 체력에서 현재 체력을 뺀 값을 대입해 줍니다.

    여기서 (int)로 형 변환을 한건 현재 Player의 체력이 float 값으로 설정되어 있는 게 제일 크지만

    값을 int값으로 받아 편리하게 계산한 것을 받아오기 위함도 있습니다.

     

    if(gainTextResult > (int)(player.GetComponent <PlayerStats>(). hp_Max * 0.2f))

    에서 (int)(player.GetComponent(). hp_Max * 0.2f)의 조건문은 최대 체력의 20%를 나타냅니다.

    최대 체력의 20%보다 gainTextResult의

     

    gainTextResult = (int)(player.GetComponent <PlayerStats>(). hp_Max * 0.2f)

    gainTextResult의

     

    gain_Text.text = string.Format($"+{gainTextResult}") 

    텍스트를 +gainTextResult으로 지정해 주어

     

    gain_Text.gameObject.SetActive(true)

    SetActive로 활성화를 시켜 줍니다.


    이후 

    player.GetComponent <PlayerStats>(). hp_Cur += (int)(player.GetComponent <PlayerStats>(). hp_Max * 0.2f)

    플레이어의 체력에 최대 체력의 20%를 += 연산자를 통해 누적시켜주었습니다.

     


     

     

    슬라이드를 사용할 때는 별 다른 이펙트가 필요 없고

    애니메이션 동작 구현만 있습니다.

    케스팅 타임만 받아 와 주었으며

    StartCoroutine로 OnCastingSlide 코 루틴 함수를 실행해 주었습니다.

    OnCastingSlide 코루틴 함수와 Invoke로 실행될 OnCastingInvokeSlide 함수입니다.

     

    슬라이드를 사용 시

    playerAxisNav.speed *= 2 : 내비게이션의 속도는 *2를 해줍니다.

     

    playerAni.Play("Slide")

    play를 이용해 "Slider" 애니메이션을 실행 주면서 

     

    SetDestination을 이용해 목적지를 slideTarget.position로 정해 주었습니다.

     

    slideTarget 그 뒤에 nothingAtkPosition이 외롭게 있는중

    Invoke 함수로 waitScond 시간을 지연시키고 난 뒤 코 루틴 함수 OnCastingInvokeSlide를 실행시켜 주면

     

    playerAxisNav.speed /= 2

    로 네비의 속도는 원상 복귀됩니다.

    네비의 속도를 바꾼 이유는,  Slide를 할 시 속도를 더 빠르게 해 주기 위함입니다.

     

    이후 

    playerAxisNav.ResetPath()로 경로를 초기화해 줍니다.

     

     

    00 : 38초

    이제 만들어 놓은 스킬들을 발사하는 동작 구현을 만들면 될 것 같습니다.

     

    캐스팅 바와 스킬들의 각 쿨타임 구현을 보시면 될 것 같습니다.

     

    이제 Skill 관련 부분에서는 이펙트와 구현 동작 그리고 몬스터에게 피격하는 효과만 남은 것 같습니다.

    //

    이 스킬 부분은 테스트 기간이 가장 길었으며, 이것저것 시도해보고 스크립트도 재활용해가면서

    재밌게 집중을 쏟았던 부분인데

    막상 이걸 설명하려고 하니깐 어디서부터 설명을 해야 할지 감을 못 잡겠습니다.

    천천히 하자니 글이 길어지고, 그렇다고 띄엄띄엄 가자니

    놓치는 스크립트들이 초롱초롱한 눈망울로 저를 보고 있는..

    //

     

    일단 오늘은 시간이 너무 늦었으니, 내일 바로 작성하겠습니다.

     

    다들 오늘 하루도 고생 많으셨고

     

    새벽 감성이라 그런지 모르겠지만..

     

    다들 좋은 일들만 가득하시길 빌겠습니다.

     

     

    오늘도

     

    감사합니다.

    댓글

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