2018年4月19日 星期四

【Unity】非固定式虛擬方向鍵製作Part.1

這次來談談如何製作非固定式的虛擬方向鍵,完成後結果會像這樣:
首先我們開啟一個空白的Unity專案,Hierarchy視窗中生成一個空物件,並重新命名為Controller,並在這個Controller下新增一個名為Controller的腳本(本文使用C#)。

在腳本中增加命名空間UnityEngine.UI,並增加幾個變數如下:
using UnityEngine;
using UnityEngine.UI;

public class Controller : MonoBehaviour {

    public RectTransform canvasRect;
    public RectTransform startImgRect;
    public RectTransform nowImgRect;
    public Transform actor;

    void Start () 
    {
    }
 
    void Update ()
    {
    }
}
startImgRect、nowImgRect這兩個變數為虛擬方向鍵圖示的RectTransform,actor為場景中角色的Transform,而canvasRect之後會做為移動量值及圖示解析度的參數。

所以接下來我們需要在Hierarchy視窗中新增一個Canvas,屬性設定如下。
並在這個Canvas新增兩個Image;StartImg和NowImg,圖示使用內建的Knob,透明度都為180,StartImg寬高為(50, 50),NowImg寬高為(35, 35),最後將兩個圖示的Raycast Target參數設為false
然後新增Sprite,重新命名為Actor,並找一張喜歡的圖替換上去。

將上面這幾個物件拖曳到腳本變數上,到這裡我們會得到以下的結果:

接著回到Controller腳本上,現在我們有了圖示,再來要處理圖示位置,而圖示位置有以下三種;滑鼠點下前的待機位置、點下後的開始位置、滑鼠點下後移動時的目前位置,所以我們新增以下變數:
using UnityEngine;
using UnityEngine.UI;
public class Controller : MonoBehaviour {

    public RectTransform canvasRect;
    public RectTransform startImgRect;
    public RectTransform nowImgRect;
    public Transform actor;

    private Vector2 waitPos = new Vector2(1000, 1000);
    private Vector2 startPos = Vector2.zero;
    private Vector2 nowPos = Vector2.zero;

    private bool dragState = false;

    void Start ()
    {
    }
 
    void Update ()
    {     
    }
}
waitPos為待機位置,startPos為開始位置,nowPos為目前位置,另外我們還需要一個判斷拖曳狀態的布林變數dragState。

有了位置變數後,就可以Update中帶入位置數值,以下是Update的內容:
void Update ()
{
    if (Input.GetMouseButton(0))
    {
        if (dragState == false)
        {
            startPos = Input.mousePosition;
            nowPos = startPos;
        }
        else
            nowPos = Input.mousePosition;

        startImgRect.anchoredPosition = startPos;
        nowImgRect.anchoredPosition = nowPos;
        dragState = true;
    }
    else
    {
        startImgRect.anchoredPosition = waitPos;
        nowImgRect.anchoredPosition = waitPos;
        dragState = false;
    }
    
}
編譯後執行Unity後會發現,圖示會隨著滑鼠點下、拖曳等動作改變位置,但這些位置並不正確,這是因為我們並沒有做位置數值的空間座標轉換。

所以最後我們要新增轉換函式,並且將滑鼠位置Input.mousePosition做轉換,再帶入startPos和nowPos 中,腳本的變更如下:
using UnityEngine;
using UnityEngine.UI;
public class Controller : MonoBehaviour {

    public RectTransform canvasRect;
    public RectTransform startImgRect;
    public RectTransform nowImgRect;
    public Transform actor;

    private Vector2 waitPos = new Vector2(1000, 1000);
    private Vector2 startPos = Vector2.zero;
    private Vector2 nowPos = Vector2.zero;

    private bool dragState = false;

    Vector2 WorldToRect(Vector3 inputPos)
    {
        Vector2 screenPoint = RectTransformUtility.WorldToScreenPoint(Camera.main, inputPos);
        Vector2 Pos;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, screenPoint, Camera.main, out Pos);
        return Pos;
    }

    void Start ()
    {

    }
 
    void Update ()
    {
        if (Input.GetMouseButton(0))
        {
            if (dragState == false)
            {
                startPos = WorldToRect(Input.mousePosition);
                nowPos = startPos;
            }
            else
                nowPos = WorldToRect(Input.mousePosition);

            startImgRect.anchoredPosition = startPos;
            nowImgRect.anchoredPosition = nowPos;
            dragState = true;
        }
        else
        {
            startImgRect.anchoredPosition = waitPos;
            nowImgRect.anchoredPosition = waitPos;
            dragState = false;
        }
        
    }
}

座標轉換函式WorldToRect在這篇有談到,簡單的講就是滑鼠座標轉螢幕座標,螢幕座標轉UI座標,現在我們可以看看結果:
第一篇就到這裡,接下來應該會是角色的實際移動。

1 則留言:

  1. Online Casino | The Gambien Hoppe
    Online Casino is a casino 온라인 카지노 경찰 that was established in 1994. It is operated by the Gambling Commission of Malta. Casino games, table games, video poker, bingo and so on.

    回覆刪除

【自製小遊戲】水平思考猜謎(海龜湯)

遊戲連結 海龜湯的玩法是由出題者提出一個難以理解的事件,參與猜題者可以提出任何問題以試圖縮小範圍並找出事件背後真正的原因。但出題者僅能以「是」、「不是」或「沒有關係」來回答問題。 本遊戲蒐集各種論壇、平台的42個題目,提供給想玩海龜湯卻愁找不到題目的你們。 ...