无聊写个手势插件

GestureCool

using UnityEngine;
using System.Collections;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

public class GestureCool : SingleFramework<GestureCool> {

    //将一个圆等分称16或者8份,从X轴开始标记,一次为0,1,2,3,4,5,6....15
    Dictionary<string, List<string>> DicGestures = new Dictionary<string, List<string>>();    //手势库

    string INI_File_Path;   //手势库配置文件信息

    //当前操作手势名称,可能用于采集识别时候用到
    string nowCollectGestureKeyName;

    public override void Init()
    {
        INI_File_Path = Application.dataPath + "/MyFrame/MyLibs/GestureRecognition/GESTURECOOLINI.ini";
    }

    /// <summary>
    /// 读取配置文件中的手势库信息,并绑定到字典库中~
    /// </summary>
    bool LoadGesturesFromINI()
    {
        try
        {
            string strLoadFromFile = File.ReadAllText(INI_File_Path);
            DicGestures = LitJson.JsonMapper.ToObject<Dictionary<string, List<string>>>(strLoadFromFile);
            return true;
        }
        catch
        {
            return false;
        }     
    }

    /// <summary>
    /// 存储字典库中的手势信息到字典
    /// </summary>
    public bool SaveGesturesToINI()
    {
        try
        {
            string json = LitJson.JsonMapper.ToJson(DicGestures);
            File.WriteAllText(INI_File_Path, json, Encoding.Default);
            return true;
        }
        catch
        {
            return false;
        }
        
    }

    /// <summary>
    /// 开始采集手势
    /// </summary>
    /// <param name="GestureName">采集手势的名称</param>
    public void StartCollectionWithKeyName(string GestureName)
    {
        nowCollectGestureKeyName = GestureName;
        //已经包含这个手势就追加
        if (!DicGestures.ContainsKey(GestureName))
        {
            DicGestures.Add(GestureName, new List<string>());
        }
    }

    /// <summary>
    /// 存储新的识别码
    /// </summary>
    /// <param name="RecString"></param>
    /// <returns></returns>
    public bool SaveRecoCode(string RecCode)
    {
        if (nowCollectGestureKeyName == "" || CheckIsRepeat(RecCode))
        {           
            return false;
        }
        //不重复就插入当前新项
        DicGestures[nowCollectGestureKeyName].Add(RecCode);     
        return true;
    }

    /// <summary>
    /// 检测是否存在重复项
    /// </summary>
    /// <param name="RecognitionString"></param>
    /// <returns></returns>
    bool CheckIsRepeat(string RecCode)
    {
        for (int i = 0; i < DicGestures[nowCollectGestureKeyName].Count; i++)
        {
            if (RecCode == DicGestures[nowCollectGestureKeyName][i])
            {
                return true;
            }
        }
        return false;
    }

    /// <summary>
    /// 根据手势名称返回识别码
    /// </summary>
    /// <param name="RecoName">手势名称</param>
    /// <returns></returns>
    public List<string> GetRecosStringByName(string RecoName)
    {
        return DicGestures[RecoName];
    }
}

DrawGesture

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
using System;
using System.Collections.Generic;
using System.IO;

public class DrawGesture : SingleFramework<DrawGesture>, IPointerDownHandler, IPointerUpHandler
{
    //将一个圆等分称16或者8份,从正上方开始标记,一次为手势0,1,2,3,4,5,6....15
    Dictionary<string, List<string>> DicGestures = new Dictionary<string, List<string>>();

    //绘制手势
    LineRenderer lineRenderer;

    //是否在绘制中
    bool isDrawing;
    public void OnPointerDown(PointerEventData eventData)
    {
        isDrawing = true;
        drawCounter = 0;
        GetPointUpdateCounter = 0;
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        isDrawing = false;
        lineRenderer.SetVertexCount(0);
        lstDrawPos3.Clear();

        //获取到识别码
        string RecoCode = GetRecoCodeByDirectionLst(lstGestures);

        //交给库去处理是否是采集
        if (GestureCool.instance.SaveRecoCode(RecoCode))
        {
            Debug.Log("追加手势成功~");
        }
        else {
            Debug.Log("追加手势失败~");
        }

        lstGestures.Clear();
    }

    public override void Init()
    {
        lineRenderer = this.GetComponent<LineRenderer>();
    }

    int drawCounter;   //绘点个数

    int GetPointFrequency = 2;  //取点频率
    int GetPointUpdateCounter;  //Update计数器

    public int RecognitionLevel = 2;   //识别的级别,出现的方向出现RecognitionLevel次以上才确定

    Vector3 DrawPos;         //绘制点坐标
    Vector3 Direction;       //拖拽的方向

