Mirror Guide Synchronization 3/3
SyncDictionary
Key와 Value의 쌍으로 순서가 매겨지지 않는 List를 포함하는 연관 배열이다. Key와 Value는 Mirror에서 지원되는 타입 어느것이라도 가능하다.
기본적으로 .Net의 Dictionaty를 사용하며 Key와 Value에 대해서 추가적으로 제한을 걸 수 있다.
SyncDictionary는 SyncLists와 동일하게 서버에서 변경을 하면 변경 내용이 모든 클라이언트에 전파되고 콜백이 호출된다.
Usage
SyncDictionary 유형의 NetworkBehaviour 클래스에 필드를 추가한다.
주의1 SyncDictionary는 readonly로 선언되고 생성자에서 초기화되어야 한다.
주의2 콜백을 Subscribe할 때 Dictionary는 이미 초기화되므로 초기 데이터에 대한 호출은 수신되지 않고 업데이트만 수신된다.
예)
using UnityEngine;
using Mirror;
public struct Item
{
public string name;
public int hitPoints;
public int durability;
}
public class ExamplePlayer : NetworkBehaviour
{
public readonly SyncDictionary<string, Item> Equipment = new SyncDictionary<string, Item>();
public override void OnStartServer()
{
Equipment.Add("head", new Item { name = "Helmet", hitPoints = 10, durability = 20 });
Equipment.Add("body", new Item { name = "Epic Armor", hitPoints = 50, durability = 50 });
Equipment.Add("feet", new Item { name = "Sneakers", hitPoints = 3, durability = 40 });
Equipment.Add("hands", new Item { name = "Sword", hitPoints = 30, durability = 15 });
}
public override void OnStartClient()
{
// Equipment is already populated with anything the server set up
// but we can subscribe to the callback in case it is updated later on
equipment.Callback += OnEquipmentChange;
// Process initial SyncDictionary payload
foreach (KeyValuePair<string, Item> kvp in equipment)
OnEquipmentChange(SyncDictionary<string, Item>.Operation.OP_ADD, kvp.Key, kvp.Value);
}
void OnEquipmentChange(SyncDictionary<string, Item>.Operation op, string key, Item item)
{
switch (op)
{
case SyncIDictionary<string, Item>.Operation.OP_ADD:
// entry added
break;
case SyncIDictionary<string, Item>.Operation.OP_SET:
// entry changed
break;
case SyncIDictionary<string, Item>.Operation.OP_REMOVE:
// entry removed
break;
case SyncIDictionary<string, Item>.Operation.OP_CLEAR:
// Dictionary was cleared
break;
}
}
}
예)
기본적으로 SyncDictionary는 Dictionary를 사용하여 데이터를 저장한다. SortedList나 SortedDictionary와 같은 IDictionary를 구현하려면 SyncIDictionary에 사용하려는 dictionary 인스턴스를 전달한다.
public class ExamplePlayer : NetworkBehaviour
{
public readonly SyncIDictionary Equipment =
new SyncIDictionary(new SortedList());
}
SyncHashSet
SyncHashSet은 C# HashSet과 유사하며 서버에서 클라이언트로 콘텐츠를 동기화한다. SyncHashSet은 Mirror에서 지원되는 어떠한 타입도 포함할 수 있다.
Usage
주의 SyncHashSet은 반드시 readonly로 선언되며 생성자에서 초기화 되어야 한다.
예)
NetworkBehaviour 클래스 필드에 SyncHashSet을 추가한다.
public class Player : NetworkBehaviour
{
[SerializeField]
public readonly SyncHashSet<string> skills = new SyncHashSet<string>();
int skillPoints = 10;
[Command]
public void CmdLearnSkill(string skillName)
{
if (skillPoints > 1)
{
skillPoints--;
skills.Add(skillName);
}
}
}
SyncHashSet이 변경되는 경우 감지할 수 있다. 클라이언트의 캐릭터를 새로 고치거나 데이터베이스를 갱신해야할 시기를 결정할 때 유용하다.
보통 Start, OnClientStart 또는 OnServerStart 중에 콜백 이벤트를 Subscribe한다.
주의 Subscribe 할 때는 Set은 이미 채워져 있기 때문에 초기 데이터에 대한 콜은 수신되지 않고 업데이트만 수신된다.
예)
public class Player : NetworkBehaviour
{
[SerializeField]
public readonly SyncHashSet<string> buffs = new SyncHashSet<string>();
// this will add the delegate on the client.
// Use OnStartServer instead if you want it on the server
public override void OnStartClient()
{
buffs.Callback += OnBuffsChanged;
// Process initial SyncHashSet payload
foreach (string buff in buffs)
OnBuffsChanged(SyncSet<string>.Operation.OP_ADD, buff);
}
// SyncHashSet inherits from SyncSet so use SyncSet here
void OnBuffsChanged(SyncSet<string>.Operation op, string buff)
{
switch (op)
{
case SyncSet<string>.Operation.OP_ADD:
// Added a buff to the character
break;
case SyncSet<string>.Operation.OP_REMOVE:
// Removed a buff from the character
break;
case SyncSet<string>.Operation.OP_CLEAR:
// Cleared all buffs from the character
break;
}
}
}
SyncSortedSet
SyncSortedSet은 C#의 SortedSet과 유사하며 서버에서 클라이언트로 콘텐츠를 동기화한다.
SyncHashset과 달리 SyncSortedSet의 모든 요소는 삽입 시 정렬되며 여기에는 몇 가지 성능 문제가 있다.
Mirror에서 지원되는 어떠한 타입도 SyncSortedSet에 포함될 수 있다.
Usage
주의 SyncSortedSet은 반드시 readonly로 선언하며 생성자로 초기화 되어야 한다.
예)
NetworkBehaviour 클래스 필드에 SyncSortedSet을 추가한다.
class Player : NetworkBehaviour
{
public readonly SyncSortedSet<string> skills = new SyncSortedSet<string>();
int skillPoints = 10;
[Command]
public void CmdLearnSkill(string skillName)
{
if (skillPoints > 1)
{
skillPoints--;
skills.Add(skillName);
}
}
}
SyncSortedSet이 변경되는 경우에 감지할 수 있어 클라이언트의 캐릭터를 새로 고치거나 데이터베이스를 갱신해야 할 시기를 결정할 때 유용하다.
보통 Start, OnClientStart 또는 OnServerStart 중에 콜백 이벤트를 Subscribe한다.
주의 Subscribe할 때 Set은 이미 초기화되어 있기 때문에 초기 데이터에 대한 콜은 수신되지 않고 업데이트만 수신된다.
class Player : NetworkBehaviour
{
[SerializeField]
public readonly SyncSortedSet<string> buffs = new SyncSortedSet<string>();
// this will add the delegate on the client.
// Use OnStartServer instead if you want it on the server
public override void OnStartClient()
{
buffs.Callback += OnBuffsChanged;
// Process initial SyncSortedSet payload
foreach (string buff in buffs)
OnBuffsChanged(SyncSortedSet<string>.Operation.OP_ADD, buff);
}
// SyncSortedSet inherits from SyncSet so use SyncSet here
void OnBuffsChanged(SyncSortedSet<string>.Operation op, string buff)
{
switch (op)
{
case SyncSortedSet<string>.Operation.OP_ADD:
// Added a buff to the character
break;
case SyncSortedSet<string>.Operation.OP_REMOVE:
// Removed a buff from the character
break;
case SyncSortedSet<string>.Operation.OP_CLEAR:
// cleared all buffs from the character
break;
}
}
}