The question is answered, right answer was accepted
Using rb.velocity causes low gravity.
I have a player controller script for controlling the player, however I ran into a snag when I tried using this line of code to control the player.
rb.velocity = new Vector3 (Time.deltaTime * h * speed, 0, Time.deltaTime * v * speed);
Where rb is a public Rigidbody, h is the horizontal input from the player, v is the vertical input of the player and speed is a public float that is not 0.
As soon as I disable this line of code, the gravity on this object returns to normal, other objects in the scene are unaffected gravity-wise.
Even if I use:
rb.velocity = new Vector3 (0, 0, 0);
The problem still persists and adding a negative number in the y velocity to "increase" gravity is not useful either since if I do that, my movement speed on the ground is much slower then in the air. I also can't just remove it because I need to control the player with it.
This is the full contents of the player controller script:
public float speed;
public float sensitivity;
public float Jump;
public Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody> ();
}
// Update is called once per frame
void Update () {
//float h = Input.GetAxisRaw ("Horizontal");
//float v = Input.GetAxisRaw ("Vertical");
float mh = Input.GetAxis ("Mouse X");
//transform.Translate (Vector3.forward * Time.deltaTime * v * speed, Space.Self);
//transform.Translate (Vector3.right * Time.deltaTime * h * speed, Space.Self);
transform.Rotate (0, mh * sensitivity * Time.deltaTime, 0);
}
void FixedUpdate()
{
bool j = Input.GetButtonDown ("Jump");
float h = Input.GetAxisRaw ("Horizontal");
float v = Input.GetAxisRaw ("Vertical");
if (j) {
rb.AddForce (transform.up * Jump);
}
rb.velocity = new Vector3 (Time.deltaTime * h * speed, Time.deltaTime * 0, Time.deltaTime * v * speed);
}
Answer by GoldenWay · Feb 21, 2017 at 10:22 PM
I was able to use rb.AddRelativeForce as I was using before I was using rb.velocity, however the problem I was having originally that made switch to rb.velocity in the first place was that the player would have very slippery controls because I was applying forces to it. I added a line of code to reset the x and z velocity every frame to fix this issue, right after the movement forces were applied, like this:
rb.AddRelativeForce(Time.deltaTime * h * speed, 0, Time.deltaTime * v * speed, ForceMode.VelocityChange);
rb.velocity = new Vector3(0, rb.velocity.y, 0);
As it turns out though now that I'm looking at it and learned more about rb.velocity (because I had to use it to reset the x and z velocity), I'm pretty sure the issue would be resolved by simply replacing that last line of code i.e:
rb.velocity = new Vector3 (Time.deltaTime * h * speed, Time.deltaTime * 0, Time.deltaTime * v * speed);
with:
rb.velocity = new Vector3 (Time.deltaTime * h * speed, rb.velocity.y, Time.deltaTime * v * speed);
Which is probably simpler, here is the new version of my player controller script that now works perfectly fine, with normal gravity, proper collision and no slippery controls. Note that I had to bump up the speed value to compensate for the velocity I removed.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour {
public float speed;
public float sensitivity;
public float Jump;
public Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody> ();
}
// Update is called once per frame
void Update () {
//float h = Input.GetAxisRaw ("Horizontal");
//float v = Input.GetAxisRaw ("Vertical");
float mh = Input.GetAxis ("Mouse X");
//transform.Translate (Vector3.forward * Time.deltaTime * v * speed, Space.Self);
//transform.Translate (Vector3.right * Time.deltaTime * h * speed, Space.Self);
transform.Rotate (0, mh * sensitivity * Time.deltaTime, 0);
}
void FixedUpdate()
{
bool j = Input.GetButtonDown ("Jump");
float h = Input.GetAxisRaw ("Horizontal");
float v = Input.GetAxisRaw ("Vertical");
if (j) {
rb.AddForce (transform.up * Jump, ForceMode.VelocityChange);
}
rb.AddRelativeForce(Time.deltaTime * h * speed, 0, Time.deltaTime * v * speed, ForceMode.VelocityChange);
rb.velocity = new Vector3(0, rb.velocity.y, 0);
}
}
Thank you @RensDevolp and @Pengocat for your help, I will include your usernames in the special thanks section of the credits (however little that might mean, just thought it would be a nice gesture).
Answer by RensDevolp · Feb 20, 2017 at 06:51 PM
I think you should use rb.addForce instead. I think, that if you use velocity, you also automatically overwrite the gravity (correct me if I'm wrong). If this is a useless answer, or just downright wrong, just ignore it!
Kind regards,
Rens van Breukelen
Yes manipulating the velocity directly will affect the gravity. The following should give you an idea of how you could handle the rigidbody.
using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
public class PlayerController : $$anonymous$$onoBehaviour
{
public float moveSensitivity = 1f;
public float rotateSensitivity = 1f;
public float jumpSensitivity = 1f;
private float verticalInput;
private float rotateXInput;
private float horizontalInput;
private bool jumpInput;
private Rigidbody rb;
// Awake is called when the script instance is being loaded
void Awake()
{
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
GetInput();
}
// This function is called every fixed framerate frame, if the $$anonymous$$onoBehaviour is enabled
void FixedUpdate()
{
if (horizontalInput != 0f || verticalInput != 0f) $$anonymous$$ove();
if (rotateXInput != 0f) Rotate();
if (jumpInput) Jump();
}
private void GetInput()
{
jumpInput = Input.GetButtonDown("Jump");
horizontalInput = Input.GetAxis("Horizontal");
verticalInput = Input.GetAxis("Vertical");
rotateXInput = Input.GetAxis("$$anonymous$$ouse X");
}
private void $$anonymous$$ove()
{
var moveForce = new Vector3(
horizontalInput * moveSensitivity,
0f,
verticalInput * moveSensitivity);
rb.AddRelativeForce(moveForce, Force$$anonymous$$ode.Force);
}
private void Rotate()
{
var rotateForce = rotateXInput * rotateSensitivity;
rb.AddTorque(new Vector3(
0f,
rotateForce,
0f));
}
private void Jump()
{
var jumpForce = transform.up * jumpSensitivity;
rb.AddForce(jumpForce, Force$$anonymous$$ode.Impulse);
}
}
@RensDevolp The reason I used rb.velocity in the first place is that addforce made movement of the player slippery as it took the properties of the rigidbody into consideration and try as I might I could not figure out how to enable the player to move normally.
You could also attach a character controller, use cc.move and tick the rigidbody.kinematic option and disable the rigidbody.use gravity. This works great for my player!
private CharacterController cc;
private Vector3 moveDirection = Vector3.zero;
float currentSpeed;
public Texture2D crosshair;
private Rect position;
// Use this for initialization
void Start () {
cc = GetComponent<CharacterController>();
position = new Rect((Screen.width - crosshair.width) / 2, (Screen.height -
crosshair.height) /2, crosshair.width, crosshair.height);
}
// Update is called once per frame
void Update () {
if (cc.isGrounded) { //only apply movement if we are on the ground
moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
if(Input.GetButton("Sprint") && Stat$$anonymous$$eeper.CurrentSta$$anonymous$$a > 0){
currentSpeed = Stat$$anonymous$$eeper.SprintSpeed;
Stat$$anonymous$$eeper.CurrentSta$$anonymous$$a -= Stat$$anonymous$$eeper.Sta$$anonymous$$aDecreaseRateSprint * Time.deltaTime;
Stat$$anonymous$$eeper.IsRunning = true;
}else if(Input.GetAxis("Horizontal") == 0 || Input.GetAxis("Vertical") == 0){
currentSpeed = Stat$$anonymous$$eeper.Speed;
Stat$$anonymous$$eeper.IsRunning = false;
Stat$$anonymous$$eeper.Is$$anonymous$$oving = true;
}else{
Stat$$anonymous$$eeper.IsRunning = false;
Stat$$anonymous$$eeper.Is$$anonymous$$oving = false;
}
//moveDirection.x *= Stat$$anonymous$$eeper.StrafeSpeed;
moveDirection *= currentSpeed;
if (Input.GetButton("Jump") && Stat$$anonymous$$eeper.CurrentSta$$anonymous$$a >= Stat$$anonymous$$eeper.Sta$$anonymous$$aDecreaseRateJump){
moveDirection.y = Stat$$anonymous$$eeper.JumpPower;
Stat$$anonymous$$eeper.CurrentSta$$anonymous$$a -= Stat$$anonymous$$eeper.Sta$$anonymous$$aDecreaseRateJump;
}
}
moveDirection.y -= Stat$$anonymous$$eeper.Gravity * Time.deltaTime;
cc.$$anonymous$$ove(moveDirection * Time.deltaTime);
}
void OnGUI(){
GUI.DrawTexture(position, crosshair);
}
void OnControllerColliderHit(ControllerColliderHit hit) {
Rigidbody body = hit.collider.attachedRigidbody;
if (body == null || body.is$$anonymous$$inematic)
return;
if (hit.moveDirection.y < -0.3F)
return;
Vector3 pushDir = new Vector3(hit.moveDirection.x, 0, hit.moveDirection.z);
body.AddForceAtPosition(pushDir * currentSpeed, hit.point);
}
In my example I used a global stat keeper
@RensDevolp I'm doing a first person game where the player is just a collider (which you can view with the link below), i'm not quite at the level of player controllers just yet.
Actually the character controller component is a collider, (sort of) rigidbody, and controller in one. Just attach my script to an capsule WITHOUT a capsule collider, and then attach an character controller. Then it should work fine. That way, you do not even need an rigidbody. $$anonymous$$y script is just a slightly modified copy-paste from the unity API, and you can use it if you want!
Follow this Question
Related Questions
Proper way to set a RigidBody's maximum velocity 1 Answer
Can only go horizontally while walking on walls, and not vertically 0 Answers
Why is my momentum not carrying over to the X axis? 0 Answers
how to dostraight ball throwing objects from returning? 0 Answers
Keeping a rigidbody character upright, without constraining, grounded or otherwise, with slopes? 1 Answer