일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- Beakjoon
- 백준 1103번 게임
- 유니티
- 17070번
- Algorithm
- 플레이어 이동
- 코테
- 2870번 수학숙제 c++
- 코딩테스트
- 2870번 c++
- 백준 17070번 c++
- c++
- 2468 c++
- 프로그래머스
- 2870번 수학숙제
- 백준 2870번
- 2870번
- Lv2
- 백준 c++ 2468번
- 오브젝트 풀링
- Lv.3
- 백준 1103번
- 백준 17070번
- C#
- 수학숙제
- 백준 1103번 c++
- Unity
- 백준 c++ 2870번
- 백준
- dfs
- Today
- Total
주녘공부일지
[더 챌린저스] 캐릭터 본문
1. 캐릭터를 제어하는 싱글톤 클래스
- 내 캐릭터와 상대 캐릭터가 존재하기 때문에 제어권을 가진 '나의 캐릭터'만 제어하는 기능을 함
- 캐릭터를 생성하고 생성 시 Action 대리자 메서드를 등록해 이벤트 발생을 감지
public void PlayerCommand(ENUM_PLAYER_STATE nextState, CharacterParam param = null)
{
if (activeCharacter == null || !activeCharacter.isControl)
return;
switch (nextState)
{
case ENUM_PLAYER_STATE.Idle:
activeCharacter.Idle();
break;
case ENUM_PLAYER_STATE.Move:
activeCharacter.Move(param);
break;
case ENUM_PLAYER_STATE.Dash:
activeCharacter.Dash();
break;
case ENUM_PLAYER_STATE.Jump:
activeCharacter.Jump();
break;
case ENUM_PLAYER_STATE.Attack:
activeCharacter.Attack(param);
break;
case ENUM_PLAYER_STATE.Skill:
activeCharacter.Skill(param);
break;
case ENUM_PLAYER_STATE.Hit:
Debug.LogError("PlayerCommand() : Hit 명령이 들어옴");
break;
case ENUM_PLAYER_STATE.Die:
activeCharacter.Die();
break;
}
}
2. 캐릭터 파라미터 클래스
- 캐릭터의 상태를 변경하는 명령에 필요한 데이터를 담은 파라미터 클래스
+ Serialize(), Deserialize() : 브로드캐스트 할 때 패킷에 커스텀 클래스를 넣을 수 없어 바이트화 하기 위해 추가된 코드
[Serializable]
public class CharacterParam : PhotonCustomType { }
[Serializable]
public class CharacterMoveParam : CharacterParam
{
public float moveDir;
public CharacterMoveParam(float _moveDir)
{
moveDir = _moveDir;
}
}
// 기본공격, 점프공격
[Serializable]
public class CharacterAttackParam : CharacterParam
{
public ENUM_ATTACKOBJECT_NAME attackTypeName;
public bool reverseState;
public CharacterAttackParam(ENUM_ATTACKOBJECT_NAME _attackTypeName, bool _reverseState)
{
attackTypeName = _attackTypeName;
reverseState = _reverseState;
}
public new static object Deserialize(byte[] data)
{
string jsonData = Encoding.UTF8.GetString(data);
return JsonUtility.FromJson<CharacterAttackParam>(jsonData);
}
public new static byte[] Serialize(object customObject)
{
var param = (CharacterAttackParam)customObject;
string jsonData = JsonUtility.ToJson(param);
return Encoding.UTF8.GetBytes(jsonData);
}
}
// 캐릭터의 스킬 번호 ( 0 ~ 4 ) 0 : Dash
[Serializable]
public class CharacterSkillParam : CharacterParam
{
public int skillNum;
public CharacterSkillParam(int _skillNum)
{
skillNum = _skillNum;
}
public new static object Deserialize(byte[] data)
{
string jsonData = Encoding.UTF8.GetString(data);
return JsonUtility.FromJson<CharacterSkillParam>(jsonData);
}
public new static byte[] Serialize(object customObject)
{
var param = (CharacterSkillParam)customObject;
string jsonData = JsonUtility.ToJson(param);
return Encoding.UTF8.GetBytes(jsonData);
}
}
3. 캐릭터 애니메이션 제어
1) 애니메이터 컨트롤러
- 복잡한 구조도를 가능한 편하게 확인하고 수정할 수 있도록 특정 모션들은 서브 머신으로 묶어서 관리
- bool 변수와 Trigger 변수로 두 번 이상 체크를 함으로써 안정성 향상
ex) isHit : 피격상태 / HitTrigger : 피격 1회
2) 애니메이터 오버라이드 컨트롤러
- 매우 복잡한 캐릭터의 애니메이터 컨트롤러를 재사용하기 위해 사용
- 원본 애니메이터 컨트롤러와 동일한 로직을 사용하지만 원본 대신 새롭게 할당된 애니메이션을 재생
- 애니메이션 클립 이벤트와 스테이트 머신 비헤이비어(후술)를 통해 해당 모션에 대한 추가적인 기능을 함
3) 스테이트 머신 비헤이비어
유니티에서 제공해주는 클래스로 스크립트를 상태 머신에 연결할 수 있음
- 모션의 상태 변경을 감지하기 위해 로직을 따로 작성할 필요 없이 해당 모션에서 수행할 특정 로직을 구현
public class DeadLanding : StateMachineBehaviour
{
ActiveCharacter activeCharacter;
public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
if (activeCharacter == null)
activeCharacter = animator.transform.gameObject.GetComponent<ActiveCharacter>();
CoroutineHelper.StartCoroutine(IDeadEffect());
}
private IEnumerator IDeadEffect()
{
SpriteRenderer charSpriteRenderer = activeCharacter.GetComponent<SpriteRenderer>();
if (charSpriteRenderer == null)
yield break;
Color color = charSpriteRenderer.color;
yield return new WaitForSeconds(1.5f);
while (color.a > 0.1f)
{
color.a -= 0.01f;
charSpriteRenderer.color = color;
yield return null;
}
color.a = 0f;
charSpriteRenderer.color = color;
activeCharacter.EndGame();
}
}
4. 캐릭터 스테이트 관리 고찰
복잡한 구조도를 가능한 편하게 확인하고 수정할 수 있도록 특정 모션들은 서브 머신으로 묶어서 관리
- 특히 Any State로 사용할 필요가 있는 Dash, Die, Skill(Attack) 등의 모션은 특히 신경써서 처리
-> 해당 트랜지션의 조건 파라미터만 충족하면 어느 상태든 넘어가버리기 때문에 불 변수와 트리거 변수를 이용해 더블체크
1) 파라미터 분류 규칙
- IsXX 변수 (Bool) : 해당 상태로 전환할 수 있다는 의미
-> 서브 스테이트 모션으로 전환, 탈출 조건 등에 사용
- XXState 변수 (Bool) : 해당 상태라는 의미
-> 중복으로 같은 스테이트에 들어가지 않게 하기 위한 조건 등에 사용
- XXTrigger 변수 (Trigger) : 해당 상태로 전환하라는 의미
-> 보통 bool변수와 함께 사용되며, AnyState로 연결된 트랜지션 조건에는 무조건 사용
- 기타 (int) : 방향 값이나 고유한 번호를 받기 위해 사용
-> SkillType : 스킬 고유 번호 // DirX : X축 방향 값 ( -1, 0, 1 )
2) Sub State Machine - Jump
점프 상태의 돌입과 끝을 관리하는 서브 스테이트
- 초기에는 JumpAttack은 다른 서브스테이트머신(Attack)에 두고 점프 모션도 BaseLayer에 있었지만,
- 점프상태에서만 할 수 있다는 점과 착지모션 추가, 점프업다운상태 분리 등의 분할된 모션이 증가된 이유로 서브 스테이트로 묶어서 관리함
3) Sub State Machine - Attack
기본공격 3타와 스킬을 관리하는 서브 스테이트
- 기본 공격은 반드시 3타를 하지 않아도 1타, 2타 직후에 공격 키가 입력상태가 아니라면 Idle, Move 상태로 전환할 수 있음 ( 단, 살짝의 딜레이 존재 )
flow) 공격 키 입력 상태 판단 -> 공격 사용가능 여부 판단 -> 공격 불 타입 True -> 공격 1회 트리거 On
- Skill은 캐릭터별로 지정된 스킬번호를 가지고 있음
flow) 스킬 사용가능 여부 판단 -> 스킬 번호 세팅 -> 스킬 트리거 On
4) Sub State Machine - Hit
히트 상태에서의 보정, 히트 상태에서의 착지, 일어나는 모션 등을 관리하는 서브 스테이트
- 다단 히트가 가능한 게임으로써 히트 모션이 여러개 필요해 Hit 모션에서 Hit가 들어오면 다른 모션이 재생되게 하였고 트리거를 히트 1회로 처리했음
- 히트를 당해 공중에 떠있는 상태와 캐릭터가 스스로 공중에 떠있는 상태(점프키 입력)에 대한 파라미터 변수는 공용으로 사용
'GameDevelopment > [Unity] Project' 카테고리의 다른 글
[마법사의 길] 캐릭터, 몬스터 AI 상태 관리 (0) | 2024.09.09 |
---|---|
[더 챌린저스] 동기화(RPC) & 네트워크(Photon) (1) | 2024.09.09 |
[더 챌린저스] 게임 플레이 영상 (2) | 2024.09.04 |
[페인트 맨] 파이어베이스 DB 관리 (0) | 2024.03.29 |
[페인트 맨] 다국어 지원 시스템 (Localization) (0) | 2024.03.29 |