*참고: Unity 리모트 설정은 현재 프리뷰 패키지로 제공됩니다. 리모트 설정은 새로운 바이너리 없이도 게임의 동작과 형상을 변경하도록 해주는 개선된 제품입니다. 기능을 원격으로 활성화하거나 비활성화하고, 특정 플레이어들을 위해 게임의 특정 요소를 변경하거나, 새 콘텐츠 릴리스를 예약하여 특별 이벤트를 진행할 수 있습니다.
Unity 스크립팅 API RemoteSettings 클래스를 사용하여 코드로 원격 설정에 액세스할 수 있습니다. RemoteSettings
클래스는 RemoteSettings.GetString()
등 원격 설정에 액세스할 수 있는 함수뿐만 아니라 설정을 페치하거나 업데이트하는 경우 함수를 트리거하는 데 사용할 수 있는 이벤트도 제공합니다.
이벤트 | 목적 |
---|---|
BeforeFetchFromServer |
RemoteSettings 클래스가 네트워크 요청을 통해 원격 설정을 검색해서 가져오기 직전에 디스패치됩니다. |
Completed | 네트워크 요청이 완료될 때 디스패치됩니다. Completed 는 네트워크 요청이 실패하고 원격 설정에 아무런 변경 사항이 없는 경우에도 항상 디스패치됩니다. 델리게이트 함수에 전달된 serverResponse 코드를 사용하여 요청의 성공 여부를 확인할 수 있습니다. 파라미터에는 일반 HTTP 리스폰스 코드 중 하나(예: 성공한 경우 200)가 들어있습니다. |
Updated | 네트워크 요청이 성공적으로 완료된 후 디스패치됩니다. 단, 원격 설정에 이전 검사 이후 변경된 부분이 있어야 합니다. 참고: Unity 2018.1 이전에는 설정 변경 사항이 없어도 Updated 이벤트가 항상 디스패치되었습니다. 변경 사항 유무에 관계없이 델리게이트 함수를 사용하여 게임에 설정을 적용한 경우에는 Updated 이벤트가 아니라 Completed 이벤트를 사용해야 합니다. |
애플리케이션이 실행되는 동안에는 가능한 한 일찍 이러한 이벤트에 대한 핸들러 함수를 등록해야 합니다. 첫 번째 Unity 씬에 로드한 MonoBehaviour의 Awake()
함수를 예로 들 수 있습니다.
설정을 페치하려면 네트워크 트랜잭션이 필요하기 때문에 RemoteSettings
오브젝트는 해당 이벤트를 비동기식으로 디스패치합니다. 핸들러 함수는 모든 플랫폼에서 또는 동일한 플랫폼을 실행할 때 다른 이벤트와 같은 순서로 호출되지 않을 수도 있습니다. 적절한 기본값으로 설정 변수를 항상 초기화하고, 애플리케이션이 시작되는 동안 이벤트 핸들러가 다른 시점에 호출될 수 있다는 가능성을 염두에 두십시오.
코드 예제
다음의 예제는 게임 난이도 조정을 위해 여러 프로퍼티를 정의하고 원격 설정을 기반으로 이러한 프로퍼티를 업데이트하는 클래스를 보여줍니다.
using UnityEngine;
public class RemoteTuningVariables : MonoBehaviour {
public float DefaultSpawnRateFactor = 1.0f;
public float DefaultEnemySpeedFactor = 1.0f;
public float DefaultEnemyStrengthFactor = 1.0f;
public static float SpawnRateFactor{ get; private set; }
public static float EnemySpeedFactor{ get; private set; }
public static float EnemyStrengthFactor{ get; private set; }
void Start () {
SpawnRateFactor = DefaultSpawnRateFactor;
EnemySpeedFactor = DefaultEnemySpeedFactor;
EnemyStrengthFactor = DefaultEnemyStrengthFactor;
RemoteSettings.Completed += HandleRemoteSettings;
}
private void HandleRemoteSettings(bool wasUpdatedFromServer, bool settingsChanged, int serverResponse){
SpawnRateFactor
= RemoteSettings.GetFloat ("SpawnRateFactor", DefaultSpawnRateFactor);
EnemySpeedFactor
= RemoteSettings.GetFloat ("EnemySpeedFactor", DefaultEnemySpeedFactor);
EnemyStrengthFactor
= RemoteSettings.GetFloat ("EnemyStrengthFactor", DefaultEnemyStrengthFactor);
}
}
RemoteSettings.GetFloat()
메서드 호출에서 클래스가 기본값을 제공한다는 점을 기억하시기 바랍니다. RemoteSettings
오브젝트가 지정된 키를 찾을 수 없는 경우 (예를 들어, 키 이름의 철자가 틀린 경우), 메서드는 여전히 기본값을 튜닝 변수에 배정합니다. 그렇지 않으면, GetFloat()
및 GetInt()
메서드는 0을 숫자에 배정하고 GetString()
은 빈 문자열을 문자열에 배정하며, GetBool()
는 false를 불 변수에 배정합니다.
또한 다른 클래스가 원격 설정이 페치되기 전에 설정에 액세스하고 이전에 캐싱된 설정을 로컬에서 이용할 수 없는 경우 클래스는 같은 기본값을 Start()
메서드의 프로퍼티에 할당합니다. Start()
메서드의 기본값을 할당하면 프로퍼티가 항상 적절한 값을 갖습니다.
게임에서 다른 시점에 원격 설정에 액세스하는 클래스가 여러 개인 경우 일부 오브젝트는 비동기 네트워크 요청이 완료되기 전에 설정에 액세스하거나 그 이후에 액세스하여 설정값 일관성을 해칠 수 있습니다. 이러한 일관성 문제를 피하려면 설정에 액세스하기 전에 비동기 네트워크 요청이 완료되기를 기다리거나, 아니면 현재 세션 시작 시 보유하고 있던 기존 설정을 그대로 사용할 수 있습니다. 후자의 경우 로컬 설정이 백그라운드상으로 업데이트되고 다음 세션 때 플레이어에게 표시됩니다.
메서드 | 장점 | 단점 |
---|---|---|
요청 완료 대기 | - 설정값이 항상 일정함 - 항상 최신 설정 사용 |
- 설정 가용성의 불확실한 지연 발생 - 비동기 코드 복잡도 |
현재 설정 사용 | - 설정값이 항상 일정함 - 설정을 즉시 이용 가능 |
- 새 설정값이 두 번째 세션까지 사용되지 않음 - 플레이어가 게임을 처음으로 실행할 때 아무런 설정도 제공되지 않음(기본값 사용) |
다음 예제는 애널리틱스 서비스에서 페치된 마지막 원격 설정 버전에 기반하여 프로퍼티를 할당하는 공급자 클래스를 보여줍니다. RemoteSettings
클래스는 여전히 백그라운드상으로 설정을 업데이트하므로, 변경된 설정값은 현재 세션이 아니라 다음 세션에 사용됩니다. 다음 예제에서는 싱글톤 패턴을 사용합니다. 따라서 이 설정을 사용하는 모든 게임 요소는 RemoteSettings
클래스가 원격 업데이트를 수신하는 시점에 관계 없이 같은 값을 얻습니다.
using UnityEngine;
public class RemoteSettingProvider : MonoBehaviour {
public float DefaultSpawnRateFactor = 1.0f;
public float DefaultEnemySpeedFactor = 1.0f;
public float DefaultEnemyStrengthFactor = 1.0f;
public float SpawnRateFactor{ get; private set; }
public float EnemySpeedFactor{ get; private set; }
public float EnemyStrengthFactor{ get; private set; }
// Singleton pattern
private static RemoteSettingProvider _instance;
public static RemoteSettingProvider Instance
{
get { return _instance; }
}
void Awake()
{
if (_instance != null && _instance != this)
{
Destroy(this.gameObject);
return;
}
_instance = this;
DontDestroyOnLoad(this.gameObject);
//Use the current settings, before remote update, or default values if
//the settings don't exist (yet)
SpawnRateFactor
= RemoteSettings.GetFloat("SpawnRateFactor", DefaultSpawnRateFactor);
EnemySpeedFactor
= RemoteSettings.GetFloat("EnemySpeedFactor", DefaultEnemySpeedFactor);
EnemyStrengthFactor
= RemoteSettings.GetFloat("EnemyStrengthFactor", DefaultEnemyStrengthFactor);
}
}
이 메서드를 사용하는 기본 설정은 플레이어가 게임을 설치한 후 처음으로 실행할 때 항상 사용됩니다.
또는 RemoteSettings.GetCount()
를 사용하여 로컬 설정이 존재하는지 검사하는 하이브리드 방식을 사용할 수도 있습니다. 해당 설정이 로컬에 존재하면 즉시 사용할 수 있지만, 그렇지 않은 경우에는 설정 Updated
이벤트를 기다리도록 이벤트 핸들러를 추가할 수 있습니다.
SpawnRateFactor
= RemoteSettings.GetFloat("SpawnRateFactor", DefaultSpawnRateFactor);
EnemySpeedFactor
= RemoteSettings.GetFloat("EnemySpeedFactor", DefaultEnemySpeedFactor);
EnemyStrengthFactor
= RemoteSettings.GetFloat("EnemyStrengthFactor", DefaultEnemyStrengthFactor);
if(RemoteSettings.GetCount() == 0){
//If there are no settings, get them from remote
RemoteSettings.Updated += HandleRemoteSettings;
Ready = false;
} else {
Ready = true;
}
원격 설정을 사용하는 다른 클래스는 공급자 클래스의 Ready
프로퍼티를 검사하여 해당 설정에 액세스해도 안전한지 확인해야 합니다. 다음 예제는 설정을 대기하고 설정 가능한 타임아웃을 사용하는 클래스를 보여줍니다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RemoteSettingConsumer : MonoBehaviour {
public float SpeedFactor = 0;
public float StrengthFactor = 0;
public float SpawnRateFactor = 0;
public float Timeout = 0.125f;
void Start () {
StartCoroutine(GetRemoteSettings(Time.time));
}
IEnumerator GetRemoteSettings(float startTime){
while(!RemoteSettingProvider.Instance.Ready && (Time.time - startTime) < Timeout)
yield return null;
SpeedFactor = RemoteSettingProvider.Instance.EnemySpeedFactor;
StrengthFactor = RemoteSettingProvider.Instance.EnemyStrengthFactor;
SpawnRateFactor = RemoteSettingProvider.Instance.SpawnRateFactor;
}
}
원격 설정을 이용할 수 있게 되기 전에 타임아웃이 경과되면 기본값이 사용됩니다. 타임아웃을 사용하면 네트워크 트랜잭션이 매우 짧은 시간에 완료되는 일반적인 경우에도 게임이 최신 설정을 가져올 수 있습니다. 또한 네트워크 실패 시에는 요청 자체가 타임아웃되도록 기다림으로써 과도한 시작 지연을 막을 수 있습니다.