Unityで簡単な「ガチャ機能」を実装してみます。敵を倒した時に「設定した確率でアイテムをドロップ」するのにも使えたりする感じです。
はじめに
Unityのバージョンは2021.3.14f1です。
今回実装するのは、下記のような赤玉が3個、黒玉が1個ある中からランダムで1個選択するという感じのものです(赤が出る確率が75%、黒が出る確率が25%)。いわゆる「ガチャ」というものですね。

実装開始
まずは動きを確認するため、簡単に実装してみます。
動きを確認するスクリプト
まずは下記のスクリプトを作成します。スクリプト名は「Randomdrop」にしておきます。
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class Randomdrop : MonoBehaviour
{
[System.Serializable]
public struct Item
{
public string ItemName;
public float dropNum;
}
public List<Item> _items = new List<Item>();
private float totalNum;
void Start()
{
totalNum = _items.Sum(item => item.dropNum);
}
private void Update()
{
if (Input.GetKey(KeyCode.Space))
{
var item = Dropitem();
Debug.Log(item.ItemName);
}
}
private Item Dropitem()
{
float randomNumber = Random.Range(0f, totalNum);
foreach (var item in _items)
{
randomNumber -= item.dropNum;
if (randomNumber <= 0)
return item;
}
throw new System.Exception("Error No Item");
}
}
構造体で「アイテム名」、「アイテム数」をセット。Startで全アイテム数を合計、スペースキーを押したらアイテムを選択するという感じです。
ランダムドロップ機能
Dropitem関数では全アイテム数からランダムに数を選び、アイテム数を引き算して対象アイテムを判定しています。下記のようにアイテムに数字を割り当てているイメージですね。例えばランダム数で2が出た場合、赤判定である-3をすると0以下になるので赤玉を返すという感じです。

カメラにスクリプトをアタッチして、下記のようにパラメータをセット。

実行してスペースキーを押すと結果がコンソールに表示されます。数字を変えたり、アイテムの数を増やしてみて確認するのも良いかもしれないですね。

ScriptableObjectで実装
次にScriptableObjectを利用して、多くのアイテム種類で実装できる形を考えてみます。まずはItemTableと言う名前で下記スクリプトを作成。
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
[CreateAssetMenu]
public class ItemTable:ScriptableObject
{
[SerializeField] private List<Item> _items;
private bool isInit = false;
private float totalNum = 0;
private void Init()
{
if (!isInit)
{
totalNum = _items.Sum(item => item.dropNum);
isInit = true;
}
}
public Item GetDropitem()
{
Init();
float randomNumber = Random.Range(0f, totalNum);
foreach (var item in _items)
{
randomNumber -= item.dropNum;
if (randomNumber <= 0)
{
return item;
}
}
throw new System.Exception("Error No Item");
}
}
[System.Serializable]
public class Item
{
public string ItemName;
public float dropNum;
}
機能的には、前のスクリプトと似たような感じです。
次にAssetsフォルダ内で「Create」→「ItemTable」を追加。

ItemTableでアイテムをセットします。下記は「斧アイテム」を例にしています。木の斧が80個、銀の斧が15個、金の斧が5個を用意する感じですね、確率で言うと80%,15%,5%です。

Randomdropスクリプトは下記のようにスッキリとした形に変更。
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class Randomdrop : MonoBehaviour
{
[SerializeField] private ItemTable _itemTable;
private void Update()
{
if (Input.GetKey(KeyCode.Space))
{
var item = _itemTable.GetDropitem();
Debug.Log(item.ItemName);
}
}
}
あとはItemTableをセットすればOK。アイテムを変更したい場合は、新しいItemTableを作成してパラメータを変更するだけ。

今回はDebug.logでアイテム名を表示しているだけですが、実際にはTableに「名前」と「数」以外に「スプライト」を追加して表示を変えたり、「レア度」を持たせて演出を変えたりする感じですね。