月別アーカイブ: 2012年3月

【Unity】2Dまわり描画方法とマップやレーダーっぽい表示

やりかた

  1. 2D表示用のカメラを用意(以下2Dカメラと呼ぶ)
  2. 2Dカメラの設定
    • Inspector内、Clear Flagsを”Don’t Clear”か”Depth Only”に。
    • Inspector内、Culling Mask を描画したいレイヤーのみ選択した状態に。
      • 例では2Dのロックオン用演出と、プレイヤーのパラメータまわりを選択中。
      • レイヤーを未だ作ってなければプルダウンの最下にあるAdd Layersで追加を行う。
    • Inspector内、Depthは値が少ない順に描画を行うのでメインカメラよりも多い数字に。
      • 背景のみを描画したい時などは-1等にして背景画像を設置する。
      • 手前側ほど後から描画するから順番としては後になる。
    • Inspector内、Transform,Camera,GUILayer以外のコンポーネントを削除

マップ、レーダー表示っぽいもの

概要

真上からパース無しで撮影した映像を手前に描画する。さらに描画させる座標を変える。マップ用に手順は作り直すやり方にしてるので前回の手順を無視してかまわない。

手順

  1. マップ表示用にカメラを追加する。
  2. PerspectiveをOrthographicにして近距離と遠距離での表示に違いを無くす。
  3. 描画順(Depth)は4とか適当な数値に。2D情報よりも手前にするか奥にするかで順番の変更をする。
  4. レーダーに表示したいGameObjectの子にSphereを追加し、そのGameObjectの居るLayerを2D_Radar(無ければAdd Layerで作成)に指定。
  5. 先ほど追加したカメラの Culling Mask を”2D_Radar”のみにチェックが入った状態にする。
  6. プレイヤーキャラとして作成しCharacterControllerコンポーネントを付けたGameObjectの子として扱うとキャラが旋回すると同時にマップも旋回してくれる。
ここまで済んだら画面は以下の様になってるはず。
Unity 2d Screen Shot 0024-03-29 at 17.00.45
赤い箱の子として赤Sphereを持たせている。
Radar表示として丸が描画されている。
プレイヤー用カメラが右を向いたらレーダ上のオブジェクト(●で表示されてるもの)が左へ移動。
Unity 2d Screen Shot 0024-03-29 at 17.00.33
同様に反対側を向くとレーダは右に旋回する。
このままでは画面中のオブジェクトとレーダー上のオブジェクトを混同するので表示位置を明確に切り分ける。
Normalized View Port Rectを変更して表示させたい位置とサイズの変更を行う。
Unity 2d Screen Shot 0024-03-29 at 17.58.50-1
View Port Rectを変更した画面。画面の右上に真上から俯瞰したカメラの画像を配置した状態。

参考

カメラを複数用意した際の設定等を参考に。
http://unity.gameenginejp.com/2010/12/2d-guitexture.html

Normalized View Port Rectの存在を知らせてくれた。
http://ws.cis.sojo-u.ac.jp/~izumi/Unity_Documentation_jp/Documentation/Manual/Cameras.html

digital CINEMATOGRAPHY&DIRECTING 日本語版 ―3D CGクリエータのための映画撮影術と監督術
Unity入門 ~高機能ゲームエンジンによるマルチプラットフォーム開発~
CUBE キューブ(買っ得THE1800) [DVD]
SHADER GURU with Direct3D10/11(シェーダーを完全にマスターできる本)

あとがき?

検索するときのワードは気をつけようと思う。
専門家に聞く事で知り得なかった固有名詞を知る事が出来た。

Xcode4.3.2 + iOS 5.1 + Unity3.5(not pro) でも実機確認する

むしろXcode4.3.2でもダメなのでXcode4.3.xにしてしまった人はXcode4.3を別途DLしておく必要がある。
またUnity側でBuildSettingsからターゲットOSをiOS5.0にしておくとさらに安全。
”さらに安全”と言ってるのは原因が定かでないし手順もこれが最小限かも分からないから。

Xcode4.3.2とXcode4.2を併存させる。

