Saya membuat lebih banyak game dan mengajukan lebih banyak pertanyaan bodoh.
Semoga yang ini sangat singkat. Saya membuat kelas yang sangat mendasar yang hanya memindahkan objek Player dengan memberikan kekuatan pada benda tegar, tapi itu membuat saya bertanya-tanya, haruskah saya membuat referensi kelas ke rb atau hanya variabel lokal di dalam Perbarui setiap frame? (mengingat itu sudah ada di kelas induk kesatuan Monobehaviour.GameObject).
Saya bertanya-tanya apakah melakukan banyak variabel lokal akan memperlambat loop secara keseluruhan (oleh lokal saya maksud di dalam fungsi itu sendiri dan bukan di bagian atas kelas - harap saya menggunakan istilah yang benar).
Inilah yang saya maksud, dua cara yang saya pikirkan untuk melakukannya:
public class Player : MonoBehaviour {
private void FixedUpdate()
{
Rigidbody rb = GetComponent<Rigidbody>();
float v = Input.GetAxis("Vertical");
rb.AddForce(v * rb.transform.forward * Const.walkForce);
}
}
atau...
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);
}
}
Jawaban:
Secara umum, saya telah menemukan bahwa Anda harus melakukan scope data sesempit mungkin untuk memulai dan memperluas cakupan sesuai dengan kebutuhan Anda. Itu berarti jika Anda dapat menjadikannya variabel lokal dan bukan anggota, Anda mungkin harus mulai dari sana.
Ini karena ruang lingkup yang lebih sempit mengurangi jumlah tempat dalam kode di mana Anda harus memberi alasan tentang data itu, dan dengan demikian mengurangi jumlah tempat yang dapat Anda alasankan dengan salah (yang mengarah ke bug).
Sebenarnya mendeklarasikan variabel lokal saja tidak pernah praktis menjadi masalah kinerja: mereka murah, dan kompiler modern bahkan dapat mengoptimalkan "ekstra".
Inisialisasi mereka mungkin menjadi perhatian; dalam kasus Anda tubuh kaku Anda dilihat setiap kali melalui
GetComponent
, yang memiliki beberapa biaya tidak nol. Jika Anda tahu bahwa komponen tubuh yang kaku tidak akan berubah untuk objek game khusus ini, Anda dapat mencarinya sekali dan menyimpan hasilnya dalam variabel anggota dan menghindari sedikit overhead per panggilan.Tidak mungkin overhead per panggilan akan menjadi signifikan dalam hal ini, tetapi seiring waktu melakukan hal ini untuk banyak komponen dapat bertambah. Anda ingin menerapkan profiler untuk memastikan.
Jadi, untuk meringkas: secara umum, default untuk membuat hal-hal lokal sebagai mungkin, tetapi dalam hal ini mungkin masuk akal untuk membuat
rb
anggota sehingga Anda dapat melakukan pencarian sekali dalamAwake
dan menghindari harus melakukannya setiapFixedUpdate
panggilan.sumber
GetComponent
adalah cukup cepat - Anda akan sulit ditekan membuat segala jenis lookup yang memiliki kecepatan yang sebanding. Kecuali jika Anda memiliki data kinerja yang menunjukkan itu masalah, tetaplah dengan pendekatan "simpan segala sesuatu yang lokal". Anda selalu dapat mengoptimalkannya nanti. Lihat answer.unity.com/questions/185164/... Jangan lupa bahwa cache juga tidak gratis - jika Anda melakukan cache setiap satuGetComponent
di game Anda, itu mungkin akan menjadi kerugian bersih. Mengukur. Identifikasi di mana optimalisasi sepadan. Fokus untuk membuat game yang luar biasa :)Jawaban Josh Petrie sangat bagus - inilah perspektif yang saling melengkapi.
Ketika Anda bekerja dengan kode yang Anda mengerti domain dengan cukup baik, Anda bisa menentukan variabel di mana mereka masuk akal.
Sebagai contoh jika saya memiliki
Person
kelas denganwaveGoodbye
metode, mungkin saja kelas saya tidak memilikihand
objek sebelumnya sehingga saya dapat mendeklarasikannya secara lokal diwaveGoodbye
. Sekarang di sini sudah jelas seseorang memiliki tangan sehingga Anda mungkin secara alami menyatakannya sebagai anggotaPerson
tanpa memikirkannya, tetapi masalah yang sama berlaku.Jika Anda menyatakan
hand
lokal kemudian Anda bisa menambahkan sebuahkarateChop
metode yang juga membutuhkan tangan. Inilah saat mendeklarasikan variabel secara lokal dapat menjadi masalah - karena pengembang junior sering kembali menyalin / menempel pernyataan dariwaveGoodbye
dan sekarang Anda memiliki konsep yang sama yang terletak di dua tempat. Setiap perubahan untukhand
kemudian perlu dimodifikasi di kedua tempat dan dengan demikian memulai bukitsemutbug.Jadi semuanya,
Jika Anda yakin dengan penempatan deklarasi Anda, ruang lingkup ke tempat itu masuk akal.
Jika Anda tidak percaya diri, mulailah secara lokal dan pastikan untuk melakukan refactor ketika Anda mendapatkan sedikit kode yang digunakan kembali.
Sunting: Oh dan jangan membuat kesalahan yang sama yang saya miliki dengan menghabiskan terlalu banyak waktu mencari tahu di mana ruang lingkup deklarasi Anda. Sulit untuk memahami struktur data Anda di muka, dan ketika Anda menulis kode Anda, struktur memiliki cara untuk mengungkapkannya sendiri.
sumber
Person
harus memilikihand
jika relevan dalam aplikasi, sering membantu pengembang lain (paling sering Anda 6 bulan kemudian) untuk lebih memahami kode. Dalam hal ini, tampaknya masuk akal untuk memiliki anggotaRigidbody
AndaPlayer
dan, saya katakan lebih banyak, bahkan jika itu menyiratkan kinerja yang lebih buruk. Dalam video-game yang merupakan titik yang relevan untuk dipertimbangkan, tetapi saya pikir dalam kode , untuk menjadi jelas seringkali lebih penting