备忘录之Babylon.js 子对象获取方法

在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)

相关推荐
ttod_qzstudio5 天前
Babylon.js内置行为介绍之三:MR 交互三件套——SurfaceMagnetism + Follow + HandConstraint 实战
hololens·手势追踪·babylon.js·webxr·mixed reality·表面吸附·手掌 ui
ttod_qzstudio6 天前
Babylon.js内置行为介绍之一:用 BoundingBoxBehavior + Gizmo 组合打造「零代码」3D 编辑器
babylon.js·boundingbox·gizmo
ttod_qzstudio6 天前
把“行为”做成乐高——Babylon.js Behavior 开发套路
生命周期·behavior·babylon.js·内存安全·非空断言
ttod_qzstudio6 天前
从一个隐蔽的 Bug 谈 Babylon.js 对象生命周期管理
babylon.js
ttod_qzstudio7 天前
Babylonjs中手搓OutlineLayer:替代HighlightLayer的高性能轮廓线
babylon.js
ttod_qzstudio11 天前
MirrorReflectionBehaviorEditor 开发心得:Babylon.js 镜面反射的实现与优化
babylon.js·mirrortexture
ttod_qzstudio11 天前
从Unity的C#到Babylon.js的typescript:“函数重载“变成“类型魔法“
typescript·c#·重载·babylon.js
ttod_qzstudio16 天前
Babylon.js TransformNode.clone() 的隐形陷阱:当 null 不等于 null
babylon.js
ttod_qzstudio1 个月前
深入理解 Babylon.js:TransformNode.setParent 与 parent 赋值的核心差异
babylon.js