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); }
/*/ * /// 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); }