Estou fazendo mais jogos e fazendo mais perguntas estúpidas.
Espero que este seja muito breve. Estou criando uma classe muito básica que apenas move um objeto Player aplicando força a um corpo rígido, mas isso me fez pensar: devo fazer uma referência de classe à rb ou apenas uma variável local dentro de Atualizar todos os quadros? (tendo em mente que ele já existe na classe pai da unidade Monobehaviour.GameObject).
Eu estou querendo saber se fazer muitas variáveis locais atrasaria o loop como um todo (por local, quero dizer dentro da própria função e não no topo da classe - espero estar usando o termo correto).
Aqui está o que eu quero dizer, as duas maneiras que eu estava pensando em fazer isso:
public class Player : MonoBehaviour {
private void FixedUpdate()
{
Rigidbody rb = GetComponent<Rigidbody>();
float v = Input.GetAxis("Vertical");
rb.AddForce(v * rb.transform.forward * Const.walkForce);
}
}
ou...
public class Player : MonoBehaviour {
Rigidbody rb;
private void Awake()
{
rb = GetComponent<Rigidbody>();
}
private void FixedUpdate()
{
float v = Input.GetAxis("Vertical");
rb.AddForce(v * rb.transform.forward * Const.walkForce);
}
}
Respostas:
Em geral, descobri que você deve escopo os dados da maneira mais estreita possível para começar e ampliar o escopo conforme você precisar. Isso significa que, se você pode torná-la uma variável local em vez de um membro, provavelmente deve começar por aí.
Isso ocorre porque um escopo mais restrito reduz o número de locais no código em que você deve raciocinar sobre esses dados e, portanto, reduz o número de locais em que você pode raciocinar incorretamente (o que leva a erros).
Na verdade, declarar apenas variáveis locais nunca será praticamente uma preocupação de desempenho: elas são baratas e os compiladores modernos podem até otimizar os "extras".
Inicializá-los pode ser uma preocupação; no seu caso, seu corpo rígido é sempre pesquisado via
GetComponent
, o que tem um custo diferente de zero. Se você sabe que o componente do corpo rígido não será alterado para esse objeto de jogo específico, procure-o uma vez e armazene o resultado em uma variável de membro e evite um pouco de sobrecarga por chamada.É improvável que a sobrecarga por chamada seja significativa nesse caso, mas com o tempo, isso pode resultar em muitos componentes. Você deseja aplicar um criador de perfil para ter certeza.
Então, para resumir: em geral, o padrão é tornar as coisas o mais local possível, mas nesse caso é provavelmente razoável criar
rb
um membro para que você possa realizar a pesquisa uma vezAwake
e evitar fazer todas asFixedUpdate
chamadas.fonte
GetComponent
é muito rápido - seria difícil fazer qualquer tipo de pesquisa com velocidade comparável. A menos que você tenha dados de desempenho que sugiram que isso é um problema, siga a abordagem "manter as coisas locais". Você sempre pode otimizá-lo mais tarde. Consulte answers.unity.com/questions/185164/… Não esqueça que o cache também não é gratuito - se você armazenar em cache todos osGetComponent
jogos do seu jogo, provavelmente será uma perda líquida. A medida. Identifique onde as otimizações valem a pena. Concentre-se em fazer um grande jogo :)A resposta de Josh Petrie é muito boa - aqui está uma perspectiva complementar.
Quando você trabalha com código no qual entende o domínio razoavelmente bem, pode definir variáveis de escopo para onde elas fazem sentido.
Por exemplo, se eu tenho uma
Person
classe com umwaveGoodbye
método, é possível que a minha turma não tinha umhand
objeto antes e então eu poderia declarar-lo localmente nowaveGoodbye
. Agora, aqui é óbvio que uma pessoa tem uma mão, então você pode naturalmente declara-la como membroPerson
sem pensar nisso, mas o mesmo problema se aplica.Se você declarar
hand
localmente, mais tarde poderá adicionar umkarateChop
método que também requer uma mão. É quando declarar variáveis localmente pode se tornar problemático - porque os desenvolvedores juniores costumam voltar a copiar / colar a declaraçãowaveGoodbye
e agora você tem o mesmo conceito localizado em dois pontos. Quaisquer alterações ahand
, em seguida, precisam ser modificados em ambos os lugares e assim começa umaformigacolina bug.Então tudo em tudo,
Se você estiver confiante no posicionamento da sua declaração, coloque-a no ponto em que faz sentido.
Se você não estiver confiante, inicie o local e refatore quando sentir o cheiro da reutilização de código.
Edit: Ah, e não cometa o mesmo erro que tenho de gastar muito tempo tentando descobrir onde escopo suas declarações. É difícil entender a estrutura dos seus dados antecipadamente e, à medida que você escreve seu código, a estrutura tem uma maneira de se revelar.
fonte
Person
deve ter o membrohand
se sua relevante na aplicação, muitas vezes ajuda outros desenvolvedores (na maioria das vezes você 6 meses mais tarde) para entender melhor o código. Nesse caso, parece lógico ter umRigidbody
membro seuPlayer
e, digo mais, mesmo que isso implique em pior desempenho. Em vídeo-jogos que é um ponto relevante considerar, mas acho que em código , para ficar claro é muitas vezes mais importante