Seperti yang dikatakan di sini :
Waktu
Waktu di awal bingkai ini (Hanya Baca). Ini adalah waktu dalam hitungan detik sejak awal permainan.
Dan seperti yang saya tahu waktu disimpan di float. Jadi, pertanyaan saya adalah apa yang akan terjadi ketika nilai waktu menjadi sangat besar? Bisakah itu meluap? Apakah akan kehilangan presisi dan menyebabkan bug? Apakah gamenya hanya crash atau apa?
Jawaban:
Ada risiko nyata hilangnya ketepatan waktu dari penggunaan pelampung presisi tunggal .
Itu masih akan mempertahankan akurasi hingga detik terdekat selama 97 hari . Tetapi dalam game kita sering peduli tentang akurasi pada urutan durasi frame.
Nilai waktu float presisi tunggal dalam detik mulai kehilangan akurasi milidetik setelah sekitar 9 jam .
Itu sudah tidak di luar bidang kemungkinan untuk sesi bermain tunggal, atau membiarkan permainan berjalan "AFK" saat Anda sedang bekerja / sekolah atau tidur. (Ini adalah salah satu alasan mengapa cara umum untuk menguji permainan adalah menjalankannya dalam semalam dan memeriksa apakah ia masih bermain dengan benar di pagi hari)
Pada konsol modern, di mana game sering ditunda dan dilanjutkan di antara sesi bermain daripada ditutup sepenuhnya, itu tidak terduga untuk "sesi tunggal" dari pandangan mata game untuk melebihi 9 jam runtime bahkan ketika dimainkan dalam ledakan singkat.
Dengan asumsi Unity's
deltaTime
dihitung dari sumber waktu dengan presisi lebih tinggi, yang dibuktikan oleh eksperimen Peter dalam jawaban lain, mengandalkandeltaTime
untuk penentuan skala waktu relatif aman (hanya berhati-hati dalam mengumpulkan durasi yang sangat lama dengan menjumlahkandeltaTime
nilai - menambahkan sedikit peningkatan pada float yang lebih besar adalah resep klasik untuk kehilangan presisi, bahkan ketika Anda mengimbangi dengan algoritma yang cerdas ).Karena
fixedDeltaTime
mempertahankan nilai yang sama dengan yang Anda tetapkan, alih-alih berubah secara dinamis dari satu frame ke frame, Anda juga dapat menempatkan perilaku sensitif waktu dalam FixedUpdate untuk mendapatkan jaminan konsistensi yang lebih kuat.deltaTime
akan secara otomatis mengembalikan delta tetap yang sesuai dalam metode ini. Meskipun ada frekuensi denyut antara pembaruan bingkai & tetap, Anda dapat memuluskan ini melalui interpolasi .Yang ingin Anda hindari adalah menghitung durasi dengan mengurangi satu stempel waktu dari yang lain . Setelah berjam-jam bermain, ini dapat menyebabkan pembatalan bencana, yang menyebabkan ketepatan yang jauh lebih rendah daripada yang Anda dapatkan di awal pertandingan. Jika membandingkan cap waktu penting untuk sistem Anda, Anda dapat menghasilkan nilai waktu resolusi lebih tinggi dengan menggunakan metode lain, seperti
System.Diagnostics.Stopwatch
sebagai gantiTime.time
.sumber
Nilai maksimum float adalah 3,40282347 * 10 ^ 38, yang sama dengan 10 ^ 31 tahun bila diukur dalam detik (atau 10 ^ 28 tahun bila diukur dalam milidetik). Percayalah, itu tidak akan meluap.
Satu-satunya hal yang mungkin muncul adalah ketidaktepatan. Tetapi satu angka floating point presisi memiliki akurasi 7-8 angka desimal. Jika menggunakannya untuk mengukur detik, itu akurat selama sekitar 194 hari. Jika mengukur milidetik hanya akurat 4,5 jam. Jadi itu benar-benar tergantung pada keakuratan yang Anda butuhkan dan Anda mungkin perlu menemukan cara alternatif jika Anda harus akurat ke milidetik (yang mungkin tidak Anda lakukan).
sumber
Berapa presisi yang dibutuhkan gim Anda?
Pelampung 32-bit memiliki presisi 24 bit. Dengan kata lain, pada waktu t, presisi adalah ± 2 -23 × t. (Ini tidak sepenuhnya benar, tetapi dekat, dan detail yang tepat tidak terlalu menarik.)
Jika Anda membutuhkan ketelitian 1ms, maka setelah 1ms ÷ 2 -23 = 8400 s = 2j 20m, pelampung 32-bit tidak lagi dapat diterima. Ketelitian 1ms tidak diperlukan untuk sebagian besar gim, tetapi dianggap perlu untuk aplikasi musik.
Jika game Anda berjalan pada monitor 144 Hz, dan Anda menginginkan grafik dengan frame-akurat, maka setelah 1 ÷ 144 Hz ÷ 2 -23 = 58000 s = 16j, pelampung 32-bit tidak lagi dapat diterima. 16h adalah waktu yang lama untuk menjalankan permainan, tetapi itu tidak terbayangkan. Saya yakin sebagian besar dari kita telah menjalankan permainan selama 16 jam dalam satu rentang - bahkan jika hanya karena kita membiarkan permainan berjalan dan tidur. Pada saat itu, pembaruan animasi dan fisika akan dikurangi hingga di bawah 144Hz.
Jika Unity's
Time.deltaTime
dihitung dari jam dengan presisi lebih tinggi, maka Anda bisa menggunakannya dan masih mendapatkan presisi penuh. Saya tidak tahu apakah ini benar atau tidak.Catatan Samping
Game dan program lain di Windows sering digunakan
GetTickCount()
untuk mengetahui waktu. Karena menggunakan bilangan bulat 32-bit untuk menghitung milidetik, ia membungkus sekitar setiap 50 hari, jika Anda meninggalkan komputer Anda selama itu. Saya menduga bahwa banyak permainan akan hang, crash, atau bertingkah aneh dengan cara yang aneh jika Anda memainkannya pada tanda 50 hari.Integer, seperti Windows '
GetTickCount()
, memiliki risiko overflow, sedangkan float, seperti UnityTime.time
, memiliki risiko kehilangan presisi.sumber
Jawaban lainnya hanya berspekulasi, jadi saya menulis proyek Unity sederhana dan membiarkannya berjalan untuk sementara waktu. Setelah beberapa jam, inilah hasilnya:
UnityEngine.Time.time
kehilangan akurasi agak cepat. Seperti yang diharapkan, setelah menjalankan game selama 4 jam nilainya melonjak 1 milidetik, dan ketidaktepatan meningkat setelah itu.UnityEngine.Time.deltaTime
menjaga akurasi awal sub-milidetik bahkan setelah Unity berjalan selama berjam-jam. Dengan demikian, dijamindeltaTime
dari turunan resolusi tinggi yang tergantung platform (yang biasanya meluap setelah 10-1000 tahun). Masih ada risiko kecil yangdeltaTime
masih akan kehilangan presisi pada beberapa platform.Ketidaktepatan Waktu adalah masalah untuk semua yang bergantung pada
UnityEngine.Time.time
. Salah satu contoh spesifik adalah rotasi (misalnya kincir angin), yang biasanya didasarkan padaUnityEngine.Mathf.Sin(UnityEngine.Time.time*rotationSpeed)
. Bahkan lebih banyak masalah_Time
yang secara eksplisit digunakan untuk animasi oleh shader. Seberapa tinggi ketidaktelitian yang dibutuhkan sebelum mulai terlihat? Akurasi 20-30 ms (2 hari) harus menjadi titik di mana orang yang menyadari masalah ini, dan memperhatikan, akan melihat. Pada 50-100 ms (5-10 hari) orang-orang sensitif yang tidak tahu tentang masalah akan mulai mencari tahu. Dari 200-300 ms (20-30 hari) masalahnya akan jelas.Sejauh ini saya belum diuji akurasi
_SinTime
,_CosTime
danUnity_DeltaTime
, jadi saya tidak bisa mengomentari ini.Ini adalah Skrip yang saya gunakan untuk pengujian. Itu dilampirkan ke
UI.Text
elemen, Pengaturan Pemain dari proyek memungkinkan proyek untuk menjalankan sementara di latar belakang, dan VSync dalam Pengaturan Kualitas diatur ke Setiap Detik V Kosong:Jika Anda bertanya-tanya tentang
0.033203
nilai, saya cukup yakin itu sebenarnya0.033203125
, yang memiliki representasi titik mengambang biner00111101000010000000000000000000
. Perhatikan banyak0
di mantissa.Penanganan masalah
Sebagian besar genre tidak membutuhkan solusi. Sebagian besar pemain bahkan tidak akan memainkan permainan untuk total 100 jam, jadi menginvestasikan uang untuk memperbaiki masalah yang orang hanya akan perhatikan setelah beberapa hari bermain secara terus-menerus secara hipotesis tidak layak secara ekonomi. Sayangnya saya tidak dapat menemukan solusi universal sederhana yang memperbaiki keseluruhan masalah tanpa membawa beberapa kelemahan yang signifikan.
sumber