기존 RushEffectManager를 확장하여 새로운 Effect Controller를 제작함
기존 문제점
이펙트 관리 주체가 존재하지 않아 번거롭게 Object Pooling을 해야했음.
Effect 관리 체계가 Effect마다 상이했음.
변경 사항
ECManager를 통해 내가 원하는 이펙트 그룹의 Effect Controller를 가져오게 함
가져온 Effect Controller를 통해 내가 원하는 이펙트를 자동으로 풀링하고 Level, Tracking 등의 기능을 활용해 이펙트를 관리할 수 있음.
개선 예정 사항
아직 플레이어의 콤보 시스템에는 적용하지 못하여 적용 필
사용법
Effect Datas Scriptable Obeject
먼저 위와 같이 EffectDatas Scriptable Object를 만들어 올바른 이펙트를 할당할 필요가 있다.
추후 Effect Controller에서는 Effect Type과 Effect Target을 기반으로 구분하는데, 어차피 스크립트 작성자가 구분하는 용도이므로, 본인의 마음대로 해도 기능적으로 문제는 없다.
그러나 가급적이면 올바르게 할당하길 바라며, Effect Type, Effect Target이 모두 같은 요소를 추가해도 되지만 가급적이면 그러지 않길 권고한다.
Effect List에는 해당 상황에 맞는 이펙트를 넣어야 하며, 보통 하나의 이펙트만 넣으나, Level Effect로 등록을 원할 경우에는 레벨에 따라 여러 개를 넣어야 한다.
아무튼 이렇게 EffectDatas에 이펙트를 모두 넣었다면 다음은 스크립트로 넘어간다.
우선 위와 같이 앞서 만든 SO를 넣어 Effect Controller를 찾아주어야 한다.
Active Effect
이후 EffectController의 ActiveEffect 메소드를 실행하여 이펙트를 생성할 수 있다.
다만 넣어주어야 할 인자가 상당히 많은데 이는 해당 메소드의 summary로 설명을 대체한다.
Level Effect
또한 LevelEffect로 등록하여 일일이 해제하고 생성할 필요 없이, 메소드를 사용해 간편하게 단계적인 이펙트를 관리할 수 있다.
ActiveEffect 메소드를 호출하면 해당 이펙트의 키를 되돌려주는데, 이를 이용해 LevelEffect로 등록할 수 있다.
이후 이펙트 키와 설정할 단계를 입력해주면 해당 단계에 맞는 이펙트로 변환되어 생성된다.
Tracking
또한 위와 같이 이펙트 키와 추적(Tracking) 대상을 인자로 넣고 이펙트가 대상을 계속 따라가도록 설정할 수 있다.
RemoveEffect
이펙트를 생성했으면 지워주어야 하는 순간도 생긴다. 이때는 RemoveEffect 메소드를 사용해야 한다.
사용법은 간단하다. 이펙트 키만 입력해주면 간단히 지워진다.
그러면 남은 두 매개변수는 무엇일까? 이건 Tracking과 Leveling관련 설정값이다.
우선 Tracking의 경우, RemoveEffect를 호출할시 등록이 해제되는데, 이때 몇 번째 인덱스에 등록된 값인지 알고 있다면 해당 매개변수를 통해 삭제해줄 수 있다. 다만 일반적인 상황에서 우리가 이걸 알지는 못하기에 null로 두면 알아서 처리해준다.
또한 Leveling의 경우, Tracking과 달리 자동으로 등록이 해제되지는 않는데, 세번째 매개변수인 isUnleveling을 true로 넘겨주면 레벨링 등록을 해제해준다다.
Effect Key 클래스
위 작업을 위한 Effect Key는 별도의 클래스로, ActiveEffect를 호출할 때 생성되는 인스턴스이다.
이를 그냥 단순히 Effect를 생성, 삭제, 관리하는 데에만 쓸 수도 있지만, 내부의 데이터를 활용할 수도 있다. 대부분 상수로 선언되어 있어 값을 읽는 용도로 쓰이나, 일부는 값을 변경할 수도 있다.
물론 Key 내의 변수를 변경하는 것은 권장하는 사항은 아니다. Key를 변경한다고 해서 당장 이펙트에 적용되지는 않겠지만, 추후 예기치 않은 현상을 야기할 수 있으니 주의하자.
파라미터
public readonly AsyncOperationHandle handle : Addressable 생성, 관리를 위한 handle
public readonly EffectData effectData : Effect 정보가 들어있음. SO에서 뽑아온 것.
public readonly AssetReference effectReference : Effect원본
public GameObject EffectObject : 생성된 오브젝트
public bool isAssigned : 오브젝트가 생성되었는지 체크
public readonly ObjectAddressablePoolManager poolManager : 오브젝트 풀링 매니저
public readonly Vector3? position : 생성 위치
public readonly Quaternion? rotation : 생성 시 회전 값
public readonly int index : 같은 Time/Target인 EffectData 중 몇 번째 값인지(보통 0)
private GameObject effectObject : 생성된 오브젝트 원본
private bool isLevelEffect : Leveling이 등록된 오브젝트인가
private bool isTrackingEffect : Tracking이 등록된 오브젝트인
IsLevelEffect
매개변수
없음
기능
isLevelEffect 반환
반환
isLevelEffect
IsTrackingEffect
매개변수
없음
기능
isTrackingEffect반환
반환
isTrackingEffect
SetLevelEffect
매개변수
isLevel(bool) : Leveling된 이펙트인지
기능
isLevelEffect 값 변경
반환
없음
SetTrackingEffect
매개변수
isTrack(bool) : Tracking된 이펙트인지
기능
isTrackingEffect 값 변경
반환
없음
Player Command Graph
설명
기존 콤보 트리는 데이터를 작업하기 비직관적이었으므로, 이를 트리형태로 시각화하여 보다 작업하기 편하도록 개편함.
우선 플레이어 최종 행동 값을 얻어오기 위해서는 Player Input Manager에 접근을 해야한다.
Player Input Manager는 Player Prefab에 붙어 있으며, 두 가지의 파라미터를 가진다.
pc는 PlayerController를 참조하는 파라미터이고, 다른 하나는 키 값을 저장할 프레임의 수이다.
예를 들어, 사진과 같이 3이라 설정되어 있다면, 현재 프레임을 n번째 프레임이라 할때, n-2, n-1, n번째에서의 입력이 저장되어 있다고 생각하면 된다.
어찌됐든 Player Input Manager에 접근했다면 두 가지 메소드를 통해 입력 값을 받아올 수 있다.
하나는 인덱스로 접근하는 방식, 다른 하나는 가장 최근의 입력 값에 접근하는 방식이다.
필요에 따라 선택하면 되며, 인덱스로 접근할 경우 가장 최근 값은 앞서 설정한 키 값을 저장할 프레임의 수이므로 이 값이 3이라면, 인덱스 기준으로 2를 입력하면 된다. 마찬가지로, 0을 입력하면 가장 최근의 입력에서 두 프레임 이전의 값이다.
또한 반환 값은 모두 Queue 형태인데, 이는 원본 데이터에서 복사된 값이므로 원하는대로 활용해도 문제없다.
주의할 점
저장된 입력 값을 갱신하는 것은 모두 LateUpdate에서 이루어진다. 가장 오래된 입력 값을 읽으려면 LateUpdate가 호출되기 전에 이루어져야 하며 LateUpdate 이후에는 인덱스가 바뀌므로 주의해야 한다.
위 사항에 의해 당연히, LateUpdate가 호출될 시점에는 입력 값의 인덱스가 보장되지 않으므로 주의해야 한다.
처음 세 프레임에서는 당연히 빈 Queue가 존재한다. 이때, 데이터는 List의 가장 뒤부터 채워진다. 즉, 초반 세 프레임에서 0번째 인덱스 및 다른 할당되지 않은 인덱스에 접근하면 비어있는 Queue가 나오게 된다.
프로토콜
사용자는 Queue 내부에서 원하는 값을 찾아 해석하면 되는데, 이 값은 모두 string이다.
이는 모두 정해진 프로토콜에 따른 데이터를 string형태로 바꾸어 저장한 것인데 그 프로토콜은 다음에서 확인할 수 있다.
Effect Controller
설명
기존 문제점
변경 사항
개선 예정 사항
사용법
Effect Datas Scriptable Obeject
먼저 위와 같이 EffectDatas Scriptable Object를 만들어 올바른 이펙트를 할당할 필요가 있다. 추후 Effect Controller에서는 Effect Type과 Effect Target을 기반으로 구분하는데, 어차피 스크립트 작성자가 구분하는 용도이므로, 본인의 마음대로 해도 기능적으로 문제는 없다. 그러나 가급적이면 올바르게 할당하길 바라며, Effect Type, Effect Target이 모두 같은 요소를 추가해도 되지만 가급적이면 그러지 않길 권고한다.
Effect List에는 해당 상황에 맞는 이펙트를 넣어야 하며, 보통 하나의 이펙트만 넣으나, Level Effect로 등록을 원할 경우에는 레벨에 따라 여러 개를 넣어야 한다.
아무튼 이렇게 EffectDatas에 이펙트를 모두 넣었다면 다음은 스크립트로 넘어간다. 우선 위와 같이 앞서 만든 SO를 넣어 Effect Controller를 찾아주어야 한다.
Active Effect
이후 EffectController의 ActiveEffect 메소드를 실행하여 이펙트를 생성할 수 있다. 다만 넣어주어야 할 인자가 상당히 많은데 이는 해당 메소드의 summary로 설명을 대체한다.
Level Effect
또한 LevelEffect로 등록하여 일일이 해제하고 생성할 필요 없이, 메소드를 사용해 간편하게 단계적인 이펙트를 관리할 수 있다. ActiveEffect 메소드를 호출하면 해당 이펙트의 키를 되돌려주는데, 이를 이용해 LevelEffect로 등록할 수 있다.
이후 이펙트 키와 설정할 단계를 입력해주면 해당 단계에 맞는 이펙트로 변환되어 생성된다.
Tracking
또한 위와 같이 이펙트 키와 추적(Tracking) 대상을 인자로 넣고 이펙트가 대상을 계속 따라가도록 설정할 수 있다.
RemoveEffect
이펙트를 생성했으면 지워주어야 하는 순간도 생긴다. 이때는 RemoveEffect 메소드를 사용해야 한다.
사용법은 간단하다. 이펙트 키만 입력해주면 간단히 지워진다. 그러면 남은 두 매개변수는 무엇일까? 이건 Tracking과 Leveling관련 설정값이다.
우선 Tracking의 경우, RemoveEffect를 호출할시 등록이 해제되는데, 이때 몇 번째 인덱스에 등록된 값인지 알고 있다면 해당 매개변수를 통해 삭제해줄 수 있다. 다만 일반적인 상황에서 우리가 이걸 알지는 못하기에 null로 두면 알아서 처리해준다.
또한 Leveling의 경우, Tracking과 달리 자동으로 등록이 해제되지는 않는데, 세번째 매개변수인 isUnleveling을 true로 넘겨주면 레벨링 등록을 해제해준다다.
Effect Key 클래스
파라미터
IsLevelEffect
IsTrackingEffect
SetLevelEffect
SetTrackingEffect
Player Command Graph
설명
기존 문제점
변경 사항
사용법
퓨처리티 - 프로그래밍 - 티켓 - [플레이어] Combo 시각화 작업 참고 or 개인 복제 문서 참고 (https://rune-hickory-a8e.notion.site/Combo-8c0641fc5ed2412eb64f0e70f2e24b19?pvs=4)
플레이어 최종 행동 반환 클래스
설명
기존 문제점
플레이어의 최종 행동 접근 불가
입력이 Player Controller의 책임으로, 과다한 책임이 부여됨
변경 사항
플레이어 입력 분리
PlayerInputManager 클래스 제작
사용법
PlayerInputManager
우선 플레이어 최종 행동 값을 얻어오기 위해서는 Player Input Manager에 접근을 해야한다.
Player Input Manager는 Player Prefab에 붙어 있으며, 두 가지의 파라미터를 가진다. pc는 PlayerController를 참조하는 파라미터이고, 다른 하나는 키 값을 저장할 프레임의 수이다. 예를 들어, 사진과 같이 3이라 설정되어 있다면, 현재 프레임을 n번째 프레임이라 할때, n-2, n-1, n번째에서의 입력이 저장되어 있다고 생각하면 된다.
어찌됐든 Player Input Manager에 접근했다면 두 가지 메소드를 통해 입력 값을 받아올 수 있다. 하나는 인덱스로 접근하는 방식, 다른 하나는 가장 최근의 입력 값에 접근하는 방식이다. 필요에 따라 선택하면 되며, 인덱스로 접근할 경우 가장 최근 값은 앞서 설정한 키 값을 저장할 프레임의 수이므로 이 값이 3이라면, 인덱스 기준으로 2를 입력하면 된다. 마찬가지로, 0을 입력하면 가장 최근의 입력에서 두 프레임 이전의 값이다.
또한 반환 값은 모두 Queue 형태인데, 이는 원본 데이터에서 복사된 값이므로 원하는대로 활용해도 문제없다.
주의할 점
프로토콜
사용자는 Queue 내부에서 원하는 값을 찾아 해석하면 되는데, 이 값은 모두 string이다. 이는 모두 정해진 프로토콜에 따른 데이터를 string형태로 바꾸어 저장한 것인데 그 프로토콜은 다음에서 확인할 수 있다.
퓨처리티 - 프로그래밍 - 티켓 - [플레이어] 최종 행동 반환 클래스 or 개인 복제 문서 (https://rune-hickory-a8e.notion.site/ed179ab2555a4a83aaefef91380655d7?pvs=4)