*

[Unity]Unity2Dチュートリアル 同じ色のパズルを消去する ソース解説

公開日: : C#, Unity, ソース

◆全文

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class GameSystem : MonoBehaviour {
	private const int TileLineNum = 5;
	private const int TileColNum = 6;
	private const float TileWidth = 0.5f;
	private const float TileHeight = 0.5f;
	private const float FirstTilePosX = -1.5f;
	private const float FirstTilePosY = -2;

	public GameObject holdObj;
	public float holdPositionX;
	public float holdPositionY;
	private float z = 10f;
	private GameObject[,] tileSet;
	
	// Use this for initialization
	void Start () {
		SetTileSet();
	}
	
	// Update is called once per frame
	void Update () {
		if(Input.GetMouseButtonDown(0)){
			LeftClick();
		}
		if(Input.GetMouseButton(0)){
			LeftDrag();
		}
		if(Input.GetMouseButtonUp(0)){
			LeftUp();
			DeleteMatchTile();
		}
	}
	
	private void LeftClick(){
		Vector3 tapPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, z);
		if(holdObj == null){
			Collider2D col = Physics2D.OverlapPoint(Camera.main.ScreenToWorldPoint(tapPoint));
			if(col != null){
				this.holdObj = col.gameObject;
				holdPositionX = this.holdObj.transform.position.x;
				holdPositionY = this.holdObj.transform.position.y;
				holdObj.transform.position = Camera.main.ScreenToWorldPoint(tapPoint);
			}
		}
		
	}
	private void LeftDrag(){
		Vector3 tapPoint = Input.mousePosition;
		if(holdObj != null){
			this.holdObj.transform.position = Camera.main.ScreenToWorldPoint(new Vector3(tapPoint.x, tapPoint.y, z));
			Collider2D[] colSet = Physics2D.OverlapPointAll(Camera.main.ScreenToWorldPoint(new Vector3(tapPoint.x, tapPoint.y, z)));
			if(colSet.Length > 1){
				foreach(Collider2D col in colSet){
					if(!col.gameObject.Equals(this.holdObj)){
						float tmpPositionX = holdPositionX;
						float tmpPositionY = holdPositionY;
						holdPositionX = col.gameObject.transform.position.x;
						holdPositionY = col.gameObject.transform.position.y;
						col.gameObject.transform.position = new Vector3(tmpPositionX, tmpPositionY, z);
					}
				}
			}
		}
	}
	private void LeftUp(){
		if(holdObj != null){
			holdObj.transform.position = new Vector3(holdPositionX, holdPositionY, z);
			holdObj = null;
		}
	}
	private void SetTileSet(){
		GameObject[,] tileSet = new GameObject[TileLineNum,TileColNum];
		for(int i = 0; i < TileLineNum; i++){
			for(int j = 0; j < TileColNum; j++){
				Collider2D col = Physics2D.OverlapPoint(new Vector2(FirstTilePosX + TileWidth * j, FirstTilePosY + TileHeight * i));
				if("tile".Equals(col.tag)){
					tileSet[i,j] = col.gameObject;
				}
			}
		}
		
		this.tileSet = tileSet;
	}

	private void DeleteMatchTile(){
		for(int i = 0; i < TileLineNum; i++){
			for(int j = 0; j < TileColNum - 1; j++){
				try{
					GameObject nowObj = this.tileSet[i,j];
					GameObject nextObj = this.tileSet[i,j+1];
					SpriteRenderer nowRenderer = nowObj.GetComponent<SpriteRenderer>();
					SpriteRenderer nextRenderer = nextObj.GetComponent<SpriteRenderer>();
					Sprite nowSprite = nowRenderer.sprite;
					Sprite nextSprite = nextRenderer.sprite;
					if(nowSprite.Equals(nextSprite)){
						Destroy(nowObj);
						Destroy(nextObj);
					}
				}catch{
				}
			}
		}
	}
}

◆解説

