Estoy haciendo más juegos y haciendo más preguntas estúpidas.
Esperemos que este sea muy breve. Estoy haciendo una clase muy básica que simplemente mueve un objeto Player aplicando fuerza a un cuerpo rígido, pero me hizo preguntarme, ¿debería hacer una referencia de clase a la rb o solo una variable local dentro de Actualizar cada cuadro? (teniendo en cuenta que ya existe en la clase monobehaviour.GameObject unity parent).
Me pregunto si hacer muchas variables locales ralentizaría el ciclo en su conjunto (por local quiero decir dentro de la función en sí y no en la parte superior de la clase, espero que esté usando el término correcto).
Esto es lo que quiero decir, las dos formas en que estaba pensando en hacerlo:
public class Player : MonoBehaviour {
private void FixedUpdate()
{
Rigidbody rb = GetComponent<Rigidbody>();
float v = Input.GetAxis("Vertical");
rb.AddForce(v * rb.transform.forward * Const.walkForce);
}
}
o...
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);
}
}
Respuestas:
En general, he descubierto que debe abarcar los datos de la manera más estrecha posible para comenzar y ampliar el alcance cuando descubra que lo necesita. Eso significa que si puede convertirlo en una variable local en lugar de un miembro, probablemente debería comenzar allí.
Esto se debe a que un alcance más reducido reduce la cantidad de lugares en el código donde debe razonar sobre esos datos y, por lo tanto, reduce la cantidad de lugares sobre los que puede razonar incorrectamente (lo que genera errores).
En realidad, declarar solo las variables locales nunca va a ser prácticamente un problema de rendimiento: son baratas y los compiladores modernos incluso pueden optimizar los "extras".
Inicializarlos puede ser una preocupación; en su caso, su cuerpo rígido se busca cada vez a través de
GetComponent
, lo que tiene un costo distinto de cero. Si sabe que el componente del cuerpo rígido no cambiará para este objeto de juego en particular, puede buscarlo una vez y almacenar el resultado en una variable miembro y evitar una pequeña sobrecarga por llamada.Es poco probable que la sobrecarga por llamada sea significativa en este caso, pero con el tiempo, esto puede sumar para muchos componentes. Desea aplicar un perfilador para estar seguro.
Entonces, para resumir: en general, el valor predeterminado es hacer que las cosas sean lo más locales posible, pero en este caso probablemente sea razonable hacer
rb
un miembro para que pueda realizar la búsqueda una vezAwake
y evitar tener que hacerlo en cadaFixedUpdate
llamada.fuente
GetComponent
es bastante rápido: sería difícil realizar cualquier tipo de búsqueda que tenga una velocidad comparable. A menos que tenga datos de rendimiento que sugieran que es un problema, siga con el enfoque de "mantener las cosas locales". Siempre puedes optimizarlo más tarde. Consulta answer.unity.com/questions/185164/… . No olvides que el almacenamiento en caché tampoco es gratuito: si guardas en caché todos los elementosGetComponent
de tu juego, probablemente será una pérdida neta. Medida. Identifique dónde valen las optimizaciones. Centrarse en hacer un gran juego :)La respuesta de Josh Petrie es muy buena: aquí hay una perspectiva complementaria.
Cuando trabajas con código del que entiendes bastante bien el dominio, puedes abarcar variables donde tengan sentido.
Por ejemplo, si tengo una
Person
clase con unwaveGoodbye
método, es posible que mi clase no haya tenido unhand
objeto antes y que pueda declararlo localmentewaveGoodbye
. Ahora, aquí es obvio que una persona tiene una mano, por lo que naturalmente puede declararlo como miembroPerson
sin pensarlo, pero se aplica el mismo problema.Si declaras
hand
localmente, luego puedes agregar unkarateChop
método que también requiera una mano. Esto es cuando declarar variables localmente puede volverse problemático, porque los desarrolladores junior a menudo recurren a copiar / pegar la declaraciónwaveGoodbye
y ahora tiene el mismo concepto ubicado en dos puntos. Cualquier cambio ahand
continuación debe modificarse en ambos lugares y, por lo tanto, comienza unhormiguero.Así que en general,
Si tiene confianza en la ubicación de su declaración, diríjase a donde tenga sentido.
Si no está seguro, entonces comience localmente y asegúrese de refactorizar cuando reciba un soplo de reutilización de código.
Editar: Ah, y no cometas el mismo error que tengo de pasar demasiado tiempo averiguando dónde buscar tus declaraciones. Es difícil entender la estructura de sus datos por adelantado, y a medida que escribe su código, la estructura tiene una forma de revelarse.
fuente
Person
deberían tener el miembrohand
si es relevante en la aplicación, a menudo ayuda a otros desarrolladores (la mayoría de las veces , 6 meses después) a comprender mejor el código. En este caso, parece lógico tener unRigidbody
miembro suyoPlayer
y, digo más, incluso si eso implica un peor rendimiento. En los videojuegos, ese es un punto relevante a tener en cuenta, pero creo que en el código , para ser claros, a menudo es más importante