にほんブログ村 IT技術ブログ IT技術メモへ ブログ村 IT技術ブログへ ブログ村 オヤジ日記へ ブログランキング・にほんブログ村へ

Try Unity _8 マウスドラッグでオブジェクトの移動

オブジェクトをドラッグして移動させるには、
OnMouseDownメソッドとOnMouseDragメソッドを組み合わせます。

下記のスクリプトを、ドラッグで移動させたいオブジェクトにアタッチします。


    private Vector3 screenPoint;
    private Vector3 offset;

    void OnMouseDown()
    {
        //カメラから見たオブジェクトの現在位置を画面位置座標に変換
        screenPoint = Camera.main.WorldToScreenPoint(transform.position);

        //取得したscreenPointの値を変数に格納
        float x = Input.mousePosition.x;
        float y = Input.mousePosition.y;

        //オブジェクトの座標からマウス位置(つまりクリックした位置)を引いている。
        //これでオブジェクトの位置とマウスクリックの位置の差が取得できる。
        //ドラッグで移動したときのずれを補正するための計算だと考えれば分かりやすい
        offset = transform.position - Camera.main.ScreenToWorldPoint(new Vector3(x, y, screenPoint.z));
    }

    void OnMouseDrag()
    {
        //ドラッグ時のマウス位置を変数に格納
        float x = Input.mousePosition.x;
        float y = Input.mousePosition.y;

        Debug.Log(x.ToString() + " - " + y.ToString());
        
        //ドラッグ時のマウス位置をシーン上の3D空間の座標に変換する
        Vector3 currentScreenPoint = new Vector3(x, y, screenPoint.z);

        //上記にクリックした場所の差を足すことによって、オブジェクトを移動する座標位置を求める
        Vector3 currentPosition = Camera.main.ScreenToWorldPoint(currentScreenPoint) + offset;

        //オブジェクトの位置を変更する
        transform.position = currentPosition;
    }


デモ。
全部、GUITextureで配置。

Try Unity _7 UNITYでのイベントを纏めてみた


実行順序は Awake → OnEnable → OnLevelWasLoaded → Start となるようです。



ロード時のイベント


using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {

    // Start 関数の前およびプレハブのインスタンス化直後に呼び出される
    void Awake () {
        print("Awake!");
    }

    // ゲームオブジェクトがインスタンス化されたときに呼び出される
    void OnEnable () {
        print("OnEnable!");
    }

    // シーンが読み込まれたときに呼び出される
    void OnLevelWasLoaded() {
        print("OnLevelWasLoaded!");
    }

}

フレームイベント


using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {   

    // スクリプトのインスタンス有効時、つまり最初のフレームのアップデート前に呼び出される。
    void Start() {
        print("Start!");
    }

    // 毎フレームごとに呼び出される。
    void Update() {
        print("Update!");
    }


}

マウスイベント


using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {
    // マウスボタンが押された時にコールされる
    void OnMouseDown() {
        print("MouseDown!");
    }

    // マウスボタンを離した時にコールされる
    void OnMouseUp() {
        print("MouseUp!");
    }

    // マウスカーソルが対象オブジェクトから退出した時にコールされる
    void OnMouseExit() {
        print("MouseExit!");
    }

    // マウスカーソルが対象オブジェクトに進入した時にコールされる
    void OnMouseEnter() {
        print("MouseEnter!");
    }

    // マウスカーソルが対象オブジェクトに重なっている間コールされ続ける
    void OnMouseOver() {
        print("MouseOver!");
    }

    // マウスボタンが押された状態でマウスを移動させてる間コールされ続ける
    void OnMouseDrag() {
        print("MouseDrag!");
    }
}


終了イベント


using UnityEngine;
using System.Collections;

public class example : MonoBehaviour {   

    // オブジェクトが破棄されたときに呼び出される。
    void OnDestroy() {
        print("OnDestroy!");
    }

    // プレイモードの停止、アプリケーションを閉じるときに呼び出される
    void OnApplicationQuit() {
        print("OnApplicationQuit!");
    }


}

Try Unity _6 GUITextureをiTween②

ども。

