//Update player position public void UpdatePosition() { if ((Input.GetButton("Aim") || (Mathf.Approximately(Input.GetAxisRaw("Horizontal"), 0f) && Mathf.Approximately(Input.GetAxisRaw("Vertical"), 0f))) && currentCamera != null) { //Positioning pointer behind camera, following forward and project it on xz cameraDirectionPosition = currentCamera.transform.position - currentCamera.transform.forward; cameraDirectionPosition.y = currentCamera.transform.position.y; cameraDirection.position = cameraDirectionPosition; //Looking the camera, camera will never be upside down cameraDirection.LookAt(currentCamera.transform, Vector3.up); playerVelocity = 0f; //If we are not targeting on a corner, player wall movement is none if (!(Input.GetButton("Aim") && playerWallMovement == PlayerWallMovement.LOOK) && !aimingFromWall) { stickDirection = Vector3.zero; playerWallMovement = PlayerWallMovement.NONE; } } else { //Calculate direction point from the center of the joystick RefreshStickDirection(); //Player move in the direction and write velocity (if not aiming from the wall) //If the player is against a wall, we reduce its speed if (!aimingFromWall) { switch (playerWallMovement) { case PlayerWallMovement.NONE: transform.position += stickDirection * Time.deltaTime * maxSpeed; playerVelocity = Vector3.Distance(Vector3.zero, stickDirection * maxSpeed); break; case PlayerWallMovement.MOVE: transform.position += stickDirection * Time.deltaTime * speedAgainstWall; playerVelocity = Vector3.Distance(Vector3.zero, stickDirection * speedAgainstWall); break; default: playerVelocity = 0f; break; } } //Orientation regarding if the player is against a wall or not playerRotation.position = transform.position; if (playerWallMovement >= PlayerWallMovement.COLLIDE) { //The player turns his back on the wall playerRotation.LookAt(transform.position + wallDirection); } else { playerRotation.LookAt(transform.position + stickDirection); } } }
void Start() { #region instanciando _playerAnimation = GetComponent <PlayerAnimation>(); _playerInput = GetComponent <PlayerInput>(); _rigidbody2D = GetComponent <Rigidbody2D>(); _playerSpriteHandler = GetComponent <PlayerSpriteHandler>(); _playerWallMovement = GetComponent <PlayerWallMovement>(); _playerJump = GetComponent <PlayerJump>(); #endregion instanciando }
void Start() { #region Instanciando _hasExtraJump = true; _playerAnimation = GetComponent <PlayerAnimation>(); _playerInput = GetComponent <PlayerInput>(); _rigidbody2D = GetComponent <Rigidbody2D>(); _playerSpriteHandler = GetComponent <PlayerSpriteHandler>(); _playerAttack = GetComponent <PlayerAttack>(); _playerShoot = GetComponent <PlayerShoot>(); _playerWallMovement = GetComponent <PlayerWallMovement>(); #endregion }
//Upload player position after aim/shoot public void LateUpdatePosition() { //Player look in the direction (with a quick smooth) transform.rotation = Quaternion.Slerp(transform.rotation, playerRotation.rotation, speedRotationSmooth); if (Input.GetButton("Aim") && GetEquipedWeapon() != null) { //If the player is looking at the corner and he wants to shoot from the corner if (!aimingFromWall && playerWallMovement == PlayerWallMovement.LOOK && Vector3.Angle(playerRotation.forward, -wallDirection) < 90f) { aimingFromWall = true; startDecalPosition = transform.position; aimingDecalPosition = transform.position + (stickDirection * decalRaycastDistance * 2f); } //If we are aiming from the wall, the player decal his position if (aimingFromWall) { transform.position = Vector3.Lerp(transform.position, aimingDecalPosition, speedRotationSmooth); playerWallMovement = PlayerWallMovement.NONE; } } else { //If we stop aiming from the wall, the player returns to its original position (we force him to) if (aimingFromWall) { playerRotation.position = transform.position; playerRotation.forward = wallDirection; transform.position = Vector3.Lerp(transform.position, startDecalPosition, speedRotationSmooth); transform.rotation = Quaternion.Slerp(transform.rotation, playerRotation.rotation, speedRotationSmooth); //To prevent the animation being long if (Vector3.Distance(transform.position, startDecalPosition) < 0.01f) { transform.position = startDecalPosition; aimingFromWall = false; playerWallMovement = PlayerWallMovement.LOOK; } } } }
//Refresh stick position related to the camera orientation. //Most of this is basicly a way to redone the Rigidbody.MovePosition, because I never trust f*****g physics. //Use 3 very short raycast at least, 4 at worst. Pretty optimized. void RefreshStickDirection() { //First, let's calculate the stick orientation and his normal stickDirection = (cameraDirection.right * Input.GetAxisRaw("Horizontal")) + (cameraDirection.forward * Input.GetAxisRaw("Vertical")); stickNormalDirection = (cameraDirection.forward * Input.GetAxisRaw("Horizontal")) - (cameraDirection.right * Input.GetAxisRaw("Vertical")); //This is a way to have a stickDirection point that is inside a circle, and not a square. if (stickDirection.magnitude > 1f) { stickDirection.Normalize(); stickNormalDirection.Normalize(); } Debug.DrawLine(transform.position, transform.position + (stickDirection * collisionDistance), Color.blue, Time.deltaTime, false); Debug.DrawLine(transform.position, transform.position + (stickNormalDirection * collisionDistance), Color.gray, Time.deltaTime, false); //Wall is detected in front of the user, or on the right, or on the left, in this order //If the player is already against a wall, we double the collision distance to check out the wall collision frontDetection = HitWallTest(stickDirection, Vector3.zero, playerWallMovement == PlayerWallMovement.NONE ? collisionDistance : collisionDistance * 2f, out frontHit, Color.red); rightDetection = HitWallTest(stickDirection, stickNormalDirection, collisionDistance, out rightHit, Color.magenta); leftDetection = HitWallTest(stickDirection, -stickNormalDirection, collisionDistance, out leftHit, Color.cyan); //If one of these detection has been made if (frontDetection || rightDetection || leftDetection) { //If the player is not against a wall, we do a second raycast but longer to catch the wall if (playerWallMovement == PlayerWallMovement.NONE) { frontDetection = HitWallTest(stickDirection, Vector3.zero, collisionDistance * 2f, out frontHit, Color.red); } //If there's a wall in front of the player, we get the normal and the right vector of the wall if (frontDetection) { wallDirection = frontHit.normal; } wallRightDirection = Vector3.Cross(wallDirection, Vector3.up); //Projecting the stick direction into the wall to know in which direction the player can go stickDirection = Vector3.ProjectOnPlane(stickDirection, wallDirection); //If the stick is nearly the opposite of the wall, we notice that the player collide with the wall if (Vector3.Distance(stickDirection, Vector3.zero) <= wallDirectionDeadZone) { stickDirection = Vector3.zero; //If there's a front detection, it's a wall, if not, it's just a corner, the player won't turn against the wall playerWallMovement = frontDetection ? PlayerWallMovement.COLLIDE : PlayerWallMovement.NONE; //Else, if the player was already against a wall... } else if (playerWallMovement != PlayerWallMovement.NONE) { //Wall left and right are not the same, we are at a corner, we stop the player if ((rightDetection && Vector3.Angle(stickDirection, wallRightDirection) > 90f && rightHit.normal != wallDirection) || (leftDetection && Vector3.Angle(stickDirection, wallRightDirection) < 90f && leftHit.normal != wallDirection)) { stickDirection = Vector3.zero; playerWallMovement = PlayerWallMovement.COLLIDE; } //If we are moving along the wall, we test if we are at a side of a wall or not. We need to test the current direction to prevent player being stucked at wall side. else if ((Vector3.Angle(stickDirection, wallRightDirection) < 90f && !HitWallTest(-wallDirection, wallRightDirection, collisionDistance * 2f, Color.yellow)) || (Vector3.Angle(stickDirection, wallRightDirection) > 90f && !HitWallTest(-wallDirection, -wallRightDirection, collisionDistance * 2f, Color.yellow))) { //If there's a hit missing, the player is looking on the side of the wall playerWallMovement = PlayerWallMovement.LOOK; } //Else the player is moving along the wall else { playerWallMovement = PlayerWallMovement.MOVE; } } //If the player wasn't already against a wall, we let the player run along the wall (without being against it) else { //Huh ! A Wild wall angle appears ! If both of the right and left cast has touch, we have nowhere to go if (rightDetection && leftDetection) { stickDirection = Vector3.zero; } else { //We normalize again the stick direction (maybe shorten by the projection) stickDirection.Normalize(); } playerWallMovement = PlayerWallMovement.NONE; } } //No detection ? All right ! else { playerWallMovement = PlayerWallMovement.NONE; } Debug.DrawLine(transform.position, transform.position + (stickDirection * collisionDistance), Color.green, Time.deltaTime, false); }