Xcode4.3.2とXcode4.2を併存させる。

AppStoreでXcodeをUpgradeしてしまったら別途DLしたXcode4.3の名前を変えて併存させる。

左がAppStore管轄の最新版。右は別途DLした4.3。

で、Xcode4.3ではiOS5.1にはアプリをコピーできない問題がある。
しかし以下の手順を踏むとなぜかコピーできてしまう。

1)Unity3.5でShift + Command + B でBuild Settingsウィンドウを開く

2)Player SettingsにあるSDK versionをlatestから5.0にしておく

Xcode4.3.2 probrem Screen Shot 0024-03-28 at 14.04.06

3)Command + B でBuild & Runを行う

4)UnityでのBuildとXcode4.3.2でのBuild

接続中のiOSデバイスへのコピーが行われるが実機起動後にSplashScreenを変えただろあんた!ダメだっつってんだろ!と起こられて起動停止する。

5)このままXcode4.3.2からのデバイスでの実行を止めてXcode4.3.2も落す。

6)Xcode4.3を起動してプロジェクトを開き、先のプロジェクトと同じプロジェクトを開き、Buildする。

7)実機にコピーがなされて起動もする。

ちなみに、一度ビルドが成功してコピーも完了するとなぜかUnity側でiOS5.1向けとしてBuildしてもコピー可能になる。

Xcode4.3.2 probrem Screen Shot 0024-03-28 at 16.43.50

Xcode4.3ではiOS5.1向けのビルドは通らないはずで、そもそも4.3.1はiOS5.1向けとしてリリースされた経緯があるほどバージョンには違いがあるのだが…。

Xcode4.3.1/Xcode4.3.2で実機にコピーして立ち上げる過程で何かが起こってるのだろうか…。

Xcode4.3.2 probrem 4.3.x project info Screen Shot 0024-03-28 at 11.58.12

※Xcode4.3.2の画面。Retina Displayの項目が空白に。これが関係してるんだと思われる。

Xcode4.3.2 probrem 4.3 project info Screen Shot 0024-03-28 at 13.16.17

※これがXcode4.3の画面。RetinaDisplayの項目は無い。

ちなみにこのバージョンでも続いているSpalashScreenイナイイナイ問題はUnity側は感知しているのでUnity3.5.1がリリースされるまでは解決しない見込み。

ただし、プロ版を買えばSplashScreenなんて変え放題なので問題は解決する。

【Unity】簡易AnimationViewer

簡易アニメーションビューワを作成してみたのでサンプルコードとその解説を残す。

MotionVIewer Screen Shot 0024-03-26 at 17.20.10

やること

  • 新しいシーンを作成
  • モーション付きのモデルをインスタンシング
  • CharacterControllerコンポーネントを追加
  • スクリプト追加

新しいシーンを作成

Command + Shift + N で新しいシーンを作成する。

シーンビューにはカメラしか写ってない。

MotionVIewer Screen Shot 0024-03-26 at 15.29.16

モーション付きのモデルをインスタンシング

アセットストア等からデータを入手できるので入手しておく。

これをプロジェクトビューからシーンビューかHierarchyにD&Dでインスタンシングする。

MotionVIewer Screen Shot 0024-03-26 at 17.33.01

インスタンシングされたオブジェクトを選択し、Inspectorに表示されたTransformの座標を全てゼロにしておく。

この時点でモノによってはカメラに納まっている。

CharacterControllerコンポーネントを追加

Component->Physics->Character Controllerを選択し、先にインスタンシングしたオブジェクトにコンポーネントを追加する。

Inspector の AnimationsにあるElementを見てアニメーションがちゃんと存在するを確認しておく。

MotionVIewer Screen Shot 0024-03-26 at 15.42.29

スクリプトの追加

下記のスクリプトをコピペして追加する。

#pragma strict
var roteSpeed:float = 3.5;

private var side : float = 1.0;
private var animationSpeed:float;
private var animationCount:uint;
private var animationList:Array;
function Start () {
     print("animationGetCount:" + animation.GetClipCount());
     print(animation.clip.name);
     animationCount = animation.GetClipCount();
     print(gameObject.animation);
     animationList = GetAnimationList();
}

