void FixedUpdate() { if (!isGrounded) { isJump = false; } //Detects collision point because it might change due to player's rotation DetectColisionPoint(); CalculateClosestPlanet(); //Calculate the direction and rotation of the player relative to the gravity source gravityRotationDirection = transform.position - gravityObject.transform.position; if (isGrounded) { // Calculate how fast we should be moving movement = transform.TransformDirection(movement); movement *= speed; // Apply a force that attempts to reach our target velocity var velocity = GetComponent <Rigidbody>().velocity; var velocityChange = (movement - velocity) + groundVelocity; velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange); velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange); //velocityChange.y = 0; //velocityChange *= Vector3.one - (transform.up * -1); GetComponent <Rigidbody>().AddForce(velocityChange, ForceMode.VelocityChange); // Jump if (canJump && isJump) { //trocar transform.up por collider.transform.up? GetComponent <Rigidbody>().velocity = velocity + (CalculateJumpVerticalSpeed() * transform.up); //new Vector3(velocity.x, CalculateJumpVerticalSpeed(), velocity.z); } isGrounded = false; } else { // Add an air force movement = transform.TransformDirection(movement) * inAirControl; GetComponent <Rigidbody>().AddForce(movement, ForceMode.VelocityChange); } PlanetData.PlanetGravityType type = gravityObject.GetComponent <PlanetData>().PlanetOrientation; //Rotation velocity relative to the distance float currDistance = Vector3.Distance(transform.position, gravityObject.transform.position) - gravityObject.GetComponent <PlanetData>().GravityForce; if (currDistance < 25) { rotationSpeed = 8.0f; } else if (currDistance > 200) { rotationSpeed = 1.0f; } else { rotationSpeed = currDistance / (200 / 8); } //Calculate the rotation according to the surface. If it is a sphere type planet the player will ALWAYS be upright relative to the center of the planet //If the planet is a plante, he will be upright relative to the plane direction //If it's a snap tipe, a raycast will be cast from the player to the planet. The normal direction of the surface hit by the raycast will be used as the angle for the player Quaternion targetRotation; switch (type) { case PlanetData.PlanetGravityType.Sphere: targetRotation = (Quaternion.FromToRotation(transform.up, gravityRotationDirection) * transform.rotation); transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, rotationSpeed); GetComponent <Rigidbody>().AddForce(this.transform.rotation * (new Vector3(0, -gravity * GetComponent <Rigidbody>().mass)), 0); break; case PlanetData.PlanetGravityType.Plane: targetRotation = (Quaternion.FromToRotation(transform.up, gravityObject.transform.up) * transform.rotation); transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, rotationSpeed); GetComponent <Rigidbody>().AddForce(gravityObject.transform.rotation * (new Vector3(0, -gravity * GetComponent <Rigidbody>().mass)), 0); break; case PlanetData.PlanetGravityType.Snap: RaycastHit hit = new RaycastHit(); if (Physics.Raycast(transform.position, transform.up * -1, out hit, 10) && hit.collider.gameObject == gravityObject) { targetRotation = (Quaternion.FromToRotation(transform.up, hit.normal) * transform.rotation); transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, rotationSpeed); GetComponent <Rigidbody>().AddForce(this.transform.rotation * (new Vector3(0, -gravity * GetComponent <Rigidbody>().mass)), 0); } else { targetRotation = (Quaternion.FromToRotation(transform.up, gravityRotationDirection) * transform.rotation); transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, rotationSpeed); GetComponent <Rigidbody>().AddForce(this.transform.rotation * (new Vector3(0, -gravity * GetComponent <Rigidbody>().mass)), 0); } break; } }
//Calculate the closest planet object to the player and sets it as the player's gravity source planet void CalculateClosestPlanet() { this.gravityObject = GravityController.instance.SelectClosestGravityPlanet(downColliderBound + transform.position, this.gravityObject); this.gravityType = gravityObject.GetComponent <PlanetData>().PlanetOrientation; }