

지원 종료 공지: 2026 AWS 년 5월 20일에에 대한 지원이 종료됩니다 AWS SimSpace Weaver. 2026년 5월 20일 이후에는 SimSpace Weaver 콘솔 또는 SimSpace Weaver 리소스에 더 이상 액세스할 수 없습니다. 자세한 내용은 [AWS SimSpace Weaver 지원 종료를 참조하세요](https://docs.aws.amazon.com/simspaceweaver/latest/userguide/simspaceweaver-end-of-support.html).

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 개체
<a name="working-with_app-sdk_ent"></a>

`CreateEntity()`에서 반환된 `Result<Api::Entity>`의 `Api:Entity`을 사용하거나 엔터티가 앱의 구독 영역에 진입할 때 소유권 변경 이벤트에서 `Store` 및 `Load` API를 호출합니다(자세한 내용은 [엔터티 이벤트](working-with_app-sdk_events.md) 섹션 참조). 이러한 API와 함께 사용할 수 있도록 `Api::Entity` 객체를 추적하는 것이 좋습니다.

**Topics**
+ [엔터티 생성](working-with_app-sdk_ent_create.md)
+ [공간 도메인으로 엔터티 이전](working-with_app-sdk_ent_transfer.md)
+ [엔터티에 필드 데이터 쓰기 및 읽기](working-with_app-sdk_ent_readwrite.md)
+ [엔터티에 대한 위치 저장](working-with_app-sdk_ent_store-position.md)
+ [엔터티에 대한 위치 로드](working-with_app-sdk_ent_load-position.md)

# 엔터티 생성
<a name="working-with_app-sdk_ent_create"></a>

`CreateEntity()`를 사용하여 엔터티를 생성합니다. 이 함수에 전달하는 `Api::TypeId`의 의미를 정의합니다.

```
Namespace
{
    constexpr Api::TypeId k_entityTypeId { /* value */ 512 };
}

Result<void> CreateEntity(Transaction& transaction)
{
    WEAVERRUNTIME_TRY(
        Api::Entity entity,
        Api::CreateEntity(
            transaction, Api::BuiltinTypeIdToTypeId(k_entityTypeId )));
}
```

**참고**  
`Api::BuiltinTypeId`에 0\$1511의 값이 예약되어 있습니다. 엔터티 TypeID(이 예제에서는 `k_entityTypeId`)의 값은 512 이상이어야 합니다.

# 공간 도메인으로 엔터티 이전
<a name="working-with_app-sdk_ent_transfer"></a>

사용자 지정 앱 또는 서비스 앱이 엔터티를 생성한 후 엔터티가 시뮬레이션에서 공간적으로 존재하도록 하려면 앱이 엔터티를 공간 도메인으로 전송해야 합니다. 공간 도메인의 엔터티는 다른 앱에서 읽을 수 있고 공간 앱에서 업데이트할 수 있습니다. `ModifyEntityDomain()` API를 사용하여 엔터티를 공간 도메인으로 전송할 수 있습니다.

```
AWS_WEAVERRUNTIME_API Result<void> ModifyEntityDomain(Transaction& txn, const Entity& entity, DomainId domainId) noexcept;
```

`DomainId`가 호출 앱에 할당된 `Partition`과 일치하지 않는 경우 `DomainId`는 `DomainType::Spatial` `Domain`에 대한 ID이어야 합니다. 새 `Domain`으로의 소유권 전송은 `Commit(Transaction&&)` 중에 이루어집니다.파라미터

`txn`  
현재의 `Transaction`입니다.

`entity`  
`Domain`를 변경할 대상 `Entity`입니다.

`domainId`  
`Entity`에 대한 대상 `Domain`의 `DomainId`입니다.

이 API는 엔터티 도메인이 성공적으로 변경되면 `Success`를 반환합니다.

# 엔터티에 필드 데이터 쓰기 및 읽기
<a name="working-with_app-sdk_ent_readwrite"></a>

모든 엔터티 데이터 필드는 blob 유형입니다. 엔터티에 최대 1,024바이트의 데이터를 쓸 수 있습니다. Blob 크기가 클수록 성능이 저하되므로 blob을 최대한 작게 유지하는 것이 좋습니다. Blob에 쓸 때 포인터 SimSpace Weaver 를 데이터 및 길이에 전달합니다. Blob에서 읽을 때 SimSpace Weaver 는 포인터 및 읽을 길이를 제공합니다. 앱이 `Commit()`을 호출하기 전에 모든 읽기가 완료되어야 합니다. 읽기 호출에서 반환된 포인터는 앱이 `Commit()`을 호출할 때 무효화됩니다.

**중요**  
`Commit()` 이후에 캐시된 blob 포인터에서의 읽기는 지원되지 않으므로 시뮬레이션이 실패할 수 있습니다.
읽기 호출에서 반환된 blob 포인터에서의 쓰기는 지원되지 않으므로 시뮬레이션이 실패할 수 있습니다.

**Topics**
+ [엔터티의 필드 데이터 저장](working-with_app-sdk_ent_readwrite_store.md)
+ [엔터티의 필드 데이터 불러오기](working-with_app-sdk_ent_readwrite_load.md)
+ [제거된 엔터티의 필드 데이터 로드](working-with_app-sdk_ent_readwrite_load-removed.md)

# 엔터티의 필드 데이터 저장
<a name="working-with_app-sdk_ent_readwrite_store"></a>

다음 예제는 앱이 소유한 엔터티의 필드 데이터를 저장(상태 패브릭에 쓰기)하는 방법을 보여줍니다. 해당 예제에는 다음 함수가 사용됩니다.

```
AWS_WEAVERRUNTIME_API Result<void> StoreEntityField(
    Transaction& txn,
    const Entity& entity,
    TypeId keyTypeId,
    FieldIndex index,
    std::int8_t* src,
    std::size_t length) noexcept;
```

`Api::TypeId keyTypeId` 파라미터는 전달된 데이터의 데이터 유형을 나타냅니다.

`Api::TypeId keyTypeId` 파라미터는 `Api::BuiltinTypeId`에서 해당 `Api::TypeId`를 수신해야 합니다. 적절한 변환이 없는 경우 `Api::BuiltinTypeId::Dynamic`을 사용할 수 있습니다.

복잡한 데이터 유형의 경우 `Api::BuiltInTypeId::Dynamic`을 사용합니다.

**참고**  
`FieldIndex index` 값은 0보다 커야 합니다. 0 값은 인덱스 키용으로 예약되어 있습니다(`StoreEntityIndexKey()` 참조).

**Example 프리미티브 데이터 유형을 사용한 예제**  

```
namespace
{
    constexpr Api::FieldIndex k_isTrueFieldId { /* value */ 1 };
}

Result<void> SetEntityFields(
    Api::Entity& entity, 
    Transaction& transaction)
{
    bool value = true;
    
    auto* src = reinterpret_cast<std::int8_t*>(value);
    size_t length = sizeof(*value);
    
    WEAVERRUNTIME_TRY(Api::StoreEntityField(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(
            Aws::WeaverRuntime::Api::BuiltinTypeId::Bool),
        k_isTrueFieldId,
        src,
        length));
}
```

**Example struct를 사용한 데이터 보관 예제**  

```
namespace
{
    constexpr Api::FieldIndex k_dataFieldId { /* value */ 1 };
}

struct Data
{
    bool boolData;
    float floatData;
};

Result<void> SetEntityFields(
    Api::Entity& entity, 
    Transaction& transaction)
{
    Data data = { /* boolData */ false, /* floatData */ -25.93 };
    
    auto* src = reinterpret_cast<std::int8_t*>(data);
    size_t length = sizeof(*data);
    
    WEAVERRUNTIME_TRY(Api::StoreEntityField(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(
            Aws::WeaverRuntime::Api::BuiltinTypeId::Dynamic),
        k_dataFieldId,
        src,
        length));
}
```

# 엔터티의 필드 데이터 불러오기
<a name="working-with_app-sdk_ent_readwrite_load"></a>

다음 예제는 엔터티의 필드 데이터를 로드(상태 패브릭에서 읽기)하는 방법을 보여줍니다. 해당 예제에는 다음 함수가 사용됩니다.

```
Result<std::size_t> LoadEntityField(
    Transaction& txn,
    const Entity& entity,
    TypeId keyTypeId,
    FieldIndex index,
    std::int8_t** dest) noexcept;
```

`Api::TypeId keyTypeId` 파라미터는 `Api::BuiltinTypeId`에서 해당 `Api::TypeId`를 수신해야 합니다. 적절한 변환이 없는 경우 `Api::BuiltinTypeId::Dynamic`을 사용할 수 있습니다.

**참고**  
`FieldIndex` 인덱스 값은 0보다 커야 합니다. 0 값은 인덱스 키용으로 예약되어 있습니다(`StoreEntityIndexKey()` 참조).

**Example 프리미티브 데이터 유형을 사용한 예제**  

```
namespace
{
    constexpr Api::FieldIndex k_isTrueFieldId { /* value */ 1 };
}

Result<void> LoadEntityFields(
    Api::Entity& entity, 
    Transaction& transaction)
{
    std::int8_t* dest = nullptr;
    
    WEAVERRUNTIME_TRY(Api::LoadEntityField(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(
            Aws::WeaverRuntime::Api::BuiltinTypeId::Bool),
        k_isTrueFieldId,
        &dest));
    
    bool isTrueValue = *reinterpret_cast<bool*>(dest);
}
```

**Example struct를 사용한 데이터 보관 예제**  

```
namespace
{
    constexpr Api::FieldIndex k_dataFieldId { /* value */ 1 };
}

struct Data
{
    bool boolData;
    float floatData;
};

Result<void> LoadEntityFields(
    Api::Entity& entity, 
    Transaction& transaction)
{
    std::int8_t* dest = nullptr;
    
    WEAVERRUNTIME_TRY(Api::LoadEntityField(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(
            Aws::WeaverRuntime::Api::BuiltinTypeId::Dynamic),
        k_dataFieldId,
        &dest));
    
    Data dataValue = *reinterpret_cast<Data*>(dest);
}
```

# 제거된 엔터티의 필드 데이터 로드
<a name="working-with_app-sdk_ent_readwrite_load-removed"></a>

앱의 소유권 및 구독 영역에서 제거된 엔터티의 엔터티 필드 데이터는 로드(상태 패브릭에서 읽기)할 수 없습니다. 다음 예제에서는 `Api::ChangeListAction::Remove`의 결과로 엔터티에 대한 `Api::LoadIndexKey()` 호출로 인해 오류가 발생합니다. 두 번째 예제는 앱에서 직접 항목 데이터를 저장하고 로드하는 올바른 방법을 보여줍니다.

**Example 잘못된 코드의 예제**  

```
Result<void> ProcessSubscriptionChanges(Transaction& transaction)
{
    /* ... */
    
    WEAVERRUNTIME_TRY(Api::SubscriptionChangeList subscriptionChangeList, 
        Api::AllSubscriptionEvents(transaction));
    
    for (const Api::SubscriptionEvent& event : 
        subscriptionChangeList.changes)
    {
        switch (event.action)
        {
        case Api::ChangeListAction::Remove:
            {
                std::int8_t* dest = nullptr;
    
                /**
                 * Error!
                 * This calls LoadEntityIndexKey on an entity that
                 * has been removed from the subscription area.
                 */
                WEAVERRUNTIME_TRY(Api::LoadEntityIndexKey(
                    transaction,
                    event.entity,
                    Api::BuiltinTypeIdToTypeId(
                        Api::BuiltinTypeId::Vector3F32),
                    &dest));
    
                AZ::Vector3 position = 
                    *reinterpret_cast<AZ::Vector3*>(dest);
                break;
            }
        }
 
    }

    /* ... */
}
```

**Example 앱에서 항목 데이터를 저장하고 로드하는 올바른 방법의 예제**  

```
Result<void> ReadAndSaveSubscribedEntityPositions(Transaction& transaction)
{
    static std::unordered_map<Api::EntityId, AZ::Vector3> 
        positionsBySubscribedEntity;

    WEAVERRUNTIME_TRY(Api::SubscriptionChangeList subscriptionChangeList, 
        Api::AllSubscriptionEvents(transaction));

    for (const Api::SubscriptionEvent& event : 
        subscriptionChangeList.changes)
    {
        switch (event.action)
        {
        case Api::ChangeListAction::Add:
            {
                std::int8_t* dest = nullptr;

                /**
                 * Add the position when the entity is added.
                 */
                WEAVERRUNTIME_TRY(Api::LoadEntityIndexKey(
                    transaction,
                    event.entity,
                    Api::BuiltinTypeIdToTypeId(
                        Api::BuiltinTypeId::Vector3F32),
                    &dest));

                AZ::Vector3 position = 
                    *reinterpret_cast<AZ::Vector3*>(dest);
                positionsBySubscribedEntity.emplace(
                    event.entity.descriptor->id, position);

                break;
            }
        case Api::ChangeListAction::Update:
            {
                std::int8_t* dest = nullptr;

                /**
                 * Update the position when the entity is updated.
                 */
                WEAVERRUNTIME_TRY(Api::LoadEntityIndexKey(
                    transaction,
                    event.entity,
                    Api::BuiltinTypeIdToTypeId(
                        Api::BuiltinTypeId::Vector3F32),
                    &dest));

                AZ::Vector3 position = 
                    *reinterpret_cast<AZ::Vector3*>(dest);
                positionsBySubscribedEntity[event.entity.descriptor->id] = 
                    position;

                break;
            }
        case Api::ChangeListAction::Remove:
            {
                /**
                 * Load the position when the entity is removed.
                 */
                AZ::Vector3 position = positionsBySubscribedEntity[
                    event.entity.descriptor->id];

                /**
                 * Do something with position...
                 */
                break;
            }
        }
    }
    
    /* ... */
}
```

# 엔터티에 대한 위치 저장
<a name="working-with_app-sdk_ent_store-position"></a>

정수 데이터 구조를 사용하여 엔터티의 위치를 저장(상태 패브릭에 쓰기)할 수 있습니다. 해당 예제에는 다음 함수가 사용됩니다.

```
Result<void> StoreEntityIndexKey(
    Transaction& txn, 
    const Entity& entity, 
    TypeId keyTypeId, 
    std::int8_t* src, 
    std::size_t length)
```

**참고**  
다음 예제에서와 같이 `Api::BuiltinTypeId::Vector3F32`를 `Api::StoreEntityIndexKey()`에 제공해야 합니다.

**Example 배열을 사용하여 위치를 나타내는 예제**  

```
Result<void> SetEntityPositionByFloatArray(
    Api::Entity& entity, 
    Transaction& transaction)
{
    std::array<float, 3> position = { /* x */ 25, /* y */ 21, /* z */ 0 };
    
    auto* src = reinterpret_cast<std::int8_t*>(position.data());
    std::size_t length = sizeof(position);
    
    WEAVERRUNTIME_TRY(Api::StoreEntityIndexKey(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(Api::BuiltinTypeId::Vector3F32),
        src,
        length));
}
```

**Example struct을 사용하여 위치를 나타내는 예제**  

```
struct Position 
{
   float x;
   float y;
   float z;
};

Result<void> SetEntityPositionByStruct(
    Api::Entity& entity, 
    Transaction& transaction)
{
    Position position = { /* x */ 25, /* y */ 21, /* z */ 0 };
    
    auto* src = reinterpret_cast<std::int8_t*>(&position);
    std::size_t length = sizeof(position);
    
    WEAVERRUNTIME_TRY(Api::StoreEntityIndexKey(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(Api::BuiltinTypeId::Vector3F32),
        src,
        length));
}
```

# 엔터티에 대한 위치 로드
<a name="working-with_app-sdk_ent_load-position"></a>

정수 데이터 구조를 사용하여 엔터티의 위치를 로드(상태 패브릭에서 읽기)할 수 있습니다. 해당 예제에는 다음 함수가 사용됩니다.

**참고**  
다음 예제에서와 같이 `Api::BuiltinTypeId::Vector3F32`를 `Api::LoadEntityIndexKey()`에 제공해야 합니다.

**Example 배열을 사용하여 위치를 나타내는 예제**  

```
Result<void> GetEntityPosition(Api::Entity& entity, 
    Transaction& transaction)
{
    std::int8_t* dest = nullptr;
    
    WEAVERRUNTIME_TRY(Aws::WeaverRuntime::Api::LoadEntityIndexKey(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(
            Aws::WeaverRuntime::Api::BuiltinTypeId::Vector3F32),
        &dest));
        
    std::array<float, 3> position = 
        *reinterpret_cast<std::array<float, 3>*>(dest);
}
```

**Example struct을 사용하여 위치를 나타내는 예제**  

```
struct Position 
{struct
   float x;
   float y;
   float z;
};

Result<void> GetEntityPosition(Api::Entity& entity, Transaction& transaction)
{
    std::int8_t* dest = nullptr;
    
    WEAVERRUNTIME_TRY(Aws::WeaverRuntime::Api::LoadEntityIndexKey(
        transaction,
        entity,
        Api::BuiltinTypeIdToTypeId(
            Aws::WeaverRuntime::Api::BuiltinTypeId::Vector3F32),
        &dest));
        
    Position position = *reinterpret_cast<Position*>(dest);
}
```