前回はiTween.MoveFromやiTween.MoveToを使って、GUITextureのTransform自体をトゥイーンさせましたが、今回は、GUITextureのPixelInsetの値をiTweenで可変させるにはどうすれば良いかというお話です。

今回も、2D画像を画面上からスライドインさせてみます。


利用するオブジェクト

①クリックするボタン用オブジェクト

_bt1 ( GUITexture )

TransFormのPositionは X=0、Y=0、Z=1
GUITextureにはアイコン画像を指定、
PixcelInsetにはX=アイコン配置位置X、Y=アイコン配置位置Y、WIDTH=アイコン横サイズ、HEIGHT=アイコン縦サイズ


②スライドイン用オブジェクト

_pop1 ( GUITexture )

TransFormのPositionは X=0、Y=0、Z=1
GUITextureにはアイコン画像を指定、
PixcelInsetにはX=0、Y=1080、WIDTH=アイコン画像の横サイズ、HEIGHT=アイコン画像の縦サイズ
※Y=1080は、僕のPCがフルHD(1920×1080)なので、画面の左上(X=0、Y=1080)に配置するという意味。


下記のスクリプトを作って、_bt1にアタッチ。
GameObject image_Logoをpublicにしていますので、
インスペクター上でimage_Logoに_pop1 を指定してください

  public GameObject image_Logo;
    
    void OnMouseDown()
    {
        
        if (gameObject.name == "_bt1")
        {
            //クリックされたオブジェクトの名前が_bt1の時の処理
            
            //開始位置の指定 X、Y位置はテクスチャの左下のピクセル位置
            Vector2 start_pos = new Vector2(0,1080);

            //終了位置の指定 X、Y位置はテクスチャの左下のピクセル位置
            Vector2 stop_pos = new Vector2(0, 0);

            // Hashの中身は 開始位置(Rect)、終了位置(Rect)、トゥイーン時間、コールバック関数(update)、イージング指定
            iTween.ValueTo(image_Logo, iTween.Hash("from", start_pos, "to", stop_pos, "time", 2.0, "onupdate", "iTween_Update", "easetype", "easeinoutback"));	
            
        }

    }

    void iTween_Update(Vector2 newCoordinates)
    {
        //コールバック引数をVector2Dで受け取る
        Rect tmp = image_Logo.guiTexture.pixelInset;
        tmp.y = newCoordinates.y;
        image_Logo.guiTexture.pixelInset=tmp;    
        
    }

2D座標(XやY)で指定できることから、FlashFlex感覚で扱えるので、
2D画像の場合は、前回のGUITextureをiTween①よりも、利便性があるかも。

Try Unity _5 GUITextureをiTween①

前回はUPDATE関数内で、pixelInset.yの値を変化させることで、上からのスライドインを実現してみました。

今回はこれをiTweenのプラグインを使って実行してみようと思うのですが、その前に基本的な位置関係についての知識のおさらいです。

① まず、GUITextureは2Dでの平坦画像として表示を行うものですが、
  あくまでもUNITYの3D空間の中に存在しているものであるということ。

② なので、配置したGUITextureをインスペクターで見た場合、TransformのPposition 
  X、Y、ZはVector3で、3D空間の位置を指定できる。GUITextureをシーンビューに
  配置したときは気づかなかったけど、GUITextureは空のゲームオブジェクト(trans
  form)にアタッチされて配置されるんだね。今ようやく全てのオブジェクトがそう
  なんだと理解できた。

③ でも、GUITextureのPixelInsetのX、Y、WIDTH、HEIGHTで調整すると3D空間やカメラ
  の位置には左右されず、常に画面上のX軸、Y軸に沿って表示されるため、アスペク
  ト比や画面の大きさには表示されない。だから当然、メインカメラの位置や向きを
  変えてもGUITextureの位置は変化しない。


上記が理解できていれば、GUITextureをトゥイーンするもの簡単だと思いますので、
いよいよ実装してみたいと思います。


iTweenの利用準備

①iTweenはUNITYのアセットストアから購入してもよいですし、
 Free版であれば、Google Codeからでも、ダウンロード可能です。
 僕はFree版なので、Google Codeからダウンロードしました。
②ダウンロードしたZIPを解凍し、iTween.csファイルをプロジェクトビューにドラッグ。
③これで、iTweenを利用する準備ができました。


