inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[유니티 레벨 업!] 모듈식으로 개발하는 스킬 시스템

Multi Layered State Machine

Statemachine 관련질문이 있습니다.

287

고우진

작성한 질문수 26

0

격투게임이나 몬스터헌터처럼 애니메이션의 특정 프레임 이후에 입력받아야 특정 애니메이션이 실행가능하게 하려하는데 이걸 어떻게 해야할까요?

기존에는 애니메이션 이벤트를 이용해서 구현했었는데 어떻게 해야할까요?

캡처.JPG

애니메이션 이벤트를 활용하려고 하니 오버로드된 함수들 때문에 이런 경고창이 뜨긴하는데 애니메이션 이벤트의 함수들은 오버로드된 함수들이 아니라 괜찮은가요?

아니면 다른 좋은 방법이 있는지 알려주실수있을까요?

unity modules

답변 3

2

Developer G

간단하게 만든다면 얘기하신대로 만드시면 될거 같구요, 좀 더 제대로 만든다고하면 SpecialCombo처럼 하드 코딩하는 것보다 Command Map을 만들어서 Check하는게 더 좋습니다.

[Serializable]
class Command
{
    public string name;
    public KeyCode Key;
    public Command[] linkedCommand;
}

Q -> W -> E -> R // name: Special Combo
  ㄴ E -> Q // name: Skill 1
  ㄴ E // name: Skill 2

0

고우진

답장해주셔서 감사합니다.

1

Developer G

수강해주셔서 감사합니다.

격투 게임과 몬스터헌터의 경우 공격이 커맨드 방식(=약공, 강공 조합)인데요,
공격 시작 시에 커맨드 수집을 끄고, 애니메이션 이벤트를 통해서 원하는 타이밍에 다시 커맨드 수집을 시작하게 만들거나, State내에서 애니메이션의 플레이타임을 확인하여 애니메이션이 어느 정도 진행되면 다시 커맨드 수집을 시작하게 만들면 됩니다. 예시 코드는 다음과 같습니다.

애니메이션 이벤트를 사용

먼저 말로 정리하면 다음과 같습니다.

CommandCollector를 통해 Command를 수집함 -> AttackingState로 들어가서 Command에 따른 Animation(=강공, 약공) 실행 및 Command 수집을 막음 -> Animation Event를 통해 특정 Frame부터 다시 Command를 수집함 -> Command 입력이 있다면 AttackState로 재진입하여 Combo를 이어감

 

// PlayerEntity - CommandCollector.cs
// Player 입력에 따라 Command(=약공, 강공, 점프 등)를 수집함
void Update()
{
    // Player의 Key 입력이 있을 시 Key에 맞는 Command를 찾아옴
    LastCommand = commands.Select(x => x.key == Input.GetButtonDown());
}

void OnDisable()
{
    LastCommand = default;
}


// EntityStateMachine.cs
public void MakeTransitions()
{
    ...
    // 입력된 Command가 있고 Attack Type이라면 다음 Combo로 이어감
    MakeTransition<AttackingState, AttackingState>(x => x.Entity.CommandCollector
.LastCommand.Type == CommandType.Attack);
}


// AttackingState.cs
// 공격 상태
void override void Enter()
{
    ...
    // Animation을 통한 공격 수행
    // name == "strongAttack" or "lightAttack"
    Entity.Animator.SetTrigger(Entity.CommandCollector.LastCommand.name);
    // Command 수집을 멈춤
    Entity.CommandCollector.enable = false;
}

void override void Exit()
{
    ...
    Entity.CommandCollector.enable = true;
}


// AnimationEvents.cs
// Animation Event로 등록하여 사용
public void ActivateCommandCollector()
{
    GetComponent<CommandCollector>().enable = true;
}

 

애니메이션 플레이 타임을 이용하는 방법은 애니메이션 이벤트 대신 AttackingState에서 애니메이션 플레이 타임을 확인해주면 됩니다.

플레이 타임을 확인

// AttackingState.cs
public override Update()
{
    // 현재 실행중인 Animation 정보를 가져옴
    var animationInfo = Entity.Animator.GetCurrentAnimatorStateInfo(0);
    // normailzedTime(=PlayTime) 0 ~ 1
    // Animation이 85퍼 진행되면 Command를 다시 수집함
    if (animationInfo.normalizedTime >= 0.85f)
        Entity.CommandCollector.enable = true;
}

 

