Beispiel #1
0
    public IEnumerator move(Vector3 movement, bool encounter = true, bool lockFollower = false)
    {
        if (movement != Vector3.zero)
        {
            Vector3 startPosition = hitBox.position;
            moving    = true;
            increment = 0;
            animPause = false;
            while (increment < 1f)
            {
                //increment increases slowly to 1 over the frames
                increment += (1f / speed) * Time.deltaTime;
                //speed is determined by how many squares are crossed in one second
                if (increment > 1)
                {
                    increment = 1;
                }
                transform.position = startPosition + (movement * increment);
                hitBox.position    = startPosition + movement;
                yield return(null);
            }

            //check for encounters unless disabled
            if (encounter)
            {
                int destinationTag = currentMap.getTileTag(transform.position);
                if (destinationTag != 1)
                {
                    //not a wall
                    if (destinationTag == 2)
                    {
                        //surf tile
                        StartCoroutine(FakePlayerMovement.player.wildEncounter(WildPokemonInitialiser.Location.Surfing));
                    }
                    else
                    {
                        //land tile
                        StartCoroutine(FakePlayerMovement.player.wildEncounter(WildPokemonInitialiser.Location.Standard));
                    }
                }
            }
        }
    }
    private bool checkDestination(Vector3 movement)
    {
        startPosition        = transform.position;
        destinationPosition1 = startPosition + movement;

        int direction = 0;

        //GlobalVariables.global.debug("move: "+movement.x +" "+movement.z);
        if (Mathf.RoundToInt(movement.x) != 0)
        {
            // moving right or left
            direction            = 1;
            destinationPosition2 = destinationPosition1 + new Vector3(0, 0, 1);
        }
        else if (Mathf.RoundToInt(movement.z) != 0)
        {
            //moving up or down
            destinationPosition2 = destinationPosition1 + new Vector3(1, 0, 0);
        }

        //GlobalVariables.global.debug("s: "+startPosition +" d1: "+destinationPosition1+" d2: "+destinationPosition2);

        //return a list of every collision at xyz position with a spherical radius of 0.4f
        hitColliders =
            Physics.OverlapSphere(new Vector3(transform.position.x, transform.position.y, transform.position.z), 0.4f);

        //Check current map
        RaycastHit[] hitRays =
            Physics.RaycastAll(transform.position + Vector3.up + Player.getForwardVectorRaw(direction), Vector3.down, 3f);
        int   closestIndex    = -1;
        float closestDistance = float.PositiveInfinity;

        if (hitRays.Length > 0)
        {
            for (int i = 0; i < hitRays.Length; i++)
            {
                if (hitRays[i].collider.gameObject.GetComponent <MapCollider>() != null)
                {
                    if (hitRays[i].distance < closestDistance)
                    {
                        closestDistance = hitRays[i].distance;
                        closestIndex    = i;
                    }
                }
            }
        }
        if (closestIndex != -1)
        {
            currentMap = hitRays[closestIndex].collider.gameObject.GetComponent <MapCollider>();

            //Check destiantion map
            hitRays = Physics.RaycastAll(transform.position + Vector3.up + Player.getForwardVectorRaw(direction),
                                         Vector3.down, 3f);
            closestIndex    = -1;
            closestDistance = float.PositiveInfinity;
            if (hitRays.Length > 0)
            {
                for (int i = 0; i < hitRays.Length; i++)
                {
                    if (hitRays[i].collider.gameObject.GetComponent <MapCollider>() != null)
                    {
                        if (hitRays[i].distance < closestDistance)
                        {
                            closestDistance = hitRays[i].distance;
                            closestIndex    = i;
                        }
                    }
                }
            }
            if (closestIndex != -1)
            {
                destinationMap = hitRays[closestIndex].collider.gameObject.GetComponent <MapCollider>();
            }
            else
            {
                destinationMap = currentMap;
            }


            //check destination for objects
            currentObjectCollider = null; //empty currentOBJC
            hitColliders          = Physics.OverlapSphere(destinationPosition1, 0.25f);
            if (hitColliders.Length > 0)
            {
                for (int i = 0; i < hitColliders.Length; i++)
                {
                    if (hitColliders[i].name.ToLowerInvariant().Contains("object"))
                    {
                        //if hits object
                        currentObjectCollider = hitColliders[i];
                    }
                }
            }
            if (currentObjectCollider == null)
            {
                hitColliders = Physics.OverlapSphere(destinationPosition2, 0.25f);
                if (hitColliders.Length > 0)
                {
                    for (int i = 0; i < hitColliders.Length; i++)
                    {
                        if (hitColliders[i].name.ToLowerInvariant().Contains("object"))
                        {
                            //if hits object
                            currentObjectCollider = hitColliders[i];
                        }
                    }
                }
            }
            if (currentObjectCollider == null)
            {
                //if both positions are free
                //ensure the slopes of the destination are both 0
                float slope1 = MapCollider.getSlopeOfPosition(destinationPosition1, direction);
                float slope2 = MapCollider.getSlopeOfPosition(destinationPosition2, direction);

                //Make sure that destination Position is at most a single square away from start.
                //this way we can ensure that the movement of the object will be one square at most
                movement = new Vector3(Mathf.Clamp(movement.x, -1, 1), Mathf.Clamp(movement.y, -1, 1),
                                       Mathf.Clamp(movement.z, -1, 1));
                destinationPosition1 = startPosition + movement;

                if (slope1 == 0 && slope2 == 0)
                {
                    //if both squares in the destination are not impassable tiles
                    //Debug.Log (destinationPosition1);
                    if (destinationMap.getTileTag(destinationPosition1) != 1 &&
                        destinationMap.getTileTag(destinationPosition1) != 2 &&
                        destinationMap.getTileTag(destinationPosition2) != 1 &&
                        destinationMap.getTileTag(destinationPosition2) != 2)
                    {
                        return(true);
                    }
                }
            }
        }
        return(false);
    }
    ///Make the player move one space in the direction they are facing
    private IEnumerator moveForward()
    {
        Vector3 movement = getForwardVector();

        bool ableToMove = false;

        //without any movement, able to move should stay false
        if (movement != Vector3.zero)
        {
            //check destination for objects/transparents
            Collider   objectCollider      = null;
            Collider   transparentCollider = null;
            Collider[] hitColliders        = Physics.OverlapSphere(transform.position + movement + new Vector3(0, 0.5f, 0),
                                                                   0.4f);
            if (hitColliders.Length > 0)
            {
                for (int i = 0; i < hitColliders.Length; i++)
                {
                    if (hitColliders[i].name.ToLowerInvariant().Contains("_object"))
                    {
                        objectCollider = hitColliders[i];
                    }
                    else if (hitColliders[i].name.ToLowerInvariant().Contains("_transparent"))
                    {
                        transparentCollider = hitColliders[i];
                    }
                }
            }

            if (objectCollider != null)
            {
                //send bump message to the object's parent object
                objectCollider.transform.parent.gameObject.SendMessage("bump", SendMessageOptions.DontRequireReceiver);
            }
            else
            {
                //if no objects are in the way
                int destinationTileTag = destinationMap.getTileTag(transform.position + movement);

                RaycastHit bridgeHit =
                    MapCollider.getBridgeHitOfPosition(transform.position + movement + new Vector3(0, 0.1f, 0));
                if (bridgeHit.collider != null || destinationTileTag != 1)
                {
                    //wall tile tag

                    if (bridgeHit.collider == null && !surfing && destinationTileTag == 2)
                    {
                        //(water tile tag)
                    }
                    else
                    {
                        if (surfing && destinationTileTag != 2f)
                        {
                            //disable surfing if not headed to water tile
                            updateAnimation("walk", walkFPS);
                            speed   = walkSpeed;
                            surfing = false;
                            StartCoroutine("dismount");
                            BgmHandler.main.PlayMain(accessedAudio, accessedAudioLoopStartSamples);
                        }

                        if (destinationMap != currentMap)
                        {
                            //if moving onto a new map
                            currentMap          = destinationMap;
                            accessedMapSettings = destinationMap.gameObject.GetComponent <MapSettings>();
                            if (accessedAudio != accessedMapSettings.getBGM())
                            {
                                //if audio is not already playing
                                accessedAudio = accessedMapSettings.getBGM();
                                accessedAudioLoopStartSamples = accessedMapSettings.getBGMLoopStartSamples();
                                BgmHandler.main.PlayMain(accessedAudio, accessedAudioLoopStartSamples);
                            }
                            destinationMap.BroadcastMessage("repair", SendMessageOptions.DontRequireReceiver);
                            if (accessedMapSettings.mapNameBoxTexture != null)
                            {
                                MapName.display(accessedMapSettings.mapNameBoxTexture, accessedMapSettings.mapName,
                                                accessedMapSettings.mapNameColor);
                            }
                            Debug.Log(destinationMap.name + "   " + accessedAudio.name);
                        }

                        if (transparentCollider != null)
                        {
                            //send bump message to the transparents's parent object
                            transparentCollider.transform.parent.gameObject.SendMessage("bump",
                                                                                        SendMessageOptions.DontRequireReceiver);
                        }

                        ableToMove = true;
                        yield return(StartCoroutine(move(movement)));
                    }
                }
            }
        }

        //if unable to move anywhere, then set moving to false so that the player stops animating.
        if (!ableToMove)
        {
            Invoke("playBump", 0.05f);
            moving    = false;
            animPause = true;
        }
    }
    private IEnumerator control()
    {
        bool still;

        while (true)
        {
            still = true;
            //the player is still, but if they've just finished moving a space, moving is still true for this frame (see end of coroutine)
            if (canInput)
            {
                if (!surfing && !bike)
                {
                    if (Input.GetButton("Run"))
                    {
                        running = true;
                        if (moving)
                        {
                            updateAnimation("run", runFPS);
                        }
                        else
                        {
                            updateAnimation("walk", walkFPS);
                        }
                        speed = runSpeed;
                    }
                    else
                    {
                        running = false;
                        updateAnimation("walk", walkFPS);
                        speed = walkSpeed;
                    }
                }
                if (Input.GetButton("Start"))
                {
                    //open Pause Menu
                    if (moving || Input.GetButtonDown("Start"))
                    {
                        if (setCheckBusyWith(Scene.main.Pause.gameObject))
                        {
                            animPause = true;
                            Scene.main.Pause.gameObject.SetActive(true);
                            StartCoroutine(Scene.main.Pause.control());
                            while (Scene.main.Pause.gameObject.activeSelf)
                            {
                                yield return(null);
                            }
                            unsetCheckBusyWith(Scene.main.Pause.gameObject);
                        }
                    }
                }
                else if (Input.GetButtonDown("Select"))
                {
                    interact();
                }
                //if pausing/interacting/etc. is not being called, then moving is possible.
                //		(if any direction input is being entered)
                else if (Input.GetAxisRaw("Horizontal") != 0 || Input.GetAxisRaw("Vertical") != 0)
                {
                    //if most recent direction pressed is held, but it isn't the current direction, set it to be
                    if (mostRecentDirectionPressed != direction && isDirectionKeyHeld(mostRecentDirectionPressed))
                    {
                        updateDirection(mostRecentDirectionPressed);
                        if (!moving)
                        {
                            // unless player has just moved, wait a small amount of time to ensure that they have time to
                            yield return(new WaitForSeconds(directionChangeInputDelay));
                        } // let go before moving (allows only turning)
                    }
                    //if a new direction wasn't found, direction would have been set, thus ending the update
                    else
                    {
                        //if current direction is not held down, check for the new direction to turn to
                        if (!isDirectionKeyHeld(direction))
                        {
                            //it's least likely to have held the opposite direction by accident
                            int directionCheck = (direction + 2 > 3) ? direction - 2 : direction + 2;
                            if (isDirectionKeyHeld(directionCheck))
                            {
                                updateDirection(directionCheck);
                                if (!moving)
                                {
                                    yield return(new WaitForSeconds(directionChangeInputDelay));
                                }
                            }
                            else
                            {
                                //it's either 90 degrees clockwise, counter, or none at this point. prioritise clockwise.
                                directionCheck = (direction + 1 > 3) ? direction - 3 : direction + 1;
                                if (isDirectionKeyHeld(directionCheck))
                                {
                                    updateDirection(directionCheck);
                                    if (!moving)
                                    {
                                        yield return(new WaitForSeconds(directionChangeInputDelay));
                                    }
                                }
                                else
                                {
                                    directionCheck = (direction - 1 < 0) ? direction + 3 : direction - 1;
                                    if (isDirectionKeyHeld(directionCheck))
                                    {
                                        updateDirection(directionCheck);
                                        if (!moving)
                                        {
                                            yield return(new WaitForSeconds(directionChangeInputDelay));
                                        }
                                    }
                                }
                            }
                        }
                        //if current direction was held, then we want to attempt to move forward.
                        else
                        {
                            moving = true;
                        }
                    }

                    //if moving is true (including by momentum from the previous step) then attempt to move forward.
                    if (moving)
                    {
                        still = false;
                        yield return(StartCoroutine(moveForward()));
                    }
                }
                else if (Input.GetKeyDown("g"))
                {
                    //DEBUG
                    Debug.Log(currentMap.getTileTag(transform.position));
                    if (followerScript.canMove)
                    {
                        followerScript.StartCoroutine("withdrawToBall");
                    }
                    else
                    {
                        followerScript.canMove = true;
                    }
                }
            }
            if (still)
            {
                //if still is true by this point, then no move function has been called
                animPause = true;
                moving    = false;
            } //set moving to false. The player loses their momentum.

            yield return(null);
        }
    }
