Kelas Penting - Mathf
Kelas Penting - Debug

Kelas Penting - Acak

Switch to Scripting

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.

Nomor acak sederhana

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.

Poin acak dalam Lingkaran atau Spheres

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.

Jenis nilai acak lainnya

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 Acak Item dari Array

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.

Memilih Item dengan Kemampuan yang Berbeda

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:-

  • 50% kemungkinan salam ramah
  • 25% kemungkinan berjalan
  • 20% kemungkinan serangan segera
  • 5% kemungkinan menawarkan uang sebagai hadiah

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.

Berat nilai acak terus menerus

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.

A linear curve does not weight values at all; the horizontal coordinate is equal to the vertical coordinate for each point on the curve.
Kurva linier tidak nilai berat sama dengan koordinat vertikal untuk setiap titik pada kurva.
This curve is shallower at the beginning, and then steeper at the end, so it has a greater chance of low values and a reduced chance of high values. You can see that the height of the curve on the line where x=0.5 is at about 0.25, which means theres a 50% chance of getting a value between 0 and 0.25.
Kurva ini lebih dangkal pada awal, dan kemudian steeper pada akhir, sehingga memiliki peluang yang lebih besar dari nilai-nilai rendah dan kemungkinan berkurang nilai-nilai tinggi. Anda dapat melihat bahwa ketinggian kurva di garis di mana x = 0,5 adalah sekitar 0,25, yang berarti ada 50% kemungkinan mendapatkan nilai antara 0 dan 0,25.
This curve is shallow at both the beginning and the end, making values close to the extremes more common, and steep in the middle which will make those values rare. Notice also that with this curve, the height values have been shifted up: the bottom of the curve is at 1, and the top of the curve is at 10, which means the values produced by the curve will be in the 1-10 range, instead of 0-1 like the previous curves.
Kurva ini dangkal pada awal dan akhir, membuat nilai dekat dengan ekstrem lebih umum, dan curam di tengah yang akan membuat nilai-nilai yang langka. Perhatikan juga bahwa dengan kurva ini, nilai-nilai tinggi telah digeserkan: bagian bawah kurva adalah pada 1, dan bagian atas kurva adalah pada 10, yang berarti nilai-nilai yang dihasilkan oleh kurva akan berada dalam kisaran 1-10, bukan 0–1 seperti kurva sebelumnya.

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().

Shuffling Daftar

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;
    }
}

Memilih dari Set Barang Tanpa Pengulangan

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.

Poin acak di Ruang

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;`
Kelas Penting - Mathf
Kelas Penting - Debug