vaguely

和歌山に戻りました。ふらふらと色々なものに手を出す毎日。

【Unity】【Windows】uGUI(Button)に触ってみた

Unity4.6から新しいGUIシステムが導入されたのですが、気にはなりつつも手を出せずにいたため、連休を機に触ってみることにしました。

環境

やったこと

今回は背景画像を2枚、ボタンを3つ用意して2画面を切り替える、という処理にしました。

Page1

  • 画像(page1.jpg)
  • ボタン1

Page2

  • 画像(page2.jpg)
  • ボタン2(button.png)
  • ボタン2のEnable/Disable切り替え用ボタン

画像はHierarchy > Create > UI > Imageを、ボタンはHierarchy > Create > UI > Buttonを選んでシーンに追加します。

Canvasの準備

最初に画像やボタンをシーンに追加すると、親としてCanvasが同時に追加されます。
ボタンや画像は、このCanvasに対して配置していて、親子関係は以下である必要があるようです。

Canvas
    LButton

以下のように間に空のGameObjectを挟んだりすると、ボタンが表示されなくなりました。

Canvas
    LGameObject
        LButton

なおHierarchy > Create > UI > Canvasでも追加できます。

Canvasのサイズ指定

今回Canvasおよび背景画像のサイズは1920×1080のフルHDサイズにすることにしました。

f:id:mslGt:20150923135303j:plain

  • 特に変更したのは「Canvas Scaler」で、「Ui Scale Mode」を「Scale With Screen Size」に、「Reference Resolution」を「x: 1920 y: 1080」にしています。

座標値の指定

デフォルトでは、画像やボタンの表示位置は画面中央から指定する設定になっているようです。
しかし、PhotoshopGimpなどで座標値をとる場合、画面左上を0として指定します。

ということでUnityでも同様に画面左上からの座標値を指定できるようにしました。

  1. Anchor Presets(Rect Transformの左上の□)をクリックして、top×leftのものを選択する
  2. Rect Transform > Scaleを「x: 1 y: 1 z: 1」に変更する
  3. Rect Transform > Pivotを「x: 0 y: 1」に変更する
  4. Rect Transform > PosX, PosY, PosZ, Width, HeightをPhotoshopGimpなどから取ってきた座標値・サイズに指定する(y値はマイナスになります)

なお、Step4の設定後にStep1~3を行うと、内容が自動で変更されてしまうため、Step4は最後に実行した方が良いかと思います。

画像の指定

ボタンに画像をセットして、通常・マウスオーバー時・クリック時にそれぞれの画像が表示されるようにします。

画像の作成

使用する画像は、もちろんそれぞれ別の画像を使うことも可能ですが、以下のように1枚の画像に複数枚分の画像をまとめておいて、それを切り分けて使用する、ということもできます。

f:id:mslGt:20150923135052p:plain

Webサイトを作るときにCSSで同様のことができますが、Unityで行った場合もパフォーマンス向上に役立つようです(今回は扱うデータ量が少なすぎるため効果は感じられませんが)。

  1. ボタンに使用する画像をInspectorで開く 2. 「Texture Type」を「Sprite (2D and UI)」に変更する 3. 「Sprite Mode」を「Multiple」に変更する
  2. 「format」を「16bit」または「truecolor」に変更する
  3. 「Sprite Editor」ボタンを押す
  4. Sprite Editorで、切り分けたい画像の範囲を選択する(次のStepで詳細に指定できるため大まかでOK)
  5. Spriteウインドウが表示されるので、X, Y, W, Hなどの値を必要に応じて変更する f:id:mslGt:20150923135152j:plain

  6. 切り分けたい画像数分、Step6とStep7を繰り返す

  7. ウインドウ右上にある「Apply」を押してウインドウを閉じる

これで以下のように、分割された画像がProjectに表示されます。

f:id:mslGt:20150923135132j:plain

画像の指定

分割した画像も、普通の画像と同じように(Spriteが使用可能な場合は)セットできます。

  1. 画像をセットするボタンをInspectorで開く 2. Image > Source Imageに、通常時のボタン画像をセットする 3. Button > Transitionを「Sprite Swap」に変更する
  2. Button > Target Graphicに、画像をセットするボタン自身をセットする(Step2のImageを使用するため)
  3. Button > Highlighted Spriteにマウスオーバー時に表示する画像をセットする
  4. Button > Pressed Spriteにボタンを押した時に表示する画像をセットする
  5. Button > Disabled SpriteにボタンがDisableになった場合に表示する画像をセットする

