Kelas acak memberi Anda cara mudah menghasilkan berbagai jenis nilai acak yang umum diperlukan.
Halaman ini menyediakan ikhtisar dari kelas acak dan kegunaannya yang umum ketika scripting dengan itu. Untuk referensi knalpot dari setiap anggota kelas acak dan rincian teknis lebih lanjut tentang hal itu, lihat Referensi skrip acak.
Ikuti tautan di bawah ini untuk rincian lebih lanjut dan contoh metode yang berguna ini.
Random.value
memberi Anda floating point number acak antara 0,0 dan 1.0. Penggunaan umum adalah untuk mengubahnya menjadi nomor antara nol dan berbagai pilihan Anda dengan menggandakan hasilnya.
Random.Range
memberi Anda number between a minimum and maximum value acak yang Anda berikan. Ini kembali baik bilangan bulat atau pelampung, tergantung pada apakah nilai min dan maks yang disediakan adalah bilangan bulat atau pelampung.
Random.insideUnitCircle
mengembalikan point inside a circle yang dipilih secara acak dengan radius 1 (Again Anda dapat menggandakan hasilnya untuk mendapatkan titik acak dalam lingkaran ukuran apa pun).
Random.insideUnitSphere
mengembalikan point inside a sphere yang dipilih secara acak dengan radius 1.
Random.onUnitSphere
mengembalikan point on the surface of a sphere yang dipilih secara acak dengan radius 1.
Kelas acak Unity juga menawarkan beberapa jenis nilai acak lainnya.
Untuk menghasilkan rotation acak, gunakan Random.rotation
.
Untuk menghasilkan color acak, gunakan Random.ColorHSV
.
Memilih elemen array pada rebus acak turun untuk memilih bilangan bulat acak antara nol dan nilai indeks maksimum array (yang sama dengan panjang array minus satu). Ini mudah dilakukan menggunakan fungsi Random.Range
built-in:-
`var element = myArray[Random.Range(0, myArray.Length)];``
Perhatikan bahwa Random.Range
mengembalikan nilai dari kisaran yang mencakup parameter pertama tetapi tidak termasuk detik, sehingga menggunakan myArray.Length
di sini memberikan hasil yang benar.
Kadang-kadang, Anda perlu memilih item secara acak tetapi dengan beberapa item lebih cenderung dipilih daripada yang lain. Misalnya, NPC dapat bereaksi dalam beberapa cara yang berbeda ketika bertemu pemain:-
Anda dapat memvisualisasikan hasil yang berbeda ini sebagai strip kertas dibagi menjadi bagian masing-masing yang menempati sebagian kecil dari panjang total strip. Sereal yang ditempati sama dengan probabilitas hasil yang dipilih. Membuat pilihan setara dengan memilih titik acak sepanjang panjang strip (kata dengan membuang dart) dan kemudian melihat bagian mana itu berada.
Dalam skrip, strip kertas sebenarnya adalah array pelampung yang mengandung kemampuan yang berbeda untuk item dalam urutan. Titik acak diperoleh dengan menggandakan Random.value
oleh total semua pelampung dalam array (mereka tidak perlu menambah 1; hal yang signifikan adalah ukuran relatif dari nilai yang berbeda). Untuk menemukan elemen array mana titik "dalam", pertama kali memeriksa untuk melihat apakah itu kurang dari nilai dalam elemen pertama. Jika demikian, maka elemen pertama adalah yang dipilih. Jika tidak, masukkan nilai elemen pertama dari nilai titik dan bandingkan dengan elemen kedua dan sebagainya sampai elemen yang benar ditemukan. Dalam kode, ini akan terlihat sesuatu seperti berikut:-
float Choose (float[] probs) {
float total = 0;
foreach (float elem in probs) {
total += elem;
}
float randomPoint = Random.value * total;
for (int i= 0; i < probs.Length; i++) {
if (randomPoint < probs[i]) {
return i;
}
else {
randomPoint -= probs[i];
}
}
return probs.Length - 1;
}
Perhatikan bahwa pernyataan pengembalian akhir diperlukan karena Random.value
dapat mengembalikan hasil 1. Dalam hal ini, pencarian tidak akan menemukan titik acak di mana saja. Mengubah garis
`if (randomPoint < probs[i])`
... untuk tes yang kurang jelas akan menghindari pernyataan pengembalian tambahan tetapi juga akan memungkinkan item untuk dipilih kadang-kadang bahkan ketika probabilitasnya adalah nol.
Array metode pelampung bekerja dengan baik jika Anda memiliki hasil yang diskrit, tetapi ada juga situasi di mana Anda ingin menghasilkan hasil yang lebih berkelanjutan - katakan, Anda ingin mengacak jumlah potongan emas yang ditemukan di dada harta, dan Anda ingin mungkin untuk berakhir dengan nomor antara 1 dan 100, tetapi untuk membuat nomor lebih rendah kemungkinan. Menggunakan metode array-of-floats untuk melakukan ini akan mengharuskan Anda mengatur array 100 pelampung (yaitu bagian pada strip kertas) yang tidak berubah; dan jika Anda tidak terbatas pada seluruh nomor tetapi bukan ingin nomor dalam kisaran, tidak mungkin untuk menggunakan pendekatan itu.
Pendekatan yang lebih baik untuk hasil terus-menerus adalah untuk menggunakan nilai acak AnimationCurve
untuk mengubah nilai acak ‘didayakan’ satu; dengan menggambar bentuk kurva yang berbeda, Anda dapat menghasilkan bobot yang berbeda. Kode juga lebih sederhana untuk menulis:
float CurveWeightedRandom(AnimationCurve curve) {
return curve.Evaluate(Random.value);
}
Nilai acak ‘raw’ antara 0 dan 1 dipilih dengan membaca dari Random.value
. Kemudian dilewatkan ke curve.Evaluate()
, yang memperlakukannya sebagai koordinat horisontal, dan mengembalikan koordinat vertikal yang sesuai dari kurva pada posisi horizontal. Bagian-bagian kurva memiliki kesempatan yang lebih besar untuk dipilih, sementara bagian yang curam memiliki peluang yang lebih rendah untuk dipilih.
Perhatikan bahwa kurva ini bukan kurva distribusi probabilitas seperti Anda mungkin menemukan dalam panduan untuk teori probabilitas, tetapi lebih seperti kurva probabilitas kumulatif terbalik.
Dengan mendefinisikan variabel AnimationCurve
publik pada salah satu scriptsSepotong kode yang memungkinkan Anda untuk membuat Komponen Anda sendiri, memicu peristiwa permainan, memodifikasi sifat komponen dari waktu ke waktu dan menanggapi input pengguna dengan cara apa pun yang Anda sukai. More info
Lihat di Glossary Anda, Anda akan dapat melihat dan mengedit kurva melalui jendela InspectorJendela Unity yang menampilkan informasi tentang Pengaturan GameObject yang dipilih saat ini, aset atau proyek, memungkinkan Anda untuk memeriksa dan mengedit nilai. More info
Lihat di Glossary secara visual, bukan perlu menghitung nilai.
Teknik ini menghasilkan nomor titik mengambang. Jika Anda ingin menghitung hasil bilangan bulat - misalnya, Anda ingin 82 potongan emas, bukan 82.1214 potongan emas - Anda hanya dapat melewati nilai yang dihitung ke fungsi seperti Mathf.RoundToInt()
.
Mekanisme permainan umum adalah memilih dari set item yang dikenal tetapi memiliki mereka tiba dalam urutan acak. Misalnya, dek kartu biasanya dihilang sehingga tidak ditarik dalam urutan yang dapat diprediksi. Anda dapat merobek item dalam array dengan mengunjungi setiap elemen dan menukarnya dengan elemen lain pada indeks acak dalam array:-
void Shuffle (int[] deck) {
for (int i = 0; i < deck.Length; i++) {
int temp = deck[i];
int randomIndex = Random.Range(i, deck.Length);
deck[i] = deck[randomIndex];
deck[randomIndex] = temp;
}
}
Tugas umum adalah untuk memilih sejumlah item secara acak dari set tanpa memilih yang sama lebih dari sekali. Misalnya, Anda mungkin ingin menghasilkan sejumlah NPC pada poin spawn acak tetapi pastikan bahwa hanya satu NPC yang dihasilkan pada setiap titik. Ini dapat dilakukan dengan memperbarui melalui item dalam urutan, membuat keputusan acak untuk setiap apakah atau tidak ditambahkan ke set yang dipilih. Seperti setiap item dikunjungi, probabilitas yang dipilih sama dengan jumlah item masih diperlukan dibagi dengan jumlah masih tersisa untuk dipilih.
Sebagai contoh, mengusulkan bahwa sepuluh poin spawn tersedia tetapi hanya lima harus dipilih. Kemungkinan item pertama yang dipilih akan 5 / 10 atau 0,5. Jika dipilih maka probabilitas untuk item kedua akan 4 / 9 atau 0.44 (yaitu empat item masih diperlukan, sembilan kiri untuk dipilih). Namun, jika yang pertama tidak dipilih maka probabilitas untuk kedua akan 5 / 9 atau 0,56 (yaitu lima masih diperlukan, sembilan kiri untuk dipilih). Ini berlanjut sampai set berisi lima item yang diperlukan. Anda dapat menyelesaikan kode ini sebagai berikut:-
Transform[] spawnPoints;
Transform[] ChooseSet (int numRequired) {
Transform[] result = new Transform[numRequired];
int numToChoose = numRequired;
for (int numLeft = spawnPoints.Length; numLeft > 0; numLeft--) {
float prob = (float)numToChoose/(float)numLeft;
if (Random.value <= prob) {
numToChoose--;
result[numToChoose] = spawnPoints[numLeft - 1];
if (numToChoose == 0) {
break;
}
}
}
return result;
}
Perhatikan bahwa meskipun seleksi acak, item dalam set yang dipilih akan berada dalam urutan yang sama yang mereka miliki dalam array asli. Jika item yang akan digunakan satu pada waktu dalam urutan maka pesanan dapat membuat mereka terprediksi sebagian, sehingga mungkin perlu untuk merobek array sebelum digunakan.
Titik acak dalam volume kubik dapat dipilih dengan mengatur setiap komponen vektor3 untuk nilai yang dikembalikan oleh Random.value
:-
` var randVec = Vector3(Random.value, Random.value, Random.value);`
Ini memberikan titik di dalam kubus dengan sisi satu unit panjang. Kubis dapat ditingkatkan hanya dengan menggandakan komponen X, Y dan Z dari vektor dengan panjang sisi yang diinginkan. Jika salah satu sumbu diatur ke nol, titik akan selalu berbaring dalam satu pesawat. Sebagai contoh, memilih titik acak di “ground” biasanya merupakan masalah untuk mengatur komponen X dan Z secara acak dan mengatur komponen Y ke nol.
Ketika volume adalah bola (yaitu, ketika Anda ingin titik acak dalam radius tertentu dari titik asal), Anda dapat menggunakan Random.insideUnitSphere
yang dikalikan oleh radius yang diinginkan:-
` var randWithinRadius = Random.insideUnitSphere * radius;`
Perhatikan bahwa jika Anda mengatur salah satu komponen vektor yang dihasilkan ke nol, Anda akan not mendapatkan titik acak yang benar dalam lingkaran. Meskipun titik memang acak dan terletak di radius yang tepat, probabilitasnya sangat bias ke arah pusat lingkaran dan sehingga poin akan menyebar sangat tidak merata. Anda harus menggunakan Random.insideUnitCircle
untuk tugas ini bukan:-
`var randWithinCircle = Random.insideUnitCircle * radius;`