본문 바로가기
게임 개발/유니티 게임 개발 일지

#13 라이트닝 스트라이크 스킬 구현하기

by FlowTree 2020. 7. 21.
반응형

1.구현할 기능 소개

1.1.정의

  • 라이트닝 스트라이크 스킬은 즉발 시전형 마법 스킬이다.
  • 거의 직선형(중심각이 좁은 부채꼴 범위) 범위의 번개 속성 스킬이다.
  • 이 스킬은 체인 라이트닝, 라이트닝 스트라이크 2단계로 실행한다.
  • 1단계: 체인 라이트닝
    -스킬 사용 시 스킬 범위 안의 적들에게 번개를 발사한다.
    -발사된 번개는 플레이어와 적 사이의 가까운 거리 순서대로 연쇄 공격을 한다.
  • 2단계: 라이트닝 스트라이크
    -연쇄 공격 이후 공격 당한 적들 머리 위에서 번개가 내리친다.

 

1.2.구현된 영상

youtu.be/B2o4XHX9HH4

 

2.구현 의도

2.1.즉발 시전 스킬

  • 스킬 사용 시 덜 정확하지만 즉각적인 조준 및 스킬 사용을 통해 속도감있는 조작의 재미 제공
  • 이 게임 플레이의 속도가 빠르기 때문에 조작 단계가 많아져서 플레이가 느려지면 재미가 반감됨                       

2.2.직선형 범위

  • 파이어볼 스킬(원 범위형)과 다른 범위의 스킬 구현해보기
  • 적과의 전투 시 주로 플레이어가 뒤로 이동하며 공격하기 때문에 적들이 일직선으로 뭉치는 상황이 많은데
    이런 상황일 때 최적의 공격 스킬 제공
  • 긴 사거리의 직선형 범위를 통해 먼 곳에서 공격하는 까다로운 적을 저격할 수 있는 방법 제공
  • 스킬 마다 공격 범위를 다르게 하여 유저들에게 특정 상황에 맞는 스킬을 선택하는 전략적 재미 제공

2.3.번개 속성

  • 즉각적인 공격 스킬에 어울리는 속성이 번개여서 선택

2.4.연쇄 기능

  • 번개의 가장 특징적인 요소가 전도성인데 이 부분을 잘 표현하는게 연쇄기능이여서 연쇄 기능 추가

 

3.구현 사항 명세

3.1.라이트닝 스트라이크 리소스 제작

  • 체인 라이트닝(적들을 연쇄하는 번개)
  • 라이트닝 스트라이크(하늘에서 내리치는 번개)

 

3.2.라이트닝 스트라이크 스킬 구현(스크립팅)

 

3.3.적 AI 수정(해당 내용은 5.구현 과정을 참고)

  • 피격 상태 구현(피격 애니메이션, AI 이동 정지)
  • 피격 시 스킬 종류에 따른 AI 이동 정지 시간 구분 기능

 

4.기능 명세

#데이터, 리소스 리스트 제외, 규칙 위주로 작성함 = 규칙 작성이 잘 안되서 연습하려고

4.1.라이트닝 스트라이크 기능 구조도

#간단하게 각 기능들 소개, 세부 정의, 내용은 아래의 세부 기능에서 설명

상위 기능 하위 기능 설명
스킬 입력 스킬 사용 가능 여부 검사 *스킬 재사용시간 검사
-스킬 재사용시간이 남아있는지 검사하는 기능
-재사용시간이 없을 경우 재사용대기시간을 실행하는 기능
*스킬 소비 마나 검사
-스킬 사용에 필요한 소비 마나가 있는지 현재 마나량을 검사하는 기능
-현재 마나가 충분할 경우 스킬 소비 마나를 소비하는 기능
체인 라이트닝 적 탐지 -스킬 범위 안에 존재하는 살아 있는 적들을 탐지하는 기능
-탐지된 적들을 적 오브젝트, 플레이어 사이와의 거리를 리스트에 저장하는 기능
적 오름차순 정렬 -리스트에 저장된 적의 거리를 기준으로 오름차순으로 정리하는 기능
체인 라이트닝 발사 -최종 선별된 첫 번째 순서의 적에게 체인 라이트닝을 발사하는 기능
-발사된 체인 라이트닝이 정렬된 적 순서대로 연쇄 공격하는 기능
스킬 데미지 적용 -최종 선별된 적들에게 체인 라이트닝 스킬 데미지를 가하는 기능
체인 라이트닝 페이드 아웃 -발사된 체인 라이트닝의 두께를 일정 시간마다 증가, 감소시켜 번개가 사라지는 연출을 하는 기능
라이트닝 스트라이크 라이트닝 스트라이크 생성 -체인 라이트닝이 페이드 아웃으로 사라진 후 적들 머리 위로 각각 라이트닝 스트라이크를 생성하는 기능
스킬 데미지 적용 -적들에게 라이트닝 스크라이크의 스킬 데미지를 가하는 기능

 

 

