画面上にオブジェクトを配置する。
オブジェクトを動かす、生成するスクリプト(指示書)を書く。
画面上にUIを配置する。
UIを動かす(更新する)スクリプトを書く。
こんな流れ。
画面上に最初からあるものを動かすスクリプトはコントローラースクリプト、画面になかったものを表示させるのはジェネレータースクリプトという、らしい。
プロジェクトの作成から始めましょう。
画面上にオブジェクトを配置する。(猫)
配置したらこんなことになった。
猫がいなくなった。
ここでplayerを選択してInspectorウィンドウズでLayerを「1」にする。backgroundが「0」になっているから、上に配置されることになる。
猫が背景の上に配置されました。
オブジェクトを動かす、生成するスクリプト(指示書)を書く。
サンプルに入っていたPlayerControllerファイルをobjectウィンドウズのPlayerにドラドロ。
本当なら右クリックをしてC#Scriptを作成するところ。
これだけでゲームが動く。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerController : MonoBehaviour { void Start() { } void Update() { // 左矢印が押された時 if(Input.GetKeyDown(KeyCode.LeftArrow)) { transform.Translate(-3, 0, 0); // 左に「3」動かす } // 右矢印が押された時 if (Input.GetKeyDown(KeyCode.RightArrow)) { transform.Translate(3, 0, 0); // 右に「3」動かす } } }
どんな指示を出しているか、わかりますか?
次に矢を落下させます。
まずオブジェクトを配置します。
Order In Layerは「1」にします。
それから、矢を動かすスクリプトをドラドロ。
ゲームをスタートすると、矢が落ちてきます。
スクリプトを見ると、当たり判定まで実装できているようです。試してみますか?
あれ・・・消えない。
エラー。
ダブルクリックして詳細を見ると。
NullReferenceException: Object reference not set to an instance of an object
でググると次のページが。

つまり、ArrowControllerファイル(スクリプト)の37行目に異常がある。読み込めない何かがあるそうです。
該当箇所を見ると、GameDirectorオブジェクトが定義されています。
まだ作ってないよ!
矢をたくさん落とす命令の前に・・・
HPゲージ(UI)を作る。
objectウィンドウで右クリックしてUI>Image
オブジェクトができる。名前を変える。
イメージをドラドロ。と思いきや!
違うらしい。
HierarchyウィンドウのhpGaugeを選択してInspectorのImageコンポーンんとのSource ImageにProjectうぃんどうのhp_Gaugeをドラドロ。
次にアンカーポイントを設置。
アンカーポイントは、「オブジェクトを置く基準となる場所」を指します。
画面の端をアンカーにしていたら、スマホのサイズや縦横が変わっても画面内にゲージが収まります。
ではアンカーをどこで設定するかというと。
このコンポーネントで設定できるようです。四角の箱が二重になって赤い十字線が引かれているアイコン?を押すとpresetが出てきます。
右上を選びました。
この点から、Posで位置を特定します。
HPゲージを減らす仕組みは・・Imageコンポーネントに付属しているようです。
ではこのUIを書き換えるスクリプトをアタッチしましょう。
「矢が猫に当たったらゲージを減らす」指示を出します。
スクリプトはサンプルで作ってあるものを使います。
何度もやってきましたね。
ProjectウィンドウのGameDirectorを・・・
エラーが出ました。
HierarchyウィンドウでGameObjectを新規に作ります。
作ったオブジェクトの名前をGameDirectorに変えて、スクリプトをドラドロ。
げーむを開始すると。減りました。
スクリプトの中身を見てみます。
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; // UIを使うので忘れずに追加 public class GameDirector : MonoBehaviour { GameObject hpGauge;//オブジェクトを認識させる void Start() { this.hpGauge = GameObject.Find("hpGauge");//オブジェクトを見つけてね } public void DecreaseHp() //ここがUpdate()でないのはなぜ? { //hpGuageオブジェクトのImageコンポーネント内のfillAmountを0.1減らす。 this.hpGauge.GetComponent<Image>().fillAmount -= 0.1f; } }
矢を生成する
prefabを作ります。プレハブです。
同じ作業で何個も同じものを作れる、プレハブ工法と同じです。
家を建てる方法の一つです。
Prefabから作り出されたオブジェクトをインスタンスと呼ぶそうです。
オブジェクトとは違い「インスタンスはコピペしたときに設定が全てのコピーに適応される」という特徴を持ちます。「設計図」だけを変更すれば、配置されたオブジェクトも自動的に変更されます。
Prefabはprojectウィンドウに置かれた「設計図」で、オブジェクトを「作る」時は「設計図」をHierarchyウィンドウにドラドロします。
何度も登場するオブジェクトはインスタンス化(prefab化?)して使うと便利だそうです。
作り方。
Hierarchyウィンドウのオブジェクトをprojectウィンドウにドラドロ。
今回はarrowのprefabを作りました。
Inspectorに(Prefab Asset)と書いてありますね。
サンプルに元から入っていたarrowPrefabを使います。
作ったprefabのInspectorを見ると、Arrow Controllerがコンポーネントにあります。コピーされています。
Hierarchyウィンドウのarrowオブジェクトは、右クリックして削除します。間違ってこっちを変更したら面倒です。
矢を生成するスクリプト
arrowGeneratorスクリプトをみてみます。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ArrowGenerator : MonoBehaviour { public GameObject arrowPrefab; float span = 1.0f; float delta = 0; void Update() { //Time.deltaTimeはフレームがUpdateされるまでにかかった時間 this.delta += Time.deltaTime; //時間の経過が1.0secより大きくなったら if(this.delta > this.span) { //次の1秒後の生成に向けて、カウントし直す this.delta = 0; //Instantiate(arrowPrefab)でインスタンスをゲームオブジェクトとして生成させる GameObject go = Instantiate(arrowPrefab) as GameObject; //生成した矢のx座標をランダムにして、配置する(コンポーネントをいじる)。 int px = Random.Range(-6, 7); go.transform.position = new Vector3(px, 7, 0); } } }
このスクリプトをどこにアタッチ(くっつける)したらいいのか・・・
HierarchyウィンドウにArrowGeneratorオブジェクトを作ってArrowGeneratorスクリプトをドラドロ。スクリプトをオブジェクトにアタッチ。
ゲームを実行してみます。
矢が、出てきません。
assignされていない、ということらしいです。
指示通りArrowGeneratorスクリプトを見てみます。(variableと書いてあるので、スクリプトに問題があるのでしょう)
arrowPrefabってどこに書いてある?
ありました。
ArrowGeneratorスクリプトを選択してInspectorを見ると、Arrow PrefabがNoneになっています。ここか?
ProjectウィンドウのarrowPrefabをドラドロ。(しかしArrow Prefabのarrwは大文字だが)
ゲームを実行してみます。
エラーです。
ArrowGeneratorスクリプトが関わっているオブジェクトを見てみます。
ArrowGeneratorオブジェクトのコンポーネントにも同じArrow Prefabが。
ドラドロします。
成功です!
何かを生成するスクリプトを描いたときには、「どのオブジェクト(もしくはプレハブ)を作るのかをInspectorウィンドウでアサインする」ことが必要であるようです。
publicってなに?
今まで見てみぬふりをしてきましたが。

//これ必要あるの? using System.Collections; //C#の言語にも色々なシステムがあり、その中でもGeneric(汎用版)を使いますよという宣言。 using System.Collections.Generic; //UnityEngineの規則を使いますよという宣言。 using UnityEngine;
あと2つ。
publicはJavaScriptでいうグローバル変数化する指令。
外で定義されたクラス(関数?)からでも参照できるようにする(ローカルで使う場合は代わりにprivateを使うらしい)。
voidは返す値を指定しないときに使う。
C#だとたとえば
int variable = 1
とかけば、変数variableはint型に限定されます。
定義をするときに型を指定できるのがC#でしたね。
スマホで動かすには、更なるUI実装(ボタンを作る)
猫を動かすのに、キーボードのキーを指定していました。
ルーレットの時はスマホをタッチすることとマウスをクリックするのが同じ意味を持ちました。
キーボードのキーに対応するUIを作ります。
- ボタンの配置
- スクリプトのアサイン
こんな流れになるでしょう。
サンプルに入っていたLButtonをHierarchyウィンドウにドラドロしてみました。
けど違うようです。
この方法で作ったオブジェクトはSceneウィンドウにドラドロできません。
出てこない。。。。
order in layerを2にしたら出てきました。
今度はテキストに書いてあった通りにやってみましょう。
Hierarchyウィンドウで右クリックをしてUI>Button
するとCanvasの子要素としてオブジェクトが出てきます。
この時点で、GameウィンドウにUIが追加されています!
名前をRButtonにしました。
ここで比較してみます。
(ゲーム)オブジェクトとして「配置した」ボタンのインスペクター
UI(オブジェクト?)として「配置した」ボタンのインスペクター
設定できるコンポーネントが違いますね。
では、(ゲーム)オブジェクトとして「配置した」ボタンを消します!
先に進みます。
Ancher Presetの設定。
Posはコンポーネントから設定しても、Sceneウィンドウで手動で決めてもいいのかな?
Imageコンポーネント内のSource ImageにRButtonをアサインする。
ボタンの中にButtonというテキストが入っているので消します。
RButtonUIの子要素にTextがある。選択するとTextコンポーネントが。あとは消すだけ。
左ボタンは右ボタンを複製していじります。
Source imageを変えて、AncherPresetを変えて・・Posを変えて・・・
これで配置は完了!
次は・・・
ボタンにスクリプトをアサイン
Playerを動かすスクリプトは一度アサインしてある。
中身はこれ
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerController : MonoBehaviour { void Start() { } void Update() { // 左矢印が押された時 if(Input.GetKeyDown(KeyCode.LeftArrow)) { transform.Translate(-3, 0, 0); // 左に「3」動かす } // 右矢印が押された時 if (Input.GetKeyDown(KeyCode.RightArrow)) { transform.Translate(3, 0, 0); // 右に「3」動かす } } }
Input.GetKeyDown(KeyCode.LeftArrow)でキーボードの入力情報を取得している。
スマホに対応させるには。。
書き換える必要がある。
スクリプトを複製して名前をPlayerControllerSmartにしてみる。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PlayerControllerSmart : MonoBehaviour { void Start() { } public void LButtonDown() { transform.Translate(-3, 0, 0); } public void RButtonDown() { transform.Translate(3, 0, 0); } }
黄色いラインの書き換えを忘れずに。
次にRButtonのinspectorにあるButtonコンポーネントを見る。On Click()が、クリックされた時の挙動を決める場所。プラスボタンを押す。
None(object)にplayerオブジェクトをドラドロ。
すると今度はFunctionを指定できるようになる。
このFunctionは・・・playerオブジェクトにアサインされているスクリプトを選択できる。
PlayerControllerSmartをアサインしておけば・・・
RButtonDown()が選べます。
LButtomも同様に。
こうなりました。
げーむを実行してみると。
Gameウィンドウのボタンでも猫が動きます!
やったね!
iPhoneにビルドしてみる。
- UnityのファイルwをXcodeが読み込める形式にする。
- XcodeでiPhoneに取り込ませる。
という手順ですね。
左ウィンドウでPlayerを選択
Other Settingを見つける
Identificationを見つける。
チェックボタンを入れて、DeafaultCompanyを別の名前にする(他の人と被らないような)
閉じる。
書き出したいSceneにチェックを入れて。
Buildをおす。
こんな画面になる。
Chooseを押したら。
はい。new folderを作りましょう。
Buildされました!!!
使うファイルはこれです。
このファイルをXcodeで開きます。
iPhoneにインストールするソフトは、Xcodeです。
ダブルクリックすルト、Xcodeが開きます。
接続されているiPhoneが認識されていますか。
左ウィンドウで選択。
Signing & Cpablitiesタブを選択。
チャックを入れる。
Unityで設定したものになっていることを確認。
自分のAppleアカウントの情報を入れる。
Teamで自分のアカウント情報を選択。
あとは、矢印を押したら、移植されます。
実装されます。
左のウィンドウにものすごい量の三角マークが出てくる。
けどSuccessしたらしい。
できた????
コメント