function Update () {
     if( -0.9 < transform.rotation.y && transform.rotation.y < 0.9 ){
     }else{
          side *= -1;
     }
     transform.rotation.y += roteSpeed/180 * side;

}

function OnGUI (){
     var sw : int = Screen.width;
     var sh : int = Screen.height;
     var margin : int = 10;
     //ghool position
     var ghoolRoteYLabel:Rect = Rect(0,margin + 0,sw,sh/10);
     GUI.Label(ghoolRoteYLabel,"Rote Y:"+ transform.rotation.y);

     margin += 10;

     //slider
     var playSpeedRect:Rect = Rect(0,margin + 30,sw,sh/10);
     animationSpeed = GUI.HorizontalSlider(playSpeedRect,animationSpeed,0.0,5.0);
     for (var state : AnimationState in animation)
     {
          state.speed = animationSpeed;
     }
     GUI.Label(playSpeedRect,"playSpeed :"+ animationSpeed);

     margin += 100;

     //Buttons
     var buttonSpace:int = 40;
     var rectWidth:int = 100;
     var rectHeight:int = 40;
     var max:int = 10;
     var rects:Array = new Array();
     var i:int = 0;

     for (var name : String in animationList)
     {
          var rect:Rect = Rect(15,margin + 20*i + buttonSpace*i, rectWidth,rectHeight);
          if(GUI.Button(rect,animationList[i].ToString())){
               animation.CrossFade(animationList[i],0.01);
          }
          i++;
     }
}

private function GetAnimationList():Array
{
     var tmpArray = new Array();
     for (var state : AnimationState in gameObject.animation)
     {
          tmpArray.Add(state.name);
     }
     return tmpArray;
}

これを先のインスタンスしたオブジェクトにD&Dするとコンポーネントとして追加される。
再生ボタンで実行を行うと保持しているモーション一覧がボタン化されて列記される。
それらをクリックするとモーションが変更される。
ループ指定がOffだとモーションは一度再生された後に最終フレームで停止する。
スライダは再生速度を変動させる。ループ再生しているモーションを確認する際は便利。

MotionVIewer Screen Shot 0024-03-26 at 17.54.11

スクリプトの解説

Startメソッドで各種初期化。

var roteSpeed:float = 3.5;

private var side : float = 1.0;
private var animationSpeed:float;
private var animationCount:uint;
private var animationList:Array;
function Start () {
     print("animationGetCount:" + animation.GetClipCount());
     print(animation.clip.name);
     animationCount = animation.GetClipCount();
     print(gameObject.animation);
     animationList = GetAnimationList();
}

自身の保持するClip(アニメーション1個の単位)の数を取得。
同時に自作の関数でClipの名前を配列で取得。

UpdateメソッドではキャラのY軸上の回転を行わせている。

function Update () {
     if( -0.9 < transform.rotation.y && transform.rotation.y < 0.9 ){
     }else{
          side *= -1;
     }
     transform.rotation.y += roteSpeed/180 * side;
}

OnGUIメソッドではUI表示。

function OnGUI (){
     var sw : int = Screen.width;
     var sh : int = Screen.height;
     var margin : int = 10;
     //ghool position
     var ghoolRoteYLabel:Rect = Rect(0,margin + 0,sw,sh/10);
     GUI.Label(ghoolRoteYLabel,"Rote Y:"+ transform.rotation.y);

     margin += 10;

     //slider
     var playSpeedRect:Rect = Rect(0,margin + 30,sw,sh/10);
     animationSpeed = GUI.HorizontalSlider(playSpeedRect,animationSpeed,0.0,5.0);
     for (var state : AnimationState in animation)
     {
          state.speed = animationSpeed;
     }
     GUI.Label(playSpeedRect,"playSpeed :"+ animationSpeed);

     margin += 100;

     //Buttons
     var buttonSpace:int = 40;
     var rectWidth:int = 100;
     var rectHeight:int = 40;
     var max:int = 10;
     var rects:Array = new Array();
     var i:int = 0;

     for (var name : String in animationList)
     {
          var rect:Rect = Rect(15,margin + 20*i + buttonSpace*i, rectWidth,rectHeight);
          if(GUI.Button(rect,animationList[i].ToString())){
               animation.CrossFade(animationList[i],0.01);
          }
          i++;
     }
}