4.2.라이트닝 스트라이크 플로우 차트

4.3.세부 기능

4.3.1.스킬 입력

4.3.1.1.정의

  • 스킬 버튼을 터치 시 해당 버튼에 등록된 스킬을 실행하는 기능이다.
  • 스킬 사용 가능 여부(조건)을 검사하고 2가지 조건을 모두 충족할 경우 스킬을 실행하는 기능이다.

 

4.3.1.2.스킬 사용 가능 조건

1.스킬 재사용대기시간 검사

  • 스킬 재사용대기시간은 스킬 사용 후 다시 사용하기까지 대기해야하는 시간이다.
  • 스킬 입력 후 스킬이 실행됐을 때 현재 스킬 재사용대기시간을 실행한다.
  • 재사용대기시간이 지나면 이후 스킬 입력 시 스킬을 실행한다.
  • 재사용대기시간이 남아있을 때 스킬 입력 시 스킬 실행이 불가하며 에러메시지를 출력한다.

 

2.스킬 소비 마나 검사

  • 스킬 소비 마나는 스킬 사용 시 필요한 마나이다.
  • 스킬 입력 후 스킬의 소비 마나 만큼 현재 마나량이 있는지 검사한다.
  • 현재 마나량이 부족한 경우 스킬 실행이 불가하며 에러메시지를 출력한다. 

 

4.3.2.체인 라이트닝

#뭐라고 적어야할지 복잡해서 모르겠으면 누군가가 물어봤을 때 뭐라고 대답해야하는지를 생각해보자

4.3.2.1.정의

  • 체인 라이트닝은 범위 안의 적들에게 직선형 번개를 발사하여 연쇄공격하는 기능이다.
  • 플레이어와 적들과의 거리가 가장 가까운 적에게 먼저 직선형 번개를 발사하고 이 후 거리 순서대로 번개를 연결하여 공격한다.
  • 공격 대상을 선별하는 기능이 주 기능이기 때문에 약한 데미지를 가하는 스킬이다.

 

4.3.2.2.적 탐지

  • 플레이어 중심으로 반경 15m의 콜라이더에서 플레이어 전방 42도 안에 있는 적들을 탐지한다.
  • 탐지된 적들의 오브젝트와 플레이어와 적 사이의 거리를 리스트에 저장한다.
  • 적 오름차순 정렬: 적 사이 거리를 기준으로 오름차순 정렬한다.
  • 적 최종 선별: 정렬된 적들은 최대 10명까지 저장한다.
  • 탐지된 적이 없으면 스킬 실행을 취소한다.
  • 스킬 마나 소비: 탐지된 적이 1명 이상이면 스킬 소비 마나 만큼 마나를 소비한다.

 

4.3.2.3.체인 라이트닝 발사

  • 플레이어의 지팡이 수정부분에서 최종 선별된 적들에게 체인 라이트닝을 발사한다.
  • 최종 선별된 적들의 정렬된 순서대로 체인 라이트닝을 연결한다. 

 

4.3.2.4.스킬 데미지 적용

  • 최종 선별된 적들에게 스킬 데미지를 가한다.
  • 스킬 데미지 공식: 지팡이 공격력 * 체인 라이트닝 스킬 계수(3)
  • 공격 당한 적들에게 라이트닝 스트라이크 스킬에 공격 당함 boolean(true)을 전달한다.

 

4.3.2.5.체인 라이트닝 페이드 아웃

  • 발사된 번개(메테리얼)를 0.07초마다 두께가 증가, 감소를 반복하며 페이드 아웃하여 번개가 번쩍이며 사라지는 연출을 한다.
  • 번쩍이는 연출을 하기 위해서 번개 두께를 반복 테스트하며 수정해야하므로 두께 변수는 수정가능해야한다.
  • 번개 두께 값 예시
순서 0 1 2 3 4 5 6 7
번개 두께 1 0.2 0.8 0.5 0.3 0.2 0.07 0

 

 

4.3.3.라이트닝 스트라이크