private void DeleteMatchTile(){
	for(int i = 0; i < TileLineNum; i++){
		for(int j = 0; j < TileColNum - 1; j++){
			try{
				GameObject nowObj = this.tileSet[i,j];
				GameObject nextObj = this.tileSet[i,j+1];
				SpriteRenderer nowRenderer = nowObj.GetComponent<SpriteRenderer>();
				SpriteRenderer nextRenderer = nextObj.GetComponent<SpriteRenderer>();
				Sprite nowSprite = nowRenderer.sprite;
				Sprite nextSprite = nextRenderer.sprite;
				if(nowSprite.Equals(nextSprite)){
					Destroy(nowObj);
					Destroy(nextObj);
				}
			}catch{
			}
		}
	}
}

特筆すべきは
SpriteRenderer nowRenderer = nowObj.GetComponent();
上記のようにSpriteRendererを取得して、その後に
Sprite nowSprite = nowRenderer.sprite;
スプライトを取得。
if(nowSprite.Equals(nextSprite)){
そして両方のスプライトを比較して、同じだったらですとろーい。

try~catch句は中でtryのなかでエラー(例外)が起きたときに、catchまで飛ぶ処理です。
今回のどこで例外が起きるかというと、

if(nowSprite.Equals(nextSprite)){
	Destroy(nowObj);
	Destroy(nextObj);
}

この部分で、オブジェクトを破壊してしまっているので、「次にクリックされたときに」ObjectがnullになってしまいMissingReferenceException(参照元のGameObjectが見つからない)が発生してしまうからです。
いまいちDestroyをかけてからのGameObjectの寿命がわからないのですが、ここの判定でぐるぐる回ってる間はまだDestroyされても参照が出来ます。
本来であればnullかどうかの判定を加えるべきですが、わかりやすく、かつtry~catchのご紹介、です。
ちなみにtry~catchは負担のかかる処理ですので、if(obj != null)という判定のほうがコストが下がります。
どのようなものがくるか分かりきっているときは、if文を入れるべきでしょう。

 

[Unity]Unity2Dチュートリアル 同じ色のパズルを消去する へ戻る

ad

関連記事

unity moving

[Unity]コードリファレンス Componentを取得する。削除する。

コンポーネントを取得して削除します。 GetComponent コンポーネントの追加と同じよ

記事を読む

Unity_

[Unity]Unity2Dチュートリアル 画面上のGameObjectを左下から取得する

前回、画面上のオブジェクトを一括で手に入れる方法はわかりました。 しかし、これではどのオブジェクト

記事を読む

Unity_

[Unity]Unity2Dチュートリアル 画面上のGameObjectを左下から取得する ソース解説

◆全文 public class GameSystem : MonoBehaviour {

記事を読む

Unity_

[Unity]Unity4.6 UIチュートリアル Lesson5.UI Text 日本語要約

前回の続き。今回はUI Textについての説明。 とはいえ、さすがにテキストなので、あまり説明

記事を読む

logo

[C#]AS400をDBに見立ててPCのPGMからODBC接続する

◆前提条件◆ PCにClient Accessがインストールされている。 PCに.NET Fra

記事を読む

logo

[C#]パスワード暗号化プログラムの初歩

パスワード暗号化の初歩的方法。 子供だましみたいなプログラムですね。 これは入社四か月の頃にプロ

記事を読む

unity pazzle

[Unity]Unity2D 番外編 消してちょっと待つ(コルーチン利用)

>タイルを再生成するときに消えたというのがわかるように、時間をおいて生成させることは可能ですか?

記事を読む

Wannabenote

[Unity]Unity2Dチュートリアル パズルをランダム生成して配置する。(PrefabとInstantiate)

Unity関連記事まとめページはこちら 前回の続き。 パズルを消すことが出来たのでランダ

記事を読む

logo

[C#]BinaryFormatterなどSerializerいろいろ書いておく

github始めました -> わなびのgithub それは置いておいて、BinaryForma

記事を読む

VisualStudio_

[C#,Excel]visual studio tools for office(VSTO)を利用してExcelのAddInをC#で作る

いい加減VBAが嫌になってきたので、調べたらC#でExcelのアドインが作れるんですね。 というわ

記事を読む

ad

Message

メールアドレスが公開されることはありません。

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

ad

  •  Auther;わなび

     「オープン系得意だよね? 俺のPCの調子悪いんだけど」という無茶振りから解き放たれゲームエンジニアに。
    C#とかUnityを扱います。
    Twitterフォロー大歓迎です。
    githubアカウント→wannabenote
  • follow us in feedly
PAGE TOP ↑