private void FixedUpdate()
    {
        if (sceneLoaded)
        {
            if (npcIsMoving == false)
            {
                // set npc current and next grid position - to take into account the npc might be animating
                npcCurrentGridPosition = GetGridPosition(transform.position);
                npcNextGridPosition    = npcCurrentGridPosition;

                if (npcPath.npcMovementStepStack.Count > 0)
                {
                    NPCMovementStep npcMovementStep = npcPath.npcMovementStepStack.Peek();

                    npcCurrentScene = npcMovementStep.sceneName;

                    // If NPC is about the move to a new scene reset position to starting point in new scene and update the step times
                    if (npcCurrentScene != npcPreviousMovementStepScene)
                    {
                        npcCurrentGridPosition       = (Vector3Int)npcMovementStep.gridCoordinate;
                        npcNextGridPosition          = npcCurrentGridPosition;
                        transform.position           = GetWorldPosition(npcCurrentGridPosition);
                        npcPreviousMovementStepScene = npcCurrentScene;
                        npcPath.UpdateTimesOnPath();
                    }


                    // If NPC is in current scene then set NPC to active to make visible, pop the movement step off the stack and then call method to move NPC
                    if (npcCurrentScene.ToString() == SceneManager.GetActiveScene().name)
                    {
                        SetNPCActiveInScene();

                        npcMovementStep = npcPath.npcMovementStepStack.Pop();

                        npcNextGridPosition = (Vector3Int)npcMovementStep.gridCoordinate;

                        TimeSpan npcMovementStepTime = new TimeSpan(npcMovementStep.hour, npcMovementStep.minute, npcMovementStep.second);

                        MoveToGridPosition(npcNextGridPosition, npcMovementStepTime, TimeManager.Instance.GetGameTime());
                    }

                    // else if NPC is not in current scene then set NPC to inactive to make invisible
                    // - once the movement step time is less than game time (in the past) then pop movement step off the stack and set NPC position to movement step position
                    else
                    {
                        SetNPCInactiveInScene();

                        npcCurrentGridPosition = (Vector3Int)npcMovementStep.gridCoordinate;
                        npcNextGridPosition    = npcCurrentGridPosition;
                        transform.position     = GetWorldPosition(npcCurrentGridPosition);

                        TimeSpan npcMovementStepTime = new TimeSpan(npcMovementStep.hour, npcMovementStep.minute, npcMovementStep.second);

                        TimeSpan gameTime = TimeManager.Instance.GetGameTime();

                        if (npcMovementStepTime < gameTime)
                        {
                            npcMovementStep = npcPath.npcMovementStepStack.Pop();

                            npcCurrentGridPosition = (Vector3Int)npcMovementStep.gridCoordinate;
                            npcNextGridPosition    = npcCurrentGridPosition;
                            transform.position     = GetWorldPosition(npcCurrentGridPosition);
                        }
                    }
                }
                // else if no more NPC movement steps
                else
                {
                    ResetMoveAnimation();

                    SetNPCFacingDirection();

                    SetNPCEventAnimation();
                }
            }
        }
    }