Beispiel #5
0
    /*/
     * /// Checks the position for player and returns the next position to check
     * private Vector3 checkPosition(Vector3 position){
     *      playerAtPosition = false;
     *      positionIsBlocked = false;
     *
     *      Vector3 nextPosition = position;
     *
     *
     *      Vector3 movement = new Vector3(0,0,0);
     *      if(trainer.direction == 0){
     *              movement = new Vector3(0,0,1f);}
     *      else if(trainer.direction == 1){
     *              movement = new Vector3(1f,0,0);}
     *      else if(trainer.direction == 2){
     *              movement = new Vector3(0,0,-1f);}
     *      else if(trainer.direction == 3){
     *              movement = new Vector3(-1f,0,0);}
     *
     *      float currentTileTag = trainer.currentMap.getTileTag(position);
     *      //check current tileTag for stairs(3)
     *      if(Mathf.Floor(currentTileTag) == 3f){
     *              //check if stair direction is same as trainer direction
     *              if(Mathf.Round(((currentTileTag) - 3f)*10) == trainer.direction){
     *                      movement += new Vector3(0,0.5f,0);}
     *              else{
     *                      float flippedDirection = trainer.direction + 2;
     *                      if(flippedDirection > 3){
     *                              flippedDirection -= 4;}
     *                      if(Mathf.Round(((currentTileTag) - 3f)*10) == flippedDirection){
     *                              movement += new Vector3(0,-0.5f,0);}
     *              }
     *      }
     *      float destinationTileTag = trainer.currentMap.getTileTag(position+movement);
     *      //check destination tileTag for stairs(3)
     *      if(Mathf.Floor(destinationTileTag) == 3f){
     *              if(Mathf.Round(((destinationTileTag) - 3f)*10) == trainer.direction){
     *                      movement += new Vector3(0,0.5f,0);}
     *      } //else if its stair-top(4)
     *      else if(Mathf.Floor(destinationTileTag) == 4f){
     *              if(Mathf.Round(((destinationTileTag) - 4f)*10) == trainer.direction){
     *                      movement += new Vector3(0,-0.5f,0);}
     *      }
     *
     *      destinationTileTag = trainer.currentMap.getTileTag(position+movement);
     *      //check destination tileTag for impassibles
     *      if(Mathf.Floor(destinationTileTag) == 0f || Mathf.Floor(destinationTileTag) == 2f){
     *              positionIsBlocked = true;}
     *      else if(trainer.trainerSurfing){ //if a surf trainer, normal tiles are impassible
     *              if(Mathf.Floor(destinationTileTag) == 1f || Mathf.Floor(destinationTileTag) == 5f){
     *                      positionIsBlocked = true;}
     *      }
     *      else if(Mathf.Floor(destinationTileTag) == 6f){
     *              positionIsBlocked = true;}
     *
     *      nextPosition = position + movement;
     *      //check nextPosition for objects/followers and check for the player
     *      Collider[] hitColliders = Physics.OverlapSphere (nextPosition, 0.2f);
     *      if (hitColliders.Length > 0){
     *              for (int i = 0; i < hitColliders.Length; i++){
     *                      if(hitColliders[i].name == "Player_Transparent"){
     *                              playerAtPosition = true;
     *                              i = hitColliders.Length;}
     *                      else if(hitColliders[i].name == "Follower_Transparent" ||
     *                              hitColliders[i].name.Contains("_Object")){
     *                              positionIsBlocked = true;
     *                              i = hitColliders.Length;}
     *              }
     *      }
     *
     *      return nextPosition;
     * }
     * //*/

    /// Checks the position for player and returns the next position to check
    private Vector3 checkPosition(Vector3 position)
    {
        playerAtPosition  = false;
        positionIsBlocked = false;

        Vector3 nextPosition = position;

        Vector3 forwardsVector = new Vector3(0, 0, 0);

        if (trainer.direction == 0)
        {
            forwardsVector = new Vector3(0, 0, 1f);
        }
        else if (trainer.direction == 1)
        {
            forwardsVector = new Vector3(1f, 0, 0);
        }
        else if (trainer.direction == 2)
        {
            forwardsVector = new Vector3(0, 0, -1f);
        }
        else if (trainer.direction == 3)
        {
            forwardsVector = new Vector3(-1f, 0, 0);
        }

        Vector3 movement = forwardsVector;


        //Check destination map																	//0.5f to adjust for stair height
        MapCollider destinationMap = trainer.currentMap;

        //cast a ray directly downwards from the position directly in front of the npc			//1f to check in line with player's head
        RaycastHit[] mapHitColliders = Physics.RaycastAll(position + movement + new Vector3(0, 1.5f, 0), Vector3.down);
        RaycastHit   mapHit          = new RaycastHit();

        //cycle through each of the collisions
        if (mapHitColliders.Length > 0)
        {
            for (int i = 0; i < mapHitColliders.Length; i++)
            {
                //if a collision's gameObject has a mapCollider, it is a map. set it to be the destination map.
                if (mapHitColliders[i].collider.gameObject.GetComponent <MapCollider>() != null)
                {
                    mapHit         = mapHitColliders[i];
                    destinationMap = mapHit.collider.gameObject.GetComponent <MapCollider>();
                    i = mapHitColliders.Length;
                }
            }
        }

        //check for a bridge at the destination
        RaycastHit bridgeHit = MapCollider.getBridgeHitOfPosition(position + movement + new Vector3(0, 1.5f, 0));

        if (bridgeHit.collider != null)
        {
            //modify the forwards vector to align to the bridge.
            movement -= new Vector3(0, (position.y - bridgeHit.point.y), 0);
        }
        //if no bridge at destination
        else if (mapHit.collider != null)
        {
            //modify the forwards vector to align to the mapHit.
            movement -= new Vector3(0, (position.y - mapHit.point.y), 0);
        }


        float currentSlope     = Mathf.Abs(MapCollider.getSlopeOfPosition(position, trainer.direction));
        float destinationSlope = Mathf.Abs(MapCollider.getSlopeOfPosition(position + forwardsVector, trainer.direction));
        float yDistance        = Mathf.Abs((position.y + movement.y) - position.y);

        yDistance = Mathf.Round(yDistance * 100f) / 100f;

        //if either slope is greater than 1 it is too steep.
        if (currentSlope <= 1 && destinationSlope <= 1)
        {
            //if yDistance is greater than both slopes there is a vertical wall between them
            if (yDistance <= currentSlope || yDistance <= destinationSlope)
            {
                //check destination tileTag for impassibles
                int destinationTileTag = destinationMap.getTileTag(position + movement);
                if (destinationTileTag == 1)
                {
                    positionIsBlocked = true;
                }
                else
                {
                    if (trainer.trainerSurfing)                     //if a surf trainer, normal tiles are impassible
                    {
                        if (destinationTileTag != 2)
                        {
                            positionIsBlocked = true;
                        }
                    }
                    else                      //if not a surf trainer, surf tiles are impassible
                    {
                        if (destinationTileTag == 2)
                        {
                            positionIsBlocked = true;
                        }
                    }
                }

                //check destination for objects/player/follower
                Collider[] hitColliders = Physics.OverlapSphere(position + movement, 0.4f);
                if (hitColliders.Length > 0)
                {
                    for (int i = 0; i < hitColliders.Length; i++)
                    {
                        if (hitColliders[i].name == "Player_Transparent")
                        {
                            playerAtPosition = true;
                        }
                        else if (hitColliders[i].name == "Follower_Transparent" ||
                                 hitColliders[i].name.ToLowerInvariant().Contains("_object"))
                        {
                            positionIsBlocked = true;
                        }
                    }
                }
            }
        }
        return(position + movement);
    }