[unity3d]UGUI实现unity摇杆

好久没有写文章了,最近在做项目是用的unity最新的ui系统UGUI,项目需要做一个摇杆,网上大部分都是用的插件和NGUI做的摇杆,unity自带的摇杆也不怎么好用,而最新的unity4.6.x来了,加入了最新的UI系统“UGUI”,那我们怎么用UGUI来制作摇杆呢~大神勿喷,本人是技术渣渣。

比较出色的摇杆插件《Easy Touch》(很强大)

还是主要讲讲我们自己怎么做。


  1. 首先在unity场景里面新建一个空物体和两个Image,把空物体放在创建Image自动生成的Canvas里面,再把两个Image放在空物体里

    Image建立方式:GameObject->UI->Image   或者直接在“Hierarchy”右键然后UI->Image,看喜好。

    空物体和两个Image的命名看个人喜好。

    威恩的节点是这样的:

    [unity3d]UGUI实现unity摇杆 - 威恩IG.CC - 1

    节点中的joystack是刚刚建立的空节点。

    Backgound是摇杆的背景。

    JoystackControl是真实的可以拖动的摇杆。

  2. BackgoundJoystackControlSourceImage替换成自己喜欢的图片,并且把JoystackControl的图片缩小点,这里我就用系统自带的图片了,威恩这两个节点的inspector如下(我修改过得地方用红框标注了,其他都没改):

    [unity3d]UGUI实现unity摇杆 - 威恩IG.CC - 2最终样子如下:

    [unity3d]UGUI实现unity摇杆 - 威恩IG.CC - 3

  3. 那么样子有了就需要让他动起来,需要三个类“EventTriggerListener”、“JoystackCc”、“PlayerMoveControl”。


    EventTriggerListener:在NGUI开发的时候处理事件都会用到UIEventListener,我们已经用的习惯的不得了,而UGUI则不是这种机制,

    并且我觉得这种是最合理的方式,所以自己写一套类似的。

    只是一个帮助类,不需要挂在任何的游戏对象上。

    JoystackCc:这是主要来控制摇杆的。

    挂在JoystackControl节点上

    PlayerMoveControl:这是主要来通过摇杆来控制角色的。

    挂在你想控制的物体上


    直接上代码,写了注释,就不哔哔了。

    EventTriggerListener.cs

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    using  UnityEngine;
    using  System.Collections;
    using  UnityEngine.EventSystems;
    using  System.Collections.Generic;
     
    /// <summary>
    /// UGUI事件监听类
    /// </summary>
    public  class  EventTriggerListener : UnityEngine.EventSystems.EventTrigger{
         public  delegate  void  VoidDelegate (GameObject go);
         public  delegate  void  VectorDelegate(GameObject go, Vector2 delta);
         public  VoidDelegate onClick;
         public  VoidDelegate onDown;
         public  VoidDelegate onEnter;
         public  VoidDelegate onExit;
         public  VoidDelegate onUp;
         public  VoidDelegate onSelect;
         public  VoidDelegate onUpdateSelect;
         
         public  VectorDelegate onDrag;
         public  VoidDelegate onDragOut;
         
         
         static  public  EventTriggerListener Get (GameObject go)
         {
             if (go== null ){
                 Debug.LogError( "EventTriggerListener_go_is_NULL" );
                 return  null ;
             }
             else {
                 EventTriggerListener listener = go.GetComponent<EventTriggerListener>();
                 if  (listener ==  null ) listener = go.AddComponent<EventTriggerListener>();
                 return  listener;
             }
         }
         
         public  override  void  OnDrag(PointerEventData eventData)
         {
             if  (onDrag !=  null ) onDrag(gameObject, eventData.delta);
         }
         
         public  override  void  OnEndDrag(PointerEventData eventData)
         {
             if  (onDragOut !=  null ) onDragOut(gameObject);
         }
         
         public  override  void  OnPointerClick(PointerEventData eventData)
         {
             if (onClick !=  null )  onClick(gameObject);
         }
         public  override  void  OnPointerDown (PointerEventData eventData){
             if (onDown !=  null ) onDown(gameObject);
         }
         public  override  void  OnPointerEnter (PointerEventData eventData){
             if (onEnter !=  null ) onEnter(gameObject);
         }
         public  override  void  OnPointerExit (PointerEventData eventData){
             if (onExit !=  null ) onExit(gameObject);
         }
         public  override  void  OnPointerUp (PointerEventData eventData){
             if (onUp !=  null ) onUp(gameObject);
         }
         public  override  void  OnSelect (BaseEventData eventData){
             if (onSelect !=  null ) onSelect(gameObject);
         }
         public  override  void  OnUpdateSelected (BaseEventData eventData){
             if (onUpdateSelect !=  null ) onUpdateSelect(gameObject);
         }
    }

    JoystackCc.cs

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    using  UnityEngine;
    using  System.Collections;
     
    public  class  JoystackCc : MonoBehaviour {
         private  Vector3 Origin;
     
         Transform mTrans;
     
         private  Vector3 _deltaPos;
         private  bool  _drag =  false ;
     
         private  Vector3 deltaPosition;
     
         float  dis;
         [SerializeField]
         private  float  MoveMaxDistance = 80;              //最大拖动距离
     
         [HideInInspector]
         public  Vector3 FiexdMovePosiNorm;  //固定8个角度移动的距离
     
         [HideInInspector]
         public  Vector3 MovePosiNorm;   //标准化移动的距离
         [SerializeField]
         private  float  ActiveMoveDistance = 1;                //激活移动的最低距离
         void  Awake()
         {
             EventTriggerListener.Get(gameObject).onDrag = OnDrag;
             EventTriggerListener.Get(gameObject).onDragOut = OnDragOut;
     
             EventTriggerListener.Get(gameObject).onDown = OnMoveStart;
         }
     
     
         // Use this for initialization
         void  Start () {
             Origin = transform.localPosition;  //设置原点
             mTrans = transform;
         }
         
         // Update is called once per frame
         void  Update()
         {
             dis = Vector3.Distance(transform.localPosition, Origin);  //拖动距离,这不是最大的拖动距离,是根据触摸位置算出来的
             if  (dis >= MoveMaxDistance)        //如果大于可拖动的最大距离
             {
                 Vector3 vec = Origin + (transform.localPosition - Origin) * MoveMaxDistance / dis;    //求圆上的一点:(目标点-原点) * 半径/原点到目标点的距离
                 transform.localPosition = vec;
             }
             if  (Vector3.Distance(transform.localPosition, Origin) > ActiveMoveDistance)   //距离大于激活移动的距离
             {
                 MovePosiNorm = (transform.localPosition - Origin).normalized;
                 MovePosiNorm =  new  Vector3(MovePosiNorm.x, 0, MovePosiNorm.y);
             }
             else
                 MovePosiNorm = Vector3.zero;
         }
         void  MiouseDown()
         {
             if  ((Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved))
             {
             }
             else
                 mTrans.localPosition = Origin;
         }
         Vector3 result;
         private  Vector3 _checkPosition(Vector3 movePos, Vector3 _offsetPos)
         {
             result = movePos + _offsetPos;
             return  result;
         }
     
         void  OnDrag(GameObject go, Vector2 delta)
         {
             if  (!_drag)
             {
                 _drag =  true ;
             }
             _deltaPos = delta;
     
             mTrans.localPosition +=  new  Vector3(_deltaPos.x, _deltaPos.y, 0);
         }
     
         void  OnDragOut(GameObject go)
         {
             _drag =  false ;
             mTrans.localPosition = Origin;
             if  (PlayerMoveControl.moveEnd !=  null ) PlayerMoveControl.moveEnd();
         }
     
         void  OnMoveStart(GameObject go)
         {
             if  (PlayerMoveControl.moveStart !=  null ) PlayerMoveControl.moveStart();
         }
    }

    PlayerMoveControl.cs

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    using  UnityEngine;
    using  System.Collections;
     
    public  class  PlayerMoveControl : MonoBehaviour {
         private  Transform _mTransform;
         public  JoystackCc _mJoystackCc;
     
         public  float  moveSpeed = 50;
     
         public  delegate  void  MoveDelegate();
         public  static  MoveDelegate moveEnd;
         public  static  MoveDelegate moveStart;
         public  static  PlayerMoveControl Instance;
         // Use this for initialization
         void  Awake()
         {
             Instance =  this ;
             _mTransform = transform;
     
             moveEnd = OnMoveEnd;
             moveStart = OnMoveStart;
         }
         void  Start () {
     
         }
         void  OnMoveEnd()
         {
             _turnBase =  false ;
         }
     
         void  OnMoveStart()
         {
             _turnBase =  true ;
         }
                 
         // Update is called once per frame
         private  float  angle;
         private  bool  _turnBase =  false ;
         void  Update()
         {
             if  (_turnBase) 
             {
                 Vector3 vecMove = _mJoystackCc.MovePosiNorm*Time.deltaTime*moveSpeed/10;
                 _mTransform.localPosition+=vecMove;
                 angle = Mathf.Atan2 (_mJoystackCc.MovePosiNorm.x, _mJoystackCc.MovePosiNorm.z) * Mathf.Rad2Deg - 10;
                 _mTransform.localRotation = Quaternion.Euler(Vector3.up*angle);
             }
         }
    }

    建好这三个类之后,把他们绑定到相应的节点上。都挂在哪,代码上面有写

  4. 测试一下,威恩新建了一个cube来作为测试对象,加了个plane作为“伪”地面,太黑了再打个灯….

    下面是测试效果:

    [unity3d]UGUI实现unity摇杆 - 威恩IG.CC - 4

如果有任何问题直接留言~尽自己所能帮忙解决~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小狼是个小程序

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值