Performance problems in a simple 2D game

Hello,

I’m having performance problems in 2D scene with a iPhone 3GS. Is a scrolling game. Every time a new platform comes into the camera frustum all platform objects are starting to Jitter (editor and iPhone). I stripped already all physics out of the game and tried to Disabled dynamic batching. The platforms are not moving anymore after the got respawned. The total mesh objects is always the same.

A second problem is that the platforms are staring to ghost with 30 fps on the device.

Here are two pics from my setup.

Camera code:

private Transform thisTransform;
	public static bool isCameraReadyToMove = false;
	public float extraSpeed = 0.015f;
	public float cameraSpeed = 16.6f;
	public static int shapesCounter;
	private Vector3 position;

	void Awake ()
	{
		thisTransform = transform;
	}
	
	void Start ()
	{	
		shapesCounter = 0;
		isCameraReadyToMove = false;
		
		position = thisTransform.position;
	}
		
	void OnLateUpdate ()
	{
		if (isCameraReadyToMove) {

			
//			if (shapesCounter > 0) {
//				cameraSpeed += extraSpeed;
//				
//				shapesCounter = 0;
//	
//			}
			
			position.y = Mathf.Lerp (position.y, position.y - cameraSpeed, Time.deltaTime);
			
			thisTransform.position = position;
		}
		
	}

What I’m doing wrong here?

Peter

Thats your only code? How many platforms do you have? If lots, aka too many, think of swapping, from a pool. Is the game endless?

It’s almost all the code thats currently left inside the game. Each platform also has some simple code inside an OnBecameInvisible () function for moving it to the new location.

There are 10 platforms inside the game and the gameplay is endless. each Platform exist out of 13 mesh objects. Even strip the platform count to 5 and spreading them equally across the screen does not make any difference.

My camera is not following a particular object but just gives a overview. Can it be interpolation?! How to interpolate the camera if it’s not following a Rigidbody?

hmmm need more data. Got profiler?

Here are a few profiler samples:


iPhone Unity internal profiler stats:
cpu-player> min: 7.1 max: 14.9 avg: 10.1
cpu-ogles-drv> min: 1.1 max: 3.6 avg: 1.5
frametime> min: 13.3 max: 29.5 avg: 17.3
draw-call #> min: 6 max: 6 avg: 6 | batched: 101
tris #> min: 860 max: 970 avg: 922 | batched: 2688
verts #> min: 1720 max: 1940 avg: 1844 | batched: 1816
player-detail> physx: 0.3 animation: 0.0 culling 0.0 skinning: 0.0 batching: 2.0 render: 1.1 fixed-update-count: 0 … 1
mono-scripts> update: 3.0 fixedUpdate: 0.0 coroutines: 0.0
mono-memory> used heap: 303104 allocated heap: 364544 max number of collections: 0 collection total duration: 0.0

iPhone Unity internal profiler stats:
cpu-player> min: 7.2 max: 14.0 avg: 10.7
cpu-ogles-drv> min: 1.1 max: 3.4 avg: 1.5
frametime> min: 13.4 max: 19.4 avg: 16.6
draw-call #> min: 5 max: 6 avg: 5 | batched: 101
tris #> min: 860 max: 970 avg: 915 | batched: 2668
verts #> min: 1720 max: 1940 avg: 1830 | batched: 1802
player-detail> physx: 0.3 animation: 0.0 culling 0.0 skinning: 0.0 batching: 2.1 render: 1.1 fixed-update-count: 0 … 1
mono-scripts> update: 2.9 fixedUpdate: 0.0 coroutines: 0.0
mono-memory> used heap: 303104 allocated heap: 364544 max number of collections: 0 collection total duration: 0.0

iPhone Unity internal profiler stats:
cpu-player> min: 7.7 max: 13.4 avg: 10.0
cpu-ogles-drv> min: 1.1 max: 3.2 avg: 1.8
frametime> min: 14.0 max: 19.1 avg: 16.6
draw-call #> min: 5 max: 5 avg: 5 | batched: 100
tris #> min: 860 max: 970 avg: 911 | batched: 2660
verts #> min: 1720 max: 1940 avg: 1822 | batched: 1794
player-detail> physx: 0.3 animation: 0.0 culling 0.0 skinning: 0.0 batching: 2.4 render: 0.6 fixed-update-count: 0 … 1
mono-scripts> update: 2.7 fixedUpdate: 0.1 coroutines: 0.0
mono-memory> used heap: 303104 allocated heap: 364544 max number of collections: 0 collection total duration: 0.0