iTweenの利用

①GUITexureを配置し、Textureに適当な画像をセットします。
②GUITexureはimage_Logoという名前をつけました。
③新規で下記のスクリプトを作成し、image_Logoにアタッチします。
④インスペクターでpublicで指定しているimage_LogoにGUITexureのimage_Logoを
 アタッチします。
⑤実行すると無事トゥイーンすると思います。

    public GameObject image_Logo;

  //OnEnableはGameObjectであるGUITexureが"active"になった瞬間に呼ばれる
    void OnEnable(){

        //初期位置: GUITexureがアクティブになった際、X=0.5、Y=0.5、Z=0.5、つまり真ん中に配置しなおす。
        image_Logo.transform.position = new Vector3(0.5f, 0.5f, 0f);
		
        //スライドイン設定: 1秒後、1秒かけて、X=0、Y=0、つまり左下から開始する。
    //この動作で左下から真ん中までのトゥイーンが行われる
        iTween.MoveFrom(image_Logo, iTween.Hash("x", 0, "y", 0, "time", 1.0, "delay", 1.0));
		
	//スライドアウト設定: 3秒後、1秒かけて、X=1、Y=1、つまり右上に移動する。
    //この処理が行われるのは3秒後なので、すでにスライドインが終了した状態、つまり
    //真ん中から右上へのトゥイーンが行われる	
        iTween.MoveTo(image_Logo, iTween.Hash("x", 1.0f, "y", 1.0f, "time", 1.0, "delay", 3.0, "easetype", "easeincubic"));
	}


今回は、実行ボタンを押下後、シーンがロードされ、GUITexureがアクティブになった時に実行されるようOnEnableメソッドを使いました。画面領域外からスライドインするようなものは、iTween.MoveToを使って、Vector3の位置指定でトゥイーンすると簡単だと思います。

Try Unity _4 GUITextureのクリックイベント③


今回はGUITexure(_bt1)をクリックした際に、別のGUITexter(_pop1)を
上からスライドインして、表示してみます。


GUITexter(_pop1)は、画面の上になるように配置します。
画面の上からスライドインさせたいので、インスペクター上での
PixelInsetの設定位置は、

x位置:0
y位置:画面解像度の高さ(僕のPCはフルHDなんで1080にしてます)
width:表示する画像の幅サイズ
height:表示する画像の高さサイズ


    public float incX = 0f;
    public float incY = 50f;

    GameObject obj = null;
    bool pop1_flg=false;
        
    void OnMouseDown()
    {
        
        if (gameObject.name == "_bt1") {

            obj = GameObject.Find("_pop1");
            if (obj)
            {
                //クリックされたオブジェクトの名前が_bt1の時の処理
                pop1_flg = true;
                
            }
            else if (gameObject.name == "_bt2")
            {
                //クリックされたオブジェクトの名前が_bt2の時の処理

            }

        }

    }

    void Update()
    {

        if (pop1_flg==true) {

            //pop1_flgがtrueの時、 _pop1のゲームオブジェクトを取得

            GameObject g = GameObject.Find("_pop1");

            Rect tmp = g.guiTexture.pixelInset;

            if (tmp.y >= 0) {

        //pop1のpixelInset y位置を変数で指定した分ずつ減算し、0以下になるまで繰り返す
                tmp.y -= incY;
                g.guiTexture.pixelInset = tmp;

            }
         
        }

    }



今回は、原始的にupdate内で行いましたが、スライドインや、フェードイン、スライドアウトやフェードアウトなど
視覚効果を伴うものはitweenというプラグインを利用するととっても便利にできるようです。

itweenはposition、scale、rotationなどのプロパティを自由にアニメーション(Tween)させるAssetです。
次回はitweenを使ってみようと思います。

Try Unity _3 GUITextureのクリックイベント②

まだ、GUITextureから前に進みません。

前回からGUITextureのクリックイベントを実装するため

Input.GetMouseButtonDown やら OnGUI を使ってみましたが、

OnGUIで指定したアイコン画像がRectで指定したサイズで表示されないなど

あいかわらず、簡単にはいきません。結局、試行錯誤した結果、

