Unity|簡単なスロットマシンを作成。Part2.ランダム回転と図柄揃いの処理

Unity2Dで「1ラインのシンプルなスロットマシン」を作成する、第2回目です。前回の続きでリールの回転数をランダムにするのと、図柄が揃った時の処理を追加していきます。

はじめに

Unityのバージョンは2022.3.14f1です。Part1ではリールを作成しました。

今回はPart1の続きでリール回転数をランダムにするのと、同じ図柄が揃った時の処理を追加していきます。

画像の準備

簡単なスロットマシンの枠として下記の画像を利用します。

リール画像と同じドット絵の設定をInspectorで行った後に、下記のような感じに配置します。

実装開始

スペースキーでリールが回っていたのをボタンに変更。また、揃った時のポイントを表示するUIを追加します。

「UI」→「Legacy」→「Text」と「Button」を追加します。

枠に合わせてボタンとテキストの位置を変更します。

スクリプトの作成

まずはGameManagerスクリプトを下記に変更。一気に追加しましたが、難しいところは特にないです。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
using UnityEngine;
using UnityEngine.UI;
public class GameManager : MonoBehaviour
{
public static GameManager instance { get; private set; }
public enum SlotValue { none, sword, key, shield, dia, box, ring, coin }
[SerializeField] private Reel[] reels;
[SerializeField] private Text winText;
private int winPrize;
private void Awake()
{
instance = this;
}
private void Update()
{
if (reels[0]._reelStop && reels[1]._reelStop && reels[2]._reelStop)
{
CheckResult();
winText.text = "Win: " + winPrize;
}
}
public void Spin()
{
if (reels[0]._reelStop && reels[1]._reelStop && reels[2]._reelStop)
RellStart();
}
private void RellStart()
{
int randomNum = Random.Range(40, 68);
for (int i = 0; i < reels.Length; i++)
{
if (randomNum % 4 != 0)
{
randomNum = (randomNum / 4) * 4;
}
reels[i].RellStart(randomNum);
randomNum += Random.Range(4, 28);
}
}
private void CheckResult()
{
if (reels[0]._slotValue == reels[1]._slotValue && reels[0]._slotValue == reels[2]._slotValue)
{
switch (reels[0]._slotValue)
{
case SlotValue.box:
winPrize = 100;
break;
case SlotValue.coin:
winPrize = 200;
break;
case SlotValue.dia:
winPrize = 300;
break;
case SlotValue.key:
winPrize = 400;
break;
case SlotValue.ring:
winPrize = 500;
break;
case SlotValue.shield:
winPrize = 600;
break;
case SlotValue.sword:
winPrize = 700;
break;
}
}
else
{
winPrize = 0;
}
}
}
using UnityEngine; using UnityEngine.UI; public class GameManager : MonoBehaviour { public static GameManager instance { get; private set; } public enum SlotValue { none, sword, key, shield, dia, box, ring, coin } [SerializeField] private Reel[] reels; [SerializeField] private Text winText; private int winPrize; private void Awake() { instance = this; } private void Update() { if (reels[0]._reelStop && reels[1]._reelStop && reels[2]._reelStop) { CheckResult(); winText.text = "Win: " + winPrize; } } public void Spin() { if (reels[0]._reelStop && reels[1]._reelStop && reels[2]._reelStop) RellStart(); } private void RellStart() { int randomNum = Random.Range(40, 68); for (int i = 0; i < reels.Length; i++) { if (randomNum % 4 != 0) { randomNum = (randomNum / 4) * 4; } reels[i].RellStart(randomNum); randomNum += Random.Range(4, 28); } } private void CheckResult() { if (reels[0]._slotValue == reels[1]._slotValue && reels[0]._slotValue == reels[2]._slotValue) { switch (reels[0]._slotValue) { case SlotValue.box: winPrize = 100; break; case SlotValue.coin: winPrize = 200; break; case SlotValue.dia: winPrize = 300; break; case SlotValue.key: winPrize = 400; break; case SlotValue.ring: winPrize = 500; break; case SlotValue.shield: winPrize = 600; break; case SlotValue.sword: winPrize = 700; break; } } else { winPrize = 0; } } }
using UnityEngine;
using UnityEngine.UI;

public class GameManager : MonoBehaviour
{
    public static GameManager instance { get; private set; }
    public enum SlotValue { none, sword, key, shield, dia, box, ring, coin }

    [SerializeField] private Reel[] reels;
    [SerializeField] private Text winText;

    private int winPrize;

    private void Awake()
    {
        instance = this;
    }
    private void Update()
    {

        if (reels[0]._reelStop && reels[1]._reelStop && reels[2]._reelStop)
        {
            CheckResult();
            winText.text = "Win: " + winPrize;
        }
    }
    public void Spin()
    {
        if (reels[0]._reelStop && reels[1]._reelStop && reels[2]._reelStop)
            RellStart();
    }
    private void RellStart()
    {
        int randomNum = Random.Range(40, 68);

        for (int i = 0; i < reels.Length; i++)
        {
            if (randomNum % 4 != 0)
            {
                randomNum = (randomNum / 4) * 4;
            }
            reels[i].RellStart(randomNum);
            randomNum += Random.Range(4, 28);
        }
    }