4.3.3.1.정의

  • 체인 라이트닝이 사라진 후 체인 라이트닝이 공격한 적들 머리 위에서 번개를 내리치는 기능
  • 스킬 이름에 어울리는 멋진 스킬 이펙트와 강한 데미지를 가하는 스킬이다.

 

4.3.3.2.라이트닝 스트라이크 생성

  • 최종 선별된 적들의 머리 위에서(약 3m 위에) 각각 번개를 생성하고 적을 향해 내리친다.
  • 라이트닝 스트라이크 이펙트 애니메이션이 모두 재생되면 프리팹을 삭제한다.(약 2.5초 후)

 

4.3.3.3.스킬 데미지 적용

  • 번개가 떨어졌을 때 적들에게 데미지를 가한다.
  • 스킬 데미지 공식: 지팡이 공격력 * 라이트닝 스트라이크 스킬 계수(6)
  • 공격 당한 적들에게 라이트닝 스트라이크 스킬에 공격당함 boolean(true)를 전달한다.

 

5.구현 과정

5.1.라이트닝 스트라이크 리소스 제작

5.1.1.체인 라이트닝

  • 라인 렌더러 이용
  • 라인 렌더러의 메테리얼을 번개 메테리얼로 추가하려고 했으나 실패
  • 유니티 스킬 구매한 것중 괜찮은 메테리얼을 이용함

 

5.1.2.라이트닝 스트라이크

  • 하늘에서 내리치는 번개 리소스를 구현하고자 했으나 적절한 리소스를 찾지 못함
  • 유튜브에서 Unity Lightning을 검색하여 파티클 시스템으로 리소스를 제작하는 영상을 참고함
    https://www.youtube.com/watch?v=e8fzWMDuMUI
  • 영상을 보면 파티클 시스템의 번개 리소스(lightning line)를 제작할 때 메쉬를 별도의 메쉬로 사용하는데 Quad메쉬를 이용하면 된다. 트랜스폼의 스케일을 조절하여 직사각형으로 만들면 됨

 

  

 

5.1.3.메테리얼 만드는 법

1.메테리얼에 텍스쳐 지정하는 방법
1.1.메테리얼 생성 > 인스펙터 > Albedo의 원형 아이콘 터치 > 원하는 텍스쳐 선택

 

2.텍스쳐의 투명한 부분 메테리얼에 적용하기

2.1.메테리얼 > 인스펙터 > Shader > Standard를 Transparent Diffuse로 변경

#이 방법으로 라이트닝 스트라이크 리소스 만듬

 

2.2.메테리얼 > 인스펙터 > Rendering Mode > Opaque를 Transparent로 변경

#이 방법도 텍스쳐의 투명한 부분을 적용할 수 있으나 테두리가 보임

 

3.파티클 바닥에 배치하기

3.1.파티클 시스템 오브젝트 > 인스펙터 > 파티클 시스템의 Renderer > Renderer Mode를 Horizontal BillBoard로 변경

 

4.텍스쳐 시트 적용 방법

4.1.파티클 시스템 오브젝트 > 인스펙터 > 파티클 시스템 > Texture Sheet Animation
    > Tiles를 사용할 텍스처에 맞게 조절

예) 사용할 텍스쳐가 가로 1 x 세로 2 형태로 있으면 Tiles에도 x 1, y 2로설정하면 됨

 

 

5.2.라이트닝 스트라이크 스크립트

5.2.1.체인 라이트닝

  • 직선형 스킬이여서 BoxCollider, OverlapBox를 이용하여 구현하려고 했지만 몇몇  문제로 실패함
  • 어쩔 수 없이 FieldOfView의 OverlapSphere의 각도를 줄여서 재활용함
  • 스킬 공격 범위를 씬 뷰에서 볼 수 있게 FieldOfView의 Editor를 이용함(나중에 Editor 정리)
  • 선별된 적의 오브젝트, 거리를 리스트에 저장하기(정보 찾기 매우 힘들었으나 마이크로소프트에서 찾음) https://docs.microsoft.com/ko-kr/dotnet/api/system.collections.generic.list-1.sort?view=netcore-3.1
  • 클래스형태의 리스트를 오름차순 정렬 방법으로 LINQ를 이용해서 쉽게 정리했으나 정렬된 오브젝트에 접근하는 방법을 찾지 못함(LINQ로 정렬방법 블로그에 작성하기)
  • 어쩔 수 없이 클래스 형태의 리스트를 정렬하는 방법을 다시 찾음 https://ntbda.tistory.com/17
  • 최종 적 선별함
  • 최종 선별된 적의 개수 중 최대 10명을 선택하고 적의 개수 만큼 라인렌더러 포지션을 추가 및 연결하기
  • 번개의 번쩍이는 연출을 라인렌더러 두께를 몇 초마다(코루틴) 증가, 감소하는 형태로 구현함

 

