private void ProcessCreatedActors()

in MREUnityRuntimeLib/App/MixedRealityExtensionApp.cs [972:1086]


		private void ProcessCreatedActors(CreateActor originalMessage, IList<Actor> createdActors, Action onCompleteCallback, string guidSeed = null)
		{
			Guid guidGenSeed;
			if (originalMessage != null)
			{
				guidGenSeed = originalMessage.Actor.Id;
			}
			else
			{
				guidGenSeed = UtilMethods.StringToGuid(guidSeed);
			}
			var guids = new DeterministicGuids(guidGenSeed);

			// find the actors with no actor parents
			var rootActors = GetDistinctTreeRoots(
				createdActors.Select(a => a.gameObject).ToArray()
			).Select(go => go.GetComponent<Actor>()).ToArray();

			var rootActor = createdActors.FirstOrDefault();
			var createdAnims = new List<Animation.BaseAnimation>(5);

			if (rootActors.Length == 1 && rootActor.transform.parent == null)
			{
				// Delete entire hierarchy as we no longer have a valid parent actor for the root of this hierarchy.  It was likely
				// destroyed in the process of the async operation before this callback was called.
				foreach (var actor in createdActors)
				{
					actor.Destroy();
				}

				createdActors.Clear();

				SendCreateActorResponse(
					originalMessage,
					failureMessage: "Parent for the actor being created no longer exists.  Cannot create new actor.");
				return;
			}

			var secondPassXfrms = new List<Transform>(2);
			foreach (var root in rootActors)
			{
				ProcessActors(root.transform, root.transform.parent != null ? root.transform.parent.GetComponent<Actor>() : null);
			}
			// some things require the whole hierarchy to have actors on it. run those here
			foreach (var pass2 in secondPassXfrms)
			{
				ProcessActors2(pass2);
			}

			if (originalMessage != null && rootActors.Length == 1)
			{
				rootActor?.ApplyPatch(originalMessage.Actor);
			}
			Actor.ApplyVisibilityUpdate(rootActor);

			_actorManager.UponStable(
				() => SendCreateActorResponse(originalMessage, actors: createdActors, anims: createdAnims, onCompleteCallback: onCompleteCallback));

			void ProcessActors(Transform xfrm, Actor parent)
			{
				// Generate actors for all GameObjects, even if the loader didn't. Only loader-generated
				// actors are returned to the app though. We do this so library objects get enabled/disabled
				// correctly, even if they're not tracked by the app.
				var actor = xfrm.gameObject.GetComponent<Actor>() ?? xfrm.gameObject.AddComponent<Actor>();

				_actorManager.AddActor(guids.Next(), actor);
				_ownedGameObjects.Add(actor.gameObject);

				actor.ParentId = parent?.Id ?? actor.ParentId;
				if (actor.Renderer != null)
				{
					// only overwrite material if there's something in the cache, i.e. not a random library material
					var matId = AssetManager.GetByObject(actor.Renderer.sharedMaterial)?.Id;
					if (matId.HasValue)
					{
						actor.MaterialId = matId.Value;
					}

					actor.MeshId = AssetManager.GetByObject(actor.UnityMesh)?.Id ?? Guid.Empty;
				}

				// native animation construction requires the whole actor hierarchy to already exist. defer to second pass
				var nativeAnim = xfrm.gameObject.GetComponent<UnityEngine.Animation>();
				if (nativeAnim != null && createdActors.Contains(actor))
				{
					secondPassXfrms.Add(xfrm);
				}

				foreach (Transform child in xfrm)
				{
					ProcessActors(child, actor);
				}
			}

			void ProcessActors2(Transform xfrm)
			{
				var actor = xfrm.gameObject.GetComponent<Actor>();
				var nativeAnim = xfrm.gameObject.GetComponent<UnityEngine.Animation>();
				if (nativeAnim != null && createdActors.Contains(actor))
				{
					var animTargets = xfrm.gameObject.GetComponent<PrefabAnimationTargets>();
					int stateIndex = 0;
					foreach (AnimationState state in nativeAnim)
					{
						var anim = new NativeAnimation(AnimationManager, guids.Next(), nativeAnim, state);
						anim.TargetIds = animTargets != null
							? animTargets.GetTargets(xfrm, stateIndex++, addRootToTargets: true).Select(a => a.Id).ToList()
							: new List<Guid>() { actor.Id };

						AnimationManager.RegisterAnimation(anim);
						createdAnims.Add(anim);
					}
				}
			}
		}