So, in following the “Roll-A-Ball” series of tutorials, I’ve been attempting to create my own physics-based game from the tutorials.
I’ve modified the basic game so that the player can jump, and it works great. However, I also needed to limit the maximum speed (or velocity) of the player, because if I didn’t, the player just ended up flying off the side of the level at ridiculous speeds.
The solutions I found to limiting the maximum velocity of the player were many - some worked, and some didn’t. The solution I found and has worked the best so far is to use Vector3.ClampMagnitude, like so:
// Make sure player isn't rolling too fast
rigidbody.velocity = Vector3.ClampMagnitude(rigidbody.velocity, maxSpeed * Time.fixedDeltaTime);
The problem, is that since it limits the velocity, this affects the “AddForce()” function, which in turn, as the title suggests, affects this jumping code…
if (Input.GetKey(KeyCode.Space) IsGrounded())
{
rigidbody.AddForce(Vector3.up * jumpHeight);
}
I’m also using the “AddForce()” function to move the player with the input axis’ described in the tutorials.
I’m wondering, is it possible to limit the player’s maximum velocity, but without affecting the “AddForce()” function? I CAN get the jumps to work just fine, as long as the jumpHeight variable matches the maxSpeed variable. But, the problems with that is that I was planning on using “AddForce()” to make things like wind tunnels with a HUGE amount of speed to push the player through certain parts of the level, and knock them off.
Here’s my whole code:
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour
{
// Declare public variables
public GUIText gemText;
public GUIText winText;
public int amountOfGems;
public float speed;
public float maxSpeed;
public float jumpHeight;
// Declare private variables
private int gems;
private float distanceToGround;
// Initialize all the things!
void Start()
{
distanceToGround = collider.bounds.extents.y;
gems = 0;
winText.text = "";
SetCountText();
}
// Handle input in fixed update
void FixedUpdate()
{
// Get and store input values
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
// Apply movement
rigidbody.AddForce(movement * speed * Time.deltaTime);
// Make sure player isn't rolling too fast (NOTE: Also affects jumping velocity, take into consideration when setting jumpHeight!)
rigidbody.velocity = Vector3.ClampMagnitude(rigidbody.velocity, maxSpeed * Time.fixedDeltaTime);
// Check for jump
if (Input.GetKey(KeyCode.Space) IsGrounded())
{
rigidbody.AddForce(Vector3.up * jumpHeight);
}
}
// Determine if player is on ground or not
bool IsGrounded()
{
return Physics.Raycast(transform.position, -Vector3.up, distanceToGround + 0.1f);
}
// Pickup gems
void OnTriggerEnter(Collider other)
{
if(other.gameObject.tag == "PickUp")
{
other.gameObject.SetActive(false);
gems += 1;
SetCountText();
}
}
void SetCountText()
{
gemText.text = "Gems Collected: " + gems.ToString() +" / " + amountOfGems;
if (gems >= amountOfGems)
{
winText.text = "YOU WIN!";
}
}
}
Thanks to anybody who can offer a solution!