如何通过UniRx监听子GameObject添加并获取新增对象?
没问题,我来帮你搞定这个需求!你遇到的问题是UniRx的OnTransformChildrenChangedAsObservable()只返回Unit,没办法直接拿到新增的子物体,下面给你两种可行的方案,一种基于UniRx扩展,另一种是不用UniRx的传统Unity方法:
方案一:扩展UniRx的Observable,直接返回新增子物体
我们可以自己写一个扩展方法,基于原有的OnTransformChildrenChangedAsObservable(),通过对比子物体数量的变化来找出新增的对象。这样就能实现你想要的直接拿到GameObject的效果:
using UnityEngine; using UniRx; using System; public static class TransformUniRxExtensions { public static IObservable<GameObject> OnTransformChildAddedAsObservable(this Transform parentTransform) { // 记录初始的子物体数量 int previousChildCount = parentTransform.childCount; return parentTransform.OnTransformChildrenChangedAsObservable() .Select(_ => { int currentChildCount = parentTransform.childCount; // 只有当子物体数量增加时,才处理新增的对象 if (currentChildCount > previousChildCount) { // 新增的子物体是最后一个(因为SetParent会把它加到末尾) GameObject addedChild = parentTransform.GetChild(currentChildCount - 1).gameObject; previousChildCount = currentChildCount; return addedChild; } // 如果是子物体被移除的情况,这里返回null,后续过滤掉 return null; }) // 过滤掉移除子物体时的null结果 .Where(child => child != null); } }
使用这个扩展方法就可以直接拿到新增的子物体了:
var parent = new GameObject("parent"); parent.transform.OnTransformChildAddedAsObservable() .Subscribe(g => { Debug.Log($"新增的子物体:{g.name}"); }); var child = new GameObject("child"); child.transform.SetParent(parent.transform);
方案二:不用UniRx,用Unity原生方法监听
如果你不想依赖UniRx,可以在父物体上挂载一个脚本,重写Unity原生的OnTransformChildrenChanged方法,通过对比前后的子物体集合来找出新增的对象:
using UnityEngine; using System.Collections.Generic; public class ChildAddedDetector : MonoBehaviour { // 用HashSet来存储已有的子物体Transform,方便快速查找 private HashSet<Transform> _existingChildren = new HashSet<Transform>(); private void Awake() { // 初始化时记录所有已有的子物体 foreach (Transform child in transform) { _existingChildren.Add(child); } } private void OnTransformChildrenChanged() { // 遍历当前所有子物体,找出新增的那个 foreach (Transform child in transform) { if (!_existingChildren.Contains(child)) { Debug.Log($"新增的子物体:{child.gameObject.name}"); _existingChildren.Add(child); } } // 如果你还需要处理子物体被移除的情况,可以在这里添加逻辑: // 遍历_existingChildren,找出不在当前子物体列表中的项 } }
使用方法很简单:给你的parent GameObject挂上这个脚本,之后每次添加子物体时,就会自动打印新增的子物体名称了。
额外说明
- 两种方案都支持批量添加子物体的情况(比如一次添加多个),会逐个检测出新增的对象。
- 如果需要区分“添加”和“移除”操作,可以在逻辑中增加对数量减少的判断,或者对比集合找出被移除的对象。
内容的提问来源于stack exchange,提问作者Shintaro Nomiya
相关产品推荐
相关产品推荐

