Confira a postagem original do blog em The Gamedev Guru: Não deixe que objetos fora da tela estraguem seu desempenho – Unity CullingGroup API

Aprenda a fazer com que seus scripts caros não custem nada enquanto estiverem fora da tela.

yt

Índice

left view

Fora de quê GameObject?

Primeiro: o que é um objeto fora da tela?

Um objeto está fora da tela quando você não pode vê-lo da perspectiva da sua câmera. Isso pode acontecer porque seu objeto está “atrás” de sua câmera (portanto, selecionado por frustrum) ou atrás de paredes/outros oclusores (exclusão de oclusão).

Então, se um objeto está fora da tela e não podemos vê-lo, não precisamos dedicar recursos computacionais caros a ele, certo?

Errado. Era o que eu pensava quando era criança. Não mais.

external pollution nuclear energy filled outline lima studio

O(s) Custo(s) de Desempenho de Objetos Fora da Tela

Aqui estão alguns dos custos de hardware que você está pagando por objetos fora da tela:

  • O preço de abate: é um objeto fora da tela? O Unity determina isso verificando sua visibilidade por meio de seleção de frustrum e oclusão, que custa recursos.
  • O preço da memória: mesmo que seu objeto não esteja visível, você ainda tem seus componentes carregados na memória.
  • O preço do script: scripts anexados e a maioria dos componentes internos ainda são executados mesmo que seu objeto esteja fora da tela.
  • O preço de renderização: talvez você não veja seu objeto, mas isso não significa que ele não esteja sendo renderizado. Talvez a seleção de oclusão falhe em detectar sua visibilidade e você ainda a renderize.
  • O preço do áudio: da última vez que verifiquei, o áudio se propaga de maneira diferente do visual, então ainda é processado.
  • O preço da física: uma bola rolante aparece atrás de uma parede após alguns segundos; física ainda são executados.
  • O preço da animação: embora isso possa ser configurado, algumas partes da computação da animação ainda são avaliadas em objetos fora da tela.

Então, o que nós podemos fazer sobre isso? Vamos falar sobre a API CullingGroup.

external dagger pirate filled outline filled outline icons

Você tem um ladino atrás de você

Você está jogando um RPG e tem um amigo atrás de você. Você só não sabe ainda.

Como esse personagem desonesto está fora da tela, você certamente não precisa executar seu comportamento?

Ok, espere, se o congelarmos completamente, não o esfaquearia com uma adaga. Então, aparentemente, ainda temos que executar algum código. Vamos pensar em alguns aspectos:

  • Multijogador: você ainda precisa sincronizar o corpo rígido do jogador com a nova posição e velocidade, certo? É melhor não mexer no multiplayer.
  • Animador: você não precisa necessariamente processar a animação do player, pois ela não é visível.
  • IU: se o jogador tiver uma interface de usuário sofisticada anexada ao pulso ou a uma barra de saúde, você não precisa necessariamente atualizar seu conteúdo/materiais e incorrer em reconstruções de tela do espaço mundial, certo?
  • Sistemas de partículas: você não precisa simulá-los, talvez você possa alcançá-los mais tarde quando eles se tornarem visíveis.
  • Expressões faciais: você certamente não precisa fazer o personagem olhar para você nos olhos… se você nem consegue vê-los. Aqui não quebramos as regras de polidez.

Em geral, você deseja evitar operações cosméticas em objetos fora da tela, como ajustar as propriedades dos materiais, pequenas rotações e afins.

Mas… como você pode fazer isso?

Vamos supor que você tenha um script chamado AngerRenderer. Ele só faz uma coisa: deixar o personagem mais vermelho, mais irritado. E faz isso simplesmente ajustando uma propriedade do material.

Algo assim:

class AngerRenderer : MonoBehavior{	void Update()  {  	var skinColor = Color.Lerp(Color.white, Color.red, 1f - _health / 100);  	_material.SetProperty("_MainColor", skinColor);    // More costly operations here    // Play sweat particles    // Play steam particles  }}

Claro que não compila. Não deveria, como eu quero fazer o ponto em vez disso.

O que podemos fazer agora para desativar esse script “caro” sempre que esse personagem não estiver à vista?

visualization skill

API Unity CullingGroup: otimizando GameObjects fora da tela no Unity

Então usamos a API CullingGroup que a Unity nos oferece.

Essa API nos informa sobre atualizações de visibilidade. E adivinhe, quando você sabe se seu objeto se torna visível ou invisível, você pode simplesmente desabilitar os componentes que deseja ou parar de executar seu comportamento.

O código poderia então ficar mais assim:

class AngerRenderer : MonoBehavior{  CullingGroup _cullingGroup;  BoundingSphere[] _boundingSpheres;  float _playerRadius = 1f;    void Start()  {  	_cullingGroup = new CullingGroup();    _cullingGroup.targetCamera = Camera.main;    _boundingSpheres = new BoundingSphere[1];  }    void OnDestroy()  {  	_cullingGroup.Dispose();		_cullingGroup = null;  }    void Update()  {  	if (_cullingGroup.IsVisible(0))    {    	var skinColor = Color.Lerp(Color.white, Color.red, 1f - _health / 100);  		_material.SetProperty("_MainColor", skinColor);      // More costly operations here      // Play sweat particles    	// Play steam particles    }    _boundingSpheres[0] = new BoundingSphere(transform.position, _playerRadius);    _cullingGroup.SetBoundingSpheres(spheres);    _cullingGroup.SetBoundingSphereCount(1);  }}

Agora, você deve selecionar um raio que funcione para o seu jogador, tomar a posição correta no centro e assim por diante. Você entendeu a ideia.

E você pode fazer muitas outras coisas lá, como receber atualizações de visibilidade em vez de pesquisar. Ou você também pode empacotar mais esferas delimitadoras na matriz para reduzir a sobrecarga de executar suas esferas delimitadoras.

A principal conclusão é: muitas vezes você pode pular certos comportamentos enquanto seu objeto não está sendo renderizado. Descubra quais scripts caros você não precisa executar em objetos invisíveis e o hardware de seus usuários agradecerá por isso.

Descubra passo a passo como a API CullingGroup funciona na prática (com exemplos) em Lição do PerformanceTaskforce “2021.10”:

https://www.PerformanceTaskforce.com

b1310029368 13348

Em suma, uma ferramenta de desempenho sólido para ter em sua caixa de ferramentas.

Até a próxima,

Ruben (O Guru Gamedev)

Com informações de GameDev.net.