39.输入处理

39.FGUI基础-Unity中的使用必备-输入处理


39.1 知识点

显示面板

TeachPanel panel = UIManager.Instance.ShowPanel<TeachPanel>("Teach");

判断是否点在了UI上

//注意:全屏界面,没有设置穿透时,空白区域也是接受输入的,只要是ture 那就一定是有UI遮挡
//鼠标不管是点击还是悬浮 只要在UI上 就会返回true
if (Stage.isTouchOnUI)
{
    print("鼠标或者手指在UI上");
    //可以通过这种方式 得到鼠标或者手指指向的UI对象
    print(GRoot.inst.touchTarget.name);
}
else
{
    print("鼠标或者手指不在UI上");
}

鼠标/触摸相关事件

//1.鼠标(左中右键)/手指 按下
panel.m_btnTest.onTouchBegin.Add((data) =>
{
    print("按下");
    //如果想要获取鼠标哪个键按下、
    //可以打印data.inputEvent.button 
    //打印结果 0左键 1右键 2中键
    print(data.inputEvent.button);
});

//2.鼠标/手指 移动
//移动 一定是先按下过后 再移动 才会响应的
panel.m_btnTest.onTouchMove.Add((eventData) =>
{
    print("移动");
    //我们也可以通过参数中的变量获取到坐标 打印的是FGUI屏幕坐标
    //这个坐标也是物理坐标 需要进行转换 才能变成我们的UI坐标
    print("移动xy  "+eventData.inputEvent.x + "_" + eventData.inputEvent.y);
});

//3.鼠标/手指 抬起
panel.m_btnTest.onTouchEnd.Add(() =>
{
    print("抬起");
});

//4.点击
//点击事件 一定是按下后 没有太多的鼠标或手指位移 松手才会响应点击
panel.m_btnTest.onClick.Add(() =>
{
    print("点击");
});

//5.鼠标右键点击
panel.m_btnTest.onRightClick.Add(() =>
{
    print("右键点击");
});

//6.鼠标或手指进入元件
panel.m_btnTest.onRollOver.Add(InObject);

//7.鼠标或手指离开元件
panel.m_btnTest.onRollOut.Add((eventData) =>
{
    //sender是触发事件的对象 sender的类型是EventDispatcher事件分发器  GObject继承EventDispatcher 
    print("鼠标离开对象" + (eventData.sender as GObject).name);
});









private void InObject(EventContext eventData )
{
    //sender是触发事件的对象 sender的类型是EventDispatcher事件分发器  GObject继承EventDispatcher 
    print("进入了某一个对象" + (eventData.sender as GObject).name);
}

获取当前鼠标或者手指的位置

//鼠标位置或者最后一个手指的位置
//打印的是FGUI屏幕坐标位置
//Stage.inst.touchPosition;

//获取指定手指位置,参数是手指ID 从0开始
//打印的是FGUI屏幕坐标位置
//Stage.inst.GetTouchPosition(0);

//得到的都是FGUI屏幕坐标位置
//如果想要使用FGUI编辑器坐标需要进行一次转换
//GRoot.inst.GlobalToLocal

//打印的是FGUI屏幕坐标位置
print(Stage.inst.touchPosition);

//打印的是FGUI屏幕坐标位置
print(Stage.inst.GetTouchPosition(0));

//打印的是FGUI编辑器坐标位置
print(GRoot.inst.GlobalToLocal(Stage.inst.touchPosition));

多点触摸

//当前按下手指数量
int num = Stage.inst.touchCount;

//获得当前所有按下的手指id
int[] touchIDs = Stage.inst.GetAllTouch(null);

//关闭多点触控
Input.multiTouchEnabled = false;

手势

//FGUI手势都是要传入元件实例化出对应的手势类 再给手势类添加监听

//长按 LongPressGesture
LongPressGesture gesture1 = new LongPressGesture(panel.m_btnTest);
gesture1.onAction.Add(() =>
{
    print("长按");
});

//手指滑动 SwipeGesture
SwipeGesture gesture2 = new SwipeGesture(panel.m_btnTest);
gesture2.onAction.Add(() =>
{
    print("手指滑动");
});

