【Unity 入門】2時間で作る五目並べゲーム!


プログラミングを学びたいけど何から始めれば良いかわからない…」そんな方にオススメな方法がUnityでゲームを作りながらプログラミングを学ぶ方法です。

今回はUnityを使って「五目並べ」を作成しながらプログラミングの基礎を学んでいきたいと思います!

本記事は2部構成で進めていきます。第1部ではUnityで五目並べを作成するための準備をします。

第2部では五目並べのアルゴリズムを考えながらC#を使用して五目並べを実装していきます。

碁石を置く処理の確認
碁石を置く処理の確認

概要

まずはじめに今回作成する五目並べの基本的な情報を整理します。

  • ルール1:縦、横、斜めのいずれかの方向に5個碁石を並べた方が勝ち
  • ルール2:禁じ手は考慮しない
  • ルール3:プレイヤー同士の対戦を想定(二人が交互に打つ)
  • マス  :10×10

以上の情報をもとに五目並べゲームを作成していきます。

ユーザーの前提知識は

  • Unityでプロジェクトを作成したり、シーンを作成したりすることができる
  • 指定されたオブジェクトを作成することができる
  • C#スクリプトを作成してオブジェクトにアタッチすることができる

以上を想定して話を進めていきます。

Unityを全く触ったことがない…」という方はまずはじめに以下記事でゲームを作成しながらUnityの使い方をキャッチアップしてみてください!

参考記事)2時間で作るユニティちゃんRunゲーム!

第1部:五目並べに必要なパーツを準備する

まずはじめにUnityで五目並べを作成するために必要なパーツ(オブジェクト)を準備します。

五目並べに必要な主なパーツは以下の通りです。

  • マス(10×10)
  • 碁石(白と黒)

基本的にこの2つを準備しておけば最低限ゲームを成立させることができます。

まずはこの2つのパーツを作成しましょう。

任意のUnityプロジェクトを作成し、シーンを作成して準備を進めてください。本記事ではプロジェクト名を「GOMOKU」、最初に作成するシーン名を「Gomoku」としますが、基本的にどちらも任意ですのでお好きな名前をご使用ください。

また、プロジェクトのフォルダ構成は「Scenes」「Materials」「Scripts」「Prefabs」の4つで構成しています。これ以降、プロジェクトウィンドウのこれらのフォルダに要素を保存していきますので、あらかじめ4つのフォルダを作成しておいてください。

フォルダ構成
フォルダ構成

マスの作成

まずはじめに碁石を置くための10×10のマスを作成します。

それぞれのマスでクリック(タップ)処理を認識させるためにそれぞれのマスは別のオブジェクトとして作成していきます。

シーンにCubeオブジェクトを作成して名前を「Cube1_1」としてください。

作成したCube1_1のTransformを以下のように変更してください。

X Y Z
Position 0 0 0
Rotation 0 0 0
Scale 1 0.5 0
Cube1_1作成
Cube1_1作成

シーンビュー左上のY軸をクリックすることで以上のような視点に変更されます。もし斜めからの視点だと見づらいという方はこちらの視点で作成を進めてみてください。

Y軸視点変更
Y軸視点変更

同様にして「Cube1_2」を作成します。作成したCube2_2のTransformを以下のように変更してください。

X Y Z
Position 1 0 0
Rotation 0 0 0
Scale 1 0.5 0

PositionのXが1に変更された以外に変更点はありません。

Cube1_2作成
Cube1_2作成

このままだと隣り合ったマスが同じ色なのでとても見づらいと思います。

そこで隣り合うマスの色を変更するためにマテリアルを2つ作成してそれぞれの色を変更します。

Materialsフォルダに「Masu1」マテリアルと「Masu2」マテリアルを作成してください。

作成したそれぞれのマテリアルのAlbedoを変更して色を設定します。

色は任意ですが今回は以下のような値をそれぞれのマテリアルに設定しました。

これらのマテリアルをCube1_1とCube1_2にアタッチして色を変更してください。

色変更後
色変更後

色がこの後の作業に影響を及ぼすことは全くありませんのでお好きな色をご使用していただいて問題ありません。

※「色をもっと工夫したい!」という方は以下記事をご参考ください。

参考記事)オブジェクトの色について

このようにして10×10のマスCube1_1〜Cube10_10の合計100個作成します。多少時間はかかってしまいますがコピペを駆使して100個作成してみてください。

座標はそれぞれ以下の通りです。

マスの座標を雑にしてしまうと後ほど配列との対応が難しくなりますので、下記の座標の通り正確に記述してください。

マス座標参考表
マス座標参考表
マスオブジェクト作成後
マスオブジェクト作成後

これでマスの作成は完了です。

碁石の作成

次に碁石を作成します。

碁石は白の碁石「White_Stone」と黒の碁石「Black_Stone」の2種類をプレハブとして作成します。

まずはじめにSphereを2つ「White_Stone」「Black_Stone」という名前で作成してください。

TransformのPositionとRotationは任意ですが、Scaleの値は以下のように変更してください。

X Y Z
Scale 0.7 0.2 0.7

