프로퍼티 동기화

# 학습 과정 소개

서버, 클라이언트 간 데이터 전송 방식 중 하나인 프로퍼티 동기화에 대해 알아봅시다.

# 동기화

메이플스토리 월드에서의 동기화는 서버, 클라이언트 간 데이터 전송 방식의 일종으로,각각의 공간에 존재하는 같은 이름의 프로퍼티를 같은 값으로 맞춰주는 것을 의미합니다. 기본적으로 프로퍼티는 선언과 동시에 서버, 클라이언트 각각의 공간에 생성되지만, 만일 프로퍼티 동기화가 되지 않는다면 이름은 같지만 서로 다른 값으로 설정할 수 있습니다. [png](1656921110965fe5ba17e21f34900892bd58c08cd2059)   
제작자의 의도에 따라서 같은 프로퍼티의 값을 각 공간에 따라 다르게 할당할 수 있지만, 일반적으로 관리 측면의 효율성을 위해 두 공간의 같은 프로퍼티를 똑같은 값으로 맞춰주게 됩니다. 그렇다면 프로퍼티 동기화는 어떻게 할 수 있을까요?   
메이플스토리 월드에서는 프로퍼티를 자동으로 동기화해주는 기능을 제공해주고 있습니다. 프로퍼티 선언 후 동기화를 할지에 대한 여부만 설정해주면 되기 때문에 동기화를 위한 별도의 구현이 필요 없습니다.

> 더 알아보기 만약 동기화가 제공되지 않는 상황에서 캐릭터의 스탯을 만든다고 가정해 봅시다. 스탯을 만든다면 먼저 Stat이라는 컴포넌트를 만들고, 그 안에 HP 프로퍼티와 MP 프로퍼티 등등을 만들게 됩니다. 그리고 여기에 더해 캐릭터가 몬스터로 부터 공격받았을 때 HP를 감소시킨다 라는 것을 만든다면, 우리는 서버에서 캐릭터의 HP를 감소시키는 로직을 만들 것입니다. 이때 서버와 클라이언트의 프로퍼티는 다른 공간에 존재해 있기 때문에 서버의 HP 프로퍼티만 값이 갱신되고, 클라이언트의 HP 프로퍼티는 갱신되지 않은 상태가 됩니다. 실제 캐릭터의 HP 값은 줄어들었지만, 클라이언트 상 (대표적으로 눈에 보이는 UI)에서는 HP가 줄어들지 않게 되는 것이죠. 이럴 때 서버의 프로퍼티가 변경되면 수동으로 클라이언트의 값을 변경해 주거나, 또는 서버와 클라이언트가 같은 로직을 돌게 해야 하는데 이는 상당히 비효율적이면서 관리가 쉽지 않습니다. [png](16353351388052ce5c7972f5f47abb1d5ff853ed1c98f) <캐릭터는 죽었지만, HP는 줄어들지 않는 이유는 서버와 클라이언트 간의 프로퍼티 동기화가 이루어지지 않아서입니다.>

# 동기화 방향

일부 네이티브 컴포넌트를 제외하면, 대체로 프로퍼티 동기화는 서버에서 클라이언트로 진행됩니다. 즉, 서버에서 프로퍼티에 값을 할당해주면, 서버에서 변경된 값이 클라이언트로 전송되어 같은 프로퍼티에 할당됩니다. 이는 반대로 클라이언트의 프로퍼티에 값을 할당한다고 서버의 값이 같이 변하지 않는다는 얘기이기도 합니다. 이유는 서버는 단독으로 존재하기 때문에 서버의 값이 변경되었을 때 각 클라이언트로 전송할 수 있지만, 클라이언트는 여러 개로 존재하면서 각자 다른 값으로 수정할 수 있기 때문에 서버 입장에서는 어떤 값으로 수정되어야 하는지 판단이 어려워지기 때문입니다.

메이플스토리 월드에서 클라이언트에서 서버로의 동기화는 대체로 제한되어 있고, 프로퍼티의 동기화 설정을 한 상태에서 클라이언트의 값만 단독으로 변경하는 것은 특수한 경우를 제외하고는 추천하는 방법은 아닙니다.

  * 서버에서 변경된 값으로 동기화를 시도할 경우 [png](1637147657269fd6b96b5c65e49ca9423a19a6f8af4c4)   

  * 클라이언트에서 변경한 값으로 동기화를 시도할 경우 [png](1637147673759d03429e5f6a64067ac73010418dc8515)   
동기화는 서버에서 변경한 값을 클라이언트로 전송한 뒤 같은 값으로 맞추는 것이기 때문에 약간의 딜레이가 발생할 수 있습니다. 이는 서버에서 값을 변경한 즉시 클라이언트에 반영되지 않는다는 뜻입니다. 서버에서 변경한 값이 클라이언트로 동기화된 시점에 맞춰 어떤 액션을 수행하고 싶다면, 기본 이벤트 함수 중 하나인 OnSyncProperty를 활용하면 됩니다. OnSyncProperty는 같은 컴포넌트에 있는 프로퍼티 값이 동기화되었을 때 호출되는 함수로, 서버로부터 동기화된 값을 클라이언트 상에 출력할 때와 같은 상황에서 유용하게 사용됩니다. OnSyncProperty에 대한 상세한 내용은 아래 가이드 참고하세요. 



# 동기화 설정

동기화에 대해 기본적인 개념을 알아보았으니 이번에는 실제 동기화를 설정하는 방법과 프로퍼티 타입에 따른 동기화 설정 가능 여부에 대해 알아보도록 하겠습니다.

#### 동기화 설정 방법

동기화 설정 방법은 매우 간단합니다. 스크립트 에디터를 한 번이라도 열어서 프로퍼티를 추가해봤다면 프로퍼티 상단에 Sync라고 쓰여 있는 것을 본 적이 있을 것입니다. 이 Sync는 프로퍼티 동기화가 되고 있다는 것을 의미합니다. [png](16353351805975c7eee1f898d423a80562096893bcc95)   
만일 프로퍼티 동기화를 원치 않는다면 Sync를 눌러 None으로 변경해 줍니다. 동기화 표시가 None으로 되어 있으면 프로퍼티 동기화는 이루어지지 않는다는 것을 의미하며, 프로퍼티 값을 공간별로 따로 관리할 수 있게 됩니다. [png](16353351874159d1ae0e2b0e148ac8fe0075ef65b2f96)   


#### 타입별 동기화 가능 여부

일부 타입의 프로퍼티는 동기화 설정이 제한됩니다.

[{"타입":"any","동기화 가능 여부":"X"},{"타입":"string","동기화 가능 여부":"O"},{"타입":"integer","동기화 가능 여부":"O"},{"타입":"number","동기화 가능 여부":"O"},{"타입":"boolean","동기화 가능 여부":"O"},{"타입":"table","동기화 가능 여부":"X"},{"타입":"SyncTable< v >","동기화 가능 여부":"O"},{"타입":"SyncTable< k,v >","동기화 가능 여부":"O"},{"타입":"Vector2","동기화 가능 여부":"O"},{"타입":"Vector3","동기화 가능 여부":"O"},{"타입":"Vector4","동기화 가능 여부":"O"},{"타입":"Color","동기화 가능 여부":"O"},{"타입":"Entity","동기화 가능 여부":"O"},{"타입":"Component","동기화 가능 여부":"O"},{"타입":"EntityRef","동기화 가능 여부":"O"},{"타입":"ComponentRef","동기화 가능 여부":"O"}]