図12でRocket_Parentを選択してInspectorの「Add Component」から新しいスクリプトを追加する。「Name」は「FlyScript」を、「Language」には「C#」を選択する。Inspector内に追加された「FlyScript」をダブルクリックしてコードエディタを起動し、リスト1のコードを記述する。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class FlyScript : MonoBehaviour { //bool型の変数flyClickedを宣言する private bool flyClicked; void Start() { //Start関数内では、flyClicked変数をfalseで初期化しておく flyClicked = false; } void Update() { //Update関数内では、変数flyClickedがtrueであれば、「transform.Translate」を使って、ロケットを空に向けて飛ばす if (flyClicked == true) { transform.Translate((Vector3.right * Time.deltaTime * (transform.localScale.x * 0.0002f))); } } //Fly関数内ではClicked変数をtrueで初期化しておく public void Fly() { flyClicked = true; } }
図12でFramethrowFireを選択して、Inspectorの「Add Component」から新しいスクリプトを追加する。「Name」には「FireScript」を、「Language」には「C#」を選択する。Inspector内に追加された「FireScript」をダブルクリックしてコードエディタを起動し、リスト2のコードを記述する。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class FireScript : MonoBehaviour { //ParticleSystem型の変数fireを宣言していおく private ParticleSystem fire; //bool型の変数isPlayningを宣言しておく private bool isPlayning; void Start() { //Start関数内では、GetComponentでPaticleSystemコンポーネントを取得して、変数fireで参照する //変数isPlayningはfalseで初期化しておく fire = GetComponent<ParticleSystem>(); isPlayning = false; } //Fire関数内の処理 //変数isPlayningがtrueなら、炎の噴出を停止して、変数isPlayningをfalseで初期化する public void Fire() { if (isPlayning) { fire.Stop(); isPlayning = false; } //そうでなければ、炎を噴出して、変数「isPlayning」をtrueで初期化する else { fire.Play(); isPlayning = true; } } }
図12でFramethrowSmokeを選択して、Inspectorの「Add Component」から新しいスクリプトを追加する。「Name」には「SmokeScript」を、「Language」には「C#」を選択する。Inspector内に追加された、「SmokeScript」をダブルクリックしてコードエディタを起動して、リスト3のコードを記述する。解説はリスト2の炎を噴出する解説と全く同じ。炎が煙に変わっただけだ
using System.Collections; using System.Collections.Generic; using UnityEngine; public class SmokeScript : MonoBehaviour { private ParticleSystem smoke; private bool isPlayning; void Start() { smoke = GetComponent<ParticleSystem>(); isPlayning = true; } public void Smoke() { if (isPlayning) { smoke.Stop(); isPlayning = false; } else { smoke.Play(); isPlayning = true; } } }
HierarchyのCanvas内の、「Fly」という名前のボタンを選択し、Inspectorを表示する。Button(Script)に「On Click()」というイベントがあるので、この右下にある「+」アイコンをクリックする。すると「On Click()」内が変化する。
連載第3回の図18で解説しているので、図が見たい方はそちらを参照してほしい。図18の下図の「None(Object)」とあるところに、Hierarchy内のRocket_Parentをドラッグ&ドロップする。グレー表示だった「None Function」が「上下▲アイコン」で選択可能になる。
「No Function」の「上下▲アイコン」で「FlyScript」→「Fly()」と選択する。
Fireボタンには、「None(Object)」とある箇所にHierarchy内のFramethrowerFireをドラッグ&ドロップし、「None Function」で「FireScript」→「Fire()」と選択する。
Smokeボタンには、「None(Object)」とある箇所にHierarchy内のFramethrowerSmokeをドラッグ&ドロップし、「None Function」で「FireSmoke」→「Smoke()」と選択する。
以上でボタンの関連付けは完了だ。
Hierarchy内のHitCubeParentの子であるRocket_Parentを選択してInspectorを表示する。「Unity AR Hit Test Example(Script)」の中に、UnityARHitTestExampleのスクリプトがあるので、これをクリックしてコードエディタで開いてリスト4のようにコードを編集する。
using UnityEngine.EventSystems; void Update () { if ((Input.touchCount > 0 && m_HitTransform != null) && !IsPointerOverUIObject()) { var touch = Input.GetTouch(0); if (touch.phase == TouchPhase.Began || touch.phase == TouchPhase.Moved) { var screenPosition = Camera.main.ScreenToViewportPoint(touch.position); ARPoint point = new ARPoint { x = screenPosition.x, y = screenPosition.y }; // prioritize reults types ARHitTestResultType[] resultTypes = { ARHitTestResultType.ARHitTestResultTypeExistingPlaneUsingExtent, // if you want to use infinite planes use this: //ARHitTestResultType.ARHitTestResultTypeExistingPlane, ARHitTestResultType.ARHitTestResultTypeHorizontalPlane, ARHitTestResultType.ARHitTestResultTypeFeaturePoint }; foreach (ARHitTestResultType resultType in resultTypes) { if (HitTestWithResultType (point, resultType)) { return; } } 〜中略〜 private bool IsPointerOverUIObject() { PointerEventData eventDataCurrentPosition = new PointerEventData(EventSystem.current); eventDataCurrentPosition.position = new Vector2(Input.mousePosition.x, Input.mousePosition.y); List<RaycastResult> results = new List<RaycastResult>(); EventSystem.current.RaycastAll(eventDataCurrentPosition, results); return results.Count > 0; }
まず、「using UnityEngine.EventSystems;」と記述して、EventSystemsの名前空間を読み込んでおく。これは、Unityのシーンのイベントを処理する役割を持っている。忘れずに追加してほしい。
4行目で「&& !IsPointerOverUIObject()」を追加している。この関数は32〜39行目で定義している。IsPointerOverUIObject()については、前回記事を参照してほしい。
ここまでのSceneを上書き保存し、前回同様ビルドして実行しよう。実行結果は図1のようになるはずだ。
次回は、無数の球がランダムにバウンドするサンプルを紹介する。お楽しみに。
薬師寺 国安(やくしじ くにやす) / 薬師寺国安事務所
薬師寺国安事務所代表。Visual Basicプログラミングと、マイクロソフト系の技術をテーマとした、書籍や記事の執筆を行う。
1950年生まれ。事務系のサラリーマンだった40歳から趣味でプログラミングを始め、1996年より独学でActiveXに取り組む。
1997年に薬師寺聖とコラボレーション・ユニット「PROJECT KySS」を結成。
2003年よりフリーになり、PROJECT KySSの活動に本格的に参加。.NETやRIAに関する書籍や記事を多数執筆する傍ら、受託案件のプログラミングも手掛ける。
Windows Phoneアプリ開発を経て、現在はWindowsストアアプリを多数公開中。
Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。
Microsoft MVP for Development Platforms - Windows Phone Development(Oct 2012-Sep 2013)。
Microsoft MVP for Development Platforms - Client Development(Oct 2013-Sep 2014)。
Microsoft MVP for Development Platforms-Windows Platform Development(Oct 2014-Sep 2015)。
Copyright © ITmedia, Inc. All Rights Reserved.