示例#2
0
    // FixedUpdate will move our NPC following the NPCMovementSteps in the NPCMovementStepStack. It processes each step in turn, waiting until it's done to start on the next step.
    // It will move the NPC one step at a time via a coroutine that moves the NPC from the current gridPosition to the next one. Once that's done, this
    // fixed update method will initiate the next step
    private void FixedUpdate()
    {
        // Make sure the scene is loaded before doing anything
        if (sceneLoaded)
        {
            // Make sure the NPC isn't already moving before doing anything. Every fixed update this will be checked, and if npcIsMoving=true, it is currently moving one step.
            // Eventually, when it's false again this will be enabled and we can move the next step
            if (npcIsMoving == false)
            {
                // Set the NPC current and next grid position - to take into account the NPC might be animating
                // The current position is where the NPC currently is, and initially we will set the next grid position to the current one
                npcCurrentGridPosition = GetGridPosition(transform.position);
                npcNextGridPosition    = npcCurrentGridPosition;

                // Only run if there are still NPCMovementSteps in the NPCMovementStepStack
                if (npcPath.npcMovementStepStack.Count > 0)
                {
                    // Populate the npcMovementStep with the npcMovementStep on the top of the stack (just peek at it, don't remove yet)
                    NPCMovementStep npcMovementStep = npcPath.npcMovementStepStack.Peek();

                    // Set the current NPC scene to the first movement step in this stack
                    npcCurrentScene = npcMovementStep.sceneName;

                    // If the NPC is about to move to a new scene, reset their position to the starting point in the new scene, and re-update the step times for the
                    // next path elements in the new scene
                    if (npcCurrentScene != npcPreviousMovementStepScene)
                    {
                        // If the current and next scenes are different, we are about to change scenes. Update the NPCs current grid position to the next movement steps grid coordinate
                        // (in the next scene), set the nextGridPosition to the current one, update the NPCs transform to immediately teleport them to the new scenes entrance point,
                        // update the NPCs current scene, and re-update the remaining times on the path (things probably got messed up between scenes because the grid coordinates changed substantially)
                        npcCurrentGridPosition       = (Vector3Int)npcMovementStep.gridCoordinate;
                        npcNextGridPosition          = npcCurrentGridPosition;
                        transform.position           = GetWorldPosition(npcCurrentGridPosition);
                        npcPreviousMovementStepScene = npcCurrentScene;
                        npcPath.UpdateTimesOnPath();
                    }

                    // If the NPC is in the current scene, then set the NPC to active to make it visiblie, then pop the movement step off
                    // The top of the stack, and then call the method to actually move the NPC
                    if (npcCurrentScene.ToString() == SceneManager.GetActiveScene().name)
                    {
                        // Set the NPC to active in the scene so we can see them
                        SetNPCActiveInScene();

                        // Pop the next npcMovementStep from the top of the npcMovementStepStack
                        npcMovementStep = npcPath.npcMovementStepStack.Pop();

                        // Find the next grid position the NPC needs to walk to from the next npcMovementStep, gridCoordinate member
                        npcNextGridPosition = (Vector3Int)npcMovementStep.gridCoordinate;

                        // This is the time this next npcMovementStep will take, from it's hour/minute/second member variables
                        TimeSpan npcMovementStepTime = new TimeSpan(npcMovementStep.hour, npcMovementStep.minute, npcMovementStep.second);

                        // This method will move the NPC to the next grid position npcNextGridPosition, and make sure they are there by the time npcMovementStepTime, starting off
                        // at the current game time
                        MoveToGridPosition(npcNextGridPosition, npcMovementStepTime, TimeManager.Instance.GetGameTime());
                    }

                    // Else, if the NPC is not in the current scene, then set the NPC to inactive to make it invisible (it's still moving but we can't see it until we move to their scene)
                    // Once the movement step time is less than the game time (i.e. in the past), then pop the movement step off the stack and set the NPC position to the
                    // movement step position. Because we can't see the NPC, we don't need to run the walking animations - just keep popping off the next movement Step and
                    // immediately teleporting the NPC there at the proper times. This will keep happening until the player enters the NPC's current scene - and then
                    // they will start smoothly walking again.
                    else
                    {
                        // Disables the sprite renderer and box collider, and sets the npcActiveInScene to false. The NPC is still on the persistent scene and moving, but we can't see them so it looks like they arent
                        SetNPCInactiveInScene();

                        // Set the current and nextGrid position and move the NPC to the current one
                        npcCurrentGridPosition = (Vector3Int)npcMovementStep.gridCoordinate;
                        npcNextGridPosition    = npcCurrentGridPosition;
                        transform.position     = GetWorldPosition(npcCurrentGridPosition);

                        // The step time needed for the next step to be completed by, and the current game time
                        TimeSpan npcMovementStepTime = new TimeSpan(npcMovementStep.hour, npcMovementStep.minute, npcMovementStep.second);
                        TimeSpan gameTime            = TimeManager.Instance.GetGameTime();

                        // Whenever the stepTime < gameTime (so they should be to the next position by now), immediately teleport the NPC to that step, and then wait for the next step to occur, and then
                        // teleport them again. This will keep going until the player enters the NPC's current scene - then they will start smoothly walking again.
                        if (npcMovementStepTime < gameTime)
                        {
                            // Pop off the next Movement Step from the Stack
                            npcMovementStep = npcPath.npcMovementStepStack.Pop();

                            // Update the current and next grid positions, and immediately teleport the NPC to the next step position, rather than the smooth walking animation if the player IS in the NPCs scene.
                            npcCurrentGridPosition = (Vector3Int)npcMovementStep.gridCoordinate;
                            npcNextGridPosition    = npcCurrentGridPosition;
                            transform.position     = GetWorldPosition(npcCurrentGridPosition);
                        }
                    }
                }

                // Else, if there are no more movement steps in the npcMovementStepStack (we've reached our target destination!), reset the move animation parameters so the NPC stops moving, then
                // set the proper NPCs facing direction, and then initiate the NPCs target animation
                else
                {
                    // Trigger all of the animator parameters to false for walking, so the NPC will stop the walking animation
                    ResetMoveAnimation();

                    // Using the npcFacingDirection set in the movement schedule, this will trigger the proper facing direction (i.e. idleUp, idleLeft, etc) once we're arrived at our destination
                    SetNPCFacingDirection();

                    // Set the NPCs target animation to play (i.e. smokeDirection, digDirection, etc) now that we're at the destination, as long as
                    // one has been specified in the NPCScheduleEvent
                    SetNPCEventAnimation();
                }
            }
        }
    }