如何在Android Sceneform中加载GLB文件并选中子网格(子节点)?
解决SceneView点击无法获取子实体的问题
核心原因
默认情况下,ModelNode的子节点未开启可交互(点击/拾取)权限,触摸检测只会返回顶层父节点。
解决方案
1. 启用所有子节点的可交互性
加载模型后,递归遍历所有子节点,开启点击和拾取权限:
// 递归开启所有子节点的可交互 private fun enableClickForAllNodes(node: Node) { node.isClickable = true node.isPickable = true node.children.forEach { enableClickForAllNodes(it) } } // 在加载模型后调用 viewLifecycleOwner.lifecycleScope.launch { val modelFile = "models/truck.glb" modelInstance = sceneView.modelLoader.createModelInstance(modelFile) val modelNode = ModelNode( modelInstance = modelInstance, centerOrigin = Position(x = 0.0f, y = 0.0f, z = 0.0f) ) modelNode.scale = Scale(.025f) sceneView.addChildNode(modelNode) // 启用所有子节点的点击与拾取 enableClickForAllNodes(modelNode) // 处理触摸事件 sceneView.onTouchEvent = { e, hitResult -> if (e.action == MotionEvent.ACTION_UP) { val clickedNode = hitResult.node // 判断是否为子节点(非顶层modelNode) if (clickedNode != modelNode) { Log.e("TAG", "选中子节点:${clickedNode.name ?: "未命名"}") // 这里添加子节点的修改逻辑,比如改变颜色、缩放等 } } true // 消费触摸事件 } loadingView.isGone = true }
2. 确保模型子网格保留独立节点结构
如果上述操作后仍无法获取子节点,检查模型文件(.glb)是否将子网格导出为独立实体。部分建模软件导出时会合并网格,导致子实体丢失,需要重新导出时保留层级结构。
3. 验证触摸事件逻辑
确保触摸事件返回true,表示消费该事件,避免事件被上层拦截。同时只在ACTION_UP(点击抬起)时处理,避免重复触发。
内容的提问来源于stack exchange,提问作者Asharali V U
相关产品推荐
相关产品推荐