//两指缩放 PinchGesture
PinchGesture gesture3 = new PinchGesture(panel.m_btnTest);
gesture3.onAction.Add(() =>
{
    print("两指缩放");
});

//两指旋转 RotationGesture
RotationGesture gesture4 = new RotationGesture(panel.m_btnTest);
gesture4.onAction.Add(() =>
{
    print("两指旋转");
});

键盘输入

Stage.inst.onKeyDown.Add((data) =>
{
    //得到当前键盘输入键是啥
    print(data.inputEvent.keyCode);
});

39.2 知识点代码

using FairyGUI;
using System.Collections;
using System.Collections.Generic;
using Teach;
using UnityEngine;

public class Lesson39_FGUI基础_Unity中的使用必备_输入处理 : MonoBehaviour
{
    void Start()
    {
        #region 知识点一 判断是否点在了UI上

        TeachPanel panel = UIManager.Instance.ShowPanel<TeachPanel>("Teach");
        //注意:全屏界面,没有设置穿透时,空白区域也是接受输入的,只要是ture 那就一定是有UI遮挡
        //鼠标不管是点击还是悬浮 只要在UI上 就会返回true
        if(Stage.isTouchOnUI)
        {
            //可以通过这种方式 得到鼠标或者手指指向的UI对象
            print(GRoot.inst.touchTarget.name);
        }
        else
        {

        }

        #endregion

        #region 知识点二 鼠标/触摸相关事件

        //1.鼠标(左中右键)/手指 按下
        panel.m_btnTest.onTouchBegin.Add((data) =>
        {
            print("按下");
            //如果想要获取鼠标哪个键按下、
            //可以打印data.inputEvent.button 
            //打印结果 0左键 1右键 2中键
            print(data.inputEvent.button);
        });

        //2.鼠标/手指 移动
        //移动 一定是先按下过后 再移动 才会响应的
        panel.m_btnTest.onTouchMove.Add((eventData) =>
        {
            print("移动");
            //我们也可以通过参数中的变量获取到坐标 打印的是FGUI屏幕坐标
            //这个坐标也是物理坐标 需要进行转换 才能变成我们的UI坐标
            print("移动xy  "+eventData.inputEvent.x + "_" + eventData.inputEvent.y);
        });

        //3.鼠标/手指 抬起
        panel.m_btnTest.onTouchEnd.Add(() =>
        {
            print("抬起");
        });

        //4.点击
        //点击事件 一定是按下后 没有太多的鼠标或手指位移 松手才会响应点击
        panel.m_btnTest.onClick.Add(() =>
        {
            print("点击");
        });

        //5.鼠标右键点击
        panel.m_btnTest.onRightClick.Add(() =>
        {
            print("右键点击");
        });

        //6.鼠标或手指进入元件
        panel.m_btnTest.onRollOver.Add(InObject);

        //7.鼠标或手指离开元件
        panel.m_btnTest.onRollOut.Add((eventData) =>
        {
            //sender是触发事件的对象 sender的类型是EventDispatcher事件分发器  GObject继承EventDispatcher 
            print("鼠标离开对象" + (eventData.sender as GObject).name);
        });

        #endregion

        #region 知识点三 获取当前鼠标或者手指的位置

        //鼠标位置或者最后一个手指的位置
        //打印的是FGUI屏幕坐标位置
        //Stage.inst.touchPosition;

        //获取指定手指位置,参数是手指ID 从0开始
        //打印的是FGUI屏幕坐标位置
        //Stage.inst.GetTouchPosition(0);

        //得到的都是FGUI屏幕坐标位置
        //如果想要使用FGUI编辑器坐标需要进行一次转换
        //GRoot.inst.GlobalToLocal

        #endregion

        #region 知识点四 多点触摸

        //当前按下手指数量
        //int num = Stage.inst.touchCount;

        //获得当前所有按下的手指id
        //int[] touchIDs = Stage.inst.GetAllTouch(null);

        //关闭多点触控
        //Input.multiTouchEnabled = false;

        #endregion

        #region 知识点五 手势

        //FGUI手势都是要传入元件实例化出对应的手势类 再给手势类添加监听

        //长按 LongPressGesture
        LongPressGesture gesture1 = new LongPressGesture(panel.m_btnTest);
        gesture1.onAction.Add(() =>
        {
            print("长按");
        });

        //手指滑动 SwipeGesture
        SwipeGesture gesture2 = new SwipeGesture(panel.m_btnTest);
        gesture2.onAction.Add(() =>
        {
            print("手指滑动");
        });

        //两指缩放 PinchGesture
        PinchGesture gesture3 = new PinchGesture(panel.m_btnTest);
        gesture3.onAction.Add(() =>
        {
            print("两指缩放");
        });

        //两指旋转 RotationGesture
        RotationGesture gesture4 = new RotationGesture(panel.m_btnTest);
        gesture4.onAction.Add(() =>
        {
            print("两指旋转");
        });

        #endregion

        #region 知识点六 键盘输入

        Stage.inst.onKeyDown.Add((data) =>
        {
            //得到当前键盘输入键是啥
            print(data.inputEvent.keyCode);
        });

        #endregion
    }

