标题: Optimizing with Unity iPhone, the first three things I’ll do… [打印本页] 作者: 晃晃 时间: 2011-11-24 20:56 标题: Optimizing with Unity iPhone, the first three things I’ll do…
Optimization is a bit of a black art when you’re dealing with an api or engine where you can’t profile the internals, and unity-iphone is no exception. I’ve collected here a few of tricks I’ve found that have helped me squeeze more performance out of my iphone projects.
1. Do Less, (aka timeslicing)
Lets be honest, it’s really easy to put lots of code in Update() or FixedUpdate() for a behavior, or have it called once a frame. However that means that no matter how fast that code is, it’s going to be called at a rate of (hopefully) 30fps.
Most of the time, you don’t need to do this. Take for example this pseudo-code of a homing script.
view plain
copy to clipboard
print
?
public
class
MyHoming : MonoBehaviour {
public
void
Update() {
// expensive targetting and not so expensive trajectory calculations in here
// currently called every frame
}
}
public class MyHoming : MonoBehaviour {
public void Update() {
// expensive targetting and not so expensive trajectory calculations in here
// currently called every frame
}
}
public void DoTargetting() {
// search for targets here, we don't do it often because it's expensive
}
public void DoTrajectory() {
// trajectory isn't as expensive but it's not something we need to do every frame
}
public void Update() {
// Just interpolate values each frame
currentTrajectory = SetTrajectory(Vector3.Lerp(currentTrajectory, updatedTrajectory, Time.DeltaTime*trajectoryBlend);
}
}
}
It looks a lot more complicated, but it’s really not. You’re still doing the same trajectory updates it’s just that they’re now being blended across multiple frames. I can’t stress how much performance can be saved by doing this to all of your update functions. If you haven’t done so already just do it now.
2. Force garbage collection frequently.
If you don’t, eventually there’ll be a huge spike when it does so automatically.
Try dropping this script into an object in your scene:
view plain
copy to clipboard
print
?
using
UnityEngine;
class
GarbageCollectManager : MonoBehaviour {
public
int
frameFreq = 30;
void
Update() {
if
(Time.frameCount % frameFreq == 0)
System.GC.Collect();
}
}
using UnityEngine;
class GarbageCollectManager : MonoBehaviour {
public int frameFreq = 30;
void Update() {
if (Time.frameCount % frameFreq == 0)
System.GC.Collect();
}
}
It won’t improve your fps, but it will cut down on the occasional spikes that memory management will cause.
3. Triangle & Draw Call counts
Stay under 7.5k tris
Stay under 20 draw calls
These are often preached as a gospel, I’d say it’s more of a guide to keep an eye on your art performance.
If you go over 7.5k triangles, or over 20 draw calls it’s not the end of the world… you’re just
likely
to be bottlnecking yourself at submitting your graphics content to the graphics API.
You can batch draw calls by sharing the same material across mutiple objects and also increase this further by marking objects as “static” when they’ll never move.
But! Don’t forget that there are other factors not displayed here… for instance fill rate, when rendering scenes with overdraw and complex shaders.
The best way to track your total graphics performance is still through xcode instruments, and the debugger log with profiling turned on.
Conclusion
While these three are by no means the only tricks to getting unity to perform on an iphone, these ones are my first port of call when things start to slow. I’ve been told about a whole lot of other optimizations, such as managers instead of unity called Update functions, coroutines better than invokes… so forth but haven’t tried them yet.
Anyone got any suggestions, techniques they’ve found saved them some performance that are different from the ones above?