Scaleの値を変更すると碁石のような形になります。

形が変更されたら、先ほどマスに色をつけたように「White」「Black」という名前でマテリアルを作成してそれぞれアタッチして色を変更してください。

次にRigidbodyコンポーネントを追加します。

それぞれのオブジェクトを選択してインスペクターウィンドウ最下部のAddComponent→Physics→Rigidbodyを選択して追加してください。

最後にすでにアタッチされているSphereColliderのRadiusを「0.15」に変更して完了です。

碁石のインスペクターウィンドウ
碁石のインスペクターウィンドウ

ここまでの操作でマスとともにシーンビューに白と黒の碁石が作成されます。

黒の碁石
黒の碁石

次にヒエラルキーウィンドウにあるWhite_StoneとBlack_Stoneをプレハブ化します。

方法はとても簡単で、ヒエラルキーウィンドウにあるそれぞれのオブジェクトをプロジェクトウィンドウのPrefabsにドラッグ&ドロップすればプレハブ化することができます。

碁石をプレハブ化
碁石をプレハブ化

プレハブを作成したらヒエラルキーウィンドウの2つの碁石は削除してください。

これでパーツの準備は完了です。

五目並べをプログラミングする

ここから本題のプログラミングに入ります。

五目並べを実装する方法は複数ありますが、本記事ではできるだけわかりやすいロジックで五目並べを実装していきたいと思います。

ご紹介する内容が全てではありませんのでご注意ください。

白と黒を配列情報として保存する

マスの情報を2次元のint型配列として管理します。

何も置かれていないマスは「0」、白が置かれているマスは「1」、黒が置かれているマスは「-1」で保存します。

まずはこれらを記述するスクリプト「GameController」をプロジェクトウィンドウのScriptsフォルダに作成してください。

以下のようにプログラムを編集してください。(デフォルト以外をハイライトしています)

プログラムの解説をします。

8行目を見てください。

これによって10×10の2次元のint型配列を作成します。

11~13行目を見てください。

privateの後ろに「const」とすることで定数化することができます。値は記述の通りです。

定数としてそれぞれの値を準備しておく理由は、値を代入する際にミスを減らすためです。

配列を初期化する

配列の値を全てEMPTY(0)にするメソッドを作成します。

先ほど作成したGameControllerを以下のように編集してください。

プログラムの解説をします。

19行目を見てください。

これによってInitializeArrayメソッドを実行することができます。引数なしメソッドは「メソッド名();」で実行することができます。

22行目も上記と同様にメソッドを呼び出しています。

32~43行目を見てください。

InitializeArrayメソッドを定義しています。このメソッドは返り値がないためvoid型で宣言します。

このメソッドでは2次元配列の各値にアクセスするためにfor文を2つ重ねて配列の中身全てにアクセスしています。

配列のアクセスは「配列名[i,j]」でアクセスすることができます。

この配列の各値を全てEMPTY(0)にしています。

45~55行目のDebugArrayメソッドは上記と同様に配列の中身にアクセスして値を確認するためにコンソールに出力しています。

これで配列を初期化することができました。

ここまで作成したGameControllerスクリプトを実行できるようにします。

ヒエラルキーウィンドウに空のオブジェクト「GameController」を作成してドラッグ&ドロップしてスクリプトをアタッチしてください。

GameControllerスクリプトをアタッチ
GameControllerスクリプトをアタッチ

この状態でコンソールを開いて実行すると、値が初期化されたことが確認できます。

配列の初期化を確認
配列の初期化を確認

碁石を置く

いよいよ碁石を置く処理を記述していきます。

ここでは一旦プログラムを記述した後、中身について詳しく解説していきます。

まずは先ほどと同様GameControllerスクリプトを以下のように編集してください。

詳しく解説していきます。

16行目を見てください。

先攻となる碁石の色を決定します。ここではWHITE(白)を先攻に設定しています。

19~20行目では後ほどオブジェクトをクリックしたかどうか判定するために必要なカメラとレイキャストを格納するための変数を宣言しています。

23~24行目を見てください。

前章で作成した碁石のプレハブを格納するための変数です。「public」で宣言することでUnityエディタから直接プレハブをアタッチすることができます。

30行目を見てください。

先ほど宣言したCamera型の変数camera_objectに「Find()」メソッドを利用してメインカメラのCameraコンポーネントを格納します。

「Find()」でメインカメラオブジェクトを取得し、「GetComponent<Camera>()」でメインカメラのCameraコンポーネントを取得しています。

43行目を見てください。

「Input.GetMouseButtonDown(0)」でマウスでのクリックしたかどうかをブーリアンで取得します。

if文の条件に入れることでクリックされた瞬間にif文の中身を実行します。

46行目を見てください。

詳しい説明は省略しますが、ここではクリックした場所をもとにRayを作成します。このRayを投げる(キャストする)し、このRayと衝突したオブジェクト情報を取得することができます。

49行目を見てください。

46行目で作成したRayをRaycastメソッドで投げて「hit」という形で返り値を取得します。

52~53行目を見てください。