    #region 知识点二 鼠标/触摸相关事件

    private void InObject(EventContext eventData )
    {
        //sender是触发事件的对象 sender的类型是EventDispatcher事件分发器  GObject继承EventDispatcher 
        print("进入了某一个对象" + (eventData.sender as GObject).name);
    }

    #endregion

    void Update()
    {
        #region 知识点一 判断是否点在了UI上
        //注意:全屏界面,没有设置穿透时,空白区域也是接受输入的,只要是ture 那就一定是有UI遮挡
        if (Stage.isTouchOnUI)
        {
            //print("鼠标或者手指在UI上");
            //可以通过这种方式 得到鼠标或者手指指向的UI对象
            //print(GRoot.inst.touchTarget.name);
        }
        else
        {
            //print("鼠标或者手指不在UI上");
        }
        #endregion


        #region 知识点三 获取当前鼠标或者手指的位置
        ////打印的是FGUI屏幕坐标位置
        //print(Stage.inst.touchPosition);

        ////打印的是FGUI屏幕坐标位置
        //print(Stage.inst.GetTouchPosition(0));

        ////打印的是FGUI编辑器坐标位置
        //print(GRoot.inst.GlobalToLocal(Stage.inst.touchPosition));
        #endregion
    }
}

39.3 练习题

在上节课的练习题基础上,请用现在所学知识,制作一个类似更换装备的功能 界面中有一个图片A,当我们按下拖动A时,会创建一个和它一样的半透明分身图片C,该分身图片C会跟随我们移动。当我们松开鼠标时C会消失,当我们在另一张图片B中松开鼠标时,AB两张图会相互替换

创建装载器A和装载器B,并发布

定义面板,图片AB,替身拖,当前选中图片,进入图片变量

//声明一个变量,表示当前面板,类型为GComponent
GComponent view;
//声明一个变量,表示图片A,类型为GLoader
private GLoader imgA;
//声明一个变量,表示图片B,类型为GLoader
private GLoader imgB;
//声明一个变量,表示当前选中的图片时创建出来的半透明替身,类型为GLoader
private GLoader tempImg;
//声明一个变量,表示当前选中的图片对象,类型为GLoader
private GLoader nowSelImg;
//声明一个变量,表示当前进入的图片对象,类型为GLoader
private GLoader nowInImg;

Start中进行基础代码设置,获取图片A和图片B的GLoader对象,并给它们添加事件监听方法。

