- Home /
Is smooth movement possible in Unity with a fixed camera?
Hi guys,
I have been trying for a few days to get Unity to produce smooth movement using a fixed Orthographic (i.e 2d!) camera.
In an effort to work out what is occurring, I have created a new project with just a single untextured cube.. no matter what approach I take to moving the cube (which of course appears as a square with an Ortho camera) the movement from one side of the screen to the other is jerky.
I am deploying to iPhone, but this behaviour happens in the editor as well as on two different iPhones. Note that neither of the iPhones (a 3GS and a 4) have no other applications running in the background!
This jerkiness appears almost rhythmic on the iPhones, but more chaotic in the editor. The jerkiness seems about twice as bad on the iPhone 3GS... i assume this is because the iPhone 4 having double the resolution thus each 'jerk' movement appears half as large.
I have tried adjusting various project settings, and enabling vSync, but to no avail.
I have four tried different approaches to movement:
gameObject.transform.position.x += Time.deltaTime in the Update method;
gameObject.transform.position.x += Time.deltaTime in the FixedUpdate method;
gameObject.transform.position.x += 0.02 in the FixedUpdate method;
..and finally using Vector3.Lerp().
None of these give smooth movement.
Please could anyone tell me how to achieve smooth 2d movement using a fixed Orthographic camera (although the same behaviour also occurs with a Perspective camera).. is it even possible with Unity?
Many thanks....
To begin with, your bit about the orthographic camera is pretty misleading. Can you take that out of the title? I'm pretty sure the camera type is completely irrelevant here.
Show us the faulty code mate, its hard to start guessing where you error might be.
I can produce a smooth moving cube that moves either by keyboard or by frame automatically, no problem. So yes, its possible.
Answer by BerggreenDK · Sep 18, 2011 at 10:40 AM
First of all:
Time.deltaTime
http://unity3d.com/support/documentation/ScriptReference/Time-deltaTime.html
"Description The time in seconds it took to complete the last frame (Read Only).
Use this function to make your game frame rate independent.
If you add or subtract to a value every frame chances are you should multiply with Time.deltaTime. When you multiply with Time.deltaTime you essentially express: I want to move this object 10 meters per second instead of 10 meters per frame.
When called from inside MonoBehaviour's FixedUpdate, returns the fixed framerate delta time."
C#
using UnityEngine;
using System.Collections;
public class example : MonoBehaviour {
void Update() {
float translation = Time.deltaTime * 10;
transform.Translate(0, 0, translation);
}
}
In other words: Time.deltaTime is a fraction of the movement since last frame, if Update is called more than once per frame = smooth movement.
If you use FixedUpdate which is for used for Ridgebody (physics), then you use Time.fixedTime.
In your question you mention that you manipulate the postion.x directly. That might be the cause of your problem.
If you need to do it like that, then keep a local variable for the postion inside the object:
using UnityEngine;
using System.Collections;
public class example2 : MonoBehaviour {
Vector3 = pos;
void Start() {
pos = transform.position; // initialize
}
void Update() {
float curSpeed = Time.deltaTime * 10.0f;
pos.x += curSpeed;
transform.position = pos;
}
}
Hi!
Thanks for your answer; I am already using deltaTime, but I was interested by your statement to not modify the transform directly; I have tried this approach and it seemed to make a difference in my test project with just one cube, but in my game it makes no difference whatsoever.. the jerkiness is still there. I will fully exa$$anonymous$$e my code and post again.
Thanks for the pointer! :)
is it the camera movement that jaggs or the player or the enemies?
It is the enemies. The camera does not move. It looks to me on the 3GS like it occurs almost rhythmically, like breathing. The more i increase the FPS in the AppController .mm the less I notice it, but it is still always there.. Although I have just noticed it seems to occur more pro$$anonymous$$ently at slightly different speeds... In my reply below to my own question I started wondering whether its some sort of rounding error...
Answer by mikeyj21 · Sep 18, 2011 at 01:13 PM
About 3:00 in the morning I was lying in bed thinking about this, and it occurred to me that the problem is probably to do with the fact that the smallest unit of movement is a single pixel. The following might be complete garbage, but here are my thoughts:
With a frame rate of 30fps, this means each frame takes 1 second/30 frames = 0.3334 (rounded to 4 decimal places) seconds to complete. Note that this is a target frame time: the time taken to render each frame varies depending on how much has to be rendered that frame! (This is the reason that deltaTime is used)
However, to my thinking, if you have a target speed of 48 pixels per second (for example you want to move across the 480 pixels iPhone3GS screen in ten seconds), then this means every frame (given our frame rate of 30fps) the sprite has to move 1.6 pixels.... which is of course not actually possible, so I assume some sort of rounding must occur?
It also occurs to me that using the Update() method will (because of the fluctuation in frame time I mentioned earlier) give a variable amount of movement per frame, even if it does mean that the same distance is travelled overall (due to deltaTime).
So, I think the first step is to move my movement code into FixedUpdate, which is set to 50 updates per second (0.02 per frame). This does remain constant, so should give at least a constant movement rate per frame. Note that deltaTime returns the length of time the last FixedUpdate() took when called from within this method.
And, if I edit the AppController.mm file in XCode to give a higher frame rate of 50fps, then there should be a 1:1 relationship between the distance the sprite is moved to the distance to move it per frame
...and these thoughts meant I came downstairs at about 4:30AM to try it out!
Firstly, increasing the frame rate made the problem a lot less noticeable to start with; in retrospect this should have been obvious to me: the more frames per second. the less noticeable each movement should be.
To be honest, I cant see any difference when moving the code from Update() into FixedUpdate(), but logically it makes sense to me!
However, it is not yet perfect, so next I am going to experiment with movement speeds that are exactly divisible by the frame rate (for example, move 50 pixels in a second rather than 48), to see if that helps.....
Any further findings I will post them here; if anyone has any comments (even if to point out that I am writing complete gibberish!) then please don't hesitate to give them. I am learning this stuff as I am going along!
Cheers,
Did you find a solution? I have this same problem. Very simple 2d side scroller scene, stutters periodically. It seems to be linked to vsync. With vsync off and application.targetframrate = 300 it removes the stutter in chrome but makes the game unplayable in safari & firefox. With vsync on it is bad in all browsers. I am desperate to find a solution for this. It seems to be beyond tweaking scripts and something broken with vsync or browser fps caps. Any suggestions or solutions would be very much appreciated.
Answer by harry1244 · Feb 14, 2012 at 11:12 PM
Not wishing to hijack this thread but :-
It doesn't appear to be possible, I have created a 2d plane (2 tris and 4verts) and attached a texture to it, converted it to a prefab and I cannot get smooth movement, I notice there is a "Time" section under the Project setting menu option, this has 3 values in it, but surely you shouldn't have to play around with those. I am kind of thinking that this seems to be only a 3d Engine (although a pretty impressive one), and yes it has 2d but it doesn't seem to perform as you might expect it to.
However, saying all this, I have not tried any of the .unitypackages (such as SM2 etc), can anyone tell me if they are worth it ? or would I get the same performance ?
Thanks
Your answer
Follow this Question
Related Questions
How to know if my player is not moving? 2 Answers
Moving player between pre-determined points 1 Answer
Moving Up, Down, Left and Right via Wasd and the arrow btns?? in 2d 2 Answers
Sprite animation 2 Answers