見出し画像

Unityパズルゲーム講座で“なぞって消す”処理を作ってみた!配列管理とタッチ判定【第6回】


「ボールをなぞって消す」―― パズルゲームの定番でありながら、自分で実装しようとすると一気に複雑に感じるところ。
今回の講座では、その“なぞり”の仕組みを Unity でどう作るのかを学んでいきました。
実際に触ってみると、タッチ判定・Ray・マテリアルのプロパティ名・動的配列など、思っていた以上に深い仕組みが必要で驚きました。

参考先:タッチ操作でボールをなぞって消す処理の作り方 ~配列で管理しよう~ | Unity入門の森 ゲームの作り方

前回


なぞったボールを光らせるために Renderer を取得する

まずは、ボールをタッチした時に “選択中” だと分かるように色を変える処理から。
Unityには、マテリアルやメッシュを描画するための Renderer クラスがあり、
スクリプトからマテリアルを変更したい場合は、まずこの Renderer を取得する必要があります。

public Renderer renderer; の意味

● これは「Inspector から Renderer をセットするための変数」

BallObject のスクリプトに


public Renderer renderer;


 

と書くことで、Inspector に「Renderer」という欄が表示されます。
ここに Ball プレハブの Renderer をドラッグ&ドロップで割り当てることができるようになります。

 
これで、以下のようにマテリアルへアクセスできるようになります。


renderer.material.SetColor("_EmissionColor", new Color(1f,1f,0,0.5f));
 


注意:SetColor の第一引数は「正しいプロパティ名」を使うこと

"_EmissionColor" という文字列は、実はシェーダー内部の正式名称です。
この名前を間違えると、何を書いても色が変わりません
正しいプロパティ名を調べるには:

  1. マテリアルを選択

  2. インスペクタ右上の「…」→ Debug を選択

  3. シェーダーのプロパティ名一覧の中に _EmissionColor が表示される

ここは一見単純なんですが、第一引数の文字列を間違えるとまったく動きません。
正しい名前を調べるには、

  1. マテリアルを選択

  2. インスペクタ右上の「…」を押す

  3. Debug モードに切り替える

 正しい文字列は マテリアルの Inspector を Debug 表示に切り替えたときにしか見えません。
Debug にしないと _EmissionColor が表示されないので注意です。


さらにハマったポイント:Renderer を“2か所”に設定しないと動かない

作業中で一番困惑したのがここ。
スクリプトを書いたあと、
BallObject のインスペクタ内にある Renderer 欄へ、Ball プレハブをドラッグ&ドロップする必要があります。
……が、実はそれだけでは足りません。

プレハブ本体の Ball 側にも Renderer を設定しないとエラーになる

これは公式記事には書かれておらず、ページ下部の動画でやっと気付けました。
こっちを設定しないと、
●      色が変わらない
●      どれだけコードを直しても改善しない


BallObject と Ball プレハブ本体の両方に設定が必要
ここは本当に落とし穴でした。

■ マウス(タッチ)でなぞる処理:GetMouseButton で判定

なぞり動作は、クリックした瞬間ではなく
押しっぱなしの間にずっと判定したいので Input.GetMouseButton(0) を使います。
●      0 → 左クリック(スマホではタッチに相当)
●      1 → 右クリック
●      2 → ホイール押し込み


今回の“なぞり”では
押し続けている間だけ Ray を飛ばす必要があるため、0 を使うのが正解
 


if(Input.GetMouseButton(0))
{
Ray ray = Camera.main.ScreenPointToRay(mousePos);
var h = Physics.RaycastAll(ray, 100.0f);
 
if(h.Length > 0 && h[0].collider.tag=="Ball")
{
h[0].collider.GetComponent<BallObject>()
.renderer.material.SetColor("_EmissionColor", new Color(1f,1f,0,0.5f));
}
}
  •  RaycastAll …… なぞった位置のオブジェクトを取得

  •  tag == "Ball" …… ボールに当たった時だけ反応

  •   Emission を黄色にして“選択中”を視覚化


 OnMouseDown/OnMouseDrag/OnMouseUp をどう使い分けるか?

今回の仕組みを作りながら痛感したのが、
3つのマウスイベントの役割がぜんぜん違うという点。

  • OnMouseDown:タッチ開始(最初に触れたボールの登録)

  • OnMouseDrag:なぞり中(次々とボールを追加)

  • OnMouseUp:タッチ終了(List 内のボールを削除)


教材では Input.GetMouseButton を使っていましたが、
Unity にはもともと この3段階を自動で管理する仕組みがあるので、
「タッチ操作にはこういう選択肢があるんだな」と理解が深まりました。
特に、


  •   初期化(List.Clear)

  •   ボール削除(ReleaseObject)

  •  色リセット

などを分かりやすく整理するには OnMouseUp がとても扱いやすい。

なぞったボールを記録するための List(動的配列)

次は、なぞったボールを順番に保存していく仕組みです。
ここでは List 型(動的配列) を使用。


  • 要素数を後から増やせる

  • 配列より扱いやすい

  • パズルの「何個なぞるか分からない」状況に最適


基本操作はこんな感じ:

var tmp = new List<T>(); // 初期化
tmp.Add(hoge); // 要素追加
tmp.Clear(); // 全消去

 
なぞっている間にボールを Add() していき、
最後に指を離したら全削除…という流れです。

最後にまとめて削除する ReleaseObject 関数

指を離した瞬間(GetMouseButtonUp)に呼び出すのが ReleaseObject()
この関数で
●      List へ入っているボールをまとめて消す
●      マテリアルの色を元に戻す
●      スコア計算
●      List.Clear()


などの後処理を行います。
“なぞり”操作の締めくくりに使う関数です。

まとめ

第6回では、パズルゲームに欠かせない なぞって消す操作 を実装しました。

  • Renderer を取得してボールの色を変える

  • シェーダープロパティの正しい名前を Debug で調べる

  • プレハブとスクリプトの両方へ Renderer を設定する(超重要)

  • GetMouseButton でタッチ判定

  • List を使って選択中ボールを管理

  • ReleaseObject でまとめて削除

表面的にはシンプルに見えて、実際に触ると“小さな落とし穴”が多い回でしたが、
ここを乗り越えると一気にパズルゲームらしさが出てきます。
次回は、ボールを増やす処理と3つ以上揃ったときにボールを消す処理やっていきます。

無料のPDF講座も登録してみました

先輩から「メルマガに登録するとPDF講座がもらえるよ」とも教えてもらったので、こちらも登録してみました。

無料でPDF講座がもらえるメルマガ

無料で受け取れるので、Unityをこれから始めようとしている方はあわせて登録してみるといいかもしれません。


引き続き頑張ります!



いいなと思ったら応援しよう!

この記事が参加している募集