void Start()
{
    //基础包和组件面板的导入
    //设置默认字体
    UIConfig.defaultFont = "Other/STHUPO";
    //设置超链接字体颜色
    HtmlParseOptions.DefaultLinkColor = Color.red;
    //基础包和组件面板的导入
    //设置适配相关
    GRoot.inst.SetContentScaleFactor(1365, 768, UIContentScaler.ScreenMatchMode.MatchHeight);
    //当前包和依赖包的加载
    UIPackage package = UIPackage.AddPackage("UI/FGUI教程");
    //遍历当前包的依赖包列表,并加载每个依赖包
    foreach (var item in package.dependencies)
    {
        UIPackage.AddPackage("UI/" + item["name"]);
    }
    //设置按钮音效和音量
    UIConfig.buttonSound = (NAudioClip)UIPackage.GetItemAssetByURL("ui://Teach/btnMusic");
    UIConfig.buttonSoundVolumeScale = 0.5f;
    //默认竖直滚动条 再FGUI全局默认设置的进unity不用代码设置会不生效 或者用UIConfig设置
    UIConfig.verticalScrollBar = "ui://Teach/MyScrollBar3";
    //创建组件对象 要设置为导出
    view = UIPackage.CreateObject("FGUI教程", "Lesson39_练习题").asCom;
    //添加到根对象
    GRoot.inst.AddChild(view);
    
    imgA = view.GetChild("imgA").asLoader;
    imgB = view.GetChild("imgB").asLoader;
    
    //给图片A和B添加事件监听方法
    LoaderAddAction(imgA);
    LoaderAddAction(imgB);
}

定义给指定的图片对象添加事件监听方法

//定义一个方法,用于给指定的图片对象添加事件监听方法
public void LoaderAddAction(GLoader img)
{
    img.onTouchBegin.Add(TouchBegin);  //添加触摸开始事件监听方法
    img.onTouchMove.Add(TouchMove);  //添加触摸移动事件监听方法
    img.onTouchEnd.Add(TouchEnd);  //添加触摸结束事件监听方法
    img.onRollOver.Add(InImg);  //添加鼠标进入事件监听方法
    img.onRollOut.Add(OutImg);  //添加鼠标离开事件监听方法
}

定义触摸开始事件方法

//定义一个方法,用于处理触摸开始事件的逻辑
public void TouchBegin(EventContext eventData)
{
    //在当前图片外部抬起鼠标时 也能响应抬起事件 
    eventData.CaptureTouch();

    nowSelImg = eventData.sender as GLoader;  //获取当前触摸的图片对象,并赋值给nowSelImg变量

    tempImg = new GLoader();  //创建一个新的GLoader对象,作为当前图片的半透明替身
    tempImg.autoSize = true;  //设置替身图片的自动大小属性为true,表示根据内容自动调整大小
    tempImg.url = nowSelImg.url;  //设置替身图片的url属性为当前图片的url属性,表示使用相同的资源
    tempImg.alpha = 0.5f;  //设置替身图片的alpha属性为0.5f,表示半透明效果
    //替身图不能触摸 否则鼠标移动上去抬起会挡住销毁的事件监听
    tempImg.touchable = false;  //设置替身图片的touchable属性为false,表示不可触摸
    tempImg.SetPivot(0.5f, 0.5f, true);  //设置替身图片的中心点为中心位置,表示以中心点为基准进行旋转和缩放
    
    //把当前选择的图片的FGUI屏幕坐标转成FGUI编辑器坐标
    Vector3 tempImgPos = GRoot.inst.GlobalToLocal(new Vector2(eventData.inputEvent.x, eventData.inputEvent.y));
    tempImg.SetPosition(tempImgPos.x, tempImgPos.y, 0);  //设置替身图片的位置为当前鼠标的位置
    
    view.AddChild(tempImg);  //把替身图片添加到当前面板中
}

定义触摸移动事件方法

//定义一个方法,用于处理触摸移动事件的逻辑
public void TouchMove(EventContext eventData)
{
    //把当前选择的图片的FGUI屏幕坐标转成FGUI编辑器坐标
    Vector3 tempImgPos = GRoot.inst.GlobalToLocal(new Vector2(eventData.inputEvent.x, eventData.inputEvent.y));
    tempImg.SetPosition(tempImgPos.x, tempImgPos.y, 0);  //设置替身图片的位置为当前鼠标的位置
}

定义触摸结束事件方法

