Exemplo n.º 1
0
    private void OnPickedFromCreationLibrary(ActorableSearchResult searchResult)
    {
        VoosActor actor = assetSearch.RequestActor(searchResult, Vector3.zero, Quaternion.identity, Vector3.one);

        actor.SetPreferOffstage(true);
        CloseAndReturn(true, actor.GetName());
    }
Exemplo n.º 2
0
    void SetActorSpawnPosition(VoosActor actor, Vector3 newPosition, bool setParent = false, string spawnParent = null)
    {
        Vector3    currPosition = actor.GetSpawnPosition();
        Quaternion currRotation = actor.GetSpawnRotation();
        string     currParent   = actor.GetSpawnTransformParent();

        undoStack.PushUndoForActor(
            actor,
            $"Set actor spawn position",
            (undoActor) =>
        {
            undoActor.SetSpawnPosition(newPosition);
            undoActor.SetSpawnRotation(currRotation);
            if (setParent)
            {
                VoosActor setSpawnParent = undoActor.GetEngine().GetActor(spawnParent);
                undoActor.SetSpawnTransformParent(setSpawnParent?.GetName());
            }
        },
            (undoActor) =>
        {
            undoActor.SetSpawnPosition(currPosition);
            undoActor.SetSpawnRotation(currRotation);
            if (setParent)
            {
                VoosActor setSpawnParent = undoActor.GetEngine().GetActor(currParent);
                undoActor.SetSpawnTransformParent(setSpawnParent?.GetName());
            }
        }
            );
    }
Exemplo n.º 3
0
 private bool ShouldActorBeListed(bool isOffstageList, VoosActor actor)
 {
     return(actor.GetName() != "__GameRules__" &&
            (actor.GetIsOffstageEffective() == isOffstageList) &&
            !actor.GetWasClonedByScript() &&
            (actor.GetDisplayName().ToLower().Contains(searchInput.text.ToLower())));
 }
