Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by SecurityOstrich · Aug 09, 2017 at 09:47 PM · physicscontrollertimebeginnerfixedupdate

Should I be using time.fixedDeltaTime here?

I'm very new and working on a simple fps movement script based on various tutorials I've found. I find my movement is not as completely smooth as I would like it to be. I am wondering if this:

     private void Run()
     {
         vel.z = vInput * speed;
         vel.x = hInput * speed;
     }
     private void FixedUpdate()
     {
         Run();
         Jump();
         rb.velocity = transform.TransformDirection(vel);
     }

should be using Time.fixedDeltaTime when setting the vel vector's x and z to the key input.

Should I be using deltaTime somewhere here, should I be using SmoothDamp, or Lerp? I don't yet understand exactly where and how I should be applying these tools for the smooth, consistent movement I want. I'll paste the entire (fairly short) script below in case anyone has any pointers for me. Thanks.

 using UnityEngine;
 
 public class PlayerMovement_1P : MonoBehaviour
 {
     private Rigidbody rb;
     private Vector3 vel;
     private float vInput, hInput, jumpInput;
     public float speed, jumpVel, distToGround, downAccel;
     public LayerMask ground;
 
     private void Start()
     {
         if (GetComponent<Rigidbody>())
             rb = GetComponent<Rigidbody>();
         else
             Debug.LogError("The character needs a rigidbody.");
 
         vInput = hInput = jumpInput = 0;
         vel = Vector3.zero;
     }
 
     private void GetInput()
     {
         vInput = Input.GetAxis("Vertical");
         hInput = Input.GetAxis("Horizontal");
         jumpInput = Input.GetAxisRaw("Jump");
     }
 
     private void Run()
     {
         vel.z = vInput * speed;
         vel.x = hInput * speed;
     }
 
     private void Jump()
     {
         if (jumpInput > 0 && IsGrounded())
         {
             vel.y = jumpVel;
         }
         else if (jumpInput == 0 && IsGrounded())
         {
             // Zero out y vel when on ground and not jumping
             vel.y = 0;
         }
         else
         {
             // Not grounded - falling
             vel.y -= downAccel;
         }
     }
 
     bool IsGrounded()
     {
         return Physics.Raycast(transform.position, Vector3.down, distToGround, ground);
     }
 
     private void Update()
     {
         GetInput();
     }
 
     private void FixedUpdate()
     {
         Run();
         Jump();
         rb.velocity = transform.TransformDirection(vel);
     }
 }
 
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

5 Replies

· Add your reply
  • Sort: 
avatar image
3
Best Answer

Answer by FlaSh-G · Aug 12, 2017 at 09:43 AM

Edit: When writing this answer, I overlooked the fact that you are setting a rigidbody velocity. A velocity is already "distance / time", so multiplying with Time.deltaTime would divide by time again, leaving you with "distance / time²", which is an acceleration, not a velocity. So, in your case, the Rigidbody internally uses Time.deltaTime already when applying its velocity, thus you shouldn't use it. Thanks @senilo for pointing that out.

Original answer:

FixedUpdate does not get called with constant timesteps - that is impossible on modern computers. But it does act like it is - by getting called more or less often in order to have the correct number of calls on average. This allows FixedUpdate code to assume a constant call rate even though there is none, so you don't have to multiply with Time.deltaTime (which, by the way, during FixedUpdate has the same constant value as Time.fixedDeltaTime).

The game will run in a deterministic way using FixedUpdate - and multiplying the (then-)constant factor of Time.deltaTime will not change that in any way.

However, the value still functions as a "per second". If you move by one meter every FixedUpdate, with the default fixed timestep of 0.02, you move 50 meters per second. So putting your speed factor to 1 means 50 m/s, which seems quite arbitrary. If you want a speed of exactly 6 m/s, you might already want to whoop out the calculator. Even worse: If you change your project's fixed timestep at some point, your scripts will change their behaviour. Top speeds will have to be fixed on all objects.

So, multiplying Time.deltaTime in FixedUpdate does serve a purpose: It changes the semantics of the values you set in your script's properties from "per fixedupdate" to "per second" and makes your scripts more robust to changes in the project's fixed timestep. Thus, I recommend using it.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image senilo · Aug 12, 2017 at 10:12 AM 0
Share

But in this case the velocity is set directly so it doesn't make sense to multiply with the time step

avatar image FlaSh-G · Aug 12, 2017 at 11:48 AM 0
Share

Oh, you are absolutely correct. I will update my answer.

avatar image
1

Answer by merkaba48 · Aug 09, 2017 at 10:05 PM

Unsure, and there'll hopefully be a better answer on its way, but have you tried setting the rigidbody's Collision Detection field to 'continuous'? It will be more expensive but it will give better physics calculations; not something you want for most things, but for the player.

