unity > Panelが属するCanvasの名前探索 > return panel.GetComponentInParent<Canvas>().name;

```txt:動作確認
Unity 5.1.3-f1 on MacOS X 10.8.5
```

##状況

以下のようなHierarchyがあるとする。それぞれのPanelの名前からCanvasの名前を取得したい。

![Main_unity_-_150912-findParentCanvasOfPanel_-_PC__Mac___Linux_Standalone__Personal_.jpg](https://qiita-image-store.s3.amazonaws.com/0/32870/5b9e55fb-01ef-2dd5-6b9b-5a25f716382e.jpeg)

##code

###try 1 (v0.1: 自作処理)
[v0.1 @ github](https://github.com/yasokada/unity-150912-findParentCanvasOfPanel/releases/tag/v0.1)

以下において、メインの処理は`getMyParentCanvasName()`。

```FindParentCanvas.cs
using UnityEngine;
using System.Collections;
using UnityEngine.UI;

/*
 * v0.1 2015/09/12
 *   - getMyParentCanvasName() worked as expected 
 */

public class FindParentCanvas : MonoBehaviour {
	
	string getMyParentCanvasName(GameObject panel) {
		GameObject parentGO;
		GameObject targetGO = panel;

		for (int loop=0; loop<3; loop++) { // search upper three levels
			parentGO = targetGO.transform.parent.gameObject;
			if (parentGO.GetComponent<Canvas> () != null) {
				return parentGO.name;
			}
			targetGO = parentGO;
		}
		return "";
	}

	void Test_each(string name) {
		GameObject myPanel = GameObject.Find (name);
		string canvasName = getMyParentCanvasName (myPanel);
		Debug.Log (canvasName + " - " + myPanel.name);
	}

	void Test_main() {
		Test_each ("Panel_1");
		Test_each ("Panel_1_1");
		Test_each ("Panel_1_2_1");

		Test_each ("Panel_2");
		Test_each ("Panel_2_1");
		Test_each ("Panel_2_2_1");
	}


	void Start () {
		Test_main ();
	}	
}
```

###結果

![Main_unity_-_150912-findParentCanvasOfPanel_-_PC__Mac___Linux_Standalone__Personal_.jpg](https://qiita-image-store.s3.amazonaws.com/0/32870/6728d237-4455-89cc-491e-b59090f3f52d.jpeg)

これでCanvasをインスペクタで関連付ける必要がなくなる。

<hr>
###try2 (v0.2: GetComponentInParent()使用)

@ ShajikuWorks さんに押していただいたGetComponentInParent()を使用するように変更した。

[GetComponentInParent](http://docs.unity3d.com/jp/current/ScriptReference/GameObject.GetComponentInParent.html)
> 有効なコンポーネントが見つかるまで上に向かって（親の親）再帰します。それでも見つからない場合は null を返します

上方向の再帰探索なので、階層がいくつというのを検討しなくてもいい。

[v0.2 @ github](https://github.com/yasokada/unity-150912-findParentCanvasOfPanel/releases/tag/v0.2)

結果、getMyParentCanvasName()が1行になった。もはやgetMyParentCanvasName()という関数にしなくてもいいかも。

```FindParentCanvas.cs
...
	string getMyParentCanvasName(GameObject panel) {
		return panel.GetComponentInParent<Canvas>().name;
	}
...
```

<hr>
### try3 (try2のnullケース対応)

[v0.3 @ github](https://github.com/yasokada/unity-150912-findParentCanvasOfPanel/releases/tag/v0.3)

v0.2の場合、実際にCanvasが見つからない時にGetComponentInParent<>()がnullを返して、.nameを返すときに以下のエラーがでる。

```
NullReferenceException: Object reference not set to an instance of an object
```

nullチェックを以下のように入れた。

```FindParentCanvas.cs
...
	string getMyParentCanvasName(GameObject panel) {
		Canvas canvasGO = panel.GetComponentInParent<Canvas> ();
		if (canvasGO != null) {
			return canvasGO.name;
		} else {
			return "";
		}
	}
...
```

nullケースとしてPanel3を追加。

![Main_unity_-_150912-findParentCanvasOfPanel_-_PC__Mac___Linux_Standalone__Personal_.jpg](https://qiita-image-store.s3.amazonaws.com/0/32870/6637e3f3-6a6c-24ad-2dd0-2e541d6776b2.jpeg)

```
	void Test_main() {
                ...
		Test_each ("Panel_2_2_1");

		Test_each ("Panel_3"); // for null case
	}
```

![Main_unity_-_150912-findParentCanvasOfPanel_-_PC__Mac___Linux_Standalone__Personal_.jpg](https://qiita-image-store.s3.amazonaws.com/0/32870/47aac600-5975-627a-eeea-9555d493e1b3.jpeg)

Panel_3の場合exceptionでなく""が返るようになった。