官术网_书友最值得收藏!

  • Unity Game Optimization
  • Dr. Davide Aversa Chris Dickinson
  • 198字
  • 2021-06-24 12:13:02

Caching component references

Repeatedly recalculating a value is a common mistake when scripting in Unity, and particularly when it comes to the GetComponent() method. For example, the following script code is trying to check a creature's health value, and if its health goes below 0, it will disable a series of components to prepare it for a death animation:

void TakeDamage() {

Rigidbody rigidbody = GetComponent<Rigidbody>();
Collider collider = GetComponent<Collider>();
AIControllerComponent ai = GetComponent<AIControllerComponent>();
Animator anim = GetComponent<Animator>();

if (GetComponent<HealthComponent>().health < 0) {
rigidbody.enabled = false;
collider.enabled = false;
ai.enabled = false;
anim.SetTrigger("death");
}
}

Each time this poorly optimized method executes, it will reacquire five different component references. This is not very friendly on CPU usage. This is particularly problematic if the main method was called during Update(). Even if it is not, it still might coincide with other important events, such as creating particle effects, replacing an object with a Ragdoll (hence invoking various activity in the Physics Engine), and so on. This coding style can seem harmless, but it can cause a lot of long-term problems and runtime work for very little benefit.

It costs us a small amount of memory space (only 32 or 64 bits each time—Unity version, platform, and fragmentation permitting) to cache these references for future use. So, unless you're extremely bottlenecked on memory, a better approach would be to acquire the references during initialization and keep them until they are needed:

private HealthComponent _healthComponent;
private Rigidbody _rigidbody;
private Collider _collider;
private AIControllerComponent _ai;
private Animator _anim;

void Awake() {
_healthComponent = GetComponent<HealthComponent>();
_rigidbody = GetComponent<Rigidbody>();
_collider = GetComponent<Collider>();
_ai = GetComponent<AIControllerComponent>();
_anim = GetComponent<Animator>();
}

void TakeDamage() {
if (_healthComponent.health < 0) {
_rigidbody.detectCollisions = false;
_collider.enabled = false;
_ai.enabled = false;
_anim.SetTrigger("death");
}
}

Caching component references in this way spares us from reacquiring them each time they're needed, saving us some CPU overhead each time. The cost is a small amount of additional memory consumption, which is very often worth the price.

The same tip applies to literally any piece of data we decide to calculate at runtime. There's no need to ask the CPU to keep recalculating the same value every Update() callback when we can just store it in memory for future reference.

主站蜘蛛池模板: 屯昌县| 河曲县| 乡城县| 乌鲁木齐市| 霍州市| 思南县| 潢川县| 南安市| 奇台县| 南川市| 萍乡市| 凤城市| 柞水县| 古田县| 云龙县| 容城县| 福建省| 砚山县| 邳州市| 孝感市| 武威市| 呼伦贝尔市| 枞阳县| 濮阳市| 浦北县| 江川县| 噶尔县| 长顺县| 合水县| 青海省| 都江堰市| 宜良县| 溧阳市| 金秀| 尉犁县| 沅江市| 诏安县| 应城市| 阿拉善左旗| 什邡市| 鄢陵县|