서버엔진

포톤 퀀텀2

ClientProgrammer 2022. 7. 24. 22:19

 

QTN에 정의 가능한 것들.

- component : 유니티 entity에 컴퍼넌트로 붙여서 값을 넣어서 퀀텀코드로 넘길 수 있음 

 

- 미리정해진키워드  ex) input, global  : component와 비슷하게 유니티에서 퀀텀코드로 넘길 변수를 추가 할 수 있는데, 

미리 정의 된 키워드를 사용해야하고, frame안에 해당 키워드들을 얻어오는 함수도 미리 정의 되어 있다.

특히 global 키워드는 여러 qtn에 중복으로 선언 되어 있을 수 있고, 빌드하면 codegen의 __global__에 통합 된다.

 

- enum : 빌드하면 codegen에 추가 되고 단순 enum뿐 아니라 관련 된 세트가 추가 된다.

 

- synced event

EVENT_TYPE_COUNT가 증가 되고 GetEventType 에 case가 추가 된다.

EventBase 상속받는 XX 클래스가 추가 된다

FrameEvents 클래스에 XX형을 리턴하는 XX이름의 함수가 추가 되고 해당 함수 호출 시 frame의 이벤트 리스트에 add 된다.

 

- signal XX(int32 value);

  ISignal 인터페이스를 상속 받는 ISignalXX 이름의 인터페이스가 생성 된다

  Frame클래스에 ISignalXX 배열형의 변수가 선언 되고, XX이름의 함수가 추가 된다.

  

 

*런타임 에러

Checksum Error Detected By Server, Simulation Halting. 

quantum.code를 리빌드하고 게임 exe 를 다시 빌드해서 테스트 하니 정상 작동.

 

 

 

퀀텀&유니티 통신 목록

—------------------------------------

퀀텀코드

Signal



퀀텀코드->유니티 CALL

Event

OnEntityInstantiated

 

유니티->퀀텀코드 CALL

[미리 정의 됨]

CallBack + input ( callback 의 구조체파라미터인 미리 정의 된 이름의 input의 변수를 사용자 정의 가능 )



[사용자 정의 가능]

EntityComponent

Command



퀀텀&유니티 통신 상세

—------------------------------------

*OnEntityInstantiated

퀀텀코드->유니티 CALL

 

entityView.OnEntityInstantiated.AddListener(OnEntityInstantiated);



*event

퀀텀코드->유니티 CALL

 

[호출 순서]

1.qtn 파일에 event{ string log; } 등록

2.unity 씬에 포함 된 오브젝트의 스크립트가 시작 되는 부분에서 case2 호출.

3.quntum.code 에서 f.events.log(“test”); 호출



ex)

case 1.QuantumCallback.Subscribe(this, (CallbackPollInput callback) => PollInput(callback));

case 2.QuantumEvent.Subscribe<EventLog>(this, EventLog);

 

 

*CallBack

유니티->퀀텀코드 CALL

 

ex)

QuantumCallback.Subscribe<CallbackPollInput>(this, PollInput);

  public  void PollInput(CallbackPollInput pollInput)

  {

    pollInput.SetInput(a, DeterministicInputFlags.Repeatable);

  }



*Command

유니티->퀀텀코드 CALL

 

[준비]

1.DeterministicCommand를 상속받는 클래스 생성 후 파라미터로 넘겨받을 변수를 멤버 변수로 선언.

1-1.추상 함수 Serialize 재정의 후 멤버변수 serialize

1-2.실제 동작 할 함수 “Excute” 선언 

 

2.모든 Command를 처리 할 System 클래스 생성 후 SystemSetup에 등록

2-1.update에서 frame.PlayerCommand 얻어온 후 실제 동작 함수 Excute 호출

var command = f.GetPlayerCommand(player->player);

                if(command is SHCommand shcommand)

                {

                    shcommand.Excute(f);

                }

 

2-2.유니티에서 호출

QuantumRunner.Default.Game.SendCommand(new SHCommand()

        {

            shNumber = 3,

        });            



*Signal

퀀텀코드->퀀텀코드 CALL.

전역적으로 접근 할 수 있는 frame 내부에 함수를 선언 하는 것이다.

 

[Signal 선언]

.qtn 에 signal FunctionName(parametertype parametername);

 

[Signal 정의]

quantum.code system 클래스를 정의한 ISignalxx 인터페이스로 상속 받는다.

함수 구현 해 주면 호출시 해당 함수가 호출 된다

 

[Signal 호출]

f.signal.xx();

 



<유니티에서 퀀텀 주요 키워드 얻어오기>

 