Also I notice you are using input to determine whether to add velocity within the fixed update; be warned that input is only updated immediately after the Update() method, and persist until the end of the next Update(). So if for example you pressed Jump and 3 fixed updates occurred before the next update, your fixedupdates will have that same jump input for those 3 updates. You're checking if the player is on the ground so you shouldn't notice the extra jump inputs (and by default there's only about 1 fixed update per update anyway), but I thought I'd mention it. One fix would be to set a bool in Update() that says whether to jump or not, then clear that bool as soon as it's resolved in fixedupdate so future fixedupdates that frame aren't affected.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image SecurityOstrich · Aug 09, 2017 at 10:26 PM 0
Share

I just assumed the velocity change should be in FixedUpdate and that getting input should be in Update. Would it make more sense to move something around?

avatar image
-1

Answer by GeroNL · Jan 24, 2021 at 04:26 AM

Try do like this :

  private void FixedUpdate()
  {   
      IsGrounded();
  {
  private void Update()
  {
      Input();
      Run();
      Jump();
      rb.velocity = transform.TransformDirection(vel);
  }

  • You can see this life cycle in here : https://docs.unity3d.com/Manual/ExecutionOrder.html

  • As you can see in the life cycle, the FixedUpdate called multiple times in one cycle, why the reason i put IsGrounded() in the FixedUpdate() is maybe when my character in the ground it not called and throug the object that should called true value.

  • That is just example for it, but when it's not needed(not troubling/ make a bug like i said before) you can put it in Update() after move or before input, it can gaining more FPS cause it just called one time.

[Edited]

  • Use Time.deltaTime that called in Update() and Use Time.fixedDeltaTime that called in FixedUpdate().

[Edited]

Hope it helps.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image FlaSh-G · Jan 24, 2021 at 08:24 AM 0
Share
  1. You can use Time.deltaTime anywhere. In a FixedUpdate context, this property will return the same value as Time.fixedDeltaTime. So no need to distinguish.

  2. Yes, FixedUpdate can be called multiple times between one Update, but Update can also happen multiple times between two FixedUpdates. In fact, since FixedUpdate runs an average of 50 times per frame with the default setting, in a 60fps context, Update will be called more often than FixedUpdate.

  3. Putting a few lines of code in Update or FixedUpdate will not create a noticeable difference in fps. However, in your example, you are setting Rigidbody.velocity in Update, which is never a good idea. Either FixedUpdate runs multiple times between two Updates, in which case the velocity is not updates between two movement ticks, or Update runs multiple times between two FixedUpdates, which means that you're overwriting the first value you've set without never even actually applying it, because the rigidbody updates its position with its velocity during the FixedUpdate cycle.

avatar image GeroNL FlaSh-G · Jan 24, 2021 at 09:56 AM 0
Share

Ahh, it's mean it is call it fixed cause it's steady in certain time and delta time by time per cycle. thanks sir, good to have new thing.

avatar image
0

Answer by Igor_Vasiak · Aug 09, 2017 at 10:45 PM

If you want smooth movement you should use Rigidbody.AddForce(). It's like that:

 [SerializeField]private float speed;
 private Rigidbody rbody;
 
 private float inputH, inputV;
 
 void Start ()
 {
     rbody = GetComponent<Rigidbody>();
 }
 
 void FixedUpdate ()
 {
 
     inputH = Input.GetAxis("Horizontal");
     inputV = Input.GetAxis("Vertical");
 
     float moveX = inputH * speed * Time.fixedDeltaTime;
     float moveZ = inputV * speed * Time.fixedDeltaTime;
 
     rbody.velocity = new Vector3(0, rbody.velocity.y,0);
 
     rbody.AddForce(transform.Forward * moveZ * Time.fixedDeltaTime, ForceMode.Force);
     rbody.AddForce(transform.Right * moveX * Time.fixedDeltaTime, ForceMode.Force);
 
 }

Hope I've helped.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image SecurityOstrich · Aug 09, 2017 at 10:49 PM 0
Share

Thanks for your suggestion, however I'm looking for unrealistically snappy FPS-style controls, just more consistent, smooth ones than I have. addForce made things very slidey and doesn't seem suited to this type of control scheme.

avatar image Igor_Vasiak SecurityOstrich · Aug 09, 2017 at 10:59 PM 1
Share

So, ins$$anonymous$$d of using AddForce try this:

 [SerializeField]private float speed;
 private Rigidbody rbody;
 
 private float inputH, inputV;
 
 void Start ()
 {
     rbody = GetComponent<Rigidbody>();
 }
 
 void FixedUpdate ()
 {
 
     inputH = Input.GetAxis("Horizontal");
     inputV = Input.GetAxis("Vertical");
 
     float moveX = inputH * speed * Time.fixedDeltaTime;
     float moveZ = inputV * speed * Time.fixedDeltaTime;
 
     rbody.velocity = new Vector3(moveX * Time.fixedDeltaTime, rbody.velocity.y, moveZ * Time.fixedDeltaTime);
 
 }
avatar image SecurityOstrich Igor_Vasiak · Aug 09, 2017 at 11:06 PM 0
Share

So I should actually be doing the input * speed part IN fixedupdate? Thanks, I'll try this and see if it helps. :)

avatar image
0

Answer by senilo · Aug 12, 2017 at 09:19 AM

Try to apply the velocity directly in Update(), I don't see any reason why you have to do it in FixedUpdate()

The default timestep for FixedUpdate() is 50 Hz, so if your game is running at 60 fps, you don't apply the controls on every frame.

Try this:

     private void Update()
     {
         GetInput();
         Run();
         Jump();
         rb.velocity = transform.TransformDirection(vel);
     }


Edit: and decrease the physics time step

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image FlaSh-G · Aug 12, 2017 at 09:33 AM 0
Share

There is a reason. Wrote a wall of text about this yesterday: answers.unity3d.com/questions/1391935/timedelta-problems.html?childToView=1392582#answer-1392582

avatar image senilo FlaSh-G · Aug 12, 2017 at 10:15 AM 0
Share

In this case the velocity is set directly so it would not make any difference, but you are right that the physics calculations are still only 50 Hz so it would not help. I have updated the answer with that the time step have to be be decreased

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

120 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How often does the internal physics calculation get called? 1 Answer

Physics update on certain objects. 2 Answers

"Fast" fixed timestep 1 Answer

Is there an equivalent of Time.frameCount for physics updates? 1 Answer

Input and applying physics, Update or FixedUpdate? 3 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges