@@ -116,6 +116,23 @@ public GameObjectData? Parent
116116
117117 public int ? ObjectId => Info ? . Data . objectId ;
118118
119+ public object Clone ( )
120+ {
121+ GameObjectData gameObject = new ( )
122+ {
123+ Info = Info != null ? new ( ) { Data = Info . Data } : null ,
124+ Components = new ( Components . Select ( item => item . CloneCached ( ) ) ) ,
125+ Instance = Instance ? . CloneCached ( ) ,
126+ } ;
127+ foreach ( var child in Children )
128+ {
129+ var newChild = ( GameObjectData ) child . Clone ( ) ;
130+ newChild . Parent = gameObject ;
131+ gameObject . Children . Add ( newChild ) ;
132+ }
133+ return gameObject ;
134+ }
135+
119136 public override string ToString ( )
120137 {
121138 return Name ?? "" ;
@@ -171,6 +188,7 @@ protected override bool DoRead()
171188 GameObjectRefInfoList . Clear ( ) ;
172189 ResourceInfoList . Clear ( ) ;
173190 UserdataInfoList . Clear ( ) ;
191+ GameObjectDatas ? . Clear ( ) ;
174192
175193 var handler = FileHandler ;
176194 var header = Header ;
@@ -312,6 +330,27 @@ public static void CollectGameObjectInstances(GameObjectData gameObject, List<Rs
312330 }
313331 }
314332
333+ /// <summary>
334+ /// 迭代GameObject以及子物体的实例和组件实例
335+ /// </summary>
336+ /// <param name="gameObject"></param>
337+ /// <returns></returns>
338+ public static IEnumerable < RszInstance > IterGameObjectInstances ( GameObjectData gameObject )
339+ {
340+ yield return gameObject . Instance ! ;
341+ foreach ( var item in gameObject . Components )
342+ {
343+ yield return item ;
344+ }
345+ foreach ( var child in gameObject . Children )
346+ {
347+ foreach ( var item in IterGameObjectInstances ( child ) )
348+ {
349+ yield return item ;
350+ }
351+ }
352+ }
353+
315354 public IEnumerable < GameObjectData > IterGameObjects ( GameObjectData ? parent = null , bool includeChildren = false )
316355 {
317356 var items = parent ? . Children ?? GameObjectDatas ;
@@ -422,6 +461,89 @@ public void PfbFromScnGameObject(ScnFile.GameObjectData scnGameObject)
422461 RebuildInfoTable ( ) ;
423462 }
424463
464+ public void RemoveGameObject ( GameObjectData gameObject )
465+ {
466+ if ( gameObject . Parent != null )
467+ {
468+ gameObject . Parent . Children . Remove ( gameObject ) ;
469+ gameObject . Parent = null ;
470+ }
471+ else
472+ {
473+ GameObjectDatas ? . Remove ( gameObject ) ;
474+ }
475+ StructChanged = true ;
476+ }
477+
478+ /// <summary>
479+ /// 导入外部的游戏对象
480+ /// 文件夹和父对象只能指定一个
481+ /// </summary>
482+ /// <param name="gameObject"></param>
483+ /// <param name="folder">文件夹</param>
484+ /// <param name="parent">父对象</param>
485+ /// <param name="isDuplicate">在原对象的位置后面添加</param>
486+ public void ImportGameObject ( GameObjectData gameObject ,
487+ GameObjectData ? parent = null , bool isDuplicate = false )
488+ {
489+ RszInstance . CleanCloneCache ( ) ;
490+ GameObjectData newGameObject = ( GameObjectData ) gameObject . Clone ( ) ;
491+
492+ newGameObject . Parent = null ;
493+ ObservableCollection < GameObjectData > collection ;
494+ if ( parent != null )
495+ {
496+ newGameObject . Parent = parent ;
497+ collection = parent . Children ;
498+ }
499+ else
500+ {
501+ GameObjectDatas ??= [ ] ;
502+ collection = GameObjectDatas ;
503+ }
504+
505+ // 为了可视化重新排序号,否则会显示序号是-1,但实际上保存的时候的序号和现在编号的可能不一致
506+ // 所以要考虑这步操作是否有必要
507+ RSZ ! . FixInstanceListIndex ( IterGameObjectInstances ( newGameObject ) ) ;
508+
509+ if ( isDuplicate )
510+ {
511+ int index = collection . IndexOf ( gameObject ) ;
512+ index = index == - 1 ? collection . Count : index + 1 ;
513+ collection . Insert ( index , newGameObject ) ;
514+ }
515+ else
516+ {
517+ collection . Add ( newGameObject ) ;
518+ }
519+ StructChanged = true ;
520+ RszInstance . CleanCloneCache ( ) ;
521+ }
522+
523+ /// <summary>
524+ /// 导入外部的游戏对象
525+ /// 批量添加建议直接GameObjectDatas添加,最后再RebuildInfoTable
526+ /// </summary>
527+ /// <param name="gameObject"></param>
528+ public void ImportGameObjects (
529+ IEnumerable < GameObjectData > gameObjects ,
530+ GameObjectData ? parent = null )
531+ {
532+ foreach ( var gameObject in gameObjects )
533+ {
534+ ImportGameObject ( gameObject , parent ) ;
535+ }
536+ }
537+
538+ /// <summary>
539+ /// 复制游戏对象
540+ /// </summary>
541+ /// <param name="gameObject"></param>
542+ public void DuplicateGameObject ( GameObjectData gameObject )
543+ {
544+ ImportGameObject ( gameObject , gameObject . Parent , true ) ;
545+ }
546+
425547 /// <summary>
426548 /// 添加组件
427549 /// </summary>
0 commit comments