public Vector3 getForwardVector(int direction, bool checkForBridge)
    {
        //set initial vector3 based off of direction
        Vector3 movement = getForwardVectorRaw(direction);

        //Check destination map	and bridge																//0.5f to adjust for stair height
        //cast a ray directly downwards from the position directly in front of the player		//1f to check in line with player's head
        RaycastHit[] hitColliders = Physics.RaycastAll(transform.position + movement + new Vector3(0, 1.5f, 0),
                                                       Vector3.down);
        RaycastHit mapHit    = new RaycastHit();
        RaycastHit bridgeHit = new RaycastHit();

        //cycle through each of the collisions
        if (hitColliders.Length > 0)
        {
            for (int i = 0; i < hitColliders.Length; i++)
            {
                //if map has not been found yet
                if (mapHit.collider == null)
                {
                    //if a collision's gameObject has a mapCollider, it is a map. set it to be the destination map.
                    if (hitColliders[i].collider.gameObject.GetComponent <MapCollider>() != null)
                    {
                        mapHit         = hitColliders[i];
                        destinationMap = mapHit.collider.gameObject.GetComponent <MapCollider>();
                    }
                }
                else if (bridgeHit.collider != null && checkForBridge)
                {
                    //if both have been found
                    i = hitColliders.Length; //stop searching
                }
                //if bridge has not been found yet
                if (bridgeHit.collider == null && checkForBridge)
                {
                    //if a collision's gameObject has a BridgeHandler, it is a bridge.
                    if (hitColliders[i].collider.gameObject.GetComponent <BridgeHandler>() != null)
                    {
                        bridgeHit = hitColliders[i];
                    }
                }
                else if (mapHit.collider != null)
                {
                    //if both have been found
                    i = hitColliders.Length; //stop searching
                }
            }
        }

        if (bridgeHit.collider != null)
        {
            //modify the forwards vector to align to the bridge.
            movement -= new Vector3(0, (transform.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, (transform.position.y - mapHit.point.y), 0);
        }


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

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

        //Debug.Log("currentSlope: "+currentSlope+", destinationSlope: "+destinationSlope+", yDistance: "+yDistance);

        //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)
            {
                return(movement);
            }
        }
        return(Vector3.zero);
    }
    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);
    }
Exemple #3
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);
    }