hello i have this code Code (CSharp): private int multiPlier = 50; private float jumpheight = 150; publicRigidbody rigidbodyonobject; void Start() { rigidbodyonobject = gameObject.GetComponent<Rigidbody>(); } void Update() { if (Input.GetKeyDown(KeyCode.Space) && CheckGrounded() == true) { rigidbodyonobject.AddForce(gameObject.transform.up * Time.deltaTime * jumpheight * multiPlier); print("Jump"); } } private bool CheckGrounded() { if (Physics.Raycast(transform.position, -gameObject.transform.up, out hit, 2f)) { if (hit.collider.gameObject.tag == "floor") { return true; } else { return false; } } return false; } but then sometimes it jump high and sometimes it jump low? any suggestions so it goes a fixed height
use FixedUpdate instead of Update if you're going to be adding forces to Physics. An explanation as to why: https://unity3d.com/learn/tutorials/modules/beginner/scripting/update-and-fixedupdate
@GoofBall101 and @sander0711 - Just remember to use Time.fixedDeltaTime and NOT Time.deltaTime, otherwise you'll be multiplying the time between render frame with something that is using the physics update. In other words, it would speed up and slow down as the FPS goes up and down. And that is massive pain to figure out. Not that I would know about that though...
Code (CSharp): using UnityEngine; using System.Collections; public class PlayerController : MonoBehaviour { private float speed = 5; private int FastSpeed = 15; public KeyCode EnableFastSpeedWithKey = KeyCode.LeftShift; public Transform cameraobject; public Rigidbody rigidbodyonobject; private float jumpheight = 150; private RaycastHit hit; private int multiPlier; // Use this for initialization void Start() { rigidbodyonobject = gameObject.GetComponent<Rigidbody>(); multiPlier = 50; } // Update is called once per frame void FixedUpdate() { #region movement if (Input.GetKey(KeyCode.C)) { transform.localScale = new Vector3(1, 0.5f, 1); } else { transform.localScale = new Vector3(1, 1, 1); } if (Input.GetKeyDown(KeyCode.Space) && CheckGrounded() == true) { rigidbodyonobject.AddForce(gameObject.transform.up * Time.fixedDeltaTime * jumpheight * multiPlier); print("Jump"); } if (Input.GetKey(EnableFastSpeedWithKey)) { speed = FastSpeed; } else { speed = 5; } //VOORUIT if (Input.GetKey(KeyCode.W)) { Vector3 moveDirection = cameraobject.transform.forward; moveDirection.y = 0f; // transform.Translate(moveDirection * Time.deltaTime * speed); transform.localPosition += moveDirection * speed * Time.deltaTime; } //links if (Input.GetKey(KeyCode.A)) { Vector3 moveDirection2 = -cameraobject.transform.right; moveDirection2.y = 0f; transform.localPosition += moveDirection2 * speed * Time.deltaTime; } //rechts if (Input.GetKey(KeyCode.D)) { Vector3 moveDirection3 = cameraobject.transform.right; moveDirection3.y = 0f; transform.localPosition += moveDirection3 * speed * Time.deltaTime; } //acheruit if (Input.GetKey(KeyCode.S)) { Vector3 moveDirection4 = -cameraobject.transform.forward; moveDirection4.y = 0f; transform.localPosition += moveDirection4 * speed * Time.deltaTime; } #endregion } private bool CheckGrounded() { if (Physics.Raycast(transform.position, -gameObject.transform.up, out hit, 2f)) { if (hit.collider.gameObject.tag == "floor") { return true; } else { return false; } } return false; } } so i did this so this is my code now: for the hole playercontrol. but it still jump weird sometimes it jump heigher then other times
"Just use FixedUpdate();" is the simple answer, but it's a bit trickier than that. You are testing Input.GetKeyDown() in FixedUpdate(). That is technically only valid for checking in Update(). For instance, if the key was NOT down, then it becomes down, Input.GetKeyDown() will only show true on the very single frame if you are looking at it in Update(). If you are looking at it in FixedUpdate, which happens at a different framerate than Update, then that Input.GetKeyDown() may return true for more than one frame, triggering multiple applications of your force. It is even possible to completely miss the key going down event. What you want to do is test for the key going down in Update() and set a bool variable that says essentially, "Player has pressed jump." Then in FixedUpdate() you would test that bool variable, and when you apply the jump, clear the variable to false. If done properly, this will ensure a one-to-one mapping between keypresses and impulses added to your character.
so you mean something like this? Roughly not tested Code (CSharp): bool jump = false; void Update() if(input.getkeydown(keycode.space) { jump = true } void fixedupdate() { if(jump == true && isgrounded == true) { //addforce for jump jump = false; } }
I think you would do good to check out a tutorial on character controllers. Here's a really good one by Sebastian Lague: Also, those variable names have got to go. Usually "camel backs" are the way to go. So instead of "jumpheight", try "jumpHeight" with the first word lower case and the first letter of the proceeding words capital. When you do it that way it will write it out correctly in the inspector as "Jump Height" if it's public. Also, also, make sure you're using names that aren't already used for something. "speed" is already used by Unity. Try "mySpeed" or something similar. Also, also, also you're multiplying with deltaTime, not fixedDeltaTime. The fixed update is done 50 times a second (by default), and the regular update is done as fast as possible. Right now you are telling Unity to apply the changes 50 times a second and multiplying it with 1/FPS. Also, also, also, also I noticed you've got a float for "speed" and an int for "FastSpeed". You can sometimes juggle the math between those two variables, but it's best practice to use one or the other. In this case, I would do a public float so you can tweak it in the editor. Honestly, I think you're better of doing a wipe and trying again after doing a few more tutorials. Looking at your code, it looks like you're trying to skip some learning steps.