スライダはアニメーションの再生速度の変更を担う。
変更時に保持するアニメーション全ての再生速度を同時に変更する。
その後、自動でアニメーション数に応じてボタンを生成。
ボタン押下時の効果はクロスフェードさせてアニメーションをスイッチする、という内容。
アニメーションの名前が分からなくてもElement#で拾えてたと思ってサンプル探したけど出て来ず。
仕方なくAnswersで検索したら発見。コピペ。

GetAnimationListメソッド

private function GetAnimationList():Array
{
     var tmpArray = new Array();
     for (var state : AnimationState in gameObject.animation)
     {
          tmpArray.Add(state.name);
     }
     return tmpArray;
}

for inで、gameObjectが保持するAnimationState形式のデータを全て取得する。
取得したAnimationState各種のClipのnameプロパティ(任意で指定可能な文字列)を取得して配列に格納している。
ループが完了したら配列は返される。

参考

[Unity]Touchクラスを使ってGameObject.transform.rotationをグリグリする

Unity でTouchクラスを使ってキューブを回す処理の最小構成を解説。

やること

  • 画面にキューブを出す
  • キューブはタッチで回せる

C#版のサンプルを載せた記事はこちら

シーン構成

  • CubeRot
    • Cube
      • Particle System
  • Plane
  • Directional light
  • GameMaster
  • Main Camera

GameMasterという空のGameObjectにゲームをコントロールさせる。
ライト少々。

サンプルソース

file:Controller.js

ソース概要

タッチイベントのMoveフェーズ中におけるタッチの移動量を取得し、Cubeに反映させる。

var Cube : GameObject;
var speed:float = 1.0;
function Start () {
    if( !Cube ) Cube = GameObject.Find("Cube");
}
function Update () {
    var fingerCount : int = 0;
    for (var touch : Touch in Input.touches)
    {
        if (touch.phase != TouchPhase.Ended && touch.phase != TouchPhase.Canceled)
            fingerCount++;
    }
    if (Input.touchCount > 0)
    {
        switch ( Input.GetTouch(0).phase )
        {
            case TouchPhase.Began:
                print("Began");
                break;

            case TouchPhase.Moved:
                print("Move");
                // Get movement of the finger since last frame
                var touchDeltaPosition:Vector2 = Input.GetTouch(0).deltaPosition;

                //Rotate cube
                Cube.transform.Rotate (  touchDeltaPosition.y * speed * 10,
                                        -touchDeltaPosition.x * speed * 10,
                                         0,
                                         Space.World);

            case TouchPhase.Ended:
                print("End");
                break;
            }
        }
    }

解説

var touchDeltaPosition:Vector2 = Input.GetTouch(0).deltaPosition;

ここではVector2構造体のオブジェクトを生成し、タッチによる入力の最初の指(0)の移動をX軸とY軸に分解して保持させている。

Cube.transform.Rotate (  touchDeltaPosition.y * speed * 10,
                        -touchDeltaPosition.x * speed * 10,
                         0,
                         Space.World);

キューブのtransformを回転をさせるメソッドを実行する。
先に取得した画面のY軸上の移動、指の上下に対する移動は、回転軸Xを中心とした回転をさせる。
同様に画面のX軸上の指の移動は、回転軸Yを中心として回転させる。
右に指を動かしたら半時計回りなので負の値にしておく。
Z軸上の回転は行わないのでゼロ。
最後の一行は要注意。
このSpaceは省略可能で、デフォルトではSpace.Selfとなるため、回転すると軸まで回転してわけわからなくなる。
SpaceクラスはWorldとSelfのValueがある。

  • World
  • 記述:Space.World
  • 効果:ワールド座標系での処理を明示する。
  • Self
  • 記述:Space.Self
  • 効果:ローカル座標系での処理で、デフォルト設定。

