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

#12 파이어볼 스킬 구현하기

by FlowTree 2020. 7. 14.
반응형

#초 간단 기록! 꼭 필요한 것만! 이전까지 설명 하는 글이 너무 길다. 작성하는 시간이 오래 걸리면 그 만큼 개발 작업을 못하니까 딱 기억날 정도, 꼭 필요한 내용만 적자.

 

1.구현 목적

1.단일 공격이 아닌 광역 공격의 필요성

  • 일반 공격은 타겟팅된 대상만 공격이 가능하여 뭉쳐있는 특정 구역의 적을 공격할 수단이 필요
  • 만약 광역 스킬이 없다면 히트앤런의 게임 플레이로 고착화됨 > 재미 저하 요소
  • 공격 위치를 지정가능한 광역 공격 필요
  • 새로운 공격 패턴 추가 = 공격 패턴 조합 = 상황에 따른 패턴 사용, 재미 유발

2.공격 애니메이션이 부족하니 화려한 마법 스킬로 멋진 연출 보여주기
   -직선형 일반 스킬이 있으니 직선이 아닌 다른 형태

   -파이어볼의 궤적을 볼 수 있도록 포물선 이동 구현해보기

 

3.마법 중에 기본적이고 화려한 마법은 파이어볼이라서 구현

  •  위의 기획의도에 부합하는게 마비노기의 파이어볼 스킬(레퍼런스)

4.현재 게임의 플레이에 맞게 잔불 시스템을 추가하여 레퍼런스+변형

  • 잔불 시스템
    -일반 공격를 할 때 일정한 거리, 공격 속도 등 조건들이 필요한데, 조건이 안될 때 특히 이동 중에 적을 공격할 수
     있는 수단이 없어서 계속 이동만 하는 경우가 발생한다.
    -이 부분을 보완 이동 중에도 적을 공격할 수 있도록 잔불을 추가했다.
    -잔불: 파이어볼이 폭발한 위치에 몇 개의 잔불을 생성하고, 적이 잔불에 닿으면 몇 초마다 데미지를 가한다.

 

2.구현된 영상

www.youtube.com/watch?v=9qX1zwRVi4Q

 

3.파이어볼 스킬 정의

스킬 이름 파이어볼
스킬 타입 데미지형, 광역범위형
스킬 속성 화염
타겟 유무 논타겟
스킬 설명 플레이어가 공격할 위치에 포물선 이동하는 파이어볼을 발사하고 파이어볼이 공격 위치에 도착 시 폭발하여 주변의 적들에게 데미지를 가한다. 

 

4.데이터 리스트

#내가 파이어볼 구현할 때 사용한 모든 데이터를 적어야 할까? 그럴경우 vector3타입의 파이어볼 시작위치, 도착위치도 적어야하는데 어떻게 적어야하고 꼭 적어야할까? 이런게 몇 가지가 있다. 버튼 터치 입력 여부에 따른 bool 등

 

이런 자잘한 부분들은 프로그래머분들이 잘 알기 때문에 굳이 적을 필요가 없을것 같다. 대신 규칙에서 상세하게 설명하기. 파이어볼에 꼭 필요한 데이터만 명시하여 불필요한 정보는 줄이기로 결정했다.

 

4.1.파이어볼 파라미터

