轩辕kuku
论坛版主
论坛版主
  • UID14
  • 粉丝6
  • 关注1
  • 发帖数78
  • 社区居民
  • 原创写手
阅读:628回复:0

Unity3d移动端输入控制事件总结

楼主#
更多 发布于:2016-07-27 23:04

前几天对工作上的工程进行了一下整理,顺便将之前写的比较乱的输入控制代码总结了一下。输入控制的方式以事件的方式来传递,需要控制的物体,仅需要注册接受事件参数即可。
(1)       定义的操作类型和事件参数
public enum InputType
{
    CLICK,
    SINGLE_ROTATE,
    DOUBLE_SCALE,
    DOUBLE_MOVE,
    NONE
}
   
public class InputEventArgs
{
    public float rotate;
    public float scale;
    public Vector2 move;
    public InputEventArgs(float _rotate,float _scale,Vector2 _move)
    {
        rotate =_rotate;
        scale = _scale;
        move = _move;
    }
    override
    public string ToString()
    {
        return "rotate:"+rotate.ToString()+"scale:"+scale.ToString()+"move:"+move.ToString("f2");
    }
}

(2)       触摸事件的触发
public class InputControl : MonoBehaviour {
    
    public static InputControl instance;
    
    public InputType currentInputType = InputType.NONE;
    
    private Vector2 oldPosition1,oldPosition2;
    
    public delegate void InputEventdelegate(InputType _type,InputEventArgs _args);
    
    public event  InputEventdelegate  InputEvent;
    
    void Awake()
    {
        instance =this;
    }
    
//    float debuginfo =0;
//
//    void OnGUI()
//    {
//        GUI.Label(new Rect(200,250,200,200),debuginfo.ToString());
//    }
    // Update is called once per frame
    void Update () {
        if(Input.touchCount>0)
        {  
            if (EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId))
            {
                currentInputType = InputType.NONE;  
                return ;
            }
    
            //记录手指按下去的个数
            int TCount = Input.touchCount;
            //但手指触屏
            if(TCount==1)
            {
                //获得单手指触屏
                Touch touch = Input.GetTouch(0);
                //单手指触屏开始
                if(touch.phase == TouchPhase.Began)
                {          
                    oldPosition1 = touch.position;
                }
                if(touch.phase == TouchPhase.Moved)
                {
                    if(Mathf.Abs(Input.GetAxis("Mouse X"))>0.05f)
                        if(InputEvent != null)
                            InputEvent(InputType.SINGLE_ROTATE,new InputEventArgs(Input.GetAxis("Mouse X")*2f,1,new Vector2(0,0)));
                }
                if(touch.phase == TouchPhase.Ended)
                {
                    if(Mathf.Sqrt((oldPosition1.x- touch.position.x)*(oldPosition1.x- touch.position.x)+(oldPosition1.y- touch.position.y)*(oldPosition1.y- touch.position.y)) < 3)
                        if(InputEvent != null)
                            InputEvent(InputType.CLICK,new InputEventArgs(0,0,new Vector2(0,0)));
                }
            }  
            else if(TCount==2)
            {    
                if (EventSystem.current.IsPointerOverGameObject(Input.GetTouch(0).fingerId)||EventSystem.current.IsPointerOverGameObject(Input.GetTouch(1).fingerId))
                {
                    currentInputType = InputType.NONE;  
                    return ;
                }
//                //获得手指点
                Touch touch1 = Input.GetTouch(0);
                Touch touch2 = Input.GetTouch(1);
                //前两只手指触摸类型都为移动触摸
                if(touch1.phase==TouchPhase.Moved||touch2.phase==TouchPhase.Moved)
                {
                    //计算出当前两点触摸点的位置
                    var tempPosition1 = Input.GetTouch(0).position;
                    var tempPosition2 = Input.GetTouch(1).position;
    
                    float _scaleDelta = isEnlarge(oldPosition1,oldPosition2,tempPosition1,tempPosition2);
                    if(_scaleDelta>3)
                    {
                        if(InputEvent != null)
                            InputEvent(InputType.DOUBLE_SCALE,new InputEventArgs(0,1.02f,new Vector2(0,0)));
                    }
                    else
                        if(isEnlarge(oldPosition1,oldPosition2,tempPosition1,tempPosition2)<-3)
                        {
                            if(InputEvent != null)
                            InputEvent(InputType.DOUBLE_SCALE,new InputEventArgs(0,0.98f,new Vector2(0,0)));
                        }
                    oldPosition1=tempPosition1;
                    oldPosition2=tempPosition2;
                    if ((touch1.deltaPosition.x * touch2.deltaPosition.x) >= 0 && (touch1.deltaPosition.y * touch2.deltaPosition.y) >= 0)  
                    {
                        if(InputEvent != null)
                            InputEvent(InputType.DOUBLE_MOVE,new InputEventArgs(0,1,new Vector2(touch1.deltaPosition.x*100,touch1.deltaPosition.y*100 )));
                    }
                }  
    
            }
        }
    }
    
    float isEnlarge(Vector2 oP1,Vector2 oP2,Vector2 nP1,Vector2 nP2)
    {
        //函数传入上一次触摸两点的位置与本次触摸两点的位置计算出用户的手势
        float leng1 =Mathf.Sqrt((oP1.x-oP2.x)*(oP1.x-oP2.x)+(oP1.y-oP2.y)*(oP1.y-oP2.y));
        float leng2 =Mathf.Sqrt((nP1.x-nP2.x)*(nP1.x-nP2.x)+(nP1.y-nP2.y)*(nP1.y-nP2.y));
        return leng2 -leng1;
    }
}

(3)       事件注册和相应(绑定到需要控制的物体上)
public class InputTest : MonoBehaviour {
   
    string debuginfo;
    // Use this for initialization
    void Start () {
        InputControl.instance.InputEvent += InputHandle;
    }
    void InputHandle(InputType _type,InputEventArgs _args)
    {
        debuginfo = _type.ToString()+_args.ToString();
        switch(_type)
        {
            case InputType.CLICK:
                break;
            case InputType.SINGLE_ROTATE:
                transform.Rotate(Vector3.up*_args.rotate*(-1),Space.World);
                break;
            case InputType.DOUBLE_MOVE:
                transform.Translate(new Vector3(_args.move.x*0.01f,_args.move.y*0.01f,0),Space.World);
                break;
            case InputType.DOUBLE_SCALE:
                transform.localScale *= _args.scale;
                break;
            default:
                break;
        }
    }
}

上面代码还可以继续简化,仅供大家参考讨论。(www.arvrschool.com

图片:68_14_a728a0831681809.jpg




最新喜欢:

归海一啸归海一啸

欢迎分享

游客

返回顶部