今回、触ってる感が欲しいのでワールド座標系を明示。

ビルドするとこんな感じ。
Unity iOS touch  IMG_1962

コード補足

一応、Startで(GameObject)CubeにモデルのCubeを割り当ててるけど、Inspectorでも割り当てられる。
これでビルドするとタッチでキューブをぐりぐり回せる。
speedのパラメータを調整すると手触り感が変わるので適当に変更を。

【Unity】【移植】XSIからエクスポートしたFBXにオリジナルのシェーダを割当てる際のメモ

  • 予めXSIでFBXを吐出す際に、.shaderも確保しておく
  • Unity側でAsset -> Import new Asset… で.shaderファイルをインポート
  • 同様にFBXもインポート
  • 新規にマテリアルを作成。
  • マテリアルのShaderに先にインポートした.shaderファイルの名前を選択する。
  • テクスチャ指定領域に貼れる枠が出現するのでそこに任意のテクスチャをD&D。
  • インポートしたモデルをHierarchyへ出現させる。
  • Hierarchyに置いたインスタンスが階層構造になっているのであればメッシュを選択し、Inspectorに作成したマテリアルをD&Dすると適用される。

注意

  • インポートしただけのオリジナルデータにはマテリアルを適用できない。
  • 一度Hierarchyにインスタンシングさせてから、メッシュに対して割り当てを行わなければならない。
  • それをPrefabにする分には問題ない。
  • インポートしたての生ファイルは_imported_materials等のディレクトリを作ってそこでオリジナルのまま管理するのが望ましいと思われる。

 

Softimageではじめる3D - XSIではじめる3D改訂版 -
坂井 登美子 武藤 栄美子
ボーンデジタル
売り上げランキング: 318364

Unity GUIText サイズ変更をiOS等のモバイル端末向けプロジェクトで行う方法

UnityでGUITextという画面にテキストを出すだけの処理がある。

これは何かと便利でコンソール代わりに画面に文字列を表示させる等の小技として重宝する。ただ、iPhone等に表示すると小さ過ぎて読めない。

表示するフォントのサイズを変更するのだけどiOS側には反映されない。

調べてみると、フォントをインポートして個別にサイズと色を指定する必要があるそうな。

この部分をいくら変更してもサイズ変更が実機に適用されない。
Unity, font Screen Shot 0024-03-19 at 21.19.47

シーンビューや開発途中のカメラには指定サイズでは表示されている。
Unity, font Screen Shot 0024-03-19 at 21.18.43

インポートしたらProjectから選択するとインスペクタにこんな風な表示が。
Unity, font Screen Shot 0024-03-19 at 21.20.02
赤丸部分を変更することでインポートしたフォントのサイズと色を一意に指定することができる。

指定したらGUITextのインスペクタのフォントにドラッグアンドドロップ。
GUIText font size Screen Shot 0024-03-21 at 10.32.08

■参考
例のごとくアンサーズ:どうやってiOSとAndroidのテキストサイズ変えるの?
アンサーズ:iOSとAndroidのGUIStyleについて。フォント/ボタンのサイズ

Unity remote 3を今更

Unity Remote3 というアプリを試しました。

http://itunes.apple.com/jp/app/unity-remote-3/id394632904?l=en&mt=8

無線で、iOSデバイスに画面を転送しつつ、入力周りを受取るテストができます。

画面は圧縮されたものが転送されて表示されるのでガッビガビです。

それでもジェスチャーを転送してくれるので入力周りに特化したテストとして用いる分には問題無いかと思います。

 

iOS5.1 + XCode4.3.1 + Unity3.5 で実機テスト不可?【3月12,16日追記】回避策あり

実機では動かない。
詳しくは調べてないけど現象としては動かない。

★3月16日追記

回避策としてXcodeをDownGradeして4.3にすると実機確認できるようになります。

https://developer.apple.com/downloads/index.action

