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