파라미터 이름 파라미터 이름
(영문)
데이터 타입 기본값
(n=null)
설명
파이어볼
스킬 이름
fireball string n 파이어볼 스킬의 이름이다.
스킬 ID 미정 string n 스킬 ID 규칙따라 이름을 정한다.
현재 ID를 사용하지않아서 미기입
스킬DB용?(엑셀)
스킬 타입 typeOfSkills byte 1 해당 스킬의 타입이다. 
0: 단일 데미지형
1: 범위 데미지형
2: 지속 데미지형
3: 순간이동형
4: 회복형
스킬 속성 propertiesOfSkills byte 2 해당 스킬의 공격 속성이다.
0: 물리
1: 마법
2: 화염
3: 전기
스킬 계수 skillMultiplier float 2 파이어볼 스킬의 데미지 계수
스킬 데미지 skillDamage float n 적에게 가하는 스킬 데미지
(스태프의 데미지 * 파이어볼 스킬 계수)로 스킬 데미지를 계산한다. 
소비 마나 manaCost float 50 스킬 사용 시 소비하는 마나의 양
스킬 재사용
대기시간
skillCoolTime float 10 스킬 사용 후 재사용이 가능하기까지의 대기 시간
파이어볼
공격 범위의
반지름
fireballDamageRadius float 3 파이어볼을 중심으로 하는 원형 범위의 반지름
파이어볼
포물선높이
fireballHeight float 3.5 파이어볼이 포물선 이동할 때의 최대 높이
파이어볼 도착시간 arrivalOfTime float 2 파이어볼이 생성 위치에서 도착 위치에 도착할 때까지 걸리는 시간
파이어볼
도착 위치
arrivalPosition ? n 파이어볼이 발사 후 이동하여 도착하는 위치이다.
유니티로는 vector3 형태인데 이게 데이터 타입은 아닌 것 같다. 뭐라고 적어야 하는거지?
검색해보니 vector3는 struct라고 하니 이거 공부해야할듯

 

4.2.잔불 파라미터

파라미터 이름 파라미터
영문 이름
데이터 타입 기본값
(n=null)
설명
잔불 스킬 이름 ember string n 잔불 스킬의 이름이다.
스킬 ID 미정 string n 스킬 ID 규칙따라 이름을 정한다.
현재 ID를 사용하지않아서 미기입
스킬 타입 typeOfSkills byte 1 해당 스킬의 타입이다. 
0: 단일 데미지형
1: 범위 데미지형
2: 지속 데미지형
3: 순간이동형
4: 회복형
스킬 속성 propertiesOfSkills byte 2 해당 스킬의 공격 속성이다.
0: 물리
1: 마법
2: 화염
3: 전기
스킬 계수 skillMultiplier float 0.2 잔불 스킬의 데미지 계수
스킬 데미지 skillDamage float n 적에게 가하는 스킬 데미지
(스태프의 데미지 * 잔불 스킬 계수)로 스킬 데미지를 계산한다. 
잔불 공격 범위의 반지름 emberDamageRadius float 2 잔불을 중심으로 하는 원형 범위의 반지름
잔불 생성 개수
emberCount float 3 잔불 스킬 생성 개수
잔불 유지 시간 emberDuration float 3 잔불 스킬의 유지시간
유지시간이 지나면 잔불은 소멸한다.
잔불 공격 시간 emberAttackTime float 0.4 잔불 공격 시간마다 공격 범위 안에 있는 적에게 데미지를 가한다.

 

#파이어볼, 잔불의 이펙트는 파라미터에 속하는가? 아닌가? 리소스 리스트에 속하는가?
= 리소스는 리소스 리스트 또는 에셋 리스트로 작성하면될 것 같다.

 

#게임오브젝트 타입, vector3 타입 등 이런 것들은 파라미터에 속하는가? 어떻게 설명해야할지...
= 위치는 특정 위치값을 실제로 구현하기 전까진 알 수 없고 절대값이 아닌 이상 파라미터 이름을 지정하고 어떤 것인지 설명하는 방식으로 하자.

5.파이어볼 기능

5.1.플로우 차트

#플로우 차트는 상세한 디테일 보다, 한 눈에 들어오게 하는 것, 크게 크게 나누고, 누구나 이해하기 쉽게

(원활한 이해, 단순화 = 추상화도 필요할 듯)

 

#실행 단계별로 크게 설명한다. 핵심 위주로, 이것이 무엇이며 무슨 용도다.
상세한 기획의도, 작동원리(규칙), 데이터는 아래의 세부 기능에서 설명한다.

번호 파이어볼 실행 단계 설명
1 기본 상태 파이어볼 스킬을 사용하기 전 플레이어의 기본 상태
2 스킬 입력 게임 화면의 파이어볼 스킬 버튼을 터치하여 파이어볼 공격 위치 지정 상태로 진입한다.
3 파이어볼 공격 지정 위치