また、4.3だとiPadがiOS5.1βまでしか対応しておらず、必然的に非プロUnityはiPad版をビルドする事ができなくなります。

なのでiOSをおいそれとアップグレードするとチェックできなくなるどころかりいrースできなくなるので注意です。

とはいえ、今日は新iPadの発売日。Unity非Proユーザが初iOS向けアプリとして新デバイスを用いようと購入した場合は残念な結果が待ってますね。

★3月12日追記

現状でも相変わらず原因特定には至って居らず、iOSデバイス実機上での確認は出来ていない。

コンパイル後の動作で出ているメッセージはSplashScreenを消す権限は無いよ、との事。

しかし件の部分は差し替えを行っておらず、デフォルトのまま。

■仮説1:3.4以前のUnityProjectデータをUnity3.5がコンバートした際に壊れたのでは?

検証:ならば3.5でゼロから作って試す。

試したのはgameObjectが回転するスクリプトを搭載したキューブを写すカメラがあるだけのシーン。

Unity3.5でビルド -> Xcode4.3.1でビルド- > 実機iOS5.1へ。

Xcodeでのビルド、転送ともに上手く行くものの起動直後(UnityのSplashScreenは出る)のタイミングで停止。

abort()がかかったような挙動。

停止時のメッセージは”You are using Unity iPhone Basic. You are not allowed to remove the Unity splash screen from your game”と。

■仮説1の結論

Unity3.5が行ったコンバートに問題があるわけではない、ということは分かった。

コンバートしてないUnity3.5自体が生成したプロジェクトもiOS5.1実機では動作不能。

■仮説2:iOS5.0ならどうなの?

iOSは5.1にアップグレードされたばかりだし様々な問題により実機で動作でいなくなってしまったのでは?

■仮説2の結論

iOS5.0でも全く同じ挙動でメッセージも同じ。

他にもXcodeをダウングレードさせる方法なども試したものの、iOS向けUnityPro使えばいけるよーという話しか見当たらず現在にいたる。

FBでも質問を立てさせて頂いたが同様の事例は1件だけで他の方々はProを使ってるからなのか起こらないみたい。

■仮説3SplashScreenが何かしらの理由により消滅したのでは?

■仮説3の結論

正常に起動するXcodeProjectファイルを解析してみないと何とも言えない…。

で、件のメッセージの2センテンス目をグーグル先生に聞いてみると似た様な現象がちらほら。

http://answers.unity3d.com/questions/26826/tracking-down-a-sigabrt-on-startup.html

ページ中央らへん。つい先日にも投稿が。

以下に似た様な事例が…。

http://answers.unity3d.com/questions/226257/35-free-version-so-not-work-on-my-iphone.html

こっちも同様。

”おれ、Splash Screen変えてないのに、でも同じメッセージでとまっちゃうんだよなぁ。”

”2ヶ月前にプロ版をお試し1ヶ月やってみた時のコードはちゃんと動くんだぜ”

と。

プロ版で出力する分には大丈夫なことはどうやら確定。

でもUnity3.5だったのか前のバージョンだったのかは分からない。

2ヶ月前は出てなかった。

3.5は2月15日にプレスリリースされている。

いずれにせよこの質問に対して回答が一つも無い。

よくみたら6時間前に投稿されたばかりだ。

http://answers.unity3d.com/questions/225504/ios-splash-screen-error.html

二つ目のリンク、回答というか解決がなされた訳ではないもののレスが一つ。

読んでみるとRetinaディスプレイ向けのSplashScreenがUnityからは吐出されない模様。

それが前述のメッセージの原因になってたので既にUnityにメールしたよーって書いてある。

なんと!

ということはUnity3.5ではXcode4.3のプロジェクト構成に対応しきれてなかったということか。

とはいえ、これも予測の域を出ず、Unityオフィシャル側からのメールの返答は未だ無い模様。

※このレス投稿者がメール着たらまた書き込むよ、と書いてるがまだ追加の投稿が無い。

とりあえずこれは放置するしかない問題だということか。

最後に発見。(FB助け合い所で質問したら指摘を頂いた)

