06-初識FairyGUI

兩段代碼:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using FairyGUI;
using DG.Tweening;

public class JoyStick : EventDispatcher
{
    //事件監聽者
    public EventListener onMove { get; private set; }
    public EventListener onEnd { get; private set; }

    //mainUI裏的對象
    private GButton joyStickButton;
    private GObject thumb;
    private GObject touchArea;
    private GObject center;

    //搖桿的屬性
    private float initX;
    private float initY;
    private float startStageX;
    private float startStageY;
    private float lastStageX;
    private float lastStageY;
    private int touchID;
    private Tweener tweener;
    public int radius { get; set; }

    public JoyStick(GComponent mainUI)
    {
        onMove = new EventListener(this, "onMove");
        onEnd = new EventListener(this, "onEnd");

        joyStickButton = mainUI.GetChild("joyStick").asButton;
        joyStickButton.changeStateOnClick = false;
        thumb = joyStickButton.GetChild("thumb");
        touchArea = mainUI.GetChild("triggleArea");
        center = mainUI.GetChild("joyStickCenter");

        initX = center.x + center.width / 2;
        initY = center.y + center.height / 2;
        touchID = -1;
        radius = 150;

        touchArea.onTouchBegin.Add(OnTouchBegin);
        touchArea.onTouchMove.Add(OnTouchMove);
        touchArea.onTouchEnd.Add(OnTouchEnd);
    }

    private void OnTouchBegin(EventContext context)
    {
        if (touchID == -1)
        {
            InputEvent inputEvent = (InputEvent)context.data;
            touchID = inputEvent.touchId;

            if (tweener != null)
            {
                tweener.Kill();
                tweener = null;
            }

            Vector2 localPos = GRoot.inst.GlobalToLocal(new Vector2(inputEvent.x, inputEvent.y));
            float posX = localPos.x;
            float posY = localPos.y;
            joyStickButton.selected = true;

            lastStageX = posX;
            lastStageY = posY;
            startStageX = posX;
            startStageY = posY;

            center.visible = true;
            center.SetXY(posX - center.width / 2, posY - center.height / 2);
            joyStickButton.SetXY(posX - joyStickButton.width / 2, posY - joyStickButton.height / 2);

            float deltax = posX - initX;
            float deltay = posY - initY;
            float degrees = Mathf.Atan2(deltay, deltax) * 180 / Mathf.PI;
            thumb.rotation = degrees;
            context.CaptureTouch();
        }
    }
    private void OnTouchMove(EventContext context)
    {
        InputEvent inputEvent = (InputEvent)context.data;
        if (touchID != -1 && inputEvent.touchId == touchID)
        {
            Vector2 localPos = GRoot.inst.GlobalToLocal(new Vector2(inputEvent.x, inputEvent.y));
            float posX = localPos.x;
            float posY = localPos.y;
            float moveX = posX - lastStageX;
            float moveY = posY - lastStageY;
            lastStageX = posX;
            lastStageY = posY;
            float buttonX = joyStickButton.x + moveX;
            float buttonY = joyStickButton.y + moveY;

            float deltaX = buttonX + joyStickButton.width / 2 - startStageX;
            float deltaY = buttonY + joyStickButton.width / 2 - startStageY;

            float rad = Mathf.Atan2(deltaY, deltaX);
            float degree = rad * 180 / Mathf.PI;
            thumb.rotation = degree;

            float maxX = radius * Mathf.Cos(rad);
            float maxY = radius * Mathf.Sin(rad);
            if (Mathf.Abs(deltaX) > Mathf.Abs(maxX))
            {
                deltaX = maxX;
            }
            if (Mathf.Abs(deltaY) > Mathf.Abs(maxY))
            {
                deltaY = maxY;
            }

            buttonX = startStageX + deltaX;
            buttonY = startStageY + deltaY;

            joyStickButton.SetXY(buttonX - joyStickButton.width / 2, buttonY - joyStickButton.height / 2);

            onMove.Call(degree);
        }
    }