파이어볼 공격 위치를 정하는 상태, 공격 위치UI를 터치, 드래그를 통해 공격 위치를 지정할 수 있다.

4 파이어볼 발사

공격 위치로 날릴 파이어볼을 생성한다.

5 파이어볼 이동 생성된 파이어볼은 공격 위치로 포물선을 그리며 이동한다.
이동 중 특정 레이어(Obstacle, Plane)의 오브젝트와 충돌 시 폭발한다.
이동 중 충돌이 없을 경우 공격 위치까지 이동한다.
6 파이어볼 폭발 파이어볼은 특정 레이어(Obstacle, Plane)의 오브젝트와 충돌 시 폭발한다.
폭발 범위 안에 있는 적에게 폭발 데미지를 가한다.
7 잔불 폭발 후 폭발 범위 안에서 (잔불 개수 변수)개의 잔불을 생성한다.
적이 잔불 범위 안에 들어올 경우 잔불 데미지를 가한다.
잔불 범위 안에 있는 적에게 (잔불 공격 시간 변수)초 마다 잔불 데미지를 가한다.
잔불은 유지시간이 지나면 소멸한다.

 

5.2.스킬 사용 상태 플로우 차트

번호 상태 이름 설명
1 기본 상태

파이어볼 스킬을 사용하기 전 플레이어의 기본 상태(대기 상태)

기본UI를 출력한다.(HP, MP, Score, 가상패드, 공격 버튼, 스킬 버튼)

게임 속도는 기본 배수(1)

2 파이어볼 공격
위치 지정 상태
게임 속도를 0.1(게임 속도 변수)배수로 느리게 한다.
파이어볼의 공격 위치UI를 상세하게 조절하기 위해서 기본UI를 숨긴다.
공격 위치 지정UI(파이어볼 공격 위치 UI, Fire/Cancel 버튼)를 출력한다.
Fire 버튼 입력 시 지정한 위치로 파이어볼을 발사한다.
Cancel 버튼 입력 시 파이어볼 공격 위치 지정을 취소한다.
취소 후 기본 상태로 돌아간다.
3 파이어볼
발사 상태

Fire 버튼 입력 시 파이어볼 공격 위치UI를 숨긴다.

기본UI를 출력한다.

게임 속도를 기본 배수(1)로 변경한다.

파이어볼 공격 애니메이션을 실행한다.
애니메이션 종료 후 기본 상태로 돌아간다.

#상태 설명 내용이 아래의 규칙 내용과 겹치는데 어떤 내용을 작성해야 하는가? 상태 플로우 설명... 이 상태는 뭐고, 어떨 때 상태가 전환이 되는지 설명? 일단 패스 

 

5.3.파이어볼 기능 구조도

 

5.4.상세 기능

#모듈화로 카테고리 나누기(모델화 = 추상화인데, 구체적인 조건이 있는 추상화같은 느낌)

모듈화 = 더이상 쪼갤 수 없을 때까지(같은목적단위), 독립적으로 돌아감

모듈화로 구분한 카테고리별 각각의 기능들을 상세하게 설명
(기능 정의, 기획의도 / 규칙 = 작동원리 / 필요한, 사용할 데이터)

 

#데이터 설명부분은 두 가지 방법이 있는데 1.데이터 타입을 정하기, 2.데이터 타입을 정하지않고 해당 데이터에 대한 용도, 의도 설명하기. 두 가지 방법 중에 좀 더 낫다고 생각하는 건 2번이다. 이유는 데이터 타입은 게임 성능, 자원(메모리 등) 최적화에 큰 영향을 주기 때문에 프로그래밍 지식이 매우 필요한데, 잘 아는 전문가에게 맡기는 게 더 효율적이고

대신 "이런 데이터는 어떤 용도, 의도가 있다." 이런 설명을 통해 프로그래머들이 사용할 타입 판단할 수 있게 하는게 더 낫다고 생각한다. 데이터 타입을 직접 정할 수준은 시스템 기획자 경력이 꽤 있거나, 프로그래밍 지식이 뒷받침될 때 유효할 것 같다.

 

