- Home /
Rigidbody.MovePosition not really smooth
For my personal 3rd person Character controller, I'm using Rigidbody.MovePosition (direction the character is facing). The camera itself (stand-alone game object in the scene) will perfectly smooth follow the character. The character, however, does not move smooth. Moving the line of code containing Rigidbody.MovePosition from FixedUpdate to Update did not solve it.
Now, I've been looking on Google for quite some time on how to do this, and every time people say "use Rigidbody.Velocity". But in the Unity documentation, it states:
"In most cases you should not modify the velocity directly, as this can result in unrealistic behavior. Don't set the velocity of an object every physics step, this will lead to unrealistic physics simulation. A typical example where you would change the velocity is when jumping in a first person shooter, because you want an immediate change in velocity."
So, because I do expect to use an explosion force, I don't want unrealistic physics behavior. I've also looked into Transform.Translate, but this does not really have a great Physics simulation...
Does anyone have any idea how to make my character move smoothly, while still having good collision detection, and not modifying the velocity parameter itself?
This is a pretty common question with a pretty tricky answer. It sounds like you're creating a rigidbody character controller. This may not necessarily be what you want, even when it seems intuitive or obvious.
For a third-person game where the player is controlling a vehicle like a marble or car or spaceship, it may be appropriate. For a game involving an animated character, it's almost certainly not what you want to do.
Can you describe your situation in more detail? We should first establish whether it's appropriate for you to use this approach to drive player motion in your situation.
Edit: The direct answer to your question probably involves velocity accumulated from the physics simulation or calls to methods like AddForce(). If you're moving a rigidbody as described that is also responding to physics, it is experiencing forces which contribute to its motion. Interactions with other objects, drag, friction, etc would explain it not being smooth.
To make clear what I mean, without lots of words: I'm trying to recreate the 3rd person controller as used in the $$anonymous$$$$anonymous$$O Tera. Controls and all are perfectly as it should be, but this slight stutter in moving the character is just annoying. Hopefully this helps?
Answer by Adam-Mechtley · Dec 27, 2016 at 05:46 PM
Hi @DevCas1! Without necessarily disagreeing with @AlwaysSunny's reply above, the answer to your specific question (in case someone searches for it later) is probably related to the fact that the physics timestep is not the same as the rendering timestep. (See the TimeManager documentation.) For example, imagine your fixed timestep is happening at exactly 100hz. If your rendering timestep is equal or less (i.e. 100fps or less) then you should see no issues. If it goes above 100fps, you will appear to drop frames for anything moving during the physics timestep that does not have some kind of interpolation applied. Moving SetPosition/SetRotation calls to the rendering timestep (i.e. Update) will have no effect because their results will not be processed until the next fixed timestep anyway.
This is an excellent point that I completely forgot to make! For a truly "perfect" simulation, all calls to methods such as AddForce belong in FixedUpdate.
In many cases the consequences of calling it elsewhere are negligible, but for every-frame logic, problems will accrue quickly. Thank you for bringing this up!
Answer by AlwaysSunny · Dec 27, 2016 at 04:58 PM
Having glanced at Tera gameplay footage, I'm not convinced driving your player motion with rigidbody physics is wise. There are various discussions of the issues this can cause, and this one is just the tip of the iceberg.
My instinct is to discourage this strategy altogether. I would hazard to say that the overwhelming majority of games with similar movement behaviors are scripting those behaviors by hand, using their engine's physics simulation exclusively for collision detection.
This suggestion also respects the requested response to explosive forces - that can be scripted by hand, bypassing the physics system altogether. Other kinds of reactions with other physically-simulated props in the scene can also be scripted (bumping into cardboard boxes knocks them over, while bumping into heavy crates does not, etc).
I'd strongly recommend switching to a system like this, which is based on Unity's native character controller and its rather-lackluster collision response system. You can build upon it safely, because despite being sparsely featured, it's a strong foundation. (Basically, on collision with a physical prop, you do your own mass-times-acceleration calculation and apply the calculated force to the hit object.)
If you insist on continuing down this path, there are many factors involved which may contribute to the unwanted behavior. Play around with various physics material settings, drag and mass values, etc. Creating a great character controller based on rigidbody physics is difficult even when that strategy is appropriate - you're in dangerous territory with regard to researching / seeking help in your case: Much of what you find may lead you astray, being written by and for folks who are mistaken about the validity of this approach.
As for something useful to work around this specific issue, I suppose I'd recommend greatly increasing the mass or drag, and / or tinkering with the friction of your actor's collider / rigidbody. Perhaps as a corrective measure - in other words, only increase the drag while the controller is receiving input, and only while the controller is grounded and hasn't recently been acted on by another physics object. But be warned, this may be the first of many corrective behaviors, each of which ultimately dilutes the purity of the physics simulation you are relying on.
Refer to my comment on the OP for a proposed explanation of why the behavior is occurring in the first place.
Best,
Thank you @AlwaysSunny and @Adam-$$anonymous$$echtley for all the info! But it's kinda overwhel$$anonymous$$g for a kinda beginning developer ^^;
So, I understand using physics in this case is not particularly the way to go, but what is? Could you please explain what would be your way of doing it, while keeping the collision detection? Indeed, the explosion force can be calculated with directions, which I did not really think of before...
Anyway, thank you for the help, and if you'd like to share your way of making this controller, please feel free
Particularly for those new to coding, starting with Unity's native "third person character controller" from the Standard Assets package is a good bet. If it's written in .js, I strongly advise converting to .cs - I strongly advise using C# exclusively, period. You'll thank me some day.
This gives you a good foundation for building a complete & robust character controller. It will go up stairs properly, includes a jump action, good collision detection, and binds well to mecanim animations. I don't think it includes a crouch function or anything more complex than what's above, but that's where you come in with your own code.
You could also maybe find a free or cheap asset which expands upon this controller to help you get started faster, but it's not necessary. Character controllers for games with many interesting actions are no small topic. Start small and be patient.
As for adding physical reactions, that's not too hard. Basically any time you collide with something, you'll trigger an OnCollisionEnter or OnCollisionStay call. You can insert code into these calls which causes your character to act on and react to those collisions using simple physics formulas.
I can't remember whether kinematic rigidbodies report their velocity, but if not, keeping your own velocity is as easy as comparing your position last frame to your position this frame. Use your character's velocity times its mass to find a force vector to add to the object you bumped into. Likewise, the object you bumped into (or that was forced into you) applies a force to you in a similar way, except it doesn't use AddForce because you're kinematic. Ins$$anonymous$$d you have to write your own logic for how your character should behave, e.g. slowing down while pushing light objects or being pushed in the direction of objects that are e.g. thrown at you.
This is a really deep topic, so again, be patient and have fun with the learning process!
@AlwaysSunny We exclusively learn C# at school, and seen I'm in the second year, I'm not completely new to coding, just the way of creating things is still a bit new to me. Definitely deciding in which way it needs to be coded. I'll look into Unity's 3rd person controller, but my goal was to create a fully functional basic 3rd person controller from scratch... That part is kinda gone with using Unity's controller. But I can always decompile their controller, and see what they did
@AlwaysSunny We exclusively learn C# at school, and seen I'm in the second year, I'm not completely new to coding, just the way of creating things is still a bit new to me. Definitely deciding in which way it needs to be coded. I'll look into Unity's 3rd person controller, but my goal was to create a fully functional basic 3rd person controller from scratch... That part is kinda gone with using Unity's controller. But I can always decompile their controller, and see what they did