Apa perbedaan antara UnityEngine.Random dan System.Random?

24

Apa bedanya ini

int randomNumber = UnityEngine.Random.Range(0, 10);

dan ini

// on top of the class
private System.Random _rnd = new System.Random();

// inside a methode of the same class
int randomNumber = _rnd.Next(0, 10);

Saya tahu System.Randomharus selalu diinisialisasi di atas kelas Anda apa yang oleh UnityEngine.Randomtidak diperlukan. Saya tahu juga bahwa System.Randombekerja dengan "jam" magang dan nomor "acak" didasarkan pada itu.

Pertanyaan saya sekarang, adakah perbedaan antara UnityEngine.Randomdan System.Randomdan kode penyihir yang lebih baik digunakan untuk proyek Unity?

H. Pauwelyn
sumber

Jawaban:

23

Perbedaan yang paling penting adalah bahwa Unity Random.Rangesedikit lebih mudah digunakan, karena statis. System.RandomNamun, pustaka kelas dasar C # menawarkan Anda lebih banyak kontrol dan isolasi.

Mungkin saja mereka juga menggunakan implementasi under-the-hood yang berbeda (walaupun dugaan saya adalah Unity Randomhanya diimplementasikan dalam hal sistem Random), tetapi itu mungkin bukan masalah yang perlu diperhatikan. Pada dasarnya mereka berdua kemungkinan jenis yang sama dari generator angka acak: generator pseudo-acak berdasarkan iterasi urutan yang ditentukan oleh beberapa seed).

Masalah kontrol lebih relevan, karena dalam beberapa konteks Anda mungkin ingin menggunakan aliran acak yang berbeda untuk hal-hal yang berbeda. Misalnya, dalam konteks jaringan jaringan langkah-kunci, Anda mungkin ingin memperbaiki seed yang digunakan untuk menghasilkan peristiwa yang mempengaruhi gameplay secara acak di semua pemain dalam game, tetapi Anda mungkin tidak terlalu peduli dengan aliran angka acak yang digunakan untuk murni acara visual dan dapat memungkinkan streaming yang akan diunggulkan dengan cara yang lebih tradisional (dengan sistem uptime saat peluncuran game, misalnya).

Demikian pula, jika Anda akan menghasilkan angka acak dalam banyak utas, Anda mungkin ingin menggunakan objek acak berbeda untuk setiap utas untuk mencegah kondisi balapan. Ini mungkin muncul jika logika game Anda berjalan di banyak utas dan Anda juga memiliki sistem permainan ulang, misalnya.

Pada akhirnya, itu tidak selalu lebih baik untuk menggunakan satu atau yang lain secara umum, melainkan ada pro dan kontra. Ketika Anda perlu mengisolasi urutan angka dari urutan acak potensial lain yang mungkin terjadi, atau ketika Anda perlu kontrol lokal atas benih urutan, gunakan instance System.Random. Jika Anda hanya memerlukan nilai acak cepat dan kotor untuk penggunaan yang dibuang atau skenario lain yang tidak berdampak, Unity yang disederhanakan Randommungkin baik-baik saja.

Josh
sumber
3
Satu hal yang dilakukan beberapa game, adalah menyimpan nilai seed ketika pemain menyimpan game. Dengan begitu, tindakan yang sama mengarah pada konsekuensi yang sama. Ini mencegah save scumming, dan jika Anda lupa untuk menyimpannya di lain waktu, Anda bisa kembali ke tempat Anda sebelumnya. XCOM terakhir melakukan itu.
GregRos
3
@GregRos Catatan yang baik, tetapi dapat memperkenalkan jenis penyimpanan-scumming yang berbeda seperti yang dijelaskan dalam artikel ini - pada dasarnya alih-alih mencoba kembali langkah yang sama sampai mereka menggulung kesuksesan, pemain mencoba urutan gerakan yang berbeda sampai gerakan yang paling mereka pedulikan di sebagian besar daratan pada gulungan yang berhasil dalam urutan yang ditentukan sebelumnya. Ternyata ada cara untuk menyimpan dalam sistem apa pun dengan menyimpan. Scummers Gonna Scum, jadi terkadang masuk akal untuk mengikuti arus seperti yang dilakukan XCOM .
DMGregory
10

UnityEngine.Random memiliki beberapa kemudahan penggunaan:

  • Statis / dapat diakses secara global - Anda tidak perlu membuat instance untuk setiap objek atau sistem yang membutuhkan keacakan. Sebagian besar atau semua skrip Anda dapat membagikan sumber ini.

  • Metode kenyamanan - Anda dapat menggunakan Random.Range (), Random.insideUnitSphere, Random.rotationUniform, Random.ColorHSV () untuk mendapatkan nilai acak yang didistribusikan dengan baik dari berbagai jenis yang berguna tanpa harus memutar matematika Anda sendiri.

(Saya belum menemukan konfirmasi mengenai apakah UnityEngine.Random memberikan jaminan konsistensi lintas-platform yang berbeda dari implementasi Mono dari System.Random - mereka mungkin sama atau mungkin tidak sama di bawah tenda)

Anda tentu saja dapat membangun kelas Anda sendiri yang menggunakan System.Random (atau perpustakaan lain, atau PRNG Anda sendiri) untuk melakukan ini, tetapi bagian baiknya adalah Anda tidak perlu - Implementasi Unity dimaksudkan untuk memberi Anda dasar yang baik untuk perilaku acak di luar kotak.

Yang mengatakan, ada kasus di mana Anda ingin menggunakan sumber keacakan lain:

  • Jika Anda menggunakan banyak utas, setiap utas harus memiliki sumber pseudorandomness sendiri untuk menghindari pertikaian (UnityEngine.Random hanya dapat diakses di utas utama)

  • Jika Anda memerlukan urutan pseudorandom deterministik (mis. Untuk generator level unggulan) Anda mungkin ingin sistem itu memiliki sumber pseudorandomness sendiri yang tidak dapat diakses oleh skrip lain, sehingga perbedaan dalam urutan eksekusi tidak menyebabkannya lewati angka dan hancurkan determinisme yang Anda andalkan. Untuk info lebih lanjut, ada posting bagus di blog Unity tentang nomor acak unggulan .

  • jika Anda memerlukan keacakan yang kuat secara kriptografis untuk keamanan, perjudian, atau membuat ID unik, Anda harus menggunakan perpustakaan khusus untuk tujuan ini. Baik UnityEngine.Random maupun System.Random tidak memberikan jaminan kualitas yang memadai.

DMGregory
sumber
Ups, permintaan maaf untuk JoshPetrie dan Jon - saya perlu waktu mengetik ini di ponsel, jadi saya tidak melihat jawaban Anda sampai saya mempostingnya. Sepertinya kita semua sudah membahas hal yang sama.
DMGregory
Untuk keacakan crypto-grade, lihat RNGCryptoServiceProvider tetapi perlu diingat bahwa ini sangat lambat dan tidak termasuk semua platform .NET yang dilucuti Unity.
McGuireV10
6

UnityEngine.Random bersifat statis. Jika Anda ingin membuat beberapa instance dari generator angka acak, maka Anda ingin menggunakan System.Random.

Tidak ada cara untuk mencari kode sumber untuk Implementasi Persatuan, namun, Microsoft menyediakan sumber untuk System.Random .

jallan
sumber
3
Bukan berarti sumber Microsoft bukan yang digunakan oleh Unity. Anda harus melihat sumber Mono saja.
Arturo Torres Sánchez