//定义一个方法,用于处理触摸结束事件的逻辑
public void TouchEnd()
{
    if (nowInImg != null && nowSelImg != null && nowSelImg != nowInImg)  //判断是否有进入和选中的图片对象,并且不是同一个对象
    {
        string tempUrl = nowSelImg.url;  //声明一个变量,用于存储当前选中图片的url属性
        nowSelImg.url = nowInImg.url;  //把当前选中图片的url属性设置为当前进入图片的url属性,表示更换资源
        nowInImg.url = tempUrl;  //把当前进入图片的url属性设置为之前存储的选中图片的url属性,表示更换资源
    }

    if (tempImg != null)  //判断是否有替身图片对象
    {
        tempImg.Dispose();  //销毁替身图片对象
    }
    tempImg = null;  //把替身图片变量置空
    
    nowInImg = null;  //把进入图片变量置空
    nowSelImg = null;  //把选中图片变量置空
}

定义进入图片方法和离开图片方法

//定义一个方法,用于处理鼠标进入事件的逻辑
private void InImg(EventContext eventData)
{
    //记录进入了谁
    nowInImg = eventData.sender as GLoader;  //获取当前鼠标进入的图片对象,并赋值给nowInImg变量
}

//定义一个方法,用于处理鼠标离开事件的逻辑
private void OutImg(EventContext eventData)
{
    //记录离开了谁
    nowInImg = null;  //把进入图片变量置空
}

运行结果



39.4 练习题代码

//using命令用于引用其他命名空间中的类或方法
using FairyGUI;
using FairyGUI.Utils;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//定义一个类,继承自MonoBehaviour,用于在Unity中执行脚本
public class Lesson39_练习题 : MonoBehaviour
{
    //在上节课的练习题基础上
    //请用现在所学知识,制作一个类似更换装备的功能 
    //界面中有一个图片A,当我们按下拖动A时,
    //会创建一个和它一样的半透明分身图片C,
    //该分身图片C会跟随我们移动。当我们松开鼠标时C会消失,
    //当我们在另一张图片B中松开鼠标时,AB两张图会相互替换

    //声明一个变量,表示当前面板,类型为GComponent
    GComponent view;
    //声明一个变量,表示图片A,类型为GLoader
    private GLoader imgA;
    //声明一个变量,表示图片B,类型为GLoader
    private GLoader imgB;
    //声明一个变量,表示当前选中的图片时创建出来的半透明替身,类型为GLoader
    private GLoader tempImg;
    //声明一个变量,表示当前选中的图片对象,类型为GLoader
    private GLoader nowSelImg;
    //声明一个变量,表示当前进入的图片对象,类型为GLoader
    private GLoader nowInImg;

    //定义一个方法,表示脚本开始执行时调用的逻辑
    void Start()
    {
        //基础包和组件面板的导入
        //设置默认字体
        UIConfig.defaultFont = "Other/STHUPO";
        //设置超链接字体颜色
        HtmlParseOptions.DefaultLinkColor = Color.red;
        //基础包和组件面板的导入
        //设置适配相关
        GRoot.inst.SetContentScaleFactor(1365, 768, UIContentScaler.ScreenMatchMode.MatchHeight);
        //当前包和依赖包的加载
        UIPackage package = UIPackage.AddPackage("UI/FGUI教程");
        //遍历当前包的依赖包列表,并加载每个依赖包
        foreach (var item in package.dependencies)
        {
            UIPackage.AddPackage("UI/" + item["name"]);
        }
        //设置按钮音效和音量
        UIConfig.buttonSound = (NAudioClip)UIPackage.GetItemAssetByURL("ui://Teach/btnMusic");
        UIConfig.buttonSoundVolumeScale = 0.5f;
        //默认竖直滚动条 再FGUI全局默认设置的进unity不用代码设置会不生效 或者用UIConfig设置
        UIConfig.verticalScrollBar = "ui://Teach/MyScrollBar3";
        //创建组件对象 要设置为导出
        view = UIPackage.CreateObject("FGUI教程", "Lesson39_练习题").asCom;
        //添加到根对象
        GRoot.inst.AddChild(view);

        //得到Loader对象
        imgA = view.GetChild("imgA").asLoader;
        imgB = view.GetChild("imgB").asLoader;

        //给图片A和B添加事件监听方法
        LoaderAddAction(imgA);
        LoaderAddAction(imgB);
    }