    private void CheckResult()
    {
        if (reels[0]._slotValue == reels[1]._slotValue && reels[0]._slotValue == reels[2]._slotValue)
        {
            switch (reels[0]._slotValue)
            {
                case SlotValue.box:
                    winPrize = 100;
                    break;
                case SlotValue.coin:
                    winPrize = 200;
                    break;
                case SlotValue.dia:
                    winPrize = 300;
                    break;
                case SlotValue.key:
                    winPrize = 400;
                    break;
                case SlotValue.ring:
                    winPrize = 500;
                    break;
                case SlotValue.shield:
                    winPrize = 600;
                    break;
                case SlotValue.sword:
                    winPrize = 700;
                    break;
            }
        }
        else
        {
            winPrize = 0;
        }
    }
}

簡単に説明すると、Update内でリールが止まっているかをチェック。全リールが止まったら同じ図柄が揃っているかをチェックしています。ボタンを押したタイミングでSpin()を呼び出し、RellStartで回転数をランダムに決めています。図柄が真ん中に止まるようにランダム数を4の倍数に調整しています。

Reelスクリプトは下記のように変更。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
using System.Collections;
using UnityEngine;
public class Reel : MonoBehaviour
{
[SerializeField] private float ResetPosition;
public GameManager.SlotValue _slotValue;
public bool _reelStop;
private float ReelSpeed;
private Vector2 StartPosition;
private float reelStep = 0.25f;
private void Awake()
{
_slotValue = GameManager.SlotValue.none;
_reelStop = true;
ReelSpeed = 0.05f;
StartPosition = new Vector2(transform.position.x, 3.5f);
}
public void RellStart(int num)
{
StartCoroutine(RellRotate(num));
}
private IEnumerator RellRotate(int num)
{
_reelStop = false;
for (int i = 0; i < num; i++)
{
if (transform.position.y <= ResetPosition)
transform.position = StartPosition;
transform.position = new Vector2(transform.position.x, transform.position.y - reelStep);
yield return new WaitForSeconds(ReelSpeed);
}
Result();
_reelStop = true;
}
private void Result()
{
switch (transform.position.y)
{
case 0:
_slotValue = GameManager.SlotValue.box;
break;
case -1:
_slotValue = GameManager.SlotValue.dia;
break;
case -2:
_slotValue = GameManager.SlotValue.shield;
break;
case -3:
_slotValue = GameManager.SlotValue.key;
break;
case 3:
_slotValue = GameManager.SlotValue.sword;
break;
case 2:
_slotValue = GameManager.SlotValue.coin;
break;
case 1:
_slotValue = GameManager.SlotValue.ring;
break;
}
}
}
using System.Collections; using UnityEngine; public class Reel : MonoBehaviour { [SerializeField] private float ResetPosition; public GameManager.SlotValue _slotValue; public bool _reelStop; private float ReelSpeed; private Vector2 StartPosition; private float reelStep = 0.25f; private void Awake() { _slotValue = GameManager.SlotValue.none; _reelStop = true; ReelSpeed = 0.05f; StartPosition = new Vector2(transform.position.x, 3.5f); } public void RellStart(int num) { StartCoroutine(RellRotate(num)); } private IEnumerator RellRotate(int num) { _reelStop = false; for (int i = 0; i < num; i++) { if (transform.position.y <= ResetPosition) transform.position = StartPosition; transform.position = new Vector2(transform.position.x, transform.position.y - reelStep); yield return new WaitForSeconds(ReelSpeed); } Result(); _reelStop = true; } private void Result() { switch (transform.position.y) { case 0: _slotValue = GameManager.SlotValue.box; break; case -1: _slotValue = GameManager.SlotValue.dia; break; case -2: _slotValue = GameManager.SlotValue.shield; break; case -3: _slotValue = GameManager.SlotValue.key; break; case 3: _slotValue = GameManager.SlotValue.sword; break; case 2: _slotValue = GameManager.SlotValue.coin; break; case 1: _slotValue = GameManager.SlotValue.ring; break; } } }
using System.Collections;
using UnityEngine;

public class Reel : MonoBehaviour
{
    [SerializeField] private float ResetPosition;
    public GameManager.SlotValue _slotValue;
    public bool _reelStop;

    private float ReelSpeed;
    private Vector2 StartPosition;
    private float reelStep = 0.25f;

    private void Awake()
    {
        _slotValue = GameManager.SlotValue.none;
        _reelStop = true;
        ReelSpeed = 0.05f;
        StartPosition = new Vector2(transform.position.x, 3.5f);
    }

    public void RellStart(int num)
    {
        StartCoroutine(RellRotate(num));
    }
    private IEnumerator RellRotate(int num)
    {
        _reelStop = false;

        for (int i = 0; i < num; i++)
        {
            if (transform.position.y <= ResetPosition)
                transform.position = StartPosition;

            transform.position = new Vector2(transform.position.x, transform.position.y - reelStep);

            yield return new WaitForSeconds(ReelSpeed);
        }

        Result();
        _reelStop = true;

    }
    private void Result()
    {
        switch (transform.position.y)
        {
            case 0:
                _slotValue = GameManager.SlotValue.box;
                break;
            case -1:
                _slotValue = GameManager.SlotValue.dia;
                break;
            case -2:
                _slotValue = GameManager.SlotValue.shield;
                break;
            case -3:
                _slotValue = GameManager.SlotValue.key;
                break;
            case 3:
                _slotValue = GameManager.SlotValue.sword;
                break;
            case 2:
                _slotValue = GameManager.SlotValue.coin;
                break;
            case 1:
                _slotValue = GameManager.SlotValue.ring;
                break;
        }
    }
}

止まった位置によって図柄の値をセットしています。

実行すると下記のような感じになります。細かいところで結構直す部分がありますが、とりあえずそれっぽい感じに。

タイトルとURLをコピーしました