找回密码
 立即注册
查看: 2804|回复: 64

[基础] UGUI实现unity摇杆

  [复制链接]
发表于 2015-5-27 17:15 | 显示全部楼层 |阅读模式
资源信息 Tutorial Information
教程名称: UGUI实现unity3d摇杆教程(发帖教程)
适用引擎:   (适用引擎,为空默认为Unity)
教程语种: 中文
教程等级: 1
教程格式: 图文(请用IE9以上浏览器访问本版块)
教程作者: 转载自互联网 (如有问题请短消息联系作者或发表回复)
下载地址: (兑换积分)
点击查看原图
美丽分割线
本帖最后由 qq534575060 于 2015-5-27 17:17 编辑

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

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

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


  • 首先在unity场景里面新建一个空物体和两个Image,把空物体放在创建Image自动生成的Canvas里面,再把两个Image放在空物体里
    Image建立方式:GameObject->UI->Image   或者直接在“Hierarchy”右键然后UI->Image,看喜好。
    空物体和两个Image的命名看个人喜好。
    威恩的节点是这样的:
    节点中的joystack是刚刚建立的空节点。
    Backgound是摇杆的背景。
    JoystackControl是真实的可以拖动的摇杆。
  • 把Backgound和JoystackControl的SourceImage替换成自己喜欢的图片,并且把JoystackControl的图片缩小点,这里我就用系统自带的图片了,威恩这两个节点的inspector如下(我修改过得地方用红框标注了,其他都没改):
    终样子如下:
  • 那么样子有了就需要让他动起来,需要三个类“EventTriggerListener”、“JoystackCc”、“PlayerMoveControl”。

    EventTriggerListener:在NGUI开发的时候处理事件都会用到UIEventListener,我们已经用的习惯的不得了,而UGUI则不是这种机制,
    并且我觉得这种是最合理的方式,所以自己写一套类似的。
    只是一个帮助类,不需要挂在任何的游戏对象上。
    JoystackCc:这是主要来控制摇杆的。
    挂在JoystackControl节点上
    PlayerMoveControl:这是主要来通过摇杆来控制角色的。
    挂在你想控制的物体上

    直接上代码,写了注释,就不哔哔了。
    EventTriggerListener.cs
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.EventSystems;
    4. using System.Collections.Generic;
    5.   
    6. /// <summary>
    7. /// UGUI事件监听类
    8. /// </summary>
    9. public class EventTriggerListener : UnityEngine.EventSystems.EventTrigger{
    10.     public delegate void VoidDelegate (GameObject go);
    11.     public delegate void VectorDelegate(GameObject go, Vector2 delta);
    12.     public VoidDelegate onClick;
    13.     public VoidDelegate onDown;
    14.     public VoidDelegate onEnter;
    15.     public VoidDelegate onExit;
    16.     public VoidDelegate onUp;
    17.     public VoidDelegate onSelect;
    18.     public VoidDelegate onUpdateSelect;
    19.       
    20.     public VectorDelegate onDrag;
    21.     public VoidDelegate onDragOut;
    22.       
    23.       
    24.     static public EventTriggerListener Get (GameObject go)
    25.     {
    26.         if(go==null){
    27.             Debug.LogError("EventTriggerListener_go_is_NULL");
    28.             return null;
    29.         }
    30.         else{
    31.             EventTriggerListener listener = go.GetComponent<EventTriggerListener>();
    32.             if (listener == null) listener = go.AddComponent<EventTriggerListener>();
    33.             return listener;
    34.         }
    35.     }
    36.       
    37.     public override void OnDrag(PointerEventData eventData)
    38.     {
    39.         if (onDrag != null) onDrag(gameObject, eventData.delta);
    40.     }
    41.       
    42.     public override void OnEndDrag(PointerEventData eventData)
    43.     {
    44.         if (onDragOut != null) onDragOut(gameObject);
    45.     }
    46.       
    47.     public override void OnPointerClick(PointerEventData eventData)
    48.     {
    49.         if(onClick != null)  onClick(gameObject);
    50.     }
    51.     public override void OnPointerDown (PointerEventData eventData){
    52.         if(onDown != null) onDown(gameObject);
    53.     }
    54.     public override void OnPointerEnter (PointerEventData eventData){
    55.         if(onEnter != null) onEnter(gameObject);
    56.     }
    57.     public override void OnPointerExit (PointerEventData eventData){
    58.         if(onExit != null) onExit(gameObject);
    59.     }
    60.     public override void OnPointerUp (PointerEventData eventData){
    61.         if(onUp != null) onUp(gameObject);
    62.     }
    63.     public override void OnSelect (BaseEventData eventData){
    64.         if(onSelect != null) onSelect(gameObject);
    65.     }
    66.     public override void OnUpdateSelected (BaseEventData eventData){
    67.         if(onUpdateSelect != null) onUpdateSelect(gameObject);
    68.     }
    69. }
    复制代码
    JoystackCc.cs
    1. using UnityEngine;
    2. using System.Collections;
    3.   
    4. public class JoystackCc : MonoBehaviour {
    5.     private Vector3 Origin;
    6.   
    7.     Transform mTrans;
    8.   
    9.     private Vector3 _deltaPos;
    10.     private bool _drag = false;
    11.   
    12.     private Vector3 deltaPosition;
    13.   
    14.     float dis;
    15.     [SerializeField]
    16.     private float MoveMaxDistance = 80;             //最大拖动距离
    17.   
    18.     [HideInInspector]
    19.     public Vector3 FiexdMovePosiNorm; //固定8个角度移动的距离
    20.   
    21.     [HideInInspector]
    22.     public Vector3 MovePosiNorm;  //标准化移动的距离
    23.     [SerializeField]
    24.     private float ActiveMoveDistance = 1;               //激活移动的最低距离
    25.     void Awake()
    26.     {
    27.         EventTriggerListener.Get(gameObject).onDrag = OnDrag;
    28.         EventTriggerListener.Get(gameObject).onDragOut = OnDragOut;
    29.   
    30.         EventTriggerListener.Get(gameObject).onDown = OnMoveStart;
    31.     }
    32.   
    33.   
    34.     // Use this for initialization
    35.     void Start () {
    36.         Origin = transform.localPosition; //设置原点
    37.         mTrans = transform;
    38.     }
    39.       
    40.     // Update is called once per frame
    41.     void Update()
    42.     {
    43.         dis = Vector3.Distance(transform.localPosition, Origin); //拖动距离,这不是最大的拖动距离,是根据触摸位置算出来的
    44.         if (dis >= MoveMaxDistance)       //如果大于可拖动的最大距离
    45.         {
    46.             Vector3 vec = Origin + (transform.localPosition - Origin) * MoveMaxDistance / dis;   //求圆上的一点:(目标点-原点) * 半径/原点到目标点的距离
    47.             transform.localPosition = vec;
    48.         }
    49.         if (Vector3.Distance(transform.localPosition, Origin) > ActiveMoveDistance)  //距离大于激活移动的距离
    50.         {
    51.             MovePosiNorm = (transform.localPosition - Origin).normalized;
    52.             MovePosiNorm = new Vector3(MovePosiNorm.x, 0, MovePosiNorm.y);
    53.         }
    54.         else
    55.             MovePosiNorm = Vector3.zero;
    56.     }
    57.     void MiouseDown()
    58.     {
    59.         if ((Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved))
    60.         {
    61.         }
    62.         else
    63.             mTrans.localPosition = Origin;
    64.     }
    65.     Vector3 result;
    66.     private Vector3 _checkPosition(Vector3 movePos, Vector3 _offsetPos)
    67.     {
    68.         result = movePos + _offsetPos;
    69.         return result;
    70.     }
    71.   
    72.     void OnDrag(GameObject go, Vector2 delta)
    73.     {
    74.         if (!_drag)
    75.         {
    76.             _drag = true;
    77.         }
    78.         _deltaPos = delta;
    79.   
    80.         mTrans.localPosition += new Vector3(_deltaPos.x, _deltaPos.y, 0);
    81.     }
    82.   
    83.     void OnDragOut(GameObject go)
    84.     {
    85.         _drag = false;
    86.         mTrans.localPosition = Origin;
    87.         if (PlayerMoveControl.moveEnd != null) PlayerMoveControl.moveEnd();
    88.     }
    89.   
    90.     void OnMoveStart(GameObject go)
    91.     {
    92.         if (PlayerMoveControl.moveStart != null) PlayerMoveControl.moveStart();
    93.     }
    94. }
    复制代码
    PlayerMoveControl.cs
    1. using UnityEngine;
    2. using System.Collections;
    3.   
    4. public class PlayerMoveControl : MonoBehaviour {
    5.     private Transform _mTransform;
    6.     public JoystackCc _mJoystackCc;
    7.   
    8.     public float moveSpeed = 50;
    9.   
    10.     public delegate void MoveDelegate();
    11.     public static MoveDelegate moveEnd;
    12.     public static MoveDelegate moveStart;
    13.     public static PlayerMoveControl Instance;
    14.     // Use this for initialization
    15.     void Awake()
    16.     {
    17.         Instance = this;
    18.         _mTransform = transform;
    19.   
    20.         moveEnd = OnMoveEnd;
    21.         moveStart = OnMoveStart;
    22.     }
    23.     void Start () {
    24.   
    25.     }
    26.     void OnMoveEnd()
    27.     {
    28.         _turnBase = false;
    29.     }
    30.   
    31.     void OnMoveStart()
    32.     {
    33.         _turnBase = true;
    34.     }
    35.               
    36.     // Update is called once per frame
    37.     private float angle;
    38.     private bool _turnBase = false;
    39.     void Update()
    40.     {
    41.         if (_turnBase)
    42.         {
    43.             Vector3 vecMove = _mJoystackCc.MovePosiNorm*Time.deltaTime*moveSpeed/10;
    44.             _mTransform.localPosition+=vecMove;
    45.             angle = Mathf.Atan2 (_mJoystackCc.MovePosiNorm.x, _mJoystackCc.MovePosiNorm.z) * Mathf.Rad2Deg - 10;
    46.             _mTransform.localRotation = Quaternion.Euler(Vector3.up*angle);
    47.         }
    48.     }
    49. }
    复制代码
    建好这三个类之后,把他们绑定到相应的节点上。都挂在哪,代码上面有写
  • 测试一下,威恩新建了一个cube来作为测试对象,加了个plane作为“伪”地面,太黑了再打个灯….
    下面是测试效果:

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


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发表于 2016-7-19 09:57 | 显示全部楼层
感谢分享!!:)
发表于 2016-7-19 10:02 | 显示全部楼层

感谢楼主的无私分享!
发表于 2016-8-1 11:16 | 显示全部楼层

不错 不错 不错
发表于 2016-8-18 00:38 | 显示全部楼层
好的一天

发表于 2017-3-7 15:33 | 显示全部楼层
楼主是超人
发表于 2017-3-7 16:08 | 显示全部楼层
好帖就是要顶
发表于 2017-3-7 15:59 | 显示全部楼层
真心顶
发表于 2017-3-7 16:19 | 显示全部楼层
难得一见的好帖
发表于 2017-3-7 15:42 | 显示全部楼层
不错不错
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-5-3 05:49 , Processed in 0.348158 second(s), 33 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表