USDZ模型加载差异:ModelEntity与Entity的动画及碰撞问题求助
Sketchfab USDZ模型加载问题:警告消除与碰撞修复
问题描述
从Sketchfab购买的2个USDZ模型加载后表现存在差异:
- 第一个模型使用
ModelEntity加载正常:可通过object.model!.mesh.bounds.extents设置CollisionComponent,且能获取object.availableAnimations[0]; - 第二个模型使用
ModelEntity加载无法显示,改用Entity类型可加载,但无法获取mesh边界来设置碰撞,同时出现「No 'async' operations occur within 'await' expression」警告。
解决方案
① 消除「No 'async' operations occur within 'await' expression」警告
这个警告的核心原因是await被用于非异步操作(即后续表达式不是Promise或异步函数),直接调整代码即可:
- 检查模型加载代码,若加载方法为同步类型,直接移除
await关键字; - 若代码误将同步逻辑包裹在
await中,把同步代码从await块中剥离。
示例:
错误写法:
const model = await loadStaticModel(); // loadStaticModel为同步方法
修正后:
const model = loadStaticModel();
② 修复第二个模型的碰撞功能
改用Entity加载后无法直接获取顶层mesh边界,可尝试以下方案:
方案1:手动指定碰撞边界
若已知模型大致尺寸,直接创建固定大小的碰撞形状:
entity.components[CollisionComponent] = CollisionComponent(shapes: [.box(width: 1.5, height: 2.0, depth: 0.8)])
方案2:递归遍历子实体查找mesh
USDZ模型可能存在嵌套结构,递归遍历所有子节点,找到包含MeshComponent的实体后获取边界:
func retrieveMeshExtents(from entity: Entity) -> SIMD3<Float>? { // 检查当前实体是否包含mesh if let meshComponent = entity.components[MeshComponent], let mesh = meshComponent.mesh { return mesh.bounds.extents } // 递归检查子实体 for child in entity.children { if let extents = retrieveMeshExtents(from: child) { return extents } } return nil } // 使用示例 if let extents = retrieveMeshExtents(from: yourLoadedEntity) { entity.components[CollisionComponent] = CollisionComponent(shapes: [.box(extents: extents)]) }
方案3:重新导出模型修复结构问题
第二个模型无法用ModelEntity加载,大概率是USDZ文件的结构或mesh数据存在异常。尝试用Blender、Autodesk Maya等工具重新导出模型为USDZ格式,确保mesh数据正确嵌入,之后再用ModelEntity加载,即可恢复正常的mesh边界获取能力。
内容的提问来源于stack exchange,提问作者Vina
相关产品推荐
相关产品推荐