iPhone Unity internal profiler stats:
cpu-player> min: 7.1 max: 13.0 avg: 10.0
cpu-ogles-drv> min: 1.1 max: 3.2 avg: 1.7
frametime> min: 13.3 max: 26.3 avg: 17.2
draw-call #> min: 5 max: 5 avg: 5 | batched: 101
tris #> min: 860 max: 970 avg: 918 | batched: 2681
verts #> min: 1720 max: 1940 avg: 1836 | batched: 1808
player-detail> physx: 0.3 animation: 0.0 culling 0.0 skinning: 0.0 batching: 2.4 render: 0.8 fixed-update-count: 0 … 1
mono-scripts> update: 2.7 fixedUpdate: 0.0 coroutines: 0.0
mono-memory> used heap: 303104 allocated heap: 364544 max number of collections: 0 collection total duration: 0.0

iPhone Unity internal profiler stats:
cpu-player> min: 6.8 max: 12.3 avg: 9.9
cpu-ogles-drv> min: 1.1 max: 2.3 avg: 1.5
frametime> min: 14.6 max: 27.5 avg: 17.3
draw-call #> min: 5 max: 6 avg: 5 | batched: 102
tris #> min: 860 max: 970 avg: 935 | batched: 2732
verts #> min: 1720 max: 1940 avg: 1871 | batched: 1843
player-detail> physx: 0.3 animation: 0.0 culling 0.0 skinning: 0.0 batching: 2.2 render: 0.9 fixed-update-count: 0 … 1
mono-scripts> update: 2.8 fixedUpdate: 0.0 coroutines: 0.0
mono-memory> used heap: 303104 allocated heap: 364544 max number of collections: 0 collection total duration: 0.0

iPhone Unity internal profiler stats:
cpu-player> min: 6.7 max: 12.8 avg: 9.6
cpu-ogles-drv> min: 1.1 max: 3.4 avg: 1.8
frametime> min: 13.7 max: 29.0 avg: 17.2
draw-call #> min: 6 max: 6 avg: 6 | batched: 102
tris #> min: 860 max: 970 avg: 935 | batched: 2728
verts #> min: 1720 max: 1940 avg: 1870 | batched: 1842
player-detail> physx: 0.3 animation: 0.0 culling 0.0 skinning: 0.0 batching: 2.4 render: 0.8 fixed-update-count: 0 … 1
mono-scripts> update: 2.7 fixedUpdate: 0.0 coroutines: 0.0
mono-memory> used heap: 303104 allocated heap: 364544 max number of collections: 0 collection total duration: 0.0

iPhone Unity internal profiler stats:
cpu-player> min: 7.4 max: 13.0 avg: 10.0
cpu-ogles-drv> min: 1.1 max: 3.2 avg: 1.7
frametime> min: 14.0 max: 26.0 avg: 17.3
draw-call #> min: 6 max: 6 avg: 6 | batched: 102
tris #> min: 860 max: 970 avg: 932 | batched: 2719
verts #> min: 1720 max: 1940 avg: 1864 | batched: 1836
player-detail> physx: 0.3 animation: 0.0 culling 0.0 skinning: 0.0 batching: 2.4 render: 0.5 fixed-update-count: 0 … 1
mono-scripts> update: 2.7 fixedUpdate: 0.0 coroutines: 0.0
mono-memory> used heap: 303104 allocated heap: 364544 max number of collections: 0 collection total duration: 0.0

iPhone Unity internal profiler stats:
cpu-player> min: 6.5 max: 14.2 avg: 9.5
cpu-ogles-drv> min: 1.1 max: 5.0 avg: 1.6
frametime> min: 12.9 max: 28.2 avg: 17.2
draw-call #> min: 5 max: 6 avg: 5 | batched: 101
tris #> min: 860 max: 970 avg: 918 | batched: 2680
verts #> min: 1720 max: 1940 avg: 1837 | batched: 1809
player-detail> physx: 0.3 animation: 0.0 culling 0.0 skinning: 0.0 batching: 2.2 render: 1.0 fixed-update-count: 0 … 1
mono-scripts> update: 2.7 fixedUpdate: 0.0 coroutines: 0.0
mono-memory> used heap: 303104 allocated heap: 364544 max number of collections: 0 collection total duration: 0.0

iPhone Unity internal profiler stats:
cpu-player> min: 7.1 max: 13.2 avg: 9.6
cpu-ogles-drv> min: 1.1 max: 3.3 avg: 1.5
frametime> min: 15.2 max: 27.6 avg: 17.3
draw-call #> min: 5 max: 5 avg: 5 | batched: 101
tris #> min: 860 max: 970 avg: 915 | batched: 2671
verts #> min: 1720 max: 1940 avg: 1830 | batched: 1802
player-detail> physx: 0.3 animation: 0.0 culling 0.0 skinning: 0.0 batching: 2.1 render: 1.4 fixed-update-count: 0 … 1
mono-scripts> update: 2.7 fixedUpdate: 0.0 coroutines: 0.0
mono-memory> used heap: 303104 allocated heap: 364544 max number of collections: 0 collection total duration: 0.0