ここではクリックしたオブジェクトのPosition情報(XとZ)を取得して、squares配列に値を格納するための情報に変換します。

56行目ではクリックした場所が空かどうか判定します。ZとXが反対な理由は、配列が[ i , j ] = [ 縦 , 横 ] = [ z軸方向 , x軸方向 ]として管理しているためです。

ここで注意しなければならないことが、マスのPositionの値を適当に決めてしまった方はマスの情報と配列の情報がマッチしない可能性がありますのでご注意ください。

59行目と73行目では今現在のプレイヤーの碁石の色を判定しています。それぞれの色のときにsquares配列にそれぞれの色を格納します。

65~66行目と78~79行目を見てください。(下記のプログラムはWHITEの部分のみ)

「Instantiate(whiteStone)」で新しくwhiteStoneオブジェクトを生成しています。これによって白の碁石が出現します。

しかしこれだけでは場所が確定しません。そこで碁石のpositionにhitで取得したオブジェクト(マス)のpositionを代入することで位置を確定させます。

69行目と82行目でプレイヤーを変更して碁石を置く処理は完了です。

メインカメラの位置変更

メインカメラの位置が変更されていないとマス全体を見ることができません。そこでMainCameraのTransformを以下の値に変更してください。

X Y Z
Position 4.5 10 4.5
Rotation 90 0 0
Scale 1 1 1

それでは実際に実行して確認してみましょう。

碁石を置く処理の確認
碁石を置く処理の確認

碁石が置けることを確認できました。

縦横斜めの判定

それでは碁石が縦横斜めに5個連続で置かれているかどうかを判定するメソッドを作成していきます。

長くなってしまいますのでメソッドのみ記述します。GameControllerスクリプトに以下のメソッドを追加してください。

どの方向の判定も基本的な考え方は同じですので横方向のみ解説します。

一旦横方向のプログラムを抽出します。

基本的な仕組みはシンプルでfor文を重ね合わせて全てのマスを探索します。

連続して5回引数であるcolorが出現したときに勝ち判定を行っています。

このロジックは無駄が多い反面、原理がシンプルなので今回はこちらのロジックを用いました。

判定方法は他にもたくさんありますのでぜひ他の方法でも実装してみてください。

このメソッドをGameControllerスクリプトのUpdateメソッドで以下のように呼び出して使用します。

ハイライト部分のように記述することでどちらかの勝利が決定した段階で碁石を置けなくなります。

実際に実行して確認してみましょう。

勝敗判定
勝敗判定

これで五目並べが完成しました!

おまけ:UIを整える

おまけとしてゲームのUIを整えていきます。

ここで実装する内容としては、

  • どちらのターンかわかりやすくする

以上1点を実装していきます。

どちらのターンかわかりやすくする

まずはじめにどちらのターンかわかりやすくするためにテキストUIを作成します。

ヒエラルキーウィンドウでUIのTextを作成してください。

テキストに関する詳しい情報は以下記事をご参考ください。

参考記事)テキストについて

テキストのサイズや色は任意ですが、今回作成したテキストの値は以下の通りです。

ターン表示テキストの値
ターン表示テキストの値
実行結果
実行結果

次にテキストを変更するためにGameControllerスクリプトを編集します。

ハイライトされた部分を新しく付け足してください。

以上のように編集したら、プレハブをアタッチしたように作成したテキストをスクリプトにアタッチして実際に実行してみましょう。

ターン表示テキスト確認
ターン表示テキスト確認

これでターンの表示は完了です。

勝ちをUIに表示する

現在は勝ったときの出力をコンソールに出力していますが、それでは実際のゲームではわかりづらいです。

そこでターン表示と同様に勝ちについてもテキストUIに表示する方法を取ることができます。

基本的な方法はターン表示テキストと同じですが、違う点は勝ったときに表示するという点です。

この機能を実装する方法は複数ありますが、今回は勝つまではテキストの値をNULL(空)にしておく方法だと簡単です。

先ほどの方法と全く同じ方法で実装することができますのでお時間がある方はぜひチャレンジしてみてください。

まとめ

いかがでしたでしょうか。

今回は「2時間で作る五目並べ」ということでゲームを作成してきました。

ボードゲームはスクリプトで実装しなければならない点が多く、プログラミングが苦手な方にとっては大変だったかもしれません。

ここまでの内容を自力で実装できるようになればかなり力がつくと思います。ここまで進めた後で改めて何も見ずに作成してみると、よりプログラミングの力がつきますのでぜひチャレンジしてみてください。

また、今回は一つのクラスでのみ実装しているため機能の分割が全くできていません。

「この部分は別クラスを作成した方がいいのになぁ」と思いながら作成していた方もいらっしゃると思いますので、ぜひプログラムの効率化にもチャレンジしてみてはいかがでしょうか。

長くなりましたが、この記事で皆様のUnityライフが少しでも充実していただければ幸いです!


五目並べアイキャッチ

この記事はいかがでしたか?
もし「参考になった」「面白かった」という場合は、応援シェアお願いします!

Twitterはじめました @FuruiYuya