/* 

大家好,我感觉到游戏开发中有许多相通的共性,如动画,特效,声音,输入,文件,网络等。其中 

逻辑部分可以自己想,动画、特效、声音等依赖资源,输入部分处理依赖平台API,网络也要依赖平台API。 

平台与平台之间有很大的差异性,一般来说一个平台的软件不能放到不同CPU的平台上直接运行,为此,产 

生了JAVA、C#、Lua等脚本语言,依赖于要执行的平台安装运行脚本语言的环境。另外一种解决办法,是源 

代码的重新编译,让编译器可以针对不同的平台编译出不同的二进制代码。于是,跨平台C++,网络方面 

POSIX Socket产生了。游戏引擎使用上面两种方式一种或两种就能实现跨平台编译运行。 

我深知时间的宝贵,为了提高开发效率,有必要用已学的知识写出可以通用的代码,方便以后再次使用。 

为了实现这个目标,需要有扎实的基本功,写出耦合性几乎没有的组件。 

Unity是组件式开发,我打算尝试着开发一套自己的包装类,用来封装经常用到的游戏功能。 

我打算先从最简单的输入着手,以后再做动画、网络部分等,敬请期待。 

输入部分分触屏操作与鼠标、键盘操作,此为触屏操作。 

触屏调试可以安装unity Remote 5 

*/ 

using System.Collections; 

using System.Collections.Generic; 

using UnityEngine; 

/* 

多点触控时系统返回的触摸点个数会变,位置会变,为了能够承接上一个状态判断移动的开始点与现在的点,继而得到向量,我 

保存了beginpositions数组为开始点,对应的nowpositions为开始的点移动到了现在的点,touchyunxucha(touch允许差让我们 

判定新得到的点是否是上一状态的某点的变化) 

*/ 

public class TouchControl : MonoBehaviour { 

    public int fingers = 1;                          //支持几点触控 

    public static TouchControl instance = null;      //单例 

    private float windowwidth;                       //窗口宽,默认为全屏 

    private float windowheight;                      //窗口高,默认为全屏 

    private Vector2 []beginpositions;                //点击事件开始位置  

    private Vector2 []nowpositions;                  //与beginPositions对应的当前移动到的位置 

    public Vector2 []movedirection;                  //供外界判断使用的移动向量,为nowPositon - beginPositon 

    public bool []istouching;                        //对应beginpositions里的点判断是否有效 

    private Rect[] fingerrects;                            //对应beginpositions点击的范围 

    private bool allout = true;                      //判断是否没有点在点击区域 

    public float touchyunxucha = 0.1f;               //在touchmoving的点与上一次的误差在此范围内视为同一点的移动 

    public delegate void processTouchBeginPosition(int index,Vector2 beginpos);//可以为点击开始添加特效 

    public delegate void processTouchMovePosition(int index,Vector2 beginpos,Vector2 movepos);//可以为点击移动添加特效 

    public delegate void processTouchEndPosition(int index,Vector2 endpos);//可以为点击结束添加特效 

    public delegate void processNoTouch();//可以为点击结束添加特效 

    public processTouchBeginPosition processtouchbegin; 

    public processTouchMovePosition processtouchmove; 

    public processTouchEndPosition processtouchend; 

    public processNoTouch processnotouch; 

    public bool isinit = false; 

    public bool isuichecked = false; 

    void setBasicValues() 

    { 

        windowwidth = Screen.width; 

        windowheight = Screen.height; 

        beginpositions = new Vector2[fingers];            //最多支持fingers点触控 

        nowpositions = new Vector2[fingers]; 

        movedirection = new Vector2[fingers]; 

        istouching = new bool[fingers]; 

        for(int i = 0 ; i < fingers; i++) 

        { 

            istouching[i] = false; 

        } 

        fingerrects = new Rect[fingers] ; 

    } 

    public bool setFingerArea(int index,Rect rect)//此处rect为窗口的比例 

    { 

        if (index >= fingers || index < 0) 

            return false; 

        fingerrects[index] = rect; 

        return true; 

    } 

    // Use this for initialization 

    void Awake() 

    { 

        instance = this; 

        this.enabled = false; 

    } 

    void Start() { 

        setBasicValues(); 

        Input.multiTouchEnabled = true;//开启多点触碰 

        isinit = true; 

    } 

    public bool OutOfControlRect(Vector2 pos) 

    { 

        for(int i = 0;i < fingers; i++) 

        { 

            if (fingerrects[i].Contains(pos)) 

                return false; 

        } 

        return true; 

    } 

    // Update is called once per frame 