iPhone Unity internal profiler stats:
cpu-player> min: 7.4 max: 15.9 avg: 10.2
cpu-ogles-drv> min: 1.1 max: 2.8 avg: 1.5
frametime> min: 13.4 max: 28.0 avg: 17.4
draw-call #> min: 5 max: 5 avg: 5 | batched: 100
tris #> min: 860 max: 970 avg: 911 | batched: 2660
verts #> min: 1720 max: 1940 avg: 1822 | batched: 1794
player-detail> physx: 0.3 animation: 0.0 culling 0.0 skinning: 0.0 batching: 2.2 render: 1.2 fixed-update-count: 0 … 1
mono-scripts> update: 2.7 fixedUpdate: 0.0 coroutines: 0.0
mono-memory> used heap: 303104 allocated heap: 364544 max number of collections: 0 collection total duration: 0.0

Peter.

Judging by that, it should be running at between 30 and 60fps. Perhaps you’ve missed a deltaTime multiplication somewhere and it is causing jerking?

frametime> min: 13.4 max: 28.0 avg: 17.4 - with some optimisation you could set the framerate at 60fps and remain smooth. I think the problem is:

position.y = Mathf.Lerp (position.y, position.y - cameraSpeed, Time.deltaTime);

And that should be in update (and rewritten).

hippocoder,

What do you mean with rewritten? Something like this: position.y = Mathf.Lerp (position.y, position.y - 1.0f, cameraSpeed * Time.deltaTime);

Thanks for clarifying :wink:

Peter.

Can you get us the profiler output straight from the device? the above posted one is obviously from the editor or desktop yet the one from the device would be much more usefull and would pinpoint the problem pretty much for sure

Here are two pictures. Can it be that the profiler is improved in 3.5.3? Never mind :face_with_spiral_eyes: . How can I improve the performance of Dynamic Batching?

Peter.

I’m using this shader:

Shader "Mobile/Vertex Colored Lighting On" {
Properties {
    _Color ("Main Color", Color) = (1,1,1,1)
    _MainTex ("Base (RGB)", 2D) = "white" {}
}

SubShader {
    Tags { "RenderType"="Opaque" }
	//LOD 150

    
    Pass {
        Material {
            Ambient [_Color]
            Diffuse [_Color]
        }
        
        
        Lighting On
        Fog { Mode Off }
        

        SetTexture [_MainTex] {
            Combine texture * primary Double, texture * primary
        }
    }
}

//Fallback "Mobile/VertexLit", 1
}

To be clear are you aiming at 30 or 60fps for this? some jerkiness is to be expected for 3GS and you should probably remove blending for the background layer and use a fullbright shader. You can increase speed exponentially with great GLSL shaders. A friend is releasing 30+ mobile GLSL shaders for 30 dollars on asset store soon which he uses to get to 60fps on 3GS and droids.

On 30 Fps the whole game starts to ghost on the device. 60 Fps runs smooth on a iPhone 4S and most of the time also on a 4 with native device resolution.

I can’t wait for that shader package :sunglasses: .

Peter.

Dynamic Batching isn’t gonna help you and you can’t raise its performance as it just means mesh recreation every single frame for it to do its work which is whats hitting you unluckily.

You should consider using static batching where possible, either from the editor or the function that unity offers you to create a ‘static batch’ basically on the fly

As a first step though I would go to the player settings and disable dynamic batching and check it again in that situation to verify that drawcalls are really a problem.
Depending on the OS version it could also just be the OS version in question as the drivers got much better at handling draw calls in iOS5+, while they aren’t that good in 4.0 and 4.1 and I wouldn’t test against iOS6 from personal experience right now when it comes to performance on 256MB RAM devices

Hippocoders advice above on the other hand is irrelevant. With only 0.5ms of your frametime going there while over 14 go into opaque drawing, you definitely need to get your opaque drawing fixed, you simply force too much in there right now.

dreamora,

I’m gonna work on it and thanks for taking a look at those pictures.

Peter.

Optimization process seems to do his work perfectly.
But this routine also consumes memory and you have an high rate on “batched” value…

In your case this could be the issue I guess?

What part of:

Flew completely over your head?

In any case, static batching should clear some of it up. But that doesn’t mean skimp on shaders.

The fact that his background blending is absolutely unimportant as it is 1/28th of the frametime of his opaque rendering which is killing the framerate. You don’t go around explaining morph target animation to someone asking you about Substances in Maya, so why the talk about the background and blending here when its obviously not related to the problem?

It doesn’t help if he toys with the blending in the background cause it is not even related to the problem so any effort in that direction is wasted development time and energy that would be better spend solving the problem for now.

He simply kills the cpu right now with too many distinct objects which are needed to be handled for batching so trying to reduce the number of distinct objects so the cpu can be freed at least partially from it is the way to go, the only way to go actually unless disabling dynamic batching fixes it (ensure to be on Unity 3.5.3 by the way, so the create VBO bug in 3.5.1 / 3.5.0 is fixed and retest it the way its right now. potentially its only that part that is in reality hitting you)

Once the opaque rendering is down to 7ms anything related to the background, assuming it is a problem at all, will show up with proper weighting in the profiled data.