그렇다고 데이터 타입을 안 적기에는 뭔가 공부를 안하는 느낌이고... 예상 데이터 타입을 적고, 설명을 추가해서 왜 필요한지 의도가 담겨있으면 될 것 같다. 프로그래머들이 봤을 때 의도와 데이터 타입이 다를 경우, 더 효율적인 방법을 알 경우 자체적으로 수정하시지 않을까?

 

#데이터 리스트를 앞에서 설명? 규칙 전에 설명? 규칙에 데이터가 들어간다

중요도를 봤을 땐 규칙이 먼전데, 규칙에서 사용하는 변수명은 또 데이터 리스트에 있다

 

가독성을 생각했을땐 정의, 데이터 리스트, 규칙으로

중요도를 생각했을 땐 정의, 규칙, 데이터 리스트

데이터 리스트 먼저 쓰자. 이해! 잘 전달! 중요하다.

 

#새로운 문제, 데이터 리스트를 한 도표에다가 정리 vs 기능 설명 시 하위 목록으로 데이터리스트 설명하기? 

 

전자의 경우 프로그래머분들이 작업하다가 데이터를 확인할 때 한 눈에 알아보기 좋다. 찾는 수고가 줄어듬

그리고 글의 카테고리를 추상화한 상태임 공통의 것을 묶어서 하나의 카테고리로 뽑아냄

 

후자의 경우 술술 읽기 좋음, 이 기능에서는 이런 데이터가 필요하다. 대신 카테고리 구조화X, 정보가 여기저기 뿌려져있음, 찾아보기 어려울지도? 기능들을 보면 하나의 데이터를 여러 기능들에서 사용하는 경우가 발생하는데 그럴 경우 사용하는 기능들의 하위 데이터 리스트에 중복 작성해야한다. 매번 데이터 리스트를 작성해야하는 비효율적인 작업

 

결정! 전자처럼 데이터 리스트를 추상화해서 하나의 카테고리 만들기 = 문서의 구조화 = 정리가 잘 되어 있어 이해하기 좋음

상세 기능에서는 기능 정의, 규칙(작동원리)로 정리해서 이해하기 좋음

그리고 중복되는 내용이 줄어들기 때문에 문서 길이 최적화, 문서 작성 시간 절약도됨 = 효율적인 문서 작성 시간

 

항상 문서는 간단명료, 구조화, 짧은 문서 길이, 빠르게 작성하기 = 문서 작성의 최적화 기억하기

 

 

#위의 데이터 리스트의 파라미터 이름을 이용하여 상세 기능을 적는다.

#규칙 설명 너무 어렵다... 참고할 것 찾자.

 

5.4.1.스킬 입력 기능

5.4.1.1.정의

  • 게임 화면의 스킬 버튼을 터치하여 스킬을 사용하는 기능

#뭔가를 설명할 때 육하원칙(누가, 언제, 어디서, 무엇을, 어떻게, )를 생각하고 설명하면 빈 내용을 채워주는 것 같다.

물론 항상 육하원칙에 맞춰서 설명할 순 없으나 주어, 목적어가 빠진다거나 왜 해야하는지 이유를 설명을 할 때 육하원칙으로 검사해보면 좋을것 같다.

 

5.4.1.2.규칙

#일반 규칙(기본, 공통의 규칙), 상세 규칙, 예외 규칙을 기본 카테고리로 이용한다. 단 무엇을 기준으로 하냐에 따라서 관련 규칙 카테고리 이름을 변경될 수 있다. 위의 틀은 참고하자는 의미이다. 우선 나열부터...

 

1.스킬 입력 규칙

  • 스킬 버튼의 기본값은 미입력(비활성화)상태이다.
  • 스킬 버튼을 터치 시 입력(활성화)상태이다.
  • 스킬 버튼을 터치하고 놓았을 때 기본값으로 변경한다.
  • 스킬 버튼을 터치 시 버튼 색상을 회색으로 출력하여 플레이어에게 버튼이 눌렸다는 시각적인 피드백을 준다.

