zoukankan      html  css  js  c++  java
  • UGUI实现unity摇杆

    http://www.winig.cc/archives/348

    好久没有写文章了,最近在做项目是用的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的命名看个人喜好。

      威恩的节点是这样的:

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

      Backgound是摇杆的背景。

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

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

      最终样子如下:

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


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

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

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

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

      挂在JoystackControl节点上

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

      挂在你想控制的物体上


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

      EventTriggerListener.cs

    4. 
      	
      	
      
      using UnityEngine;
      
      using System.Collections;
      
      using UnityEngine.EventSystems;
      
      using System.Collections.Generic;
      
      
      /// <summary>
      
      /// UGUI事件监听类
      
      /// </summary>
      
      public class EventTriggerListener : UnityEngine.EventSystems.EventTrigger{
      	
      	publicdelegate void VoidDelegate (GameObject go);
      	
      	publicdelegate void VectorDelegate(GameObject go, Vector2 delta);
      	
      	publicVoidDelegate onClick;
      	
      	publicVoidDelegate onDown;
      	
      	publicVoidDelegate onEnter;
      	
      	publicVoidDelegate onExit;
      	
      	publicVoidDelegate onUp;
      	
      	publicVoidDelegate onSelect;
      	
      	publicVoidDelegate onUpdateSelect;
      	
      	
      	
      	publicVectorDelegate onDrag;
      	
      	publicVoidDelegate onDragOut;
      	
      	
      	
      	
      	
      	staticpublic 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;
      			
      		}
      		
      	}
      	
      	
      	
      	publicoverride void OnDrag(PointerEventData eventData)
      		
      	{
      		
      		if(onDrag != null) onDrag(gameObject, eventData.delta);
      		
      	}
      	
      	
      	
      	publicoverride void OnEndDrag(PointerEventData eventData)
      		
      	{
      		
      		if(onDragOut != null) onDragOut(gameObject);
      		
      	}
      	
      	
      	
      	publicoverride void OnPointerClick(PointerEventData eventData)
      		
      	{
      		
      		if(onClick !=null)  onClick(gameObject);
      		
      	}
      	
      	publicoverride void OnPointerDown (PointerEventData eventData){
      		
      		if(onDown !=null) onDown(gameObject);
      		
      	}
      	
      	publicoverride void OnPointerEnter (PointerEventData eventData){
      		
      		if(onEnter !=null) onEnter(gameObject);
      		
      	}
      	
      	publicoverride void OnPointerExit (PointerEventData eventData){
      		
      		if(onExit !=null) onExit(gameObject);
      		
      	}
      	
      	publicoverride void OnPointerUp (PointerEventData eventData){
      		
      		if(onUp !=null) onUp(gameObject);
      		
      	}
      	
      	publicoverride void OnSelect (BaseEventData eventData){
      		
      		if(onSelect !=null) onSelect(gameObject);
      		
      	}
      	
      	publicoverride void OnUpdateSelected (BaseEventData eventData){
      		
      		if(onUpdateSelect !=null) onUpdateSelect(gameObject);
      		
      	}
      	
      } 


       

       
       

       

    5. JoystackCc.cs

    6. using UnityEngine;
      
      using System.Collections;
      
      
      public class JoystackCc : MonoBehaviour {
      	
      	privateVector3 Origin;
      	
      	
      	Transform mTrans;
      	
      	
      	privateVector3 _deltaPos;
      	
      	privatebool _drag = false;
      	
      	
      	privateVector3 deltaPosition;
      	
      	
      	floatdis;
      	
      	[SerializeField]
      	
      	privatefloat MoveMaxDistance = 80;            //最大拖动距离
      	
      	
      	[HideInInspector]
      	
      	publicVector3 FiexdMovePosiNorm; //固定8个角度移动的距离
      	
      	
      	[HideInInspector]
      	
      	publicVector3 MovePosiNorm;  //标准化移动的距离
      	
      	[SerializeField]
      	
      	privatefloat ActiveMoveDistance = 1;              //激活移动的最低距离
      	
      	voidAwake()
      		
      	{
      		
      		EventTriggerListener.Get(gameObject).onDrag = OnDrag;
      		
      		EventTriggerListener.Get(gameObject).onDragOut = OnDragOut;
      		
      		
      		EventTriggerListener.Get(gameObject).onDown = OnMoveStart;
      		
      	}
      	
      	
      	
      	// Use this for initialization
      	
      	voidStart () {
      		
      		Origin = transform.localPosition;//设置原点
      		
      		mTrans = transform;
      		
      	}
      	
      	
      	
      	// Update is called once per frame
      	
      	voidUpdate()
      		
      	{
      		
      		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;
      		
      	}
      	
      	voidMiouseDown()
      		
      	{
      		
      		if((Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved))
      			
      		{
      			
      		}
      		
      		else
      			
      			mTrans.localPosition = Origin;
      		
      	}
      	
      	Vector3 result;
      	
      	privateVector3 _checkPosition(Vector3 movePos, Vector3 _offsetPos)
      		
      	{
      		
      		result = movePos + _offsetPos;
      		
      		returnresult;
      		
      	}
      	
      	
      	voidOnDrag(GameObject go, Vector2 delta)
      		
      	{
      		
      		if(!_drag)
      			
      		{
      			
      			_drag = true;
      			
      		}
      		
      		_deltaPos = delta;
      		
      		
      		mTrans.localPosition +=new Vector3(_deltaPos.x, _deltaPos.y, 0);
      		
      	}
      	
      	
      	voidOnDragOut(GameObject go)
      		
      	{
      		
      		_drag =false;
      		
      		mTrans.localPosition = Origin;
      		
      		if(PlayerMoveControl.moveEnd != null) PlayerMoveControl.moveEnd();
      		
      	}
      	
      	
      	voidOnMoveStart(GameObject go)
      		
      	{
      		
      		if(PlayerMoveControl.moveStart != null) PlayerMoveControl.moveStart();
      		
      	}
      	
      }


       

    7.  
       

      PlayerMoveControl.cs

    8. using UnityEngine;
      
      using System.Collections;
      
      
      public class PlayerMoveControl : MonoBehaviour {
      	
      	privateTransform _mTransform;
      	
      	publicJoystackCc _mJoystackCc;
      	
      	
      	publicfloat moveSpeed = 50;
      	
      	
      	publicdelegate void MoveDelegate();
      	
      	publicstatic MoveDelegate moveEnd;
      	
      	publicstatic MoveDelegate moveStart;
      	
      	publicstatic PlayerMoveControl Instance;
      	
      	// Use this for initialization
      	
      	voidAwake()
      		
      	{
      		
      		Instance =this;
      		
      		_mTransform = transform;
      		
      		
      		moveEnd = OnMoveEnd;
      		
      		moveStart = OnMoveStart;
      		
      	}
      	
      	voidStart () {
      		
      		
      	}
      	
      	voidOnMoveEnd()
      		
      	{
      		
      		_turnBase =false;
      		
      	}
      	
      	
      	voidOnMoveStart()
      		
      	{
      		
      		_turnBase =true;
      		
      	}
      	
      	
      	
      	// Update is called once per frame
      	
      	privatefloat angle;
      	
      	privatebool _turnBase = false;
      	
      	voidUpdate()
      		
      	{
      		
      		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);
      			
      		}
      		
      	}
      	
      }


       

       
       

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

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

      下面是测试效果:

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

  • 相关阅读:
    Vulkan Tutorial 06 逻辑设备与队列
    Vulkan Tutorial 05 物理设备与队列簇
    过滤器Filter(2)
    Filter过滤器(1)
    Java-Web监听器
    Filter案例
    <context:annotation-config/>
    @Autowired 和 @Resource
    Hibernate各种主键生成策略与配置详解
    eclipse新建workspace使用之前workspace的个性配置
  • 原文地址:https://www.cnblogs.com/nafio/p/9137498.html
Copyright © 2011-2022 走看看