동기화 값
모든 클라이언트가 가지는 변수, 그 안에 넣을 수 있는 것, 변화를 직접 알려야 하는 두 경우.
선언하기
동기화 값은 비헤이비어의 필드이거나, 원한다면 자동 프로퍼티입니다.
private Synced<int> score = new Synced<int>();
public Synced<string> Message { get; } = new Synced<string>();
둘 다 쓴 이름 그대로의 복제 변수 하나가 됩니다. 접근자를 직접 쓴 프로퍼티는 동작할 수 없어 거부됩니다. Udon 이 복제하는 것은 이름이 있는 변수이고, 접근자는 각 클라이언트에서 새로 실행되는 코드이기 때문입니다.
비헤이비어 위에 있어야 합니다. 비헤이비어가 쓰는 평범한 클래스에 둔 동기화 값은 컴파일은 되지만 복제되지 않으므로, 그것도 필드 이름을 대며 거부합니다.
넣을 수 있는 것
모든 C# 기본 형식, string, Vector2, Vector3, Vector4, Quaternion, Color, Color32, VRCUrl, 그리고 그 배열들. 이것은 이 패키지가 아니라 VRChat 의 목록입니다. 그 밖의 것은 실행 중에 조용히 빠지는 대신 컴파일할 때 거부됩니다.
시작 값은 생성자에 넣습니다.
private Synced<int> lives = new Synced<int>(3);
읽고 쓰기
score.Value = score.Value + 1;
쓰면 복제됩니다. 짝지어 불러야 할 직렬화 호출이 없으므로, 대입해 놓고 호출을 잊어 동기화가 조용히 멈추는 실패가 사라집니다. 한 프레임에 여러 번 써도 전송은 한 번입니다. VRChat 이 합쳐 보냅니다.
쓸 수 있는 쪽은 소유자뿐입니다. 다른 클라이언트에서의 대입은 그 자리에 남습니다. 이 패키지가 감추지 않는 유일한 Udon 규칙입니다. Ownership.Claim(gameObject) 으로 먼저 가져오거나, 애초에 알맞은 클라이언트가 소유한 오브젝트에 두세요.
변화 받기
score.Subscribe(OnScoreChanged);
값이 도착하면 쓴 클라이언트를 포함해 모두의 핸들러가 돕니다. 같은 핸들러를 두 번 구독해도 늘지 않고, Unsubscribe 로 뗍니다.
무엇에서 바뀌었는지도 필요한 핸들러는 둘 다 받습니다.
score.Subscribe(OnScoreChanged);
private void OnScoreChanged(int previous, int current)
{
scoreboard.Show(current, current - previous);
}
첫 변화 이전에는 그 앞의 값이 없으므로 그 형식의 기본값입니다. 같은 값에 두 형태를 함께 구독할 수 있고, 둘 다 돕니다.
핸들러는 갱신이 전부 도착한 뒤에 돕니다. VRChat 은 한 번에 하나씩 적용하므로, 도착하는 대로 부르면 핸들러가 읽은 다른 값이 아직 이전 값일 수 있습니다. 두 클라이언트로 확인했습니다. 카운터가 도착한 옆에서 문자열은 아직 비어 있었습니다. 지금은 같은 갱신으로 들어온 값을 읽습니다.
배열
배열은 값 전체로 복제되므로 통째로 바꾸는 것은 기대대로 동작합니다.
private Synced<int[]> scores = new Synced<int[]>(new int[8]);
scores.Value = fresh;
원소 하나를 쓰는 것은 대입만으로는 컴파일러가 볼 수 없는 경우이니, 직접 알려주세요.
scores.Value[2] = 7;
scores.MarkChanged();
MarkChanged 는 배열을 통째로 대입했을 때와 똑같이 복제하고 이 클라이언트의 구독자에게도 알립니다. 없으면 변경은 쓴 클라이언트에 조용히 남습니다.
소유권
Ownership.IsMine(gameObject) |
이 클라이언트가 그 오브젝트의 동기화 값을 쓸 수 있는지 |
Ownership.Claim(gameObject) |
거부되지 않으면 가져오기 |
Ownership.GiveTo(player, gameObject) |
누군가에게 넘기기 |
Ownership.Of(gameObject) |
누가 가졌는지 |
OnOwnershipRequest 를 재정의해 false 를 돌려주면 이전을 거부할 수 있습니다. MasterOwned 는 그 재정의를 이미 써 둔 것입니다. 상속하면 조율하는 클라이언트만 그 오브젝트를 가질 수 있어, 다른 누구도 쓰지 못할 값을 둘 자리가 됩니다.
ClientSim 은 소유권 요청을 일으키지 않습니다. 이것만은 업로드한 월드에서 확인해야 합니다.