2.스킬 실행 규칙

  • 스킬 버튼을 터치 시 해당 버튼에 등록된 스킬을 실행한다.
  • 해당 스킬을 사용이 가능할 때만 스킬 입력이 가능하다.
  • 스킬 사용이 가능한 상태: 재사용대기시간이 지났을 때, 스킬 사용에 필요한 마나를 보유 중일 때

 

5.4.2.공격 범위 지정 기능

5.4.2.1.정의

  • 파이어볼 스킬의 공격 범위를 정밀하게 지정할 수 있게 도와주는 기능

5.4.2.2.규칙

1.공격 범위 지정 상태 규칙

  • 파이어볼 스킬 버튼을 입력 시 공격 범위 지정 상태가 된다.
  • 해당 상태에서는 공격 범위 지정에 집중할 수 있도록 기본UI(가상패드, Hpbar, Mpbar, 점수UI, 스킬 버튼들)을 숨긴다.
  • 공격 범위 지정UI, 확인 버튼, 취소 버튼을 출력한다.
  • 정밀한 공격 범위 지정을 위해서 게임 배속을 0.1배속으로 변경한다.
  • 공격 범위 지정UI 초기 위치: 플레이어 캐릭터 전방 1m, 높이 0.01m 위치에 공격 범위 지정UI를 출력한다.

2.공격 범위 지정UI 조작 규칙

  • 조작 방법: 공격 범위 지정UI를 터치, 드래그하여 게임 내 원하는 위치로 이동시킨다.
  • 공격 범위 지정UI를 이동할 때 높이는 0.01m로 고정한다.
  • 공격 범위 지정UI는 플레이어 캐릭터를 중심으로 최대 반경(10m)를 넘지 않는다.
  • 최대 반경은 모바일 화면에서 공격 범위 지정UI를 눈으로 보면서 이동시킬 수 있는 최대 거리로 설정했다. 

3.공격 범위 지정 확인 버튼 규칙

3.1.확인 버튼 입력 시

  • 공격 범위 지정UI의 현재 위치를 파이어볼의 도착 지점으로 설정한다.
  • 게임 속도를 기본 배속(1배속)으로 변경한다.
  • 공격 범위 지정UI, 확인 버튼, 취소 버튼을 숨기고 기본UI를 출력한다.
  • 공격 범위 지정 상태에서 파이어볼 발사 상태로 변경한다.
  • 현재 마나에서 파이어볼 소비 마나량 만큼 소비한다.(미구현)
  • 파이어볼 재사용대기시간을 적용한다.(미구현)

4.공격 범위 지정 취소 버튼 규칙

4.1.취소 버튼 입력 시

  • 공격 범위 지정UI의 현재 위치를 초기화한다.
  • 공격 범위 지정UI, 확인 버튼, 취소 버튼을 숨기고 기본UI를 출력한다.
  • 게임 속도를 기본 배속(1배속)으로 변경한다.
  • 공격 범위 지정 상태에서 기본 상태로 변경한다.

#확인 버튼과 중복되는 규칙들이 있는데 이건 어떻게 그룹핑해야 하는가? 공격 범위 지정 상태일 때, 상태 변경 시로 나눠서 설명?
#상태 변경 시 공격 범위UI, 확인 버튼, 취소 버튼을 숨긴다. 기본UI를 출력한다. 게임 속도를 기본 속도로 변경한다. 이렇게 작성하고 위의 특정 버튼 입력 시 상태 변경한다 적고, 해당 버튼을 입력했을 때의 결과를 적으면 될듯???

 

5.4.3.파이어볼 발사 기능

5.4.3.1.정의

  • 파이어볼을 발사하는 애니메이션 실행과 지정한 도착 위치을 목표로 하는 파이어볼을 생성하는 기능

5.4.3.2.규칙

1.발사 애니메이션 규칙

  • 파이어볼 발사 상태가 되면 제자리에서 파이어볼 도착 위치 방향을 바라보며 발사 애니메이션을 실행한다.
  • 발사 애니메이션이 종료되면 기본 상태로 변경한다.