    private void OnTouchEnd(EventContext context)
    {
        InputEvent inputEvent = (InputEvent)context.data;
        if (touchID != -1 && inputEvent.touchId == touchID)
        {
            touchID = -1;
            thumb.rotation = thumb.rotation + 180;
            center.visible = false;
            tweener = joyStickButton.TweenMove(new Vector2(initX - joyStickButton.width / 2, initY - joyStickButton.height / 2), 0.3f).OnComplete(() =>
             {
                 tweener = null;
                 joyStickButton.selected = false;
                 thumb.rotation = 0;
                 center.visible = true;
                 center.SetXY(initX - center.width / 2, initY - center.height / 2);
             });
        }
        onEnd.Call();
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using FairyGUI;

public class JoyStickMain : MonoBehaviour
{
    private GComponent mainUI;
    private GTextField gTextField;
    private JoyStick joyStick;
    // Start is called before the first frame update
    void Start()
    {
        mainUI = GetComponent<UIPanel>().ui;
        gTextField = mainUI.GetChild("T5").asTextField;
        joyStick = new JoyStick(mainUI);
        joyStick.onMove.Add(Move);
        joyStick.onEnd.Add(End);
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    private void Move(EventContext context)
    {
        float degree = (float)context.data;
        gTextField.text = degree.ToString();
    }
    private void End()
    {
        gTextField.text = "";
    }
}

首先是EventListener:用來對事件調用回調函數的

如:

//第一段代碼中定義和初始化: 
public EventListener onMove { get; private set; }
public EventListener onEnd { get; private set; }
onMove = new EventListener(this, "onMove");
onEnd = new EventListener(this, "onEnd");

//第二段代碼中添加回調函數:
joyStick.onMove.Add(Move);
joyStick.onEnd.Add(End);
//第一段代碼中調用:
onMove.Call(degree);
onEnd.Call();

初始化需要說明一下:第一個參數是該事件偵聽器的擁有者,第二個參數偵聽事件的類型,不能亂寫

關於回調函數:就是在某個事件發生後去調用的一個函數,有兩種形式,兩種形式的使用方法都是相同的,差別在於不帶參數或帶一個參數,只是爲了方便在不需要用到EventContext時少寫一點而已

如:

private void Move(EventContext context)
{
    float degree = (float)context.data;
    gTextField.text = degree.ToString();
}
private void End()
{
    gTextField.text = "";
}

關於EventContext:該類中包含了一些事件中可能會用到的信息,如輸入信息(也就是InputEvent)等

關於InputEvent:包含了鍵盤事件和鼠標/觸摸事件的一些數據

如:

InputEvent inputEvent = (InputEvent)context.data;

注意context是一個EventContext類型的變量,這句話的意思就是將context中的data屬性中的數據包裝爲一個InputEvent類型的變量。data:事件的數據。根據事件不同,可以有不同的含義

 

joyStickButton.changeStateOnClick = false;

將按鈕的自動切換狀態關閉

 

touchArea.onTouchBegin.Add(OnTouchBegin);
touchArea.onTouchMove.Add(OnTouchMove);
touchArea.onTouchEnd.Add(OnTouchEnd);

對touchArea對象的開始移動,移動中,結束移動事件添加回調函數

 

touchID = inputEvent.touchId;

inputEvent.touchId:當前事件相關的手指ID;在PC平臺,該值爲0,沒有意義。

 

private Tweener tweener;
if (tweener != null)
{

    tweener.Kill();
    tweener = null;
}
tweener = joyStickButton.TweenMove(new Vector2(initX - joyStickButton.width / 2, initY - joyStickButton.height / 2), 0.3f).OnComplete(() =>
{
    tweener = null;
    joyStickButton.selected = false;
    thumb.rotation = 0;
    center.visible = true;
    center.SetXY(initX - center.width / 2, initY - center.height / 2);
});

Tweener:和緩動有關的一個類 。Kill()命令將當前tweener的緩動效果給刪除,然後再設爲空。下面是爲joyStickButton對象添加緩動效果,同時將該緩動效果賦值給tweener。TweenMove的兩個參數第一個是目標位置,第二個是所用時間

OnComplete是緩動執行完之後調用其中的函數

Selected表示按鈕是否已被點擊

 

 Vector2 localPos = GRoot.inst.GlobalToLocal(new Vector2(inputEvent.x, inputEvent.y));

將屏幕座標(點擊的位置)轉換爲本地座標(理想中的位置)

 

Mathf.Atan2(deltay, deltax)

將其中的正切值轉換爲弧度

 

context.CaptureTouch();

再OnTouchBegin中調用,用來捕獲Move和End事件的,沒有它OnTouchMove將不會觸發,OnTouchEnd可能不會觸發,詳細請參考:http://www.fairygui.com/guide/unity/input.html

 

private GTextField gTextField;

對應於文本框組件的類

參考:http://www.fairygui.com/guide/unity/event.html

http://www.fairygui.com/guide/unity/input.html

https://baike.baidu.com/item/%E4%BA%8B%E4%BB%B6/6129089#viewPageContent

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章