public VoosActor RequestActor(ActorableSearchResult _requestedResult, Vector3 rootSpawnPosition, Quaternion additionalRotation, Vector3 spawnScale) { Quaternion spawnRotation = additionalRotation * _requestedResult.preferredRotation; // NOTE: We could also have additionalScale here, in which case we'd want to multiply it with preferredLocalScale and apply it. // If, for example, the new tool gave you the ability to scale (like it lets you rotate now). if (_requestedResult.renderableReference.assetType == AssetType.Actor || _requestedResult.renderableReference.assetType == AssetType.AssetPack) { return(_requestedResult.actorPrefab.Instantiate(voosEngine, behaviorSystem, rootSpawnPosition, spawnRotation, setupActor => { // IMPORTANT! The setupActor could be a child of the hierarchy! So the // position is not necessarily rootSpawnPosition. setupActor.SetSpawnPosition(setupActor.transform.position); setupActor.SetSpawnRotation(setupActor.transform.rotation); // Post-setup for effect results string pfxId = _requestedResult.pfxId; if (pfxId != null) { setupActor.SetPfxId(pfxId); ParticleEffect pfx = particleEffectSystem.GetParticleEffect(pfxId); if (pfx != null) { setupActor.SetDisplayName(pfx.name); } } string sfxId = _requestedResult.sfxId; if (sfxId != null) { setupActor.SetSfxId(sfxId); SoundEffect sfx = soundEffectSystem.GetSoundEffect(sfxId); if (sfx != null) { setupActor.SetDisplayName(sfx.name); } } })); } else { return(voosEngine.CreateActor(rootSpawnPosition, spawnRotation, actor => { if (_requestedResult.forceConcave) { actor.SetUseConcaveCollider(true); } actor.SetLocalScale(spawnScale); actor.SetDisplayName(_requestedResult.name); actor.SetRenderableUri(_requestedResult.renderableReference.uri); })); } }
VoosActor CreatePanel(Vector3 position, Quaternion rotation) { return(engine.CreateActor(position, rotation, actor => { actor.SetPreferOffstage(false); actor.SetDisplayName("Text"); actor.SetLocalScale(Vector3.one * DEFAULT_TEXT_SCALE); actor.SetRenderableUri(IsBillboard() ? billboardRenderableUri : dimensionalRenderableUri); actor.SetIsSolid(false); actor.SetTint(new Color32(1, 1, 1, 190)); })); }
public IEnumerator TestBasic() { yield return(Setup()); VoosActor actor = voosEngine.CreateActor(new Vector3(1, 2, 3), Quaternion.identity, _ => { }); Assert.NotNull(actor); Assert.AreEqual(1.0, actor.GetTint().r, 1e-4); string brainId = actor.GetBrainName(); string behaviorId = NewGUID(); string js = @" export function onTick(api) { setTint(0.12, 0.34, 0.56); } "; behaviorSystem.PutBehavior(behaviorId, new Behavior { javascript = js }); var use = new BehaviorUse { id = NewGUID(), behaviorUri = IdToEmbeddedBehaviorUri(behaviorId) }; var brain = new Brain { behaviorUses = new BehaviorUse[] { use } }; behaviorSystem.PutBrain(brainId, brain); // Let it run at least one voos update yield return(new WaitForEndOfFrame()); yield return(new WaitForEndOfFrame()); Assert.AreEqual(0.12, actor.GetTint().r, 1e-4); }
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]); }