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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值