2.파이어볼 생성 규칙

  • 파이어볼 생성 위치: 플레이어 캐릭터가 착용한 지팡이의 수정 위치에서 파이어볼을 생성한다.
  • 파이어볼 생성 프레임: 지팡이를 전방으로 완전히 뻗는 애니메이션 프레임에서 파이어볼을 생성한다.

 

5.4.4.파이어볼 이동 기능

5.4.4.1.정의

  • 생성된 파이어볼이 도착 위치로 포물선 이동하는 기능

5.4.4.2.규칙

  • 생성된 파이어볼은 베지어 곡선으로 경로를 계산하고 경로를 따라 포물선 이동한다.
  • 파이어볼은 도착 위치 방향을 바라보며 자연스럽게 이동한다.

포물선 이동

  • 베지어 곡선을 이용하여 파이어볼이 이동할 포물선 경로를 계산한다.
  • 베지어 곡선을 이용하기 위해서는 4개의 포인트가 필요하다.
  • 파이어볼의 생성 위치, 도착 위치, 파이어볼 높이를 이용하여 4개의 포인트(생성 위치, 생성위치+높이, 도착 위치+높이, 도착 위치)설정한다.
  • 이동 시간 t에 따라 포인트들을 선형 보간한다.
  • 계산된 포물선 경로를 따라 파이어볼이 이동한다.
  • 파이어볼은 이동 시간 t초 후 도착 위치에 도착한다.

 

5.4.5.파이어볼 폭발 기능

5.4.5.1.정의

  • 파이어볼이 특정 레이어의 오브젝트와 충돌 시 폭발하며 폭발 범위 안의 적에게 데미지를 가하는 기능

5.4.5.2.규칙

1.파이어볼 충돌 규칙

  • 파이어볼은 Obstacle, Plane 레이어의 오브젝트와 충돌하면 그 자리에서 폭발한다.
  • 충돌 시 파이어볼 리소스를 제거하고 폭발 리소스를 출력한다.

2.적 탐지 규칙

  • 파이어볼 폭발 범위 안의 살아있는 적 오브젝트들을 탐지한다.
  • 파이어볼 충돌 위치에서 각각의 탐지된 적 오브젝트 방향으로 레이캐스트를 발사하여 장애물이 있는지 검사한다.

3.데미지 적용 규칙

  • 적 탐지를 통해 충돌 위치와 적 오브젝트 사이에 장애물이 없을 경우 해당 적에게 파이어볼의 데미지를 가한다.

 

5.4.6.잔불 기능

5.4.6.1.정의

  • 파이어볼 폭발 주변에 지속 데미지를 가하는 잔불 오브젝트를 생성하는 기능 

 

5.4.6.2.규칙

1.잔불 생성 규칙

  • 파이어볼이 폭발한 뒤 폭발 범위 안의 무작위한 위치에 잔불을 생성한다.
  • emberCount개의 무작위한 위치에 잔불을 1개씩 생성한다.

2.잔불 데미지 규칙

  • 잔불 범위 안의 살아있는 적 오브젝트에게 emberAttackTime초마다 데미지를 가한다.
  • 잔불은 emberDuration초 이후 소멸한다.

구현 과정

#어떤 기능을 구현할 때 무엇을 이용했다. 정도 간략하게 설명

 

스킬 입력 기능

  • 유니티 버튼 컴포넌트

공격 범위 지정 기능

  • 터치 앤 드래그( Input.mousePoint, OnMouseDrag)
  • 유니티 게임 속도 조절(Time.timeScale = 1f;)

파이어볼 발사 기능

  • Instantiate()
  • LookAt()

파이어볼 이동 기능

  • Vector3.Lerp를 이용한 BezierCurve() 구현 후 이용

파이어볼 폭발 기능

  • FieldOfView 스크립트의 OverlapSphere를 이용

잔불 기능

  • Instantiate()
  • FieldOfView 스크립트의 OverlapSphere를 이용
  • 순간이동형AI의 순간 이동 기능을 이용(Random.insideUnitCircle * viewRadius;)

 

 

반응형

댓글