    void Update () { 

        if (Input.touchCount < 1)               //没有点击时istouching全为false 

        { 

            for (int i = 0; i < fingers; i++) 

            { 

                istouching[i] = false;       

            } 

            if (!isuichecked) 

            { 

                processnotouch(); 

            } 

            return; 

        } 

         

        for (int i = 0; i < Input.touchCount; i++) 

        { 

            

            var temp = new Vector2(Input.touches[i].position.x / windowwidth, Input.touches[i].position.y / windowheight); //点击处转换为屏幕的比例点 

            if (Input.touches[i].phase == TouchPhase.Began)     //要处理的点击为TouchPhase.Began时处理方法 

            { 

                for (int j = 0;j < fingers;j++) 

                { 

                    if( fingerrects[j].Contains(temp)) 

                    { 

                   

                            Debug.Log("touch begin"); 

                            beginpositions[j] = nowpositions[j] = temp; 

                            processtouchbegin(j, temp); 

                            isuichecked = false; 

                            istouching[j] = true; 

                            allout = false; 

                         

                    } 

                } 

            } 

            if (Input.touches[i].phase == TouchPhase.Moved)    //要处理的点击为TouchPhase.Moved时处理方法 

            { 

                for(int j = 0;j < fingers;j++) 

                { 

                    if(istouching[j] && Vector2.Distance(nowpositions[j],temp) <= touchyunxucha) 

                    { 

                        nowpositions[j] = temp; 

                        processtouchmove(j,beginpositions[j],temp); 

                        isuichecked = false; 

                    } 

                } 

            } 

            if (Input.touches[i].phase == TouchPhase.Ended)    //要处理的点击为TouchPhase.Ended时处理方法 

            { 

                for(int j = 0;j < fingers;j++) 

                { 

                    if (istouching[j] && Vector2.Distance(nowpositions[j], temp) <= touchyunxucha) 

                    { 

                        istouching[j] = false; 

                        processtouchend(j, temp); 

                        isuichecked = false; 

                    } 



                } 

            } 

        } 

        for(int i = 0;i < fingers;i++) 

        { 

            if(istouching[i]) 

            { 

                movedirection[i] = nowpositions[i] - beginpositions[i]; 

                 

            } 

        } 

      

    } 

} 







/* 

虽然很想什么都不做就用本组件,但实际应用中按钮有千差万别,所以还是要初始化本类来正常使用。 

要使用本类请把本类挂到任意一个Unity组件上,建议拖到摄像机上。接下来,要对本类进行初始化,以得到正确的表现方式。 

具体如: 

1.设置fingers整形,为处理的最多点数 

2.设置每个fingerrects,从0到fingers-1下标 

*/ 

/* 

以下为使用本脚本的示例: 

using System.Collections; 

using System.Collections.Generic; 

using UnityEngine; 



public class test : MonoBehaviour { 

    TouchControl tc; 

 // Use this for initialization 

    IEnumerator waitForTouchControlInit() 

    { 

        while (!tc.isinit) 

        { 

            yield return null; 

        } 

        tc.setFingerArea(0, new Rect(0, 0, 0.3f, 0.3f)); 

        tc.setFingerArea(1, new Rect(0.7f, 0, 0.3f, 0.3f)); 



    } 

    void processTouchBeginPosition(int index, Vector2 beginpos) 

    { 

        Debug.Log("显示触控球与小球在位置" + beginpos.ToString()); 

    } 

    void processTouchMovePosition(int index, Vector2 beginpos, Vector2 movepos) 

    { 

        Debug.Log("显示小球在位置" + movepos.ToString()); 

        Debug.Log("按钮index为:" + index + "按钮移动向量为" + tc.movedirection[index]); 

    } 

    void processTouchEndPosition(int index, Vector2 endpos) 

    { 

        Debug.Log("隐藏编号为index触控球与小球" + endpos.ToString()); 

    } 

    void processNoTouch() 

    { 

        Debug.Log("把显示的触控UI检查一下防止还有意外留下的按钮图片"); 

        tc.isuichecked = true; 

    } 

    void Start () { 

        tc = TouchControl.instance;//Camera.main.GetComponent<TouchControl>(); 

        tc.fingers = 2; 

        tc.enabled = true; 

        StartCoroutine(waitForTouchControlInit()); 

        tc.processtouchbegin += processTouchBeginPosition; 

        tc.processtouchmove += processTouchMovePosition; 

        tc.processtouchend += processTouchEndPosition; 

        tc.processnotouch += processNoTouch; 

    } 

  

 // Update is called once per frame 

 void Update () { 

  

 } 

} 



*/