*

[Unity]Unity2Dでパズドラのようにタイルを動かす ソース解説

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

◆全文

using UnityEngine;
using System.Collections;

public class GameSystem : MonoBehaviour {
	public GameObject holdObj;
	public float holdPositionX;
	public float holdPositionY;
	private float z = 10f;

	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
		if(Input.GetMouseButtonDown(0)){
			LeftClick();
		}
		if(Input.GetMouseButton(0)){
			LeftDrag();
		}
		if(Input.GetMouseButtonUp(0)){
			LeftUp();
		}
	}

	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(){
		Vector3 tapPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, z);
		if(holdObj != null){
			holdObj.transform.position = new Vector3(holdPositionX, holdPositionY, z);
			holdObj = null;
		}
	}
}

◆解説

public GameObject holdObj;
public float holdPositionX;
public float holdPositionY;
private float z = 10f;

クリックしたときに保持する情報です。
上から
保持したGameObject。
保持したときのGameObjectのX座標。
保持したときのGameObjectのy座標。

void Update () {
	if(Input.GetMouseButtonDown(0)){
		LeftClick();
	}
	if(Input.GetMouseButton(0)){
		LeftDrag();
	}
	if(Input.GetMouseButtonUp(0)){
		LeftUp();
	}
}

マウスのボタンの状態によって動きを変更します。
GetMouseButtonDownはボタンを押下した瞬間。
GetMouseButtonはボタンを押し続けてる間。
GetMouseButtonUpはボタンが上がった瞬間。
ごちゃごちゃするのを嫌って関数を呼んでいます。

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);
		}
	}
}

左クリックした瞬間の処理です。
細かく解説します。

if(holdObj == null){

GameObjectを保持していないときのみ動作するように判定しています。

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);
}

タッチしたところにスプライトが存在しているときのみ、スプライトを保持して、
また、初期座標をプロパティに保管しています。
初期座標を保管する前にtransform.positionを変更しないように注意。

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);
				}
			}
		}
	}
}

ドラッグしているときの処理です。こちらも細かく解説。

this.holdObj.transform.position = Camera.main.ScreenToWorldPoint(new Vector3(tapPoint.x, tapPoint.y, z));

保持しているGameObjectの座標を変更しています。
こちらはドラッグしているときは常に呼ばれます。

Collider2D[] colSet = Physics2D.OverlapPointAll(Camera.main.ScreenToWorldPoint(new Vector3(tapPoint.x, tapPoint.y, z)));

クリック(タッチ)したところに存在するスプライト重なっているものを含めて全て取得しています。
こちらは入れ替えるためにこのようなことをしています。
複数のCollider2Dを得るのでCollider2D[]という配列になっています。

if(colSet.Length > 1){

現在保持しているスプライトとスプライトが重なった場合、スプライトの数は2なので、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);
	}
}

foreachで配列の全てを処理して、現在保持しているGameObjectではないGameObjectがあった場合は座標を入れ替えるように処理をしています。

private void LeftUp(){
	if(holdObj != null){
		holdObj.transform.position = new Vector3(holdPositionX, holdPositionY, z);
		holdObj = null;
	}
}

マウスのボタンが上がったときの処理。
保持している座標に移動するように書き換えて、GameObjectを開放しています。
これにより、変なところにスプライトが配置されないようにしています。

[Unity]Unity2Dでパズドラのようにタイルを動かす に戻る

↓どうしても待ちきれない人へお勧めの書籍↓

読んでみたけど、なかなか手軽な内容です。初心者に丁度よい情報量だと思います。初心者を抜け出した頃だと少し物足りないかも? Scriptについても超基本までは解説してあるのでこれを覚えてアルゴリズムを考えて覚えていきました。

ad

関連記事

wannabenote

[C#]ポートを使用しているプロセスを特定してAcivateするやつ

ポートからプロセスを特定してAcivateするやつ作りました。 https://github.

記事を読む

Unity_

[Unity]Unity2Dでパズドラのようにタイルを動かす

今回からスクリプトがかなり難しくなってくるかも。 前回の続き。 というわけで前回はドラッグで

記事を読む

logo

[Unity]Unity 2Dチュートリアル スプライトをドラッグ(タップ)して移動する ソース解説

◆全文 using UnityEngine; using System.Collection

記事を読む

Unity1_5

[Unity]Unity2Dで3マッチパズルを作ろう~インストール編~

Unityの2D機能で3マッチパズルでも作ろうかと思ったのですが、ほとんど資料がない。Unity

記事を読む

logo

[C#]文字列のプロパティを初期化したい。空文字で初期化したい。

Twitterで適当に叫んでたときのネタをメモ。 C#でプロパティの初期化が面倒です。 たと

記事を読む

Wannabenote

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

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

記事を読む

logo

[iTextSharp,C#]TifファイルをPDFに変換する。

TifファイルをPDFに変換してほしいと言われて作ったときのソースのメイン部分を抜粋です。 確

記事を読む

instantiate cube unity

[Unity]コードリファレンス GameObjectの複製

GameObjectを複製します。 Object.Instantiate(Object ori

記事を読む

wannabenote

[Excel,C#]C#でExcelにデータを一括出力する

大体いつも忘れるこのやり方。 Excelにデータを出力する 方法論 単純な方法ではデータを一行

記事を読む

unity ご祝儀

[Unity?]割り切れない関係のためのご祝儀計算シミュレータ

今日、親友が結婚します。 なので、ご祝儀を用意するんですが、相場は3万円ですね。 じゃあ、な

記事を読む

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 ↑