언제나 그렇듯 보여드린 예시 코드가 무조건적 정답은 아니구요, 강의 내용을 활용해서 이렇게 만들 수 있다 정도로 보시면 됩니다.

 

오버로딩 경고는 애니메이션 이벤트가 SendMessage 방식이라 이름이 같은 함수들이 있으면 그 함수들 중에서 무엇이 실행될지 알 수 없기 때문에 나오는 경고입니다. Fuction에 해당 함수들을 사용하지 않으면 괜찮구요, 해당 함수들을 사용해야할 경우 래핑 함수 하나를 만들어서 사용해주시면 됩니다.

ex.
Show라는 함수들이 여럿 있을 경우 Show 대신 사용하려는 Show 함수를 래핑한 ShowCallback 함수를 사용해줌
public void ShowCallback()
{

display.Show();

}

 

감사합니다.

0

고우진

답변해주셔서 감사합니다

커맨드를 저장하는건 이런식으로

List<KeyCode> keyList = new List<KeyCode>();
void Update()
{
if (Input.anyKeyDown)
{

foreach (KeyCode key in System.Enum.GetValues(typeof(KeyCode)))

{

if (Input.GetKeyDown(key)) { keyList.Add(key); } }

}
}

리스트로 구현하고 공격 애니메이션이 끝날때마다 리스트를 초기화 해준 다음에


커멘더 콜렉터에 bool값을 만든 다음에 해당 리스트에서 특정 조합과 순서가 해당되는게 있다면 참으로 만든 다음에
애니메이션의 transition 넘어가는 조건으로 해당 bool값을 넣어주는 방식으로 구현도 괜찮을까요?
MakeTransition<AttackState, SpecialAttackState>( state => Owner.CommandController.SpecialAttackBool)


입력받은 키의 비교는 예를들어 qwer이 순서대로 눌려야 한다면
List<KeyCode> SpecailCombo = new List<KeyCode> { KeyCode.Q, KeyCode.W, KeyCode.E, KeyCode.R };

bool SpecialAttackBool()

{

for (int i = 0; i < SpecailCombo.Count; i++)

{

if (keyList[i] != SpecailCombo[i])

{

return false;

}

}

return true;

}

Indicator와 SelectionAction 및 SearchAction 간의 관계에 대해 질문있습니다.

0

69

2

ChargingState에서 질문이 있습니다.

0

48

1

Effect.GetData 함수 질문있습니다.

0

44

2

CanTransitionToSelf 질문 있습니다.

0

52

2

Stat의 MaxValue에 관하여 질문이 있습니다.

0

41

1

Stat vs StatScaleFloat

0

74

4

애니매이션 버그가 있는것 같습니다.

0

64

2

StatsOverride질문이 있습니다.

0

49

2

SetBonusValue함수 질문있습니다.

0

45

2

오늘 수강시작한 취준생입니다.

0

48

1

사소하지만 에디터 관련 질문있습니다

0

68

1

스킬시스템을 데이터 테이블화 하는 법에 대해 감이안잡혀서 질문드립니다.

0

143

2

TargetSearcher에 대해서 질문이 있습니다

0

51

1

돌진해서 몸박을하면 피격자를 날리면서 데미지를 입히는 스킬은 이 시스템에서 어떻게 만들 수 있을까요??

0

115

2

스킬 관련 질문입니다

0

109

2

통일된 Stat을 사용하지 않고 모듈화 방식으로 Stats를 만드신 이유가 궁금합니다.

0

151

1

Effect에 기능 확장에 대해서 질문이 있습니다.

0

149

2

SkillData 구조체 질문

0

121

1

스킬트리 저장 질문입니다

0

134

2

BT와 FSM을 활용해 몬스터 AI 구현

0

348

2

MonoStateMachine을 만든 이유가 잘 이해가 가지 않습니다.

0

127

1

근접 콤보 공격을 만들고 싶습니다.

0

152

1

하나의 스킬 내에서 타겟, 이펙트가 여러번 바뀌게 하는 방법이 궁금합니다.

0

188

1

올해에 예정된 새로운 강의가 있으신지요?

0

113

2