http://forum.unity3d.com/threads/126905-Xcode-4.3.1-iOS-SDK-5.1-Known-Issues-(postpone-upgrade)

Xcode4.3.1では無理だよーって確定、オフィシャルが言ってた残念。

ちなみにこのリンクに記述されているBack IssueはDLできませんでした。

[Unity]MonoBehaviour

http://unity3d.com/support/documentation/ScriptReference/Behaviour.html

MonoBehaviour Inherits from Behaviour MonoBehaviour is the base class every script derives from.

Using Javascript every script automatically derives from MonoBehaviour. When using C# or Boo you have to explicitly derive from MonoBehaviour.

Note: The checkbox for disabling a MonoBehavior (on the editor) will only prevent Start(), Awake(), Update(), FixedUpdate(), and OnGUI() from executing. If none of these functions are present, the checkbox is not displayed.

See Also: The chapter on scripting in the manual.

訳:

MonoBehaviour Behaviourから継承。

MonoBehaviour は全てのスクリプトが導き出される基底クラス。

Javascriptを使用した際のスクリプトは自動的にMonoBehaviourから導き出されます。

C#やBooを使用する時はMonoBehaviourから導き出す事を明示しなければなりません。

Note:

MonoBehaviorの機能を切るためのエディター上の

チェックボックスは、次の処理を無効化。

Start(), Awake(), Update() FixedUpdate() OnGUI()

これらの関数が用意されてなければチェックボックスが表示されません。

マニュアルの chapter on scripting を参照。

UnityでUI上にボタンを配置してボタンからメソッドを実行させる最小構成

UI上にボタンを表示してタッチ/クリックできるようにします。

作業手順

  1. GUIスキンを用意
  2. OnGUIイベントにボタン表示と処理を書いたスクリプトを用意
  3. 実行

GUIスキン

GUIをProject上を右クリックしてGUI Skinを選択する。

Unity_Button_WhereIsGUIAsset

黒いアイコンのAssetが出現。

これを選択してInspector上で各種定義を行う。

今回はボタンをメインで扱うのでボタンの要素を触ってみる。
Unity_Button_UISkinInspector

“Hover”はマウスオーバー時の変化であり、iOSではタッチのみなので表現されない。
実際には”Active”のみ。

スクリプト

var skin:GUISkin;//グローバル変数
function OnGUI(){
GUI.skin = skin;

var sw:int = Screen.width;
var sh:int = Screen.height;
var buttonRect:Rect = Rect(0, sh*7/8, 60,30);
if(GUI.Button(buttonRect,"left"))
{
    Destroy(gameObject.FindWithTag("Player"));
}

スクリプトを書き終えたらGUIを割り当てる。スクリプ上のグローバル変数化しているSkinに対して、先に用意したGUISkinをドラッグ&ドロップで割り当てる。

Unity_Button_SetUISkinToScript

これでGUISkinで定義したボタンの色などが適用される。やらないとデフォルトの定義が割り当てられるので不要ならば”割り当てない”選択もアリ。

そして Shift + Command + N でNullオブジェクトを生成し、そのコンポーネントとしてスクリプトをドラッグ&ドロップで割り当てると完成。

ちなみにだけど、ほんとは

gameObject.FindWithTag("Player").SendMessage("Kill")

とかでメッセージ送信だけにしておくべき。が、最小構成ではなくなるので今回は凄く単純なスクリプトにしておきました。

↓結果はかの通り。文字色が赤いのはマウスオーバーのタイミングでキャプチャしたため。

Unity_Button_result

参考

http://www.uxic.net/archives/tag/unity

Unity入門 ~高機能ゲームエンジンによるマルチプラットフォーム開発~

雑記

本件とちょっと主旨ズレるけどサンプルコード載せてるサイトでちょくちょく入ってる

var sw:int = Screen.width;

というコードがあると「あ、Screenってクラスから何か取得できるんだ、へー」って事があって助かる。

前に一度、サンプルコードはどんどん載せるべき、というはてなのエントリがあったけどその通りだと思う。