Exemplo n.º 4
0
    public void DrawActorDebugGUI(VoosActor actor)
    {
        using (new Util.GUILayoutFrobArea(actor.transform.position, 100, 500))
        {
            PhotonView photonView = PhotonView.Get(actor);
            if (photonView == null)
            {
                return;
            }
            PlayerBody playerBody = actor.GetPlayerBody();
            //string pbodyInfo = playerBody == null ? "" : $"Claimed? {playerBody.IsClaimed()} ..play mode? {playerBody.GetIsClaimerPlaying()}";
            string color         = photonView.isMine ? "yellow" : "grey";
            string hash          = actor.GetName().Substring(0, 9);
            bool   locked        = actor.IsLockedByAnother() || actor.IsLockWantedLocally();
            string lockingString = locked ? " LOCKED" : "";
            string lastPos       = actor.unrel == null ? "" : actor.unrel.lastPosition.x.ToFourDecimalPlaces();
            GUILayout.Label($@"<color={color}>{actor.GetDisplayName()}
rot: {actor.GetRotation().ToFourDecimalPlaces()}
last unrel: {actor.lastUnreliableUpdateTime}
lastPX: {lastPos}</color>".Trim());
            GUILayout.Toggle(actor.GetReplicantCatchUpMode(), "Catchup?");
            actor.debug = GUILayout.Toggle(actor.debug, "Debug");
            // owner: {photonView.ownerId}{lockingString}
            // {hash} view {actor.reliablePhotonView.viewID}
            // X: {actor.transform.position.x.ToFourDecimalPlaces()}
            // lastRBMPX: {actor.lastRBMovedPos.x.ToFourDecimalPlaces()}
        }
    }
Exemplo n.º 5
0
    public static void SetCurrentParentForActor(
        VoosActor actor, VoosActor selectedActor, UndoStack undoStack, bool autosetParent = false)
    {
        string newParentName       = selectedActor?.GetName();
        string prevParentName      = actor.GetTransformParent();
        string prevSpawnParentName = actor.GetSpawnTransformParent();

        undoStack.PushUndoForActor(
            actor,
            $"Set actor parent",
            (undoActor) =>
        {
            VoosActor newParent = undoActor.GetEngine().GetActor(newParentName);
            string parentName   = VoosActor.IsValidParent(undoActor, newParent) ? newParent?.GetName() : null;
            undoActor.SetTransformParent(parentName);
            if (autosetParent)
            {
                undoActor.SetSpawnTransformParent(parentName);
            }
        },
            (undoActor) =>
        {
            VoosActor prevParent = undoActor.GetEngine().GetActor(prevParentName);
            undoActor.SetTransformParent(VoosActor.IsValidParent(undoActor, prevParent) ? prevParent?.GetName() : null);
            if (autosetParent)
            {
                VoosActor prevSpawnParent = undoActor.GetEngine().GetActor(prevSpawnParentName);
                undoActor.SetSpawnTransformParent(
                    VoosActor.IsValidParent(undoActor, prevSpawnParent) ? prevSpawnParent?.GetName() : null);
            }
        });
    }
Exemplo n.º 6
0
 public ICardManagerModel GetCardManager(VoosActor actor)
 {
     // TODO we should think about, is it possible to return the same instance of
     // this object for the same actor? Then users could use reference equality,
     // hold on to old instances, etc...what if the brain changes? There is
     // implicit state in ABE..
     return(new ManagerImpl(new ActorBehaviorsEditor(actor.GetName(), engine, undo)));
 }
Exemplo n.º 7
0
    public IEnumerator TestHandleMultipleInOneFrame()
    {
        yield return(Setup());

        VoosActor actor = voosEngine.CreateActor(new Vector3(1, 2, 3), Quaternion.identity, newActor => { });

        actor.SetTint(new Color(0.1f, 0.1f, 0.1f));
        Assert.NotNull(actor);
        Assert.AreEqual(1.0, actor.transform.position.x, 1e-4);

        string brainId    = actor.GetBrainName();
        string behaviorId = behaviorSystem.GenerateUniqueId();
        string js         = @"
    export function onMoveRight() {
      const c = getTint();
      c.r += 0.1;
      setTint(c.r, c.g, c.b);
    }
    ";

        behaviorSystem.PutBehavior(behaviorId, new Behaviors.Behavior {
            javascript = js
        });
        PutTestUse(new TestUse
        {
            behaviorUri = IdToEmbeddedBehaviorUri(behaviorId),
            brainId     = brainId
        });

        // We expect x to increment by 2..
        voosEngine.EnqueueMessage(new VoosEngine.ActorMessage {
            name = "MoveRight", targetActor = actor.GetName()
        });
        voosEngine.EnqueueMessage(new VoosEngine.ActorMessage {
            name = "MoveRight", targetActor = actor.GetName()
        });

        // Let it run at least one voos update
        yield return(new WaitForEndOfFrame());

        yield return(new WaitForEndOfFrame());

        Assert.AreEqual(0.3, actor.GetTint().r, 1e-4);
    }
Exemplo n.º 8
0
 public void PlaySoundEffect(SoundEffect sfx, VoosActor actor, Vector3 position)
 {
     PlaySoundEffectLocal(sfx, actor, position);
     unreliableMessageSystem.Send <SfxPlayRequest>(NetworkingEventCodes.SFX, new SfxPlayRequest
     {
         actorName = actor != null ? actor.GetName() : null,
         sfxId     = sfx.id,
         position  = position
     });
 }
    private void BreakLink(bool withUndo = true)
    {
        VoosActor actor = currActor;

        // Save for undo
        string prevParent = actor.GetCloneParent();

        SetActorInternal(null);
        actor.SetCloneParent(null);
        actor.MakeOwnCopyOfBrain();

        if (withUndo)
        {
            // Setup undo item
            string actorName = actor.GetName();
            string newBrain  = actor.GetBrainName();
            undo.Push(new UndoStack.Item
            {
                actionLabel         = $"Break copy-link of {actor.GetDisplayName()}",
                getUnableToDoReason = () => ActorUndoUtil.GetUnableToEditActorReason(voosEngine, actorName),
                doIt = () =>
                {
                    var redoActor = voosEngine.GetActor(actorName);
                    redoActor.SetCloneParent(null);
                    // A bit sloppy: We're relying on the fact that brains are never deleted
                    // (except on load).
                    redoActor.SetBrainName(newBrain);
                    OnBreakLinkChanged(redoActor);
                },
                getUnableToUndoReason = () =>
                {
                    var prevParentActor = voosEngine.GetActor(prevParent);
                    if (prevParentActor == null)
                    {
                        return($"The original copy no longer exists.");
                    }
                    return(null);
                },
                undo = () =>
                {
                    var undoActor       = voosEngine.GetActor(actorName);
                    var prevParentActor = voosEngine.GetActor(prevParent);
                    Debug.Assert(prevParent != null, "BreakLink undo action: prevParent does not exist anymore");
                    undoActor.SetCloneParent(prevParent);
                    undoActor.SetBrainName(prevParentActor.GetBrainName());
                    OnBreakLinkChanged(undoActor);
                }
            });
        }

        SetActorInternal(actor);
    }
Exemplo n.º 10
0
    public static void PushUndoForActor(this UndoStack stack, VoosActor theActor, string label, System.Action <VoosActor> doIt, System.Action <VoosActor> undo)
    {
        // IMPORTANT: Do *NOT* use a reference to the actor! It may be deleted,
        // un-deleted, etc. So use its name, which is stable.
        string actorName = theActor.GetName();

        // Assume the VoosEngine instance is stable.
        VoosEngine engineRef = theActor.GetEngine();

        stack.Push(new UndoStack.Item
        {
            actionLabel           = label,
            getUnableToDoReason   = () => GetUnableToEditActorReason(engineRef, actorName),
            getUnableToUndoReason = () => GetUnableToEditActorReason(engineRef, actorName),
            doIt = () => GetValidActorThen(engineRef, actorName, doIt),
            undo = () => GetValidActorThen(engineRef, actorName, undo)
        });
    }
Exemplo n.º 11
0
    static IEnumerable <string> GetUsedSojoIds(VoosActor actor)
    {
        string pfxId = actor.GetPfxId();
        string sfxId = actor.GetSfxId();

        if (!pfxId.IsNullOrEmpty())
        {
            yield return(pfxId);
        }
        if (!sfxId.IsNullOrEmpty())
        {
            yield return(sfxId);
        }

        var brain = new ActorBehaviorsEditor(actor.GetName(), actor.GetEngine(), null);

        foreach (var beh in brain.GetAssignedBehaviors())
        {
            foreach (var prop in beh.GetProperties())
            {
                if (prop.propType == BehaviorProperties.PropType.Image ||
                    prop.propType == BehaviorProperties.PropType.ParticleEffect ||
                    prop.propType == BehaviorProperties.PropType.Prefab ||
                    prop.propType == BehaviorProperties.PropType.Sound)
                {
                    if (prop.propType == BehaviorProperties.PropType.Prefab)
                    {
                        throw new System.Exception("Sorry, exporting an actor with prefab ref is not supported yet.");
                    }

                    // Yes, we should crash if the string cast fails.
                    string sojoId = (string)prop.data;
                    if (!sojoId.IsNullOrEmpty())
                    {
                        yield return(sojoId);
                    }
                }
            }
        }
    }
Exemplo n.º 12
0
    public void Show(VoosActor actor)
    {
        // Start with player 0 to avoid warnings/etc.
        AssignPlayerToActor(0, actor.GetName());

        string name = actor.GetDisplayName();
        List <PopupButton.Params> buttons = new List <PopupButton.Params>();

        int myPlayerNumber = playerControlsManager.GetMyPlayerNumber();

        int maxPlayerSlotNumber = 4; // Show at least player 1-4, unless there are more players.

        foreach (VirtualPlayerManager.VirtualPlayerInfo player in virtualPlayerManager.EnumerateVirtualPlayers())
        {
            maxPlayerSlotNumber = Mathf.Max(player.slotNumber, maxPlayerSlotNumber);
        }
        for (int i = 1; i <= maxPlayerSlotNumber; i++)
        {
            int thisNumber = i; // For closures below
            buttons.Add(new PopupButton.Params
            {
                getLabel = () => $"Player {thisNumber}" + ((thisNumber == myPlayerNumber) ? " (myself)" : ""),
                onClick  = () => OnClickedPlayerNumber(actor, thisNumber)
            });
        }
        buttons.Add(new PopupButton.Params {
            getLabel = () => "Nobody for now", onClick = () => OnClickedPlayerNumber(actor, 0)
        });
        buttons.Add(new PopupButton.Params {
            getLabel = () => "It's an NPC", onClick = () => OnClickedIsNpc(actor)
        });
        popups.Show(new DynamicPopup.Popup
        {
            getMessage = () => $"Who will control this {name}?",
            buttons    = buttons,
        });
    }
Exemplo n.º 13
0
 public static ActorBehaviorsEditor FromActor(VoosActor actor)
 {
     return(new ActorBehaviorsEditor(actor.GetName(), actor.GetEngine(), null));
 }
Exemplo n.º 14
0
    void PrepareInputForScript(ControllerInput input)
    {
        if (input == null)
        {
            return;
        }

        if (userMain == null)
        {
            // Not ready yet.
            return;
        }

        inputStateForScript = new InputStateForScript();

        if (input.GetKeyDown(PlayerBody.VKEY_JUMP))
        {
            // V1 name:
            voosActor.EnqueueMessage("JumpTriggered");
            // V2 name:
            voosActor.EnqueueMessage("Jump");
        }

        if (input.GetKeyDown(PlayerBody.VKEY_PRIMARY_ACTION))
        {
            // V1 name:
            voosActor.EnqueueMessage("Action1Triggered");
            // V2 name:
            voosActor.EnqueueMessage("PrimaryAction");
        }

        if (input.GetKeyDown(PlayerBody.VKEY_SECONDARY_ACTION))
        {
            // V1 name:
            voosActor.EnqueueMessage("Action2Triggered");
            // V2 name:
            voosActor.EnqueueMessage("SecondaryAction");
        }

        List <string> keysHeld         = new List <string>();
        List <string> keysJustPressed  = new List <string>();
        List <string> keysJustReleased = new List <string>();

        foreach (string key in ScriptableKeyNames)
        {
            bool isDown = input.GetKeyDown(key) && !keysHeldAsReportedToScript.Contains(key);
            bool isUp   = !input.GetKeyHeld(key) && keysHeldAsReportedToScript.Contains(key);
            bool isHeld = input.GetKeyHeld(key);

            if (isHeld)
            {
                keysHeldAsReportedToScript.Add(key);
            }
            else
            {
                keysHeldAsReportedToScript.Remove(key);
            }

            if (isDown)
            {
                voosActor.EnqueueMessage("KeyDown", $"{{\"keyName\": \"{key}\"}}");
                keysJustPressed.Add(key);
            }
            if (isHeld)
            {
                voosActor.EnqueueMessage("KeyHeld", $"{{\"keyName\": \"{key}\"}}");
                keysHeld.Add(key);
            }
            if (isUp)
            {
                voosActor.EnqueueMessage("KeyUp", $"{{\"keyName\": \"{key}\"}}");
                keysJustReleased.Add(key);
            }
        }

        bool mouseIsDown = Input.GetMouseButton(0) && !userMain.CursorOverUI() && !userMain.InEditMode();

        if (mouseIsDown && !reportedMouseDown)
        {
            voosActor.EnqueueMessage("MouseDown");
            reportedMouseDown = true;
            inputStateForScript.mouseButtonJustPressed = true;
        }
        if (reportedMouseDown)
        {
            voosActor.EnqueueMessage("MouseHeld");
            inputStateForScript.mouseButtonIsPressed = true;
        }
        if (!mouseIsDown && reportedMouseDown)
        {
            voosActor.EnqueueMessage("MouseUp");
            reportedMouseDown = false;
            inputStateForScript.mouseButtonJustReleased = true;
        }

        Vector2 mousePosUiCoords;
        Vector3 mousePosRaw = Input.mousePosition;

        mousePosUiCoords = gameUiMain.UnityScreenPointToGameUiPoint(mousePosRaw);

        inputStateForScript.mouseX           = mousePosUiCoords.x;
        inputStateForScript.mouseY           = mousePosUiCoords.y;
        inputStateForScript.keysHeld         = keysHeld.ToArray();
        inputStateForScript.keysJustPressed  = keysJustPressed.ToArray();
        inputStateForScript.keysJustReleased = keysJustReleased.ToArray();

        Ray mouseRay = userMain.GetCamera().ScreenPointToRay(mousePosRaw);

        inputStateForScript.mouseRayOrigin    = mouseRay.origin;
        inputStateForScript.mouseRayDirection = mouseRay.direction;

        if (inputStateForScript.mouseButtonJustPressed)
        {
            RaycastHit hit;
            if (Physics.Raycast(mouseRay.origin, mouseRay.direction, out hit, 1000, VoosActor.LayerMaskValue, QueryTriggerInteraction.Collide))
            {
                VoosActor clickedActor = hit.collider.GetComponentInParent <VoosActor>();
                if (clickedActor != null)
                {
                    clickedActor.GetEngine().EnqueueMessage(new VoosEngine.ActorMessage
                    {
                        name        = "ActorClicked",
                        targetActor = clickedActor.GetName(),
                        argsJson    = "{}"
                    });
                }
            }
        }

        inputStateForScript.mouseWheelRaw = Input.GetAxis("Mouse ScrollWheel");
        inputStateForScript.mouseWheel    = inputStateForScript.mouseWheelRaw * MOUSEWHEEL_FACTOR;
    }
Exemplo n.º 15
0
    void EndTextEditing()
    {
        if (IsEditing())
        {
            // Erm, do this first, cuz deactivating stuff could cause this to be
            // called again recursively. Like deactivating the inputFieldObject!
            lastActorEdited  = actorBeingEdited;
            actorBeingEdited = null;

            inputFieldObject.SetActive(false);
            cooldownRoutine = StartCoroutine(CooldownRoutine());
            if (inputField.text == EMPTY_TEXT)
            {
                engine.DestroyActor(lastActorEdited);
            }
            else
            {
                editMain.SetTargetActor(lastActorEdited);
                // editMain.SetFocusedTargetActor(lastActorEdited);

                string undoText = actorTextBeforeEditing;

                if (actorWasJustCreated)
                {
                    var engine    = lastActorEdited.GetEngine();
                    var actorData = engine.SaveActor(lastActorEdited);
                    undoStack.PushUndoForCreatingActor(lastActorEdited, $"Create text panel");
                }
                else
                {
                    string currText = lastActorEdited.GetCommentText();
                    if (ActorUndoUtil.GetUnableToEditActorReason(lastActorEdited.GetEngine(), lastActorEdited.GetName()) == null)
                    {
                        undoStack.PushUndoForActor(
                            lastActorEdited,
                            $"Edit text panel",
                            redoActor =>
                        {
                            redoActor.SetCommentText(currText);
                            redoActor.ApplyPropertiesToClones();
                        },
                            undoActor =>
                        {
                            undoActor.SetCommentText(undoText);
                            undoActor.ApplyPropertiesToClones();
                        });
                    }
                }
            }
        }
    }
Exemplo n.º 16
0
 private void SetPlayerNumberOnPlayerControlsPanel(VoosActor actor, Behaviors.BehaviorUse use, int playerNumber)
 {
     use = use.DeepClone();
     use.SetPropertyValue(PLAYER_NUMBER_PROP_NAME, playerNumber);
     Behaviors.Brain brain = actor.GetBehaviorSystem().GetBrain(actor.GetBrainName());
     if (brain == null)
     {
         Debug.LogErrorFormat("Could not set player# on actor {0} ({1}). No brain.", actor.GetName(), actor.GetDisplayName());
         return;
     }
     brain.SetUse(use);
     actor.GetBehaviorSystem().PutBrain(actor.GetBrainName(), brain);
 }
Exemplo n.º 17
0
 private void DeletePlayerControlsPanel(VoosActor actor)
 {
     Debug.Assert(actor.IsLocallyOwned(), "Actor should be locally owned");
     Behaviors.BehaviorUse playerControlsPanel = TryGetPlayerControlsPanel(actor);
     if (playerControlsPanel == null)
     {
         return;
     }
     Behaviors.Brain brain = actor.GetBehaviorSystem().GetBrain(actor.GetBrainName());
     if (brain == null)
     {
         Debug.LogErrorFormat("Could not set player# on actor {0} ({1}). No brain.", actor.GetName(), actor.GetDisplayName());
         return;
     }
     // PLAYER_CONTROLS_PANEL_HAS_NO_DECKS_ASSUMPTION
     // WARNING: this is a naive delete that doesn't recursively look for behavior uses mentioned
     // in any decks used by the Player Controls panel, so if in the future we do add decks to it,
     // we need to update this logic to remove the panel properly.
     brain.DeleteUse(playerControlsPanel.id);
     actor.GetBehaviorSystem().PutBrain(actor.GetBrainName(), brain);
 }
Exemplo n.º 18
0
        // Ideally this wouldn't live here, but for now, whatever.
        internal void CallService(string serviceName, string argsJson, System.IntPtr reportResultPtr)
        {
            Native.ReportResultFunction reportResult = null;
            if (CacheReportResult)
            {
                if (cachedReportResult == null)
                {
                    cachedReportResult   = Marshal.GetDelegateForFunctionPointer <Native.ReportResultFunction>(reportResultPtr);
                    firstReportResultPtr = reportResultPtr;
                }

                reportResult = cachedReportResult;
                Debug.Assert(firstReportResultPtr == reportResultPtr, $"Different reportResultPtr was given!");
            }
            else
            {
                reportResult = Marshal.GetDelegateForFunctionPointer <Native.ReportResultFunction>(reportResultPtr);
            }

            try
            {
                switch (serviceName)
                {
                case "BeginProfileSample":
                {
                    InGameProfiler.BeginSection(argsJson);
                    reportResult("0");
                    break;
                }

                case "EndProfileSample":
                {
                    InGameProfiler.EndSection();
                    reportResult("0");
                    break;
                }

                case "OverlapSphere":
                    using (Util.Profile(serviceName))
                    {
                        var args    = JsonUtility.FromJson <OverlapSphereArgs>(argsJson);
                        int numHits = Physics.OverlapSphereNonAlloc(args.center, args.radius, SharedColliderBuffer, VoosActor.LayerMaskValue, QueryTriggerInteraction.Collide);
                        if (numHits == SharedColliderBuffer.Length)
                        {
                            Util.LogError($"The OverlapSphere call exceeded the maximum number of allowed results ({SharedColliderBuffer.Length}). You are probably not getting what you want. Please try to adjust the parameters so you get less hits, like reducing the radius.");
                        }
                        using (Util.Profile("report actors"))
                        {
                            var jsoner = SharedStringBuilder;
                            jsoner.Clear();
                            jsoner.Append("[");
                            bool gotOneActor = false;
                            for (int i = 0; i < numHits; i++)
                            {
                                Collider  obj   = SharedColliderBuffer[i];
                                VoosActor actor = obj.GetComponentInParent <VoosActor>();
                                if (actor == null)
                                {
                                    continue;
                                }
                                if (!args.tag.IsNullOrEmpty())
                                {
                                    if (!actor.HasTag(args.tag))
                                    {
                                        continue;
                                    }
                                }

                                if (gotOneActor)
                                {
                                    jsoner.Append(",");
                                }
                                jsoner.Append("\"");
                                jsoner.Append(actor.GetName());
                                jsoner.Append("\"");
                                gotOneActor = true;
                            }
                            jsoner.Append("]");
                            reportResult(jsoner.ToString());
                        }
                        break;
                    }

                case "CheckBox":
                    using (Util.Profile(serviceName))
                    {
                        var  args        = JsonUtility.FromJson <CheckBoxArgs>(argsJson);
                        bool hitAnything = Physics.CheckBox(args.box.center, args.box.dimensions * 0.5f, args.box.rotation,
                                                            -1,                            // We're probably looking for clearance, so return true if the box hits actors OR just static terrain.
                                                            QueryTriggerInteraction.Ignore // Ignore triggers for checks. We are probably looking for clearance, in which case triggers don't matter.
                                                            );
                        reportResult(hitAnything ? "true" : "false");
                        break;
                    }

                case "Cast":
                    using (Util.Profile(serviceName))
                    {
                        PhysicsCastRequest req = JsonUtility.FromJson <PhysicsCastRequest>(argsJson);

                        int layerMask = (req.includeActors ? VoosActor.LayerMaskValue : 0) |
                                        (req.includeTerrain ? LayerMask.GetMask("Default") : 0);
                        int numHits = req.radius < 0.01 ?
                                      Physics.RaycastNonAlloc(req.origin, req.dir, SharedRaycastHitBuffer, req.maxDist, layerMask, QueryTriggerInteraction.Collide) :
                                      Physics.SphereCastNonAlloc(req.origin, req.radius, req.dir, SharedRaycastHitBuffer, req.maxDist, layerMask, QueryTriggerInteraction.Collide);

                        // These variables things are somewhat redundant, but for performance we keep all three and
                        // only use the appropriate ones per req.castMode, to avoid unnecessary allocations.
                        // List of results. Only allocate if we have to.
                        List <PhysicsCastHit> results = null;
                        // Did we have any hit?
                        bool anyHit = false;
                        // The closest hit we got. Only valid if anyHit == true.
                        PhysicsCastHit closestHit = new PhysicsCastHit();

                        if (req.mode == CastMode.ALL_SORTED || req.mode == CastMode.ALL_UNSORTED)
                        {
                            // We will need to return a list, so allocate it.
                            results = new List <PhysicsCastHit>();
                        }

                        for (int i = 0; i < numHits; i++)
                        {
                            RaycastHit     hit = SharedRaycastHitBuffer[i];
                            PhysicsCastHit thisHit;
                            if (hit.collider != null && hit.collider.gameObject != null &&
                                hit.collider.gameObject.GetComponent <IgnoreRaycastFromScript>() != null)
                            {
                                continue;
                            }
                            if (req.includeActors && IsScriptReadyActor(hit.collider) && GetActorName(hit.collider) != req.excludeActor)
                            {
                                // Hit an actor.
                                // (PhysicsCastHit is a struct, not allocating on heap)
                                thisHit = new PhysicsCastHit
                                {
                                    actor    = GetActorName(hit.collider),
                                    distance = hit.distance,
                                    point    = hit.point
                                };
                            }
                            else if (req.includeTerrain && hit.collider.tag == "Ground")
                            {
                                // Hit terrain.
                                // (PhysicsCastHit is a struct, not allocating on heap)
                                thisHit = new PhysicsCastHit
                                {
                                    actor    = null,
                                    distance = hit.distance,
                                    point    = hit.point
                                };
                            }
                            else
                            {
                                continue;
                            }
                            closestHit = (!anyHit || thisHit.distance < closestHit.distance) ? thisHit : closestHit;
                            anyHit     = true;
                            results?.Add(thisHit);
                            if (req.mode == CastMode.BOOLEAN)
                            {
                                // If we're just returning true/false, that's all we need.
                                break;
                            }
                        }

                        // Sort results by distance, if requested.
                        if (req.mode == CastMode.ALL_SORTED)
                        {
                            results.Sort((a, b) => a.distance.CompareTo(b.distance));
                        }

                        // Report results as requested.
                        if (req.mode == CastMode.ALL_SORTED || req.mode == CastMode.ALL_UNSORTED)
                        {
                            PhysicsCastResult result = new PhysicsCastResult {
                                hits = results.ToArray()
                            };
                            reportResult(JsonUtility.ToJson(result));
                        }
                        else if (req.mode == CastMode.CLOSEST)
                        {
                            reportResult(anyHit ? JsonUtility.ToJson(closestHit) : "null");
                        }
                        else
                        {
                            reportResult(anyHit ? "true" : "false");
                        }
                        break;
                    }

                case "GetPlayerActors":
                    using (Util.Profile(serviceName))
                    {
                        var jsoner = SharedStringBuilder;
                        jsoner.Clear();
                        jsoner.Append("[");
                        bool gotOneActor = false;

                        foreach (VoosActor actor in engine.EnumerateActors())
                        {
                            if (actor.GetIsPlayerControllable())
                            {
                                if (gotOneActor)
                                {
                                    jsoner.Append(",");
                                }
                                jsoner.Append("\"");
                                jsoner.Append(actor.GetName());
                                jsoner.Append("\"");
                                gotOneActor = true;
                            }
                        }
                        jsoner.Append("]");
                        reportResult(jsoner.ToString());
                        break;
                    }

                case "SetTerrainCell":
                {
                    var args = JsonUtility.FromJson <TerrainManager.SetCellRpcJsonable>(argsJson);
                    terrainSystem.SetCellValue(args.cell, args.value);
                    reportResult("true");
                    break;
                }

                case "GetTerrainCell":
                {
                    Vector3 coords = JsonUtility.FromJson <Vector3>(argsJson);
                    TerrainManager.CellValue cellValue = terrainSystem.GetCellValue(
                        new TerrainManager.Cell((int)coords.x, (int)coords.y, (int)coords.z));
                    GetTerrainCellResult result = new GetTerrainCellResult
                    {
                        shape = (int)cellValue.blockType,
                        dir   = (int)cellValue.direction,
                        style = (int)cellValue.style
                    };
                    reportResult(JsonUtility.ToJson(result));
                    break;
                }

                case "IsMultiplayer":
                {
                    reportResult(GameBuilderApplication.CurrentGameOptions.playOptions.isMultiplayer ? "true" : "false");
                    break;
                }

                case "TransferPlayerControl":
                {
                    VoosEngine.TransferPlayerControlRequest request =
                        JsonUtility.FromJson <VoosEngine.TransferPlayerControlRequest>(argsJson);
                    // Engine will handle this asynchronously because the actor might not be immediately
                    // available (maybe it was a clone that was just created, for instance).
                    GetEngine().RequestTransferPlayerControl(request);
                    reportResult("true");
                    break;
                }

                case "GetPlayerControlledActor":
                {
                    VoosActor actor = GetUserMain().GetPlayerActor();
                    reportResult(actor == null ? "null" : "\"" + actor.GetName() + "\"");
                    break;
                }

                case "IsMasterClient":
                {
                    reportResult(PhotonNetwork.isMasterClient ? "true" : "false");
                    break;
                }

                case "GetPlayersInfo":
                {
                    Dictionary <int, string> nicknames = new Dictionary <int, string>();
                    int i;
                    for (i = 0; i < PhotonNetwork.playerList.Length; i++)
                    {
                        int    id   = PhotonNetwork.playerList[i].ID;
                        string nick = PhotonNetwork.playerList[i].NickName;
                        nicknames[id] = nick;
                    }

                    VirtualPlayersResult result = new VirtualPlayersResult();
                    result.allPlayers = new VirtualPlayerResultEntry[virtualPlayerManager.GetVirtualPlayerCount()];

                    i = 0;
                    foreach (VirtualPlayerManager.VirtualPlayerInfo virtualPlayer in virtualPlayerManager.EnumerateVirtualPlayers())
                    {
                        Debug.Assert(i < result.allPlayers.Length);
                        result.allPlayers[i].id         = virtualPlayer.virtualId;
                        result.allPlayers[i].slotNumber = virtualPlayer.slotNumber;
                        result.allPlayers[i].nickName   = virtualPlayer.nickName;
                        ++i;
                    }
                    Debug.Assert(i == result.allPlayers.Length);

                    result.localPlayerId = playerControlsManager.GetVirtualPlayerId();
                    reportResult(JsonUtility.ToJson(result));
                    break;
                }

                case "RequestUi":
                {
                    using (Util.Profile("RequestUi"))
                    {
                        GameUiMain.UiCommandList list = JsonUtility.FromJson <GameUiMain.UiCommandList>(argsJson);
                        gameUiMain.SetUiCommands(list);
                        reportResult("true");
                    }
                    break;
                }

                case "GetActorColorField":
                {
                    GetActorFieldArgs args = JsonUtility.FromJson <GetActorFieldArgs>(argsJson);
                    reportResult(JsonUtility.ToJson(engine.GetActorColor(args.actorId, args.fieldId)));
                    break;
                }

                case "SetActorColorField":
                {
                    SetActorColorFieldArgs args = JsonUtility.FromJson <SetActorColorFieldArgs>(argsJson);
                    engine.SetActorColor(args.actorId, args.fieldId, args.newValue);
                    reportResult("true");
                    break;
                }

                case "CloneActor":
                    using (Util.Profile(serviceName))
                    {
                        VoosEngine.CloneActorRequest  args     = JsonUtility.FromJson <VoosEngine.CloneActorRequest>(argsJson);
                        VoosEngine.CloneActorResponse response = GetEngine().CloneActorForScript(args);
                        reportResult(JsonUtility.ToJson(response));
                        break;
                    }

                case "InstantiatePrefab":
                    using (Util.Profile(serviceName))
                    {
                        VoosEngine.InstantiatePrefab.Request  args     = JsonUtility.FromJson <VoosEngine.InstantiatePrefab.Request>(argsJson);
                        VoosEngine.InstantiatePrefab.Response response = GetEngine().InstantiatePrefabForScript(args);
                        reportResult(JsonUtility.ToJson(response));
                        break;
                    }

                case "DestroyActors":
                    using (Util.Profile(serviceName))
                    {
                        VoosEngine.DestroyActorsRequest args = JsonUtility.FromJson <VoosEngine.DestroyActorsRequest>(argsJson);
                        GetEngine().DestroyActorsForScript(args);
                        reportResult("true");
                        break;
                    }

                case "PlaySound":
                    using (Util.Profile(serviceName))
                    {
                        PlaySoundRequest args = JsonUtility.FromJson <PlaySoundRequest>(argsJson);
                        SoundEffect      sfx  = soundEffectSystem.GetSoundEffect(args.soundId);
                        if (sfx != null)
                        {
                            if (string.IsNullOrEmpty(args.actorName))
                            {
                                soundEffectSystem.PlaySoundEffect(sfx, null, args.position);
                            }
                            else
                            {
                                VoosActor actor = engine.GetActor(args.actorName);
                                if (actor == null)
                                {
                                    Debug.LogError("Could not play sound on actor. Actor not found: " + args.actorName);
                                    reportResult("false");
                                }
                                soundEffectSystem.PlaySoundEffect(sfx, actor, Vector3.zero);
                            }
                            reportResult("true");
                        }
                        else
                        {
                            Debug.LogWarning("No SFX with ID: " + args.soundId);
                            reportResult("false");
                        }
                        break;
                    }

                case "SpawnParticleEffect":
                    using (Util.Profile(serviceName))
                    {
                        ParticleEffectRequest args = JsonUtility.FromJson <ParticleEffectRequest>(argsJson);
                        ParticleEffect        pfx  = particleEffectSystem.GetParticleEffect(args.pfxId);
                        if (pfx != null)
                        {
                            particleEffectSystem.SpawnParticleEffect(
                                pfx, args.position, args.rotation * Mathf.Rad2Deg, args.scale);
                            reportResult("true");
                        }
                        else
                        {
                            Debug.LogWarning("No particle effect with ID: " + args.pfxId);
                            reportResult("false");
                        }
                        break;
                    }

                case "PlayOneShotAnimation":
                {
                    OneShotAnimationRequest req = JsonUtility.FromJson <OneShotAnimationRequest>(argsJson);
                    VoosActor actor             = engine.GetActorByTempId(req.actorTempId);
                    if (actor != null)
                    {
                        actor.PlayOneShotAnimation(req.animationName);
                    }
                    else
                    {
                        Util.LogError($"PlayOneShotAnimation: Could not find actor for temp ID {req.actorTempId}. Ignoring.");
                    }
                    reportResult("true");
                    break;
                }

                case "ProjectPoint":
                {
                    Camera  cam         = GetUserMain().GetCamera();
                    Vector3 point       = JsonUtility.FromJson <Vector3>(argsJson);
                    Vector3 screenPoint = cam.WorldToScreenPoint(point);
                    if (screenPoint.z > 0)
                    {
                        Vector2 gameUiPoint = gameUiMain.UnityScreenPointToGameUiPoint(screenPoint);
                        reportResult(JsonUtility.ToJson(gameUiPoint));
                    }
                    else
                    {
                        reportResult("null");
                    }
                    break;
                }

                case "ProjectSphere":
                {
                    Camera    cam          = GetUserMain().GetCamera();
                    SphereArg inSphere     = JsonUtility.FromJson <SphereArg>(argsJson);
                    Vector3   screenCenter = cam.WorldToScreenPoint(inSphere.center);
                    if (screenCenter.z > 0)
                    {
                        Vector3   centerGameUi     = gameUiMain.UnityScreenPointToGameUiPoint(screenCenter);
                        Vector3   rightPoint       = cam.WorldToScreenPoint(inSphere.center + cam.transform.right * inSphere.radius);
                        Vector3   rightPointGameUi = gameUiMain.UnityScreenPointToGameUiPoint(rightPoint);
                        SphereArg outSphere        = new SphereArg
                        {
                            center = centerGameUi,
                            radius = Mathf.Abs(rightPointGameUi.x - centerGameUi.x)
                        };
                        reportResult(JsonUtility.ToJson(outSphere));
                    }
                    else
                    {
                        reportResult("null");
                    }
                    break;
                }

                case "GetActorScreenRect":
                {
                    string    actorName   = JsonUtility.FromJson <GetActorScreenRectRequest>(argsJson).actor;
                    VoosActor actor       = engine.GetActor(actorName);
                    Bounds    worldBounds = new Bounds(actor.GetWorldRenderBoundsCenter(), actor.GetWorldRenderBoundsSize());

                    // Depending on the orientation, any of the 8 corners of the world-space bounding box
                    // can contribute to the screen-space bounding box, so we have to go through them all.
                    Bounds screenBounds = new Bounds();
                    bool   success      = true;
                    for (int i = 0; i < 8; i++)
                    {
                        Vector3 worldPoint = new Vector3(
                            (i & 1) > 0 ? worldBounds.min.x : worldBounds.max.x,
                            (i & 2) > 0 ? worldBounds.min.y : worldBounds.max.y,
                            (i & 4) > 0 ? worldBounds.min.z : worldBounds.max.z);
                        Vector3 screenPoint = GetUserMain().GetCamera().WorldToScreenPoint(worldPoint);
                        if (screenPoint.z < 0)
                        {
                            // Off-screen (behind camera).
                            success = false;
                            break;
                        }
                        Vector2 gameUiPoint = gameUiMain.UnityScreenPointToGameUiPoint(screenPoint);
                        if (i == 0)
                        {
                            // Note: due to the Bounds() constructor assuming Vector3.zero as the center
                            // (known Unity bug), we have to reinitialize it here:
                            screenBounds = new Bounds(gameUiPoint, Vector3.zero);
                        }
                        else
                        {
                            screenBounds.Encapsulate(gameUiPoint);
                        }
                    }
                    reportResult(success ? JsonUtility.ToJson(new GetActorScreenRectResponse
                        {
                            x = screenBounds.min.x,
                            y = screenBounds.min.y,
                            w = screenBounds.size.x,
                            h = screenBounds.size.y
                        }) : "null");
                    break;
                }

                case "GetCameraInfo":
                {
                    Transform  cameraTransform = GetUserMain().GetCamera().transform;
                    CameraInfo info            = new CameraInfo
                    {
                        pos = cameraTransform.position,
                        rot = cameraTransform.rotation
                    };
                    reportResult(JsonUtility.ToJson(info));
                    break;
                }

                case "ReportBehaviorException":
                {
                    Util.LogError($"ReportBehaviorException {argsJson}");
                    VoosEngine.BehaviorLogItem e = JsonUtility.FromJson <VoosEngine.BehaviorLogItem>(argsJson);
                    engine.HandleBehaviorException(e);
                    reportResult("true");
                    break;
                }

                case "LogBehaviorMessage":
                {
                    Util.Log($"LogBehaviorMessage {argsJson}");
                    VoosEngine.BehaviorLogItem msg = JsonUtility.FromJson <VoosEngine.BehaviorLogItem>(argsJson);
                    engine.HandleBehaviorLogMessage(msg);
                    reportResult("true");
                    break;
                }

                case "GetCameraActor":
                {
                    string cameraActorName = GetUserMain().GetCameraActor()?.GetName();
                    reportResult(cameraActorName == null ? "null" : ("\"" + cameraActorName + "\""));
                    break;
                }

                case "RequestTempCameraOffset":
                {
                    TempCameraOffsetRequest request = JsonUtility.FromJson <TempCameraOffsetRequest>(argsJson);
                    if (request.actor == GetUserMain().GetPlayerActor()?.GetName())
                    {
                        GetUserMain().GetNavigationControls().RequestTemporaryCameraOffset(request.offset);
                    }
                    reportResult("true");
                    break;
                }

                case "GetScreenInfo":
                {
                    reportResult(JsonUtility.ToJson(gameUiMain.GetScreenInfoForScript()));
                    break;
                }

                case "SetSkyType":
                {
                    JsonWrapper <string>     request = JsonUtility.FromJson <JsonWrapper <string> >(argsJson);
                    GameBuilderStage.SkyType skyType;
                    if (Util.TryParseEnum(request.value ?? "", out skyType, true))
                    {
                        gbStage.SetSkyType(skyType);
                        reportResult("true");
                    }
                    else
                    {
                        Debug.LogError("Invalid sky type requested: " + request.value);
                        reportResult("false");
                    }
                    break;
                }

                case "GetSkyType":
                {
                    reportResult(JsonUtility.ToJson(JsonWrapper <string> .Wrap(gbStage.GetSkyType().ToString())));
                    break;
                }

                case "SetSkyColor":
                {
                    JsonWrapper <Color> request = JsonUtility.FromJson <JsonWrapper <Color> >(argsJson);
                    gbStage.SetSkyColor(request.value);
                    reportResult("true");
                    break;
                }

                case "GetSkyColor":
                {
                    reportResult(JsonUtility.ToJson(JsonWrapper <Color> .Wrap(gbStage.GetSkyColor())));
                    break;
                }

                case "SetSceneLighting":
                {
                    JsonWrapper <string> request = JsonUtility.FromJson <JsonWrapper <string> >(argsJson);
                    GameBuilderStage.SceneLightingMode sceneLightingMode;
                    if (Util.TryParseEnum <GameBuilderStage.SceneLightingMode>(request.value, out sceneLightingMode, ignoreCase: true))
                    {
                        gbStage.SetSceneLightingMode(sceneLightingMode);
                        reportResult("true");
                    }
                    else
                    {
                        Debug.LogError("Invalid scene lighting mode: " + request.value);
                        reportResult("false");
                    }
                    break;
                }

                case "GetSceneLighting":
                {
                    reportResult(JsonUtility.ToJson(JsonWrapper <string> .Wrap(gbStage.GetSceneLightingMode().ToString().ToUpperInvariant())));
                    break;
                }

                default:
                    Util.LogError($"VOOS script tried to call unknown service {serviceName}.");
                    break;
                }
            }
            catch (System.Exception e)
            {
                // We cannot let exceptions escape. It will tend to crash the process.
                Util.LogError($"Exception during CallService({serviceName}):\n{e}");
                reportResult("false");
            }
        }
Exemplo n.º 19
0
 void OnClickedIsNpc(VoosActor actor)
 {
     AssignPlayerToActor(ASSIGN_ACTOR_AS_NPC, actor.GetName());
 }
Exemplo n.º 20
0
 void OnClickedPlayerNumber(VoosActor actor, int playerNumber)
 {
     AssignPlayerToActor(playerNumber, actor.GetName());
 }
Exemplo n.º 21
0
    private void SetSpawnParent()
    {
        VoosActor actor = editMain.GetSingleTargetActor();

        SelectActor((selectedActor) =>
        {
            string newParentName  = selectedActor?.GetName();
            string prevParentName = actor.GetSpawnTransformParent();
            undoStack.PushUndoForActor(
                actor,
                $"Set actor parent on reset",
                (undoActor) =>
            {
                VoosActor newParent = undoActor.GetEngine().GetActor(newParentName);
                undoActor.SetSpawnTransformParent(VoosActor.IsValidParent(undoActor, newParent) ? newParent?.GetName() : null);
            },
                (undoActor) =>
            {
                VoosActor prevParent = undoActor.GetEngine().GetActor(prevParentName);
                undoActor.SetSpawnTransformParent(VoosActor.IsValidParent(undoActor, prevParent) ? prevParent?.GetName() : null);
            }
                );
        });
    }