GUI Texureにクリックイベントを実装するには、下記の方法が良いように思います。

①GUITextureを配置し、インスペクターでTextureに使用する画像を指定

②TransFormのPositionはx:0、y:0、z:1とし、X座標とY座標の2D位置はPixel Insetで指定する(x、y、width、height)

③OnMouseDown()で処理を行うスクリプトファイルを作成し、GUITextureにアタッチする。


   void OnMouseDown()
    {
               
        if (gameObject.name == "_bt1") {

            //クリックされたオブジェクトの名前が_bt1の時の処理

        }
        else if (gameObject.name == "_bt2")
        {

            //クリックされたオブジェクトの名前が_bt2の時の処理

        }

    }

次はボタン1がクリックされたら、別のGUITextureがスライドイン・・。とかやってみたいですね。
なかなか3Dに辿り着けません。

Try Unity _2 GUITextureのクリックイベント1

前回の記事、「UNITYをはじめてみる GUITexture」より、

単に画像を読み込んで表示するだけならGUITextureはとっても簡単で、

便利だと書きましたが、いざこのGUITextureにクリックなどのイベントを与え、

処理を行おうとすると、いろいろと面倒であることがわかったので

その事について書こうと思います。

 

まず、GUITextureのクリックイベントを検知するには

下記のようなスクリプトを作成し、GUITextureのオブジェクトにアタッチすることで

クリックイベントを検知することができました。

 

   void Update () {
        //マウスDownイベントを検知
        if (Input.GetMouseButtonDown(0))
        {
            //シーン上の全GUIElementに対して当たり判定を行う
            GUIElement hit = guiLayer.HitTest(Input.mousePosition);
            if (Input.GetMouseButtonDown(0) && hit != null)
            {
                Debug.Log(hit.name);
            }
        }
  }

 

しかーし。この感じでボタンとして使用する画像ファイルをGUITextureで

複数作成し、上記のスクリプトをアタッチ後、実行してみると、Debug.Logが

3つ表示されました。

 

そーです。Input.GetMouseButtonDown(0)はマウス押下を検出するイベントなので、

こいつをアタッチした画像ファイル全てが感知(検知)してしまうんですねー。

 

「UnityのGUIはOnGUI()の中に書くのが基本です」

ようやく上記の意味がつかめてきました。

スクリプトを下記のように修正し、GUITextureを一旦削除して、

空のゲームオブジェクトを作成(Create Empty)し、スクリプトをアタッチ、

インスペクタービューでicon1に画像ファイルをドラッグアンドドロップで指定

してあげると、画像ファイルが表示され、、無事ひとつのオブジェクトだけを

検知することが出来ました。 

using UnityEngine;
using System.Collections;

public class bt_clickgui : MonoBehaviour {

    public Texture2D icon1;
    
  void Start () {	
  }	

  void Update () {
  }

    void OnGUI()
  {
    if (GUI.Button(new Rect(32, 582, 320, 240), icon1))   {   print("クリック1");    } } }

 

ちなみに、僕はこのあと、 2つ目の画像ファイルを表示したいときは、

別のスクリプトを用意しないといけないのか・・と思いましたが、そんな

面倒なことはなかったです。下記のように2つ目のアイコンをonGUIの中に

指定してあげれば、ひとつのスクリプトで簡単に指定することが出来ました。

 

GUI.Button(new Rect(x位置, y位置, 幅, 高さ), ボタンに表示するアイコンファイル)

GUItextureは左下指定なのに、GUI.Buttonの原点は右上みたいですね。

なぜなんでしょう・・・・。分かる方いたら教えてくだされ。

 

using UnityEngine;
using System.Collections;

public class bt_clickgui : MonoBehaviour {

    public Texture2D icon1; //1つ目の画像ファイル
  
public Texture2D icon2; //2つ目の画像ファイル
  void Start () {   }   void Update () {   } void OnGUI()
  {
    //1つ目のアイコンの指定 
    if (GUI.Button(new Rect(32, 582, 320, 240), icon1))   {   print("クリック1");
    }

    //2つ目のアイコンの設定
if (GUI.Button(new Rect(370, 582, 320, 240), icon2)) { print("クリック2"); }
} }