private void Update() { ActorGroupSpec groupSpec = ActorGroupSpec.FromString((string)editor.data); buttonLabel.text = groupSpec.ToUserFriendlyString(engine); }
public virtual VoosActor Instantiate(VoosEngine engine, BehaviorSystem behaviorSystem, Vector3 position, Quaternion rotation, System.Action <VoosActor> setupActor) { // TODO TODO we should make a copy of 'saved' in case Instantiate is called again.. if (this.saved.sojos != null) { foreach (var savedSojo in this.saved.sojos) { if (sojos.GetSojoById(savedSojo.id) == null) { sojos.PutSojo(Sojo.Load(savedSojo)); } } } // Import behaviors. For now, create entirely new brain IDs. var brainIdMap = new Dictionary <string, string>(); for (int i = 0; i < this.saved.brainDatabase.brainIds.Length; i++) { string brainId = this.saved.brainDatabase.brainIds[i]; string newId = behaviorSystem.GenerateUniqueId(); brainIdMap[brainId] = newId; this.saved.brainDatabase.brainIds[i] = newId; } // Use the new brain IDs.. for (int i = 0; i < saved.actors.Length; i++) { if (brainIdMap.ContainsKey(saved.actors[i].brainName)) { saved.actors[i].brainName = brainIdMap[saved.actors[i].brainName]; } else { // Always default to default brain. Some prefabs have dangling brain // IDs, and bad stuff can happen if we just keep those. Util.LogWarning($"WARNING: Actor prefab '{saved.actors[i].displayName}' ({saved.actors[i].name}) had dangling brainName: {saved.actors[i].brainName}"); saved.actors[i].brainName = VoosEngine.DefaultBrainUid; } } var expectedBrainIds = new HashSet <string>(from actor in this.saved.actors select actor.brainName); behaviorSystem.MergeNonOverwrite(saved.brainDatabase, expectedBrainIds); // Instantiate the actor hierarchy - very important we update the parent // references, as well as any property references in the use.. // Create new names for all actors var actorNameMap = new Dictionary <string, string>(); foreach (var savedActor in saved.actors) { actorNameMap[savedActor.name] = engine.GenerateUniqueId(); } // Compute xform to go from saved to instance... then just apply to all. var savedRoot = saved.actors[0]; Matrix4x4 savedRootLocalToWorld = new Matrix4x4(); savedRootLocalToWorld.SetTRS(savedRoot.position, savedRoot.rotation, savedRoot.localScale); Matrix4x4 instRootLocalToWorld = new Matrix4x4(); instRootLocalToWorld.SetTRS(position, rotation, savedRoot.localScale); Matrix4x4 savedToInstance = instRootLocalToWorld * savedRootLocalToWorld.inverse; // Instantiate the tree. List <VoosActor> instances = new List <VoosActor>(); foreach (var savedActor in saved.actors) { string instanceName = actorNameMap[savedActor.name]; Vector3 instPos = savedToInstance * savedActor.position.ToHomogeneousPosition(); Quaternion instRot = savedToInstance.rotation * savedActor.rotation; System.Action <VoosActor> setupThisActor = actor => { Debug.Assert(actor.GetName() == instanceName, "New instance did not have the new name we generated"); // Push the saved data to this new actor var actorDataCopy = savedActor; actorDataCopy.position = instPos; actorDataCopy.rotation = instRot; actorDataCopy.name = instanceName; // Make sure we update the transform parent! if (!actorDataCopy.transformParent.IsNullOrEmpty() && actorNameMap.ContainsKey(actorDataCopy.transformParent)) { actorDataCopy.transformParent = actorNameMap[actorDataCopy.transformParent]; } if (!actorDataCopy.spawnTransformParent.IsNullOrEmpty() && actorNameMap.ContainsKey(actorDataCopy.spawnTransformParent)) { actorDataCopy.spawnTransformParent = actorNameMap[actorDataCopy.spawnTransformParent]; } actor.UpdateFrom(actorDataCopy); setupActor(actor); }; VoosActor instance = engine.CreateActor(instPos, instRot, setupThisActor, instanceName); instances.Add(instance); } // FINALLY...fix up any actor refs! foreach (VoosActor inst in instances) { var brain = ActorBehaviorsEditor.FromActor(inst); foreach (var assigned in brain.GetAssignedBehaviors()) { foreach (var prop in assigned.GetProperties()) { if (prop.propType == BehaviorProperties.PropType.Actor) { string refActorName = (string)prop.data; if (!refActorName.IsNullOrEmpty() && actorNameMap.ContainsKey(refActorName)) { prop.SetData(actorNameMap[refActorName]); } } else if (prop.propType == BehaviorProperties.PropType.ActorGroup) { ActorGroupSpec group = ActorGroupSpec.FromString((string)prop.data); if (group.mode == ActorGroupSpec.Mode.BY_NAME && actorNameMap.ContainsKey(group.tagOrName)) { group = group.WithTagOrName(actorNameMap[group.tagOrName]); prop.SetData(group.ToString()); } } } } } return(instances[0]); }