f:id:mslGt:20150923135225j:plain

なお、Step3で「Color Tint」を指定した場合、マウスオーバーしたりするとStep2で指定した画像の背景色が自動で切り替えることができます。
今回のようにシンプルで、背景色が変化するだけのデザインならこちらを選んでも良いかもしれませんね。

Scriptの指定

ボタンが押されたら、それに応じて何か動作してほしいですよね。
GUI.Buttonの場合はそれ自体がScript内で実行されるもので、クリックされたかはbool値で返ってきます。
uGUIの場合は、クリックされたときに呼ばれるメソッドを指定することができます。

  1. 以下のような内容でScriptを作成する(CtrlGuiParts.cs)
using UnityEngine;
using UnityEngine.UI;

public class CtrlGuiParts : MonoBehaviour {
    public GameObject _gmoPage1;

~省略~

    // Page1のボタンが押されたら呼ばれる.
    public void BtnPage1Clicked(){
        // ボタンが押されたときの処理.
    }
~省略~
  1. Step1のScriptを任意のGameObjectにアタッチする
  2. ボタンをInspectorで開く
  3. Button > OnClick()で「+」ボタンをクリックする 5. UnityEventCallState(OnClick()の左上の項目)を「Editor And Runtime」に変更する
  4. OnClick()の左下の◎をクリックして、Step2のGameObjectを選択する 7. OnClick()の右の項目をクリック > CtrlGuiParts > BtnPage1Clicked(Step1で作成した、ボタンが押されたときに呼ばれるメソッド名)を選択する

f:id:mslGt:20150923135435j:plain

Script内でボタンを操作する

ScriptではuGUIはUnityEngine.UIの名前空間に置かれています。 そのため、「using UnityEngine.UI;」を追加するか、「UnityEngine.UI.Button btnTest;」のように呼んでやればOKですね。

using UnityEngine;
using UnityEngine.UI;

public class CtrlGuiParts : MonoBehaviour {
    public GameObject _gmoPage1;
    public GameObject _gmoPage2;

    public Button _btnTest2;
    bool _isBtnEnabled = true;
   
    void Start () {
        _gmoPage1.SetActive(true);
        _gmoPage2.SetActive(false);
    }
    // Page1のボタンが押されたら呼ばれる.
    public void BtnPage1Clicked(){
        _gmoPage1.SetActive(false);
        _gmoPage2.SetActive(true);
    }
    // Page2のボタンが押されたら呼ばれる.
    public void BtnPage2Clicked(){
        _gmoPage1.SetActive(true);
        _gmoPage2.SetActive(false);
    }
    // Page2でEnable/Disable切り替えボタンが押されたら呼ばれる.
    public void BtnStatusClicked(){
        // Page2のボタンのEnable/Disableを切り替える.
        _isBtnEnabled = !_isBtnEnabled;
        _btnTest2.enabled = _isBtnEnabled;
    }
}

改行コード

今回Script EditorとしてVisual Studioを使用しているのですが、UnityでScript作成 > Visual Studioで編集 + 保存とすると、以下の警告が表示されました。

There are inconsistent line endings in the 'Assets/Scripts/CtrlGuiParts.cs' script. Some are Mac OS X (UNIX) and some are Windows.
This might lead to incorrect line numbers in stacktraces and compiler errors. Many text editors can fix this using Convert Line Endings menu commands.

これはVisual Studioの File > Advanced Save Options... で、「Line endings」をWindows用の「CR LF」に変更すれば解決しました。

感想など

最初ちょっと手間取りましたが、GUIでボタンなどの追加ができたり、実行前に見た目などを確認できるのが良いと思いました。

GUIによる操作の弱点として、メソッド名などを変更したときにエラーが起こらずただ実行されないだけ、という状態になるのは少し怖いですが、OnGUIのコードなどを削減できそうなのは強みですね。

画像(Sprite)の設定やCanvasやButtonにアタッチされているScriptで、今回特にいじらなかったものももう少し突っ込んでみてみたいところです。

参考

Visual Studioの改行コード設定