Hi, i found some time and took a look at the build Unity offers, these are my quick thoughts, perceptions and a solution, please dont mind my dirty writing style, i wrote it while scripting this out:
- Info (blabla)
- Solution Info (blablablabla)
- Solution Source (skip above and just test those damn scripts)
1. INFO:
Yes, it is stuttering like shit and the Unity-Interpolation doesn’t do anything, why do they even release something like this??
- 3 possible sources of the stutter: camera-movement-script, parallax-scrolling-script and the character-controlling-scripts
Parallax script: Should be fine, it updates in Update()… but we keep in mind that the camera-script may be called before the scrolling-script, so we should set the camera Updater to LateUpdate() later.
Camera Follow: uses Fixed Update, that means the camera re-positioning happens in physics frames, not in the render frames. We have to fix this! (-> put every “transform.position = …” into Late Update and inter-/extrapolate the Rigidbody-position-input for the renderframes)
Character Controller: The CharacterController is a script that sets the Characters velocity and applies forces, so everything in here is physic-engine dependent, nothing is setting positions directly, that’s fine so far.
We take a look at the Character Game Object and find that it has Rigidbody Interpolation enabled so if we access the transform position of that gameobject in Update(), it should appear smooth due to Interpolation (Unity - Manual: Rigidbody component reference), but it isn’t.
2. SOLUTION INFO:
Solution1. You could set the Camera to follow the interpolated rigidbody position (renderPos in script):
-problem, rigidbodys will still jitter around like crap, try the source. In this source the Camera is pinned to the renderPos. I also edited the “TrackPlayer”-function because the smooth follow was messed up because it was tied to the jumpy rigidbody. In code, look for this to switch between inter or extrapolation, tracking mode is set via a bool flag:
void LateUpdate (){
//Choose Inter, or Extrapolation:
CameraInterpolation();
// CameraExtrapolation();
//default track function, if you like it, set the trackFunction bool
if(trackFunction){TrackPlayerNEW();}
}
Solution2. You could detach the Rendered parts of the Rigidbody and move them independent to the renderPos from the rigidbody (you can also use this position as camera placement origin =Solution1). (Be aware that if the audio-listener is on the character and a renderObject has a 3D- Audio source on it, it could create weird stereo effects, move the listener to a renderObject).
But detaching may be bad for some reasons or could interfere with existiing code that accesses childs. So you can also keep the Renderparts as children and only add an temporary Offset to them (reset this offset in the next frame because we get a new offset that is independent of tzhe first). Just gather all children in the Character that have an “Sprite Renderer” Component.
Bonusblablabla: Basically Solution2 tries to give all visible parts of a rigidbody-gameObject a new position that is updated every render-frame instead of every physics-frame. Physic-frames have no timing-connection with render-frames. A Render-frame just samples the last rigidbody-position of the rigidbody - and this could happen twice between two physic-frames. The rigidbody-position is updated in FixedUpdate() and 2 Updates()calls could happen before the next FixedUpdate()call. Practical Example: If you have 50physic-frames/s and 60 render-frames/s(both very common values), about 10 positions per second would be sampled twice and jitter is introduced. Setting fixedTimestep to a value that yields 60 physic frames is also not a guaranteed jitter-kill since render-frames can vary greatly and you would have a double sample every once in a while.
3. SOLUTION SOURCE:
Solution1: replace “CameraFollow.cs” with this file and test the build, background will stop stuttering
after that
Solution2: additional to above, attach this component “SmoothRigidbodyRender.cs” to the hero (and or enemies) to stop the now visible rigidbody stuttering
It is perfectly smooth in standalone, except the health bar that my scripts don’t touch yet.
*however, one problem remains with the scripts, i don’t know anything about sprite animations and how they work but they seem to manipulate the actual localPositions of the sprites and reset them from time to time, so my script messes up those animations, i did a small workaround to disable animations. … but if you create a child - within the RigidbodyObject - that holds the animation logic and all gameObjects that have SpriteRenderers, then you could set that child to renderPos and animations should still work…
If you have any questions or problems to understand why we have jitter in the first place, just ask
1697435–106624–CameraFollow.cs (3.75 KB)
1697435–106625–SmoothRigidbodyRender.cs (2.9 KB)