你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

实体

实体表示空间中的可移动对象,是远程渲染内容的基本构造块

实体属性

实体具有由位置、旋转和比例定义的转换。 本身,实体没有任何可观察的功能。 而行为是通过附加到实体的组件添加的。 例如,附加 CutPlaneComponent 会在实体的位置创建剪切平面。

实体本身的最重要方面是层次结构和产生的分层转换。 例如,将多个实体作为子级附加到共享的父实体时,可以通过更改父实体的转换,同时移动、旋转和缩放所有这些实体。 此外,实体的 enabled 状态可用于关闭层次结构中完整子关系图的可见性和对光线投射的响应。

实体由其父级唯一拥有,这意味着,当父级被 Entity.Destroy() 销毁时,其子级和所有连接的组件也会被销毁。 因此,从场景中删除模型(由 RenderingSession.Connection.LoadModelAsync() 或其 SAS 变体 RenderingSession.Connection.LoadModelFromSasAsync() 返回)可以通过在模型的根节点上调用 Destroy 来实现。

当服务器加载内容或用户想要将对象添加到场景中时,会创建实体。 例如,如果用户想要添加裁切平面来可视化网格内部,则用户可以创建应存在平面的实体,然后将该裁切平面组件添加到其中。

创建实体

若要将新实体添加到场景中,例如,若要将其作为根对象传递以加载模型或向其附加组件,请使用以下代码:

Entity CreateNewEntity(RenderingSession session)
{
    Entity entity = session.Connection.CreateEntity();
    entity.Position = new LocalPosition(1, 2, 3);
    return entity;
}
ApiHandle<Entity> CreateNewEntity(ApiHandle<RenderingSession> session)
{
    ApiHandle<Entity> entity(nullptr);
    if (auto entityRes = session->Connection()->CreateEntity())
    {
        entity = entityRes.value();
        entity->SetPosition(Double3{ 1, 2, 3 });
        return entity;
    }
    return entity;
}

查询函数

实体上有两种类型的查询函数:同步调用和异步调用。 同步查询只能用于客户端上存在的数据,并且不涉及太多计算。 例如,查询组件、相对对象转换或父/子关系。 异步查询用于仅驻留在服务器上或涉及成本太高而无法在客户端上运行的额外计算的数据。 例如,空间边界查询或元数据查询。

查询组件

若要查找特定类型的组件,请使用 FindComponentOfType

CutPlaneComponent cutplane = (CutPlaneComponent)entity.FindComponentOfType(ObjectType.CutPlaneComponent);

// or alternatively:
CutPlaneComponent cutplane = entity.FindComponentOfType<CutPlaneComponent>();
ApiHandle<CutPlaneComponent> cutplane = entity->FindComponentOfType(ObjectType::CutPlaneComponent)->as<CutPlaneComponent>();

// or alternatively:
ApiHandle<CutPlaneComponent> cutplane = entity->FindComponentOfType<CutPlaneComponent>();

查询转换

转换查询是对对象的同步调用。 请务必注意,存储在 API 端的转换是相对于对象的父级的本地空间转换。 例外情况是本地空间和世界空间相同的根对象。

// local space transform of the entity
Double3 translation = entity.Position;
Quaternion rotation = entity.Rotation;
Float3 scale = entity.Scale;
// local space transform of the entity
Double3 translation = entity->GetPosition();
Quaternion rotation = entity->GetRotation();
Float3 scale = entity->GetScale();

如果所有树转换组件(位置、旋转和缩放)都需要同时检索或设置,建议使用实体 LocalTransform 的属性:

// local space transform of the entity
Transform localTransform = entity.LocalTransform;
Double3 translation = localTransform.Position;
Quaternion rotation = localTransform.Rotation;
Float3 scale = localTransform.Scale;
// local space transform of the entity
Transform localTransform = entity->GetLocalTransform();
Double3& translation = localTransform.Position;
Quaternion& rotation = localTransform.Rotation;
Float3& scale = localTransform.Scale;

还有一个帮助程序函数来检索实体的全局(世界空间)转换:

// global space transform of the entity
Transform globalTransform = entity.GlobalTransform;
Double3 translation = globalTransform.Position;
// global space transform of the entity
Transform globalTransform = entity->GetGlobalTransform();
Double3& translation = globalTransform.Position;

调用时 GlobalTransform ,将通过遍历实体层次结构来实时计算全局转换。 此遍历涉及大量计算,但与通过类 Entity在客户端执行相同操作相比,内置函数速度更快。 不过,调用 GlobalTransform 一组较大的实体可能会造成性能瓶颈。

LocalToGlobalMatrix 是将全局转换计算为矩阵的 GlobalTransform 变体,在 Unity 上下文中很方便:

UnityEngine.Matrix4x4 globalMatrix = entity.LocalToGlobalMatrix.toUnity();
UnityEngine.Vector3 localPos = new UnityEngine.Vector3(0, 0, 0);
UnityEngine.Vector3 globalPos = globalMatrix.MultiplyPoint(localPos);

查询空间边界

边界查询是使用一个实体作为根实体在整个对象层次结构上操作的异步调用。 请参阅有关对象边界的专用章节。

查询元数据

元数据是存储在服务器忽略的对象上的额外数据。 对象元数据实质上是一组(名称、值)对,其中值可以是数字、布尔值或字符串类型。 可以使用 模型导出元数据。

元数据查询是对特定实体的异步调用。 查询仅返回单个实体的元数据,而不返回子图形的合并信息。

Task<ObjectMetadata> metaDataQuery = entity.QueryMetadataAsync();
ObjectMetadata metaData = await metaDataQuery;
ObjectMetadataEntry entry = metaData.GetMetadataByName("MyInt64Value");
System.Int64 intValue = entry.AsInt64;
// ...
entity->QueryMetadataAsync([](Status status, ApiHandle<ObjectMetadata> metaData) 
{
    if (status == Status::OK)
    {
        ApiHandle<ObjectMetadataEntry> entry = *metaData->GetMetadataByName("MyInt64Value");
        int64_t intValue = *entry->GetAsInt64();

        // ...
    }
});

即使对象不保存任何元数据,查询也会成功。

API 文档

后续步骤