在Babylon.js中,TransformNode提供了三个常用方法来获取子对象,但它们的行为差异经常让人混淆。本文帮你理清核心区别。
核心区别一览
| 方法名 | 返回类型 | 默认深度 | 参数顺序 | 主要用途 |
|---|---|---|---|---|
getChildMeshes |
AbstractMesh[] |
所有层级 | (directDescendantsOnly?, predicate?) |
只获取网格对象 |
getChildTransformNodes |
TransformNode[] |
所有层级 | (directDescendantsOnly?, predicate?) |
获取TransformNode(不含网格) |
getChildren |
Node[] |
仅直接子级 | (predicate?, directDescendantsOnly?) |
获取所有类型节点 |
深度遍历 vs 仅直接子级
1. getChildMeshes() - 默认递归所有层级
TypeScript
// 获取所有层级的子网格(包括孙级、曾孙级...)
const allMeshes = parent.getChildMeshes();
// 仅获取直接子网格
const directMeshes = parent.getChildMeshes(true);
特点 :自动排除非网格对象,只返回AbstractMesh及其子类(Mesh、InstancedMesh等)。
2. getChildTransformNodes() - 默认递归所有层级
TypeScript
// 获取所有层级的TransformNode(但会排除网格)
const allNodes = parent.getChildTransformNodes();
// 仅获取直接TransformNode子节点
const directNodes = parent.getChildTransformNodes(true);
⚠️ 特殊行为 :虽然Mesh继承自TransformNode,但此方法会主动过滤掉所有网格对象,只返回Camera、Light、TransformNode等。
3. getChildren() - 默认仅直接子级
TypeScript
// 获取所有直接子节点(不递归)
const directChildren = parent.getChildren();
// 获取所有层级的所有类型子节点
const allChildren = parent.getChildren(null, false);
⚠️ 参数顺序陷阱 :此方法的两个参数顺序与其他两个方法相反!第一个参数是predicate,第二个才是directDescendantsOnly。
实际场景示例
假设有以下场景树:
Parent (TransformNode)
├─ Mesh_A (AbstractMesh)
│ └─ Mesh_A1 (A的子网格)
├─ TransformNode_B
└─ Camera_C
TypeScript
// getChildMeshes() - 只返回网格,递归
parent.getChildMeshes(); // [Mesh_A, Mesh_A1]
parent.getChildMeshes(true); // [Mesh_A](仅直接子级)
// getChildTransformNodes() - 返回TransformNode但排除网格,递归
parent.getChildTransformNodes(); // [TransformNode_B, Camera_C]
parent.getChildTransformNodes(true); // [TransformNode_B, Camera_C](因为都在直接子级)
// getChildren() - 返回所有类型,仅直接子级
parent.getChildren(); // [Mesh_A, TransformNode_B, Camera_C]
parent.getChildren(null, false); // [Mesh_A, Mesh_A1, TransformNode_B, Camera_C]
常见陷阱与最佳实践
陷阱1:深度默认值混淆
TypeScript
// 错误预期:获取所有子节点(包括孙级)
const children = parent.getChildren(); // ❌ 实际只得到直接子级
// 正确做法
const allChildren = parent.getChildren(null, false); // ✅
陷阱2:参数顺序错误
TypeScript
// 想获取直接子网格,但写错了
parent.getChildMeshes(false); // ❌ 实际获取所有层级
// 正确做法
parent.getChildMeshes(true); // ✅
陷阱3:类型过滤误解
TypeScript
// 想获取所有TransformNode(包括Mesh)
parent.getChildTransformNodes(); // ❌ Mesh被过滤掉了!
// 正确做法
parent.getChildren(null, false); // ✅ 获取所有节点
最佳实践总结
-
需要所有网格 :
node.getChildMeshes() -
需要所有TransformNode(不含网格) :
node.getChildTransformNodes() -
需要所有类型的直接子节点 :
node.getChildren() -
需要所有类型的所有层级节点 :
node.getChildren(null, false)