시작하기
값을 저장하고, 기본값과 함께 읽어 오고, 그 답이 진짜인 유일한 순간에 읽기까지의 흐름.
설치
먼저 VCC(VRChat Creator Companion)를 통해 Unity 프로젝트에 영속성 패키지를 추가합니다. 프로젝트의 vccproject.json을 열고 패키지를 추가하거나, VCC 인터페이스를 사용해 직접 설치하세요.
설치 후 패키지는 프로젝트에서 사용 가능하며 아래의 영속성 API를 사용하기 시작할 수 있습니다.
저장하기
Save.Set("coins", 25);
Save.Set("name", "ada");
Save.Set("spawn", transform.position);
어떤 타입이든 동사는 하나입니다. 어느 것이 쓰이는지는 값이 정하므로 SetInt를 틀릴 방법이 없습니다. 쓰기는 언제나 이 클라이언트의 플레이어에게 적용됩니다. 클라이언트가 바꿔도 되는 것은 자기 데이터뿐이기 때문입니다.
읽어 오기
int coins = Save.Get("coins", 100);
string name = Save.Get("name", "friend");
Vector3 spawn = Save.Get("spawn", Vector3.zero);
두 번째 인자는 아무것도 저장되어 있지 않을 때 받는 값이고, 생략할 수 없습니다. 그것이 핵심입니다. 돌아온 플레이어는 자기 25개를, 새 플레이어는 100개를 받고, 둘 중 무엇인지를 TryGet과 if 없이 코드가 말해 줍니다.
키가 요청한 타입과 다른 타입을 담고 있을 때도 같은 값이 돌아옵니다. 그래서 "level"이라는 이름을 함께 고른 두 시스템은 뜻이 깨진 값이 아니라 기본값으로 내려앉습니다.
올바른 순간에 읽기
public class Shop : SaveBehaviour
{
private int coins;
public override void OnSaveReady()
{
coins = Save.Get("coins", 100);
}
}
Start에서 읽지 마세요. 저장 데이터는 플레이어가 참가한 조금 뒤에 도착하고, 그 전에 읽은 것은 모두 기본값입니다. 한 문단을 쓸 값어치가 있는 실수인데, 실수처럼 보이지 않기 때문입니다. 에디터에서는 애초에 저장된 것이 없는 경우가 많아서, 진행 상황을 가진 진짜 플레이어가 들어오기 전까지 월드는 의도대로 동작합니다.
SaveBehaviour를 상속하면 OnSaveReady를 쓸 수 있습니다. 이 클라이언트의 플레이어 데이터가 읽히는 순간에 한 번 실행됩니다.
다른 사람의 데이터
public override void OnPlayerSaveReady(VRCPlayerApi player)
{
int theirs = Save.Get(player, "best", 0);
}
누구의 저장값이든 읽을 수 있지만, 그 사람의 데이터가 읽히는 순간은 내 것과 다릅니다. 그 사람이 도착할 때이고, 그것은 한 시간 뒤일 수도 있습니다. 그래서 메서드가 갈라져 있습니다. 낯선 사람이 들어올 때마다 자기 상태를 다시 불러오는 behaviour는 그동안 쌓은 것을 버리게 됩니다.
첫 방문과 재방문 가리기
if (!Save.Has("visits"))
{
// 환영 꾸러미를 건넨다.
}
Save.Has는 그 키가 한 번이라도 쓰였는지 답합니다. 대개는 기본값이 같은 말을 더 곧바로 합니다. "없다"는 사실 자체가 정보일 때 쓰세요.
알아 둘 만한 두 가지 제한
키를 지우는 수단은 없습니다. VRChat은 덮어쓸 수는 있어도 지울 수는 없습니다. 그러니 월드가 쓰는 키의 집합은 늘려 가는 것이 아니라 한 번 정하는 것으로 다루는 편이 낫습니다.
키는 월드 전체가 공유합니다. "level"을 저장하는 두 시스템은 같은 키를 쓰고 있습니다. 접두사를 붙이세요.