EntityRef

GetComponent<EntityView>().EntityRef

 

Frame

var frame = QuantumRunner.Default.Game.Frames.Predicted;

 

 

<퀀텀문법>

*GetPointer

파라미터로 generic 형식에 Quantum.IComponent 형 struct를 넣어주면 entityRef 가 가지고 있는 컴퍼넌트를 리턴 한다. Quantum.IComponent 형 struct를 만들기 위해서는 qtn 파일에 component로 선언 해 주면 된다.

 

ex)

PlayerData data = f.Unsafe.GetPointer<PlayerData>(entityRef);



*TryGetPointer

GetPointer과 사용 목적이 같다.

 

ex)

if( f.Unsafe.TryGetPointer<PlayerData>(entityRef, out PlayerData* playerData))

{


}

 

 

*QuantumRunner : 유니티에서 Quantum에 접근하기 위한 MonoBehavior을 상속받는 인스턴스.

Session이라는 객체를 가지고 있고 내부의 update에서 Session.Update 돌면 퀀텀코드의 각종 콜백들이 호출 된다. 그중 하나가 “OnGameStart”

 

사용법

QuantumCallback.Subscribe(this, (CallbackGameStarted callback) => GameStarted(callback));

 

 그런데 정작 필요한 OnGameStart가 호출 됐을 때 퀀텀코드에서 처리 할 함수는 재정의가 안 된다. OnEntityInstantiated는 Signal을 상속 받아서 처리 할 수 있는데 콜백은 안 돼서 아쉽다. command를 쏴서 구현 가능.

 

 

퀀텀 dsl component 는 component를 상속받은 struct이다

 

qtn에 struct를 정의 할 수 있고, struct에 함수를 추가 하고 싶으면 같은 이름의 구조체 하나 만들고 patial키워드 붙인 후 함수 선언 해 주면 된다.

 

 

*자료형변환

float time; 

FP time;

 

float To FP

확장함수를 사용해서 time.ToFP(); 해 주면 되고

 

FP To float

time.AsFloat



*퀀텀 프록시 패턴 사용 예 ( 대리자 )

스킬 쿨타임을 퀀텀코드에서 관리 한다고 했을 때 유니티 UI에서 출력하기 위해 값을 얻어와야 하는데, event를 계속 쏴서 얻어오긴 부담스럽기 때문에 프록시패턴을 이용해서

프록시 클래스를 만들고 그 안에 얻어 올 퀀텀 코드에서의 프로타입컨퍼넌트들을 멤버 변수로 선언 해 준다.

static 으로 자기 자신을 리턴하는 Resolve 함수를 만들고, frame과 entityRef를 이용해서 GetPoint로 값을 가져온 뒤 프록시에 담아서 리턴한다.

 

 

callback+command 주의사항

퀀텀에서 정의 한 콜백을 사용 할 때  QuantumCallback.Subscribe 으로 콜백 등록을 하는데, 유니티 실행 후 바로 활성화 되는 게임오브젝트의  Awake에 Subscribe를 한 후, 콜백에서 Command를 했더니 퀀텀에서 받질 못했고 Start에서 Subscribe 하니 받아졌다. 콜백 자체는 호출 되는걸 보면 Command가 전송이 안 되는것같은데 아마 콜백 등록당시에는 QuantumRunner.Default.Game이 비정상 상태이지 않을까 싶다. 각각 로그를 찍어봤을때는 모두 QuantumRunner.Defualt가 null이고, 내부적으로 아직 다른 요소가 Awake에서는 준비가 안 된 상태이지 않을까싶다.



퀀텀코드 포인터주의

Get을 할 때는 상관없지만 Set을 할 때는 포인터를 다른 변수에 넣어두고 그 변수의 값을 셋팅하면 값이 변하지 않는다. 자신 없으면 좀 길더라도 원본에 셋 하도록 한다



GetPointer의 반복버전

var abilityHolders = f.Unsafe.GetComponentBlockIterator<Abilitys>();

foreach (var (e, a) in abilityHolders)

 

*퀀텀 WokerJob ( 쓰레드 ) 사용

SystemMainThread가 아닌 SystemBase 상속 받아서 작업

 

 

<???????????????????????>

?프레임개념?
Frame의 Predicted , Verified 차이

 

?아이콘 모양 차이는?

같은 프로젝트인데 솔루션에 따라 아이콘이 다르게 보이는 경우가 있다. 아래 c#이 보이는 아이콘의 프로젝트는 속성 보기가 가능하고, 위의 아이콘 프로젝트는 속성 보기가 안 된다.