5.2.2.라이트닝 스트라이크

  • Instantiate()로 적 머리 위에 라이트닝 스트라이크 프리팹을 생성
  • Destroy()로 프리팹이 다 실행되면 해당 오브젝트 삭제함
  • for문으로 최종 선별된 적들 마다 데미지 적용을 했으나 이중 for문으로 실행하여 데미지가 중복되는 문제 발생함
  • 이중 for이여서 i개수x i개수 만큼 반복 실행 되는것 확인함
  • 과거에 작성된 코루틴 함수를 보고 데미지 함수에 변수 할당해서 해결함
    public void StrikeLightning()
    {
        //정렬된 적 리스트 가져오기 최대 10명
        //리스트 안의 적들이 10명 이상일 때
        if(confirmedTargets.Count > 10)
        {
            for (int i = 0; i < 10; i++)
            {
                OnStrikeDamage(i);
                //라이트닝 프리팹을 적들 위치에 생성한다.
                var lightningPrefabClone = Instantiate(lightningStrikePrefab, confirmedTargets[i].transform.position + lightningPrefabOffset, Quaternion.identity);
            }
        }

        else
        {
            for (int i = 0; i < confirmedTargets.Count; i++)
            {
                OnStrikeDamage(i);
                //라이트닝 프리팹을 적들 위치에 생성한다.
                var lightningPrefabClone = Instantiate(lightningStrikePrefab, confirmedTargets[i].transform.position + lightningPrefabOffset, Quaternion.identity);
                Destroy(lightningPrefabClone, 2.5f); //생성한 프리팹 리소스 실행 후 제거
            }
        }
     }
    
    //함수 괄호안에 변수를 할당해서 해결했음
    void OnStrikeDamage(int i)
    {
        LivingEntity attackTarget = confirmedTargets[i].GetComponent<LivingEntity>();

        //데미지 처리
        attackTarget.OnDamage(damageNormal);
        Debug.Log("현재 데미지" + damageNormal);

        //라이트닝에 공격 당함
        attackTarget.beDamagedLightning = true;
    }

 

5.3.적 AI 피격 기능 추가

  • 기존의 적 AI는 피격 시 특별한 피드백이 없었다.
  • 그래서 라이트닝 스트라이크를 맞아도 계속 이동함
  • 생성된 라이트닝 스트라이크와 적의 위치가 안 맞는 문제 발생함
  • 이 문제를 해결하기 위해서 적 피격 애니메이션 실행, 이동 정지 기능을 추가함
  • 상태를 추가하여 해결함. 15분30초 https://www.youtube.com/watch?v=sPiVz1k-fEs

 - Hit > Die 전이 조건으로 bool 추가함.

 - 온전히 피격 애니메이션, 사망 애니메이션을 실행하기 위해서 둘다 Has Exit Time 체크함

 

  • 정지 기능을 구현하다보니 모든 스킬을 맞을 경우 동일 시간 정지하는 게 비효율적으로 판단
  • 라이트닝 스트라이크에 맞으면 꽤 오랜 기간 적이 정지하기 떄문
  • 빠르고 유도되는 일반 공격을 맞아도 정지하면 게임 난이도 너무 쉬워짐
  • 적 상위 클래스 LivingEntity에 피격 시 스킬 공격 별 Boolean을 추가함, 원래는 Enemy 클래스에 추가하고 싶었는데 Enemy 클래스를 구현 못하고 LivingEntity를 상속하는 개별 클래스로 만들었음 (= 비효율적)
  • 일반 공격, 파이어볼, 라이트닝 스트라이크, 잔불은 제외(지속 시간마다 이동 정지하면 그 자리에서 계속 피격되서 X, 이렇게 구현했는데 잔불 지속 데미지 시간이 짧아서 피격이 반복되서 부자연스러운 문제 발생, 데미지를 조금 더 높이고 공격 속도를 느리게 하자)
  • 어떤 스킬 공격을 받았냐에 따라서 적 이동 정지 시간을 구분하여 구현했음
  • 특정 조건들을 Swich문으로 구현해볼려고 했으나 실패하고 결국 if, else if문으로 구현함

 

반응형

댓글