    //定义一个方法,用于给指定的图片对象添加事件监听方法
    public void LoaderAddAction(GLoader img)
    {
        img.onTouchBegin.Add(TouchBegin);  //添加触摸开始事件监听方法
        img.onTouchMove.Add(TouchMove);  //添加触摸移动事件监听方法
        img.onTouchEnd.Add(TouchEnd);  //添加触摸结束事件监听方法
        img.onRollOver.Add(InImg);  //添加鼠标进入事件监听方法
        img.onRollOut.Add(OutImg);  //添加鼠标离开事件监听方法
    }

    //定义一个方法,用于处理触摸开始事件的逻辑
    public void TouchBegin(EventContext eventData)
    {
        //在当前图片外部抬起鼠标时 也能响应抬起事件 
        eventData.CaptureTouch();

        nowSelImg = eventData.sender as GLoader;  //获取当前触摸的图片对象,并赋值给nowSelImg变量

        tempImg = new GLoader();  //创建一个新的GLoader对象,作为当前图片的半透明替身
        tempImg.autoSize = true;  //设置替身图片的自动大小属性为true,表示根据内容自动调整大小
        tempImg.url = nowSelImg.url;  //设置替身图片的url属性为当前图片的url属性,表示使用相同的资源
        tempImg.alpha = 0.5f;  //设置替身图片的alpha属性为0.5f,表示半透明效果
        //替身图不能触摸 否则鼠标移动上去抬起会挡住销毁的事件监听
        tempImg.touchable = false;  //设置替身图片的touchable属性为false,表示不可触摸
        tempImg.SetPivot(0.5f, 0.5f, true);  //设置替身图片的中心点为中心位置,表示以中心点为基准进行旋转和缩放

        //把当前选择的图片的FGUI屏幕坐标转成FGUI编辑器坐标
        Vector3 tempImgPos = GRoot.inst.GlobalToLocal(new Vector2(eventData.inputEvent.x, eventData.inputEvent.y));
        tempImg.SetPosition(tempImgPos.x, tempImgPos.y, 0);  //设置替身图片的位置为当前鼠标的位置

        view.AddChild(tempImg);  //把替身图片添加到当前面板中
    }

    //定义一个方法,用于处理触摸移动事件的逻辑
    public void TouchMove(EventContext eventData)
    {
        //把当前选择的图片的FGUI屏幕坐标转成FGUI编辑器坐标
        Vector3 tempImgPos = GRoot.inst.GlobalToLocal(new Vector2(eventData.inputEvent.x, eventData.inputEvent.y));
        tempImg.SetPosition(tempImgPos.x, tempImgPos.y, 0);  //设置替身图片的位置为当前鼠标的位置
    }

    //定义一个方法,用于处理触摸结束事件的逻辑
    public void TouchEnd()
    {
        if (nowInImg != null && nowSelImg != null && nowSelImg != nowInImg)  //判断是否有进入和选中的图片对象,并且不是同一个对象
        {
            string tempUrl = nowSelImg.url;  //声明一个变量,用于存储当前选中图片的url属性
            nowSelImg.url = nowInImg.url;  //把当前选中图片的url属性设置为当前进入图片的url属性,表示更换资源
            nowInImg.url = tempUrl;  //把当前进入图片的url属性设置为之前存储的选中图片的url属性,表示更换资源
        }

        if (tempImg != null)  //判断是否有替身图片对象
        {
            tempImg.Dispose();  //销毁替身图片对象
        }
        tempImg = null;  //把替身图片变量置空

        nowInImg = null;  //把进入图片变量置空
        nowInImg = null;  //把选中图片变量置空
    }

    //定义一个方法,用于处理鼠标进入事件的逻辑
    private void InImg(EventContext eventData)
    {
        //记录进入了谁
        nowInImg = eventData.sender as GLoader;  //获取当前鼠标进入的图片对象,并赋值给nowInImg变量
    }

    //定义一个方法,用于处理鼠标离开事件的逻辑
    private void OutImg(EventContext eventData)
    {
        //记录离开了谁
        nowInImg = null;  //把进入图片变量置空
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