- Home /
Rigidbody velocity capped at 0.4
Hi
I have a sphere that I move by applying a force, my problem is that the velocity is capped at 0.4 when that force is on the vertical axis unless at some point in time I applied a force on the horizontal axis.
Code follows :
void inputMovement(){
float moveHori = 0;
float moveVert = 0;
//float moveHorizontal = Input.GetAxis("Horizontal");
//float moveVertical = Input.GetAxis("Vertical");
//right
if (Input.GetKey (KeyCode.D)) {
moveHori = 1;
}
//left
if (Input.GetKey (KeyCode.A)) {
moveHori = -1;
}
//forward
if (Input.GetKey (KeyCode.W)) {
moveVert = 1;
}
//back
if (Input.GetKey (KeyCode.S)) {
moveVert = -1;
}
Vector3 movement = new Vector3 (moveHori, 0, moveVert);
rigidbody.AddForce (movement * speed * Time.deltaTime);
}
speed = 500
Example situation :
Game starts and sphere is intantiated.
I press W/S and sphere moves forward/backward. rigidBody.velocity prints as 0.4.
Now press only A/D and sphere moves left/right. rigidBody.velocity prints as changing value.
Now press W/S and sphere moves forward/backward. rigidBody.velocity now print correctly.
Thanks
More code as requested : In the same script as input movement :
public float speed;
void FixedUpdate(){
if(networkView.isMine){
inputMovement();
}
}
In my network manager script I instantiate player as follows :
private void SpawnPlayer(){
// Instantiate the player on the network
GameObject player = (GameObject) Network.Instantiate(playerPrefab, new Vector3(0f, 0f, 0f), Quaternion.identity, 0);
player.transform.Find ("PlayerCamera").gameObject.SetActive (true);
player.GetComponent<Player> ().enabled = true;
}
In my script that updates players on the network :
void FixedUpdate(){
if(!networkView.isMine){
transform.position = Vector3.Lerp(transform.position, truePos, 0.1f);
transform.rotation = Quaternion.Lerp(transform.rotation, trueRot, 0.1f);
}
}
void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info){
Vector3 pos = transform.position;
Quaternion rot = transform.rotation;
if(stream.isWriting){
stream.Serialize (ref pos);
stream.Serialize (ref rot);
}else{
stream.Serialize(ref pos);
stream.Serialize(ref rot);
truePos = pos;
trueRot = rot;
}
}
I doubt it has something to do with my network code though as this happens even when only the servers player is connected and moving.
==UPDATE==
I found that I froze the rigidbodd's rotation, after unfreezing the problem still exists but this time the cap is 2 instead of 0.4
==UPDATE==
I found that tweaking the sphere collider radius increases/decreases the velocity cap but doesn't unlimit it completely.
Also if I turn convex on the mesh collider of the plane it's rolling on on then the problem is fixed but then the plane is bigger than it looks.
I would think it has something to do with how you are starting your code out. Is there anyway we can see more code?
Also put input into update ins$$anonymous$$d of fixedupdate $$anonymous$$y game also used fixedupdate and a lot of times fixed won't catch input where update will. $$anonymous$$ost of the time there are more update frames than fixed.
I will try this just to see if it fixes the problem however I have found various people recommending to put forces in FixedUpdate(can't remember the reason though).
All Physics code should run through FixedUpdate()
It keeps it framerate independent.
Answer by StewVanB · Jun 21, 2014 at 05:47 PM
Try using this with a lower speed:
rigidbody.AddForce(movement * speed * Time.deltaTime,ForceMode.VelocityChange);
Adding this ForceMode should make the acceleration feel more immediate.
Nope doesnt work
Created a new project and all I did was add a plane(as the floor), a sphere as the player, and two cubes to be on the x axis and z axis. I then test the time it takes the sphere to reach each cube and its different. Would you $$anonymous$$d trying this your side and seeing if you get the same result?
Script to control the player that I use :
using UnityEngine;
using System.Collections;
public class Player$$anonymous$$ovementController : $$anonymous$$onoBehaviour {
public float speed;
float start = 0;
float end = 0;
void FixedUpdate(){
float moveX = Input.GetAxis("Horizontal");
float moveZ = Input.GetAxis("Vertical");
if ((moveX != 0) & (start == 0)) {
start = Time.realtimeSinceStartup;
}
if ((moveZ != 0) & (start == 0)) {
start = Time.realtimeSinceStartup;
}
Vector3 movement = new Vector3(moveX, 0.0f, moveZ);
rigidbody.AddForce(movement * speed * Time.deltaTime, Force$$anonymous$$ode.VelocityChange);
Debug.Log ("Start : " + start);
Debug.Log ("End : " + end);
Debug.Log ("Time : " + (end-start));
}
void input$$anonymous$$ovement(){
}
void OnCollisionEnter(Collision collision) {
if (collision.gameObject.name.Equals("XCube")) {
end = Time.realtimeSinceStartup;
}else if(collision.gameObject.name.Equals("ZCube")){
end = Time.realtimeSinceStartup;
}
}
}
I set speed at 20 and the x and z cubes 10 units from origin. If not using Force$$anonymous$$ode.VelocityChange I use speed = 500 or 1000, either works.
I don't believe that the issue is your code. It is in the way you are thinking about your problem. Since you are using gravity your sphere is being slowed by the contact with the ground plane.
Force$$anonymous$$ode.VelocityChange applies the force needed to make the object move at full speed instantly.
If you import the "Physics $$anonymous$$aterials" in the asset menu you can set the sphere to be "Ice" which will lower the friction between the sphere and the ground.
The original question was about why your velocity was capped, so I don't see how the time is relevant.
What is the issue now?
Ok yes the original problem has been fixed, the problem is now that my sphere accelerates faster on the x axis than it does on the z axis unless I apply a force on the x axis before the z.
Essentially the original problem just ins$$anonymous$$d of velocity being on the z axis I accelerate slower on z under same conditions.
Solution The ball moves the same speed in X and Z. Compare this to your current setup and see what is wrong.