Unityを再勉強するためのブログ記事の第14回目です。
今回は、以前色々と調べ物をしている時に、一度やってみたいなと感じていた以下のエントリーを実際にやってみました。
Unityでつむつ○みたいなパズルゲーム – 株式会社BEFOOL
このブログではJavaScriptで書かれているのでC#でやってみたかったのです。
言語が違うので色々と難しいところがありましたが、何とか思ったように動きました。
前回:【Unity 2D】GameObjectにタッチ処理を実装する | albatrus.com
準備
Collider2Dを付けたオブジェクトをいくつか用意します。名前は全て同じにしてください。
コード
先ほどのブログの記事に載っているコードをそのまま使っています。詳しくはそちらを見て下さい。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
List<GameObject> removeObjectList; void Update () { if(gameStatus == 1){ if(Input.GetMouseButton(0) && clickStartObject == null){ removeObjectList = new List<GameObject>(); RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition),Vector2.zero); if(hit.collider != null){ if(hit.collider.gameObject.name.IndexOf("circle") != -1){ clickStartObject = hit.collider.gameObject; preObject = clickStartObject; //add removeList removeObjectList.Add(preObject); //select object setAlpha hit.collider.gameObject.transform.localScale = new Vector2(1.2f,1.2f); Debug.Log("circle touch"); } } } else if(clickStartObject && Input.GetMouseButtonUp(0)){ if(lineObject != null){ Destroy(lineObject) ; } if(removeObjectList.Count >=3){ int dropCount = removeObjectList.Count; for(int i=0;i<removeObjectList.Count; i++){ GameObject ib = removeObjectList[i]; Destroy(ib); } removeObjectList = new List<GameObject>(); }else{ for(int i=0;i<removeObjectList.Count;i++){ GameObject ib = removeObjectList[i]; Transform form = ib.collider2D.gameObject.transform; Vector2 newLock = new Vector2(1.0f,1.0f); form.localScale = newLock; } } preObject = clickStartObject = null; clickStartObject = null; }else if(clickStartObject){ RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition),Vector2.zero); if(hit.collider != null){ if(hit.collider.gameObject.name == preObject.name){ if(preObject != hit.collider.gameObject){ float dist = Vector2.Distance(preObject.transform.position,hit.collider.gameObject.transform.position); if(dist <= 1.5){ int idExistNo = -1; for(int i = 0;i < removeObjectList.Count;i++){ GameObject _obj = removeObjectList[i]; if(_obj == hit.collider.gameObject){ idExistNo = i; } } if(idExistNo == -1){ preObject = hit.collider.gameObject; hit.collider.gameObject.transform.localScale = new Vector2(1.2f,1.2f); removeObjectList.Add(preObject); }else{ for(int i = 0;i<removeObjectList.Count;i++){ GameObject _obg = (GameObject)removeObjectList[i]; _obg.collider2D.gameObject.transform.localScale = new Vector2(1.0f,1.0f); } removeObjectList.RemoveRange(idExistNo + 1 , removeObjectList.Count-idExistNo-1); preObject = removeObjectList[removeObjectList.Count - 1]; //removeObjectList.splice(idExistNo + 1, removeObjectList.length - idExistNo - 1); //prevObject = removeObjectList[removeObjectList.length - 1]; } if(lineObject != null){ Destroy(lineObject); } lineObject = (GameObject)Instantiate(Resources.Load<GameObject>("prefabs/LineObject")); LineRenderer _lineL = lineObject.GetComponent<LineRenderer>(); _lineL.SetVertexCount(removeObjectList.Count); _lineL.SetWidth(0.1f,0.1f); for(int i=0;i<removeObjectList.Count;i++){ GameObject obj = removeObjectList[i]; _lineL.SetPosition(i,obj.transform.position); } } } } } } } } |
挙動
どのような動きになるか説明します。まずは、マウスを押した時にオブジェクトがあれば、オブジェクトが大きくなります。
そのままマウスを移動して同じオブジェクトがあれば、そのオブジェクトも大きくなります。
オブジェクトを3つ以上大きくした場合、マウスを離すと消えます。
なお、このコードは未完成で本当はLineRendererがあり、マウスを動かすと同時に線を引けるみたいなのですが、これは上手く動いていません。
LineRendererの使い方について勉強します。
学んだこと
配列
一番困ったのは配列です。JavascriptではArrayクラスがあり、これがとても便利に利用できるみたいなのですが、C#の場合、どうしたらいいのか悩みました。
ArrayListというクラスがあるのですが、これは一度Objectクラスに変換をするので、ゲームに多少なりとも負担がかかるみたいで、どのサイトを見ても推奨されていませんでした。
そこで利用したのがListクラスです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
//これを付けないと使えません(注意) using System.Collections.Generic; List<GameObject> removeObjectList = new List<GameObject>(); //追加 removeObjectList.Add(_object); //要素の取り出し GameObject obj = removeObjectList[1]; //要素の個数 int arrays = removeObjectList.Count; //2番目の要素から3つ削除する(jsの場合splice) removeObjectList.RemoveRange(2,3); |
特に苦労したのがJavascriptで利用されていたspliceをどう置き換えたらいいかです。
結果RemoveRange()を利用すれば解決できました。
また、デフォルトのまま利用できませんので、「using System.Collections.Generic;」を頭に付ける必要があります。
その他
プログラミングのやり方がとても新鮮でcocos2dxでも利用できるのではないかと思いました。私は完全に独学でプログラミングしているので、他の人のコードの中に自分では考えのつかないことが実装されているのでとても勉強になります。
ですので、時間を見つけて真似をするだけでもいいので、自分以外のコードを読むようにしないといけないなと感じました。
![]() | ゲーム開発者になるための Unity4 徹底ガイド プロが教える効果的なゲーム制作技法 李在賢,金凡峻 インプレス 売り上げランキング : 5834 Amazonで詳しく見る |