    List<Vector3> lstDrawPos3 = new List<Vector3>();  //所有点集合
    List<int> lstGestures = new List<int>();          //所有方向码

    void Update()
    {
        if (isDrawing)
        {
            //绘画中,取点
            if (GetPointUpdateCounter++ % GetPointFrequency == 0)   //满足取点频率开始取点
            {
                drawCounter++;      //绘制点的个数
                lineRenderer.SetVertexCount(drawCounter);

                DrawPos = new Vector3(Input.mousePosition.x - Screen.width / 2, Input.mousePosition.y - Screen.height / 2, Input.mousePosition.z);
                lineRenderer.SetPosition(drawCounter - 1, DrawPos);
                lstDrawPos3.Add(DrawPos);

                //打印出方向
                if (drawCounter > 1)
                {
                    Direction = (DrawPos - lstDrawPos3[drawCounter - 2]).normalized;
                    if (Direction != Vector3.zero)
                    {
                        lstGestures.Add(CalculateGesture8art(GetAngelByTwoVector3(Direction)));
                    }
                }
            }
        }
    }

    /// <summary>
    /// 去除手势中的无效项
    /// </summary>
    /// <param name="OriLst"></param>
    /// <returns></returns>
    List<int> RemoveInvalid(List<int> OriLst)
    {
        List<int> newLst = new List<int>();
        int repeatCounter = 1;
        for (int i = 0; i < OriLst.Count; i++)
        {
            if (i != 0)
            {
                //等于前一项
                if (OriLst[i] == OriLst[i - 1])
                {
                    repeatCounter++;
                    if (repeatCounter == RecognitionLevel)
                    {
                        newLst.Add(OriLst[i]);
                    }
                }
                else   //不等于前一项
                {
                    repeatCounter = 1;
                }
            }
        }
        return newLst;
    }

    //根据角度计算出对应的部分单一手势(16区域手势)
    int CalculateGesture16Part(float Angel)
    {
        return (int)(((Angel + 11.25f) % 360) / 22.5f);
    }

    //(默认)根据角度计算出对应的部分单一手势(8区域手势)
    int CalculateGesture8art(float Angel)
    {
        return (int)(((Angel + 22.5f) % 360) / 45f);
    }

    //返回目标向量_与X轴正方向 的夹角
    float GetAngelByTwoVector3(Vector3 vec3_target)
    {
        float angelRes = 0;
        //先判断方向是否是坐标轴朝向
        if (vec3_target.x == 0 && vec3_target.y > 0)    //Y轴正向
        {
            angelRes = 90;
        }
        else if (vec3_target.x == 0 && vec3_target.y < 0)    //Y轴反向
        {
            angelRes = 270;
        }
        else if (vec3_target.y == 0 && vec3_target.x > 0)    //X轴正向
        {
            angelRes = 0;
        }
        else if (vec3_target.y == 0 && vec3_target.x < 0)    //X轴反向
        {
            angelRes = 180;
        }
        else if (vec3_target.x > 0 && vec3_target.y > 0)     //第一象限
        {
            angelRes = (Mathf.Atan(Mathf.Abs(vec3_target.y) / Mathf.Abs(vec3_target.x)) * Mathf.Rad2Deg);
        }
        else if (vec3_target.x < 0 && vec3_target.y > 0)     //第二象限
        {
            angelRes = 180 - (Mathf.Atan(Mathf.Abs(vec3_target.y) / Mathf.Abs(vec3_target.x)) * Mathf.Rad2Deg);
        }
        else if (vec3_target.x < 0 && vec3_target.y < 0)     //第三象限
        {
            angelRes = 180 + (Mathf.Atan(Mathf.Abs(vec3_target.y) / Mathf.Abs(vec3_target.x)) * Mathf.Rad2Deg);
        }
        else if (vec3_target.x > 0 && vec3_target.y < 0)     //第四象限
        {
            angelRes = 360 - (Mathf.Atan(Mathf.Abs(vec3_target.y) / Mathf.Abs(vec3_target.x)) * Mathf.Rad2Deg);
        }
        return angelRes;
    }

    /// <summary>
    /// 根据方向集合返回手势识别码
    /// </summary>
    /// <param name="lstDirections"></param>
    /// <returns></returns>
    public string GetRecoCodeByDirectionLst(List<int> lstDirections)
    {
        string RecoCode = "";  
        for (int i = 0; i < lstDirections.Count; i++)
        {
            RecoCode += lstDirections[i].ToString() + "_";
        }
        RecoCode = RecoCode.TrimEnd('_');
        return RecoCode;
    }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值