This document is about: QUANTUM 2
SWITCH TO

수정중인 페이지 입니다.

유니티에서의 에셋

개요

Quantum은 유니티에서 사용할 수 있는 각 에셋 유형에 대해 ScriptableObject 기반 래퍼 부분 클래스를 생성합니다. 이러한 래퍼의 기본 클래스는 AssetBase입니다. AssetBase 인스턴스를 관리하는 기본 클래스는 UnityDB입니다.

editing a data asset
유니티에서 데이터 에셋의 속성 편집.
Quantum SDK는 각 에셋에 대해 고유한 GUID를 생성합니다.

시뮬레이션이 시작될 때 사용 가능한 모든 에셋의 AssetGuids를 알아야 합니다.

이를 위한 과정은 다음과 같습니다.:

  • 편집기에서:

    1. QuantumEditorSettings.AssetSearchPaths에 정의된 위치(기본적으로 Assets/Resources/DB입니다)에서 모든 AssetBase 에셋을 수집합니다.
    2. AssetBase에는 실행 시 AssetGuidAssetBase를 로드하는 데 필요한 정보가 포함된 생성된 항목이 있습니다.
    3. 항목은 QuantumEditorSettings.AssetResourcePath에 정의된(기본값 Assets/Resources/AssetResources.asset) AssetResourceContainer 에셋에 저장됩니다.
  • 런타임 시:

    1. AssetResourceContainer에 사용된 UnityDB 멤버의 최초 사용은 Resources.Load를 사용하여 로드됩니다(QuantumEditorSettings.AssetResourcePath 기반).
    2. 엔트리 목록은 각 에셋을 동적으로 로드하는 데 필요한 정보와 함께 시뮬레이션의 IResourceManager를 초기화하는 데 사용됩니다.

데이터베이스의 현재 일부인 에셋 개체 목록을 찾아보려면 Quantum/Show AssetDB InspectorWindow/Quantum/AssetDB Inspector 메뉴 항목을 통해 접근할 수 있는 AssetDB 인스펙터 창을 사용하십시오.

리소스, Addressables 및 에셋 번들

Quantum은 AssetBase 에셋에 대해 하드 레퍼런스를 형성하지 않습니다. 이렇게 하면 동적 컨텐츠 전달을 사용할 수 있습니다. 다음과 같은 에셋 로드 방법이 즉시 지원됩니다:

  • 리소스
  • Addressables (명시적으로 사용으로 되어야 함)
  • 에셋 번들(프로젝트별 맞춤형 접근 방식을 요구하는 에셋 번들로 인한 개념 증명)입니다.
enabling addressables
Enabling Addressables in QuantumEditorSettings. Alternatively, define `QUANTUM_ADDRESSABLES` and `QUANTUM_ADDRESSABLES_WAIT_FOR_COMPLETION` (for Addressables 1.17 or newer).

위의 방법을 사용하여 AssetBase를 동적으로 로드할 수 있는 추가 단계는 없습니다. 각 에셋을 로드하는 방법에 대한 자세한 내용은 AssetResourceContainer에 저장됩니다. 이 정보는 시뮬레이션에서 Frame.FindAsset 호출할 때 또는 UnityDB.FindAsset가 호출되어 적절한 로드 방법을 사용될 때 접근됩니다.

  • 에셋이 Resource 폴더에 있는 경우 Resources API를 사용하여 로드됩니다.
  • 에셋에 주소(명시적 또는 암시적)가 있는 경우 Addressables API를 사용하여 로드됩니다.
  • 에셋이 에셋 번들에 속하는 경우(명시적으로 또는 암묵적으로) AssetBundle API를 사용하여 로드하려고 시도합니다.

에셋 목록(AssetResourceContainer) 자체를 동적으로 만들려면 추가 코드가 필요합니다. 자세한 내용은 실행 시 Quantum 에셋 업데이트 섹션을 참조하십시오.

사용자 스크립트는 Quantum 에셋을 참조하기 위해 AssetRef 참조(예: SimulationConfig) 대신 AssetRef 타입(예: AssetRefSimulationConfig)을 사용하여 하드 참조를 피할 수 있습니다.

C#

public class TestScript : MonoBehaviour {
  // hard reference
  public SimulationConfigAsset HardRef;
  // soft reference
  public AssetRefSimulationConfig SoftRef;

  void Start() {
    // depending on the target asset's settings, this call may result in
    // any of the supported loading methods being used
    SimulationConfigAsset config = UnityDB.FindAsset<SimulationConfigAsset>(SoftRef.Id);
  }
}

유니티에서 에셋 드래그하여 드롭하기

에셋 인스턴스를 추가하고 시뮬레이션 시스템 내부에서 Frame 클래스를 통해 검색할 수만 있습니다. 훨씬 더 흥미로운 접근 방식은 에셋 인스턴스가 서로 데이터베이스 참조를 가리키도록 하는 기능(유니티에서 이러한 참조를 끌어다 놓을 수 있음)입니다.

한 가지 일반적인 용도는 사전 빌드 RuntimePlayer을 연장하는 것입니다. 플레이어 클래스는 플레이어가 선택한 특정 CharacterSpec 에셋에 대한 AssetRef를 포함합니다. 생성된 유형 안전 asset_ref 유형은 에셋 또는 다른 구성 개체 간의 참조를 연결하는 데 사용됩니다.

C#

// this is added to the RuntimePlayer.User.cs file
namespace Quantum {
  partial class RuntimePlayer {
    public AssetRefCharacterSpec CharacterSpec;

    partial void SerializeUserData(BitStream stream) {
      stream.Serialize(ref CharacterSpec);
    }
  }
}

이 코드는 asset_ref 필드가 생성되고 이 필드는 CharacterSpec 유형의 에셋에 대한 링크만 허용합니다. 이 필드는 유니티 인스펙터에 표시되며 슬롯에 에셋을 끌어다 놓으면 채울 수 있습니다.

drag & drop asset
Asset ref properties are shown as type-safe slots for Quantum scriptable objects.

맵 에셋 베이킹 파이프라인

Quantum에서 사용자 지정 데이터를 생성하는 또 다른 진입점은 맵 베이킹 파이프라인입니다. MapAssetMap 에셋을 위한 AssetBase 기반 래퍼입니다.

Map 에셋은 Quantum 시뮬레이션에 필요하며 Navmesh 및 정적 콜라이더와 같은 기본 정보를 포함합니다. 추가 사용자 지정 데이터는 사용자 지정 에셋 슬롯에 배치된 에셋의 일부로 저장할 수 있습니다. 이것은 모든 사용자 지정 데이터 에셋의 인스턴스가 될 수 있습니다. 사용자 지정 에셋을 사용하여 초기화 중 또는 런타임에 사용할 정적 데이터를 저장할 수 있습니다. 일반적인 예로는 위치, 스폰 유형 등과 같은 스폰 포인트 데이터의 배열을 들 수 있습니다.

유니티 씬이 MapAsset과 연결되려면 MapData MonoBehaviour 컴포넌트가 씬의 GameObject에 있어야 합니다. MapData.Asset이 유효한 MapAsset을 가리키면, 베이킹 프로세스를 수행할 수 있습니다. 기본적으로 Quantum은 씬이 저장되거나 플레이 모드로 전환될 때 자동으로 navmesh, 정적 콜라이더 및 씬 프로토타입을 베이킹합니다. 이 동작은 QuantumEditorSettings에서 변경할 수 있습니다.

베이킹이 발생할 때마다 호출할 사용자 지정 코드를 할당하려면 추상 MapDataBakerCallback 클래스에서 상속되는 클래스를 만듭니다.

C#

public abstract class MapDataBakerCallback {
  public abstract void OnBake(MapData data);
  public abstract void OnBeforeBake(MapData data);
  public virtual void OnBakeNavMesh(MapData data) { }
  public virtual void OnBeforeBakeNavMesh(MapData data) { }
}

그리고나서 필수인 OnBake(MapData data)OnBakeBefore(MapData data) 메소드를 오버라이드 합니다.

C#

public class MyCustomDataBaker: MapDataBakerCallback {
  public void OnBake(MapData data) {
    // any custom code to live-load data from scene to be baked into a custom asset
    // generated custom asset can then be assigned to data.Asset.Settings.UserAsset
  }
  public void OnBeforeBake(MapData data) {
  
  }
}

사전 로딩 Addressable 에셋

퀀텀은 에셋을 동기식으로 로드할 수 있어야 합니다.

v1.16 및 이전

1.17 이전 Addressables 버전에서는 시뮬레이션을 시작하기 전에 사전 로드하거나 유니티의 SyncAddressables 샘플을 사용하는 것 외에 Addressable 에셋을 동기적으로 로드하는 방법이 없었습니다.

v1.17 또는 그 이상

Addressables 1.17에 WaitForCompletion이 추가되어 에셋을 동기적으로 로드할 수 있습니다. Quantum에 대해 이 기능을 사용하려면 QUANTUM_ADDRESSABLES_USE_WAIT_FOR_COMPLETION을 정의하거나 QuantumEditorSettings 에셋의 Build Features 섹션에 있는 토글을 사용하십시오.

동기 로딩이 가능하지만 에셋을 프리 로딩하는 것이 더 나을 수도 있습니다. QuantumRunnerLocalDebug.cs 스크립트는 이를 달성하는 방법을 보여줍니다.

AssetBase 로드 정보 베이킹

AssetResourceContainer는 각 AssetBase를 로드하는 방법에 대한 정보가 들어 있는 ScriptableObject로, 이를 AssetGuids에 매핑합니다.

N.B.: `AssetBase` 는 Quantum 에셋 자체가 아닙니다.

Quantum > Generate Asset Resources 메뉴 옵션을 사용하거나 QuantumEditorSettings.AssetSearchPaths에서 하나가 임포트 될 때 AssetResourceContainerQuantumEditorSettings.AssetResourcePath에 지정한 위치에서 완전히 재생성됩니다.

AssetResourceContainer를 생성하는 동안 QuantumEditorSettings.AssetSearchPaths에 위치해 있는 모든 AssetBase는 하나의 그룹에 할당됩니다. 기본적으로 세 개의 그룹이 있습니다.

  • ResourcesGroup;
  • AssetBundlesGroup; 그리고,
  • AddressablesGroup.

에셋을 할당할 그룹을 결정하는 프로세스는 아래 다이어그램에 나와 있습니다.

assetresourcecontainer generation
The flow of assigning an asset a group.

만약 다음의 경우에 에셋은 Addressable로 간주됩니다:

  • 주소 할당됨
  • 부모 폴더가 Addressable 또는
  • 다른 Addressable 에셋에 중첩되어 있음

에셋이 에셋 번들의 일부인지 여부를 결정할 때도 동일한 로직이 적용됩니다.

에셋을 가져올 때 AssetBase 굽기를 비활성화하려면 QuantumEditorSettings.UseAssetBasePostprocessor을 틱하지 않습니다.

빌드에서 Quantum 에셋 업데이트

외부 CMS에서 데이터 에셋을 제공할 수 있습니다. 이는 플레이어가 업데이트해야 하는 새 빌드를 만들지 않고 이미 출시된 게임에 대한 균형 잡힌 업데이트를 제공하는 데 특히 유용합니다.

이 방법을 사용하면 캐릭터 사양, 맵, NPC 사양 등과 같은 데이터 기반 측면에 대한 정보가 포함된 균형 조정 시트를 사용할 수 있습니다. 게임 빌드 자체와 독립적으로 업데이트됩니다. 이 경우 게임 클라이언트는 온라인 매치를 시작하거나 참가하기 전에 항상 CMS 서비스에 연결하고 업데이트가 있는지 확인하고(필요한 경우) 게임 데이터를 최신 버전으로 업그레이드합니다.

기존 에셋 업데이트

Addressables 또는 에셋 번들은 즉시 지원되므로 사용하는 것이 좋습니다. Addressable 또는 에셋 번들의 일부인 AssetBase는 적절한 방법을 사용하여 런타임에 로드됩니다.

게임 시뮬레이션 중에 에셋을 다운로드하여 발생하는 예측 불가능한 지연을 방지하려면 여기서 설명하는 대로 에셋을 다운로드하고 사전 로드하십시오. Addressable 에셋 사전 로딩.

새로운 에셋 추가

편집기에서 생성된 AssetResourceContainer에는 생성 시 존재하는 모든 에셋 목록이 포함됩니다. 프로젝트의 동적 컨텐츠에 새 빌드를 만들지 않고 중간에 새 Quantum 에셋을 추가하는 것이 포함된 경우 목록을 업데이트하는 방법을 구현해야 합니다.

이를 위해 권장되는 접근 방식은 부분적인 UnityDB.LoadAssetResourceContainerUser 메소드의 확장입니다. 첫 번째 시뮬레이션이 시작되거나 UnityDB 메서드를 호출하면 Quantum이 AssetResourceContainer를 로드하려고 시도합니다. 기본적으로 AssetResourcesContainerQuantumEditorSettings.AssetResourcePath.에 있는 리소스로 간주됩니다. 이 동작을 재정의하려면 UnityDB.LoadAssetResourceContainerUser를 구현해야 합니다.

구현 예제

먼저 AssetResourceContainerResources 폴더 밖으로 이동해야 합니다. QuantumEditorSettings.AssetResourcePath를 설정하여 이 작업을 수행합니다:

assetresourcecontainer path override

둘째, 새 AssetResourceContainer를 Addressable로 만들어야 합니다:

addressable assetresourcecontainer

마지막으로 부분 메서드를 구현하는 코드입니다.

C#

partial class UnityDB {
  static partial void LoadAssetResourceContainerUser(ref AssetResourceContainer container) {
    var path = QuantumEditorSettings.Instance.AssetResourcesPath;

#if UNITY_EDITOR
    if (!UnityEditor.EditorApplication.isPlaying) {
      container = UnityEditor.AssetDatabase.LoadAssetAtPath<AssetResourceContainer>(path);
      Debug.Assert(container != null);
      return;
    }
#endif

    var op = Addressables.LoadAssetAsync<AssetResourceContainer>(path);
    container = op.WaitForCompletion();
    Debug.Assert(container != null);
  }
}
이는 단순화된 구현이며 프로젝트의 필요에 따라 `Addressables.LoadAssetAsync`에서 반환되는 `AsyncOperationHandle`가 추가될 수 있습니다.

DynamicAssetDB로 새로운 에셋 추가

결정론적 방법으로 새로운 에셋을 만들 수 있다면, 여기서 설명하는 것처럼 DynamicAssetDB를 사용할 수 있습니다. 다이나믹 에셋.

Back to top