ETC Joystick 继承自 ETCBase类, 并且要实现 PointerEnterHandler  IDragHandler, IBeginDragHander IPointerDownHandler IPointerUpHandler,等接口。

ETCJoystick 类

/***********************************************EasyTouch ControlsCopyright © 2016 The Hedgehog Teamhttp://www.thehedgehogteam.com/Forum/The.Hedgehog.Team@gmail.com**********************************************/
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using UnityEngine.EventSystems;[System.Serializable]
public class ETCJoystick : ETCBase,IPointerEnterHandler,IDragHandler, IBeginDragHandler, IPointerDownHandler, IPointerUpHandler {//事件定义#region Unity Events[System.Serializable] public class OnMoveStartHandler : UnityEvent{}  //   开始移动的时候,[System.Serializable] public class OnMoveSpeedHandler : UnityEvent<Vector2> { } //滑动 速度,  泛型 带 Vector2 参数[System.Serializable] public class OnMoveHandler : UnityEvent<Vector2> { }// 在移动时候, 带Vector2 参数[System.Serializable] public class OnMoveEndHandler : UnityEvent{ }// 移动结束的时候, 无参数[System.Serializable] public class OnTouchStartHandler : UnityEvent{} // 触摸开始的时候  无参数[System.Serializable] public class OnTouchUpHandler : UnityEvent{ }// 触摸 抬起(结束) 的时候, 无参数[System.Serializable] public class OnDownUpHandler : UnityEvent{ } // 按住 上的时候 , 无参数[System.Serializable] public class OnDownDownHandler : UnityEvent{ } //按住下的时候[System.Serializable] public class OnDownLeftHandler : UnityEvent{ }//按住左的时候[System.Serializable] public class OnDownRightHandler : UnityEvent{ }//按住右的时候 [System.Serializable] public class OnPressUpHandler : UnityEvent{ }  //按上的时候[System.Serializable] public class OnPressDownHandler : UnityEvent{ } //按下的时候[System.Serializable] public class OnPressLeftHandler : UnityEvent{ }//安左的时候[System.Serializable] public class OnPressRightHandler : UnityEvent{ }//按右的时候。//定义 声明  委托 [SerializeField] public OnMoveStartHandler onMoveStart; //移动开始的  委托[SerializeField] public OnMoveHandler onMove;   // 移动的时候 的 委托[SerializeField] public OnMoveSpeedHandler onMoveSpeed; //在移动  速度时 的委托[SerializeField] public OnMoveEndHandler onMoveEnd; //在移动 结束 的委托[SerializeField] public OnTouchStartHandler onTouchStart;// 触摸开始的 委托 [SerializeField] public OnTouchUpHandler onTouchUp;//触摸 抬起 的 委托[SerializeField] public OnDownUpHandler OnDownUp; // 按住上的 委托[SerializeField] public OnDownDownHandler OnDownDown;//按住下的 委托[SerializeField] public OnDownLeftHandler OnDownLeft; //以下类同。。。。[SerializeField] public OnDownRightHandler OnDownRight;[SerializeField] public OnDownUpHandler OnPressUp;[SerializeField] public OnDownDownHandler OnPressDown;[SerializeField] public OnDownLeftHandler OnPressLeft;[SerializeField] public OnDownRightHandler OnPressRight;#endregion//列举#region Enumerationpublic enum JoystickArea { UserDefined,FullScreen, Left,Right,Top, Bottom, TopLeft, TopRight, BottomLeft, BottomRight}; //移动摇杆的  区域面积。 自定义,全屏,上下左右中的组合。public enum JoystickType {Dynamic, Static};// 移动摇杆 类型, 动态 静态, 区别 动态的时候,不固定它的位置,在 触摸屏幕的时候,就显示 摇杆,静态就是固定好在一个位置public enum RadiusBase {Width, Height, UserDefined}; //半径基于 width,height   这个 属性就是 决定 移动摇杆的Thumb的 移动角度#endregion#region Members#region Public memberspublic JoystickType joystickType;//移动摇杆类型, 默认 静态public bool allowJoystickOverTouchPad; //允许  虚拟摇杆 TouchPad, 在FPS中,TouchPad 用来控制 镜头旋转,public RadiusBase radiusBase; //半径基于 默认 基于widthpublic float radiusBaseValue; //半径基于值public ETCAxis axisX; //  ETCAxis x轴public ETCAxis axisY;//  ETCAxis y轴public RectTransform thumb; //中间的 圆  滑杆拇指public JoystickArea joystickArea;//移动摇杆 区域public RectTransform userArea; // 用户 区域public bool isTurnAndMove = false;//允许 旋转与移动public float tmSpeed = 10; //tm速度public float tmAdditionnalRotation = 0;//tm附加旋转public AnimationCurve tmMoveCurve;//tm移动 动画 曲线, 调整 移动 和 旋转public bool tmLockInJump = false;// tm 锁跳private Vector3 tmLastMove;//tm 最后的移动速度 #endregion#region Private membersprivate Vector2 thumbPosition;//  中间 拇指位置private bool isDynamicActif; //private Vector2 tmpAxis;//Tmp轴private Vector2 OldTmpAxis;//老 tmp轴 private bool isOnTouch;// 是否 触摸#endregion#region Joystick behavior option[SerializeField]private bool isNoReturnThumb;//是否 不返回 拇指, 勾选后,中间thumb 在拖动后 不会去public bool IsNoReturnThumb {get {return isNoReturnThumb;}set {isNoReturnThumb = value;}}   private Vector2 noReturnPosition; // 不返回的 位置,  根据这个位置与原来的位置的距离,去 计算 移动的大小private Vector2 noReturnOffset;// 不返回的Thumb的 偏移[SerializeField]private bool isNoOffsetThumb;//是否 无偏移public bool IsNoOffsetThumb {get {return isNoOffsetThumb;}set {isNoOffsetThumb = value;}}#endregion#region Inspector#endregion#endregion#region Constructor //构造函数  默认值public ETCJoystick(){joystickType = JoystickType.Static;allowJoystickOverTouchPad = false;radiusBase = RadiusBase.Width;axisX = new ETCAxis("Horizontal");axisY = new ETCAxis("Vertical");_visible = true;_activated = true;joystickArea = JoystickArea.FullScreen;isDynamicActif = false;isOnDrag = false;isOnTouch = false;axisX.unityAxis = "Horizontal";axisY.unityAxis = "Vertical";enableKeySimulation = true;isNoReturnThumb = false;showPSInspector = false;showAxesInspector = false;showEventInspector = false;showSpriteInspector = false;}#endregion//Monobehaviours  回调   赋值Transform RectTransform 在ETCInput,注册控制, 设置 可见, 判断 移动摇杆类型  设置锚点#region Monobehaviours Callbackprotected override void Awake (){base.Awake ();if (joystickType == JoystickType.Dynamic){this.rectTransform().anchorMin = new Vector2(0.5f,0.5f);this.rectTransform().anchorMax = new Vector2(0.5f,0.5f);this.rectTransform().SetAsLastSibling();visible = false;}if (allowSimulationStandalone && enableKeySimulation && !Application.isEditor && joystickType!=JoystickType.Dynamic){SetVisible(visibleOnStandalone);}}public override void Start(){//初始化 轴axisX.InitAxis();axisY.InitAxis();if (enableCamera){//初始化 摄像机跟随InitCameraLookAt();}//初始化 轴位置tmpAxis = Vector2.zero;OldTmpAxis = Vector2.zero;// 赋予拇指 初始 位置noReturnPosition = thumb.position;pointId = -1;//动态 就隐藏,if (joystickType == JoystickType.Dynamic){visible = false;}//找到 摄像机 连接 摄像机, 位置信息 base.Start();// Init Camera position  初始化 摄像机 位置 if (enableCamera && cameraMode == CameraMode.SmoothFollow){if (cameraTransform && cameraLookAt){cameraTransform.position = cameraLookAt.TransformPoint( new Vector3(0,followHeight,-followDistance));cameraTransform.LookAt( cameraLookAt);}}if (enableCamera && cameraMode == CameraMode.Follow){if (cameraTransform && cameraLookAt){cameraTransform.position = cameraLookAt.position + followOffset;cameraTransform.LookAt( cameraLookAt.position);}}}public override void Update (){base.Update ();#region dynamic joystickif (joystickType == JoystickType.Dynamic && !_visible && _activated){Vector2 localPosition = Vector2.zero;Vector2 screenPosition = Vector2.zero;//如果 触碰到 移动摇杆的区域if (isTouchOverJoystickArea(ref localPosition, ref screenPosition)){//获取第一个 选到的 UI 元素GameObject overGO = GetFirstUIElement( screenPosition);//如果是  覆盖到TouchPad  并且有挂载 ETCTouchPad,并且 在 区域上if (overGO == null || (allowJoystickOverTouchPad && overGO.GetComponent<ETCTouchPad>()) || (overGO != null && overGO.GetComponent<ETCArea>() ) ) {//显示 移动摇杆,更新 位置cachedRectTransform.anchoredPosition = localPosition;visible = true;}}}if (joystickType == JoystickType.Dynamic && _visible){if (GetTouchCount()==0){visible = false;}}#endregion}public override void LateUpdate (){//初始化  摄像机看向 的方向if (enableCamera && !cameraLookAt ){InitCameraLookAt();}//找到摄像机,判断类型 设置跟随,更新 控制 状态base.LateUpdate ();}//初始化  摄像机看向 的方向private void InitCameraLookAt(){if (cameraTargetMode == CameraTargetMode.FromDirectActionAxisX){cameraLookAt = axisX.directTransform;}else if (cameraTargetMode == CameraTargetMode.FromDirectActionAxisY){cameraLookAt = axisY.directTransform;if (isTurnAndMove){cameraLookAt = axisX.directTransform;}}else if (cameraTargetMode == CameraTargetMode.LinkOnTag){GameObject tmpobj = GameObject.FindGameObjectWithTag(camTargetTag);if (tmpobj){cameraLookAt = tmpobj.transform;}}if (cameraLookAt)cameraLookAtCC = cameraLookAt.GetComponent<CharacterController>();}//重写  更新 控制 状态protected override void UpdateControlState (){//如果可见, 就更新虚拟摇杆信息, 位置,移动....if (_visible){UpdateJoystick();}else{if (joystickType == JoystickType.Dynamic){OnUp( false);}}}#endregion#region UI Callbackpublic void OnPointerEnter(PointerEventData eventData){if (joystickType == JoystickType.Dynamic && !isDynamicActif && _activated &&  pointId==-1){eventData.pointerDrag = gameObject;eventData.pointerPress = gameObject;isDynamicActif = true;pointId = eventData.pointerId;}if (joystickType == JoystickType.Dynamic &&  !eventData.eligibleForClick){OnPointerUp( eventData );}}public void OnPointerDown(PointerEventData eventData){onTouchStart.Invoke();pointId = eventData.pointerId;if (isNoOffsetThumb){OnDrag( eventData);}}public void OnBeginDrag(PointerEventData eventData){}public void OnDrag(PointerEventData eventData){if (pointId == eventData.pointerId){isOnDrag = true;isOnTouch = true;float radius =  GetRadius();if (!isNoReturnThumb){thumbPosition =  (eventData.position - eventData.pressPosition);// / (cachedRootCanvas.rectTransform().localScale.x  ) ;}else{thumbPosition =((eventData.position - noReturnPosition) /cachedRootCanvas.rectTransform().localScale.x) + noReturnOffset;}if (isNoOffsetThumb){thumbPosition =  (eventData.position - (Vector2)cachedRectTransform.position) / cachedRootCanvas.rectTransform().localScale.x;}thumbPosition.x = Mathf.FloorToInt( thumbPosition.x);thumbPosition.y = Mathf.FloorToInt( thumbPosition.y);if (!axisX.enable){thumbPosition.x=0;}if (!axisY.enable){thumbPosition.y=0;}if (thumbPosition.magnitude > radius){if (!isNoReturnThumb){thumbPosition = thumbPosition.normalized * radius ;}else{thumbPosition = thumbPosition.normalized * radius;}}thumb.anchoredPosition =  thumbPosition; }}public void OnPointerUp (PointerEventData eventData){if (pointId == eventData.pointerId){OnUp();}}private void OnUp(bool real=true){isOnDrag = false;isOnTouch = false;if (isNoReturnThumb){noReturnPosition = thumb.position;noReturnOffset = thumbPosition;}if (!isNoReturnThumb){thumbPosition =  Vector2.zero;thumb.anchoredPosition = Vector2.zero;axisX.axisState = ETCAxis.AxisState.None;axisY.axisState = ETCAxis.AxisState.None;}if (!axisX.isEnertia && !axisY.isEnertia){axisX.ResetAxis();axisY.ResetAxis();tmpAxis = Vector2.zero;OldTmpAxis = Vector2.zero;if (real){onMoveEnd.Invoke();}}if (joystickType == JoystickType.Dynamic){visible = false;isDynamicActif = false;}pointId=-1;if (real){onTouchUp.Invoke();}}#endregion#region Joystick Updateprotected override void DoActionBeforeEndOfFrame (){axisX.DoGravity();axisY.DoGravity();}//更新  虚拟摇杆 信息private void UpdateJoystick(){#region Unity axes  //如果允许 按键模拟,并且 没有在触摸, 可用,可见  更新位置信息if (enableKeySimulation && !isOnTouch && _activated && _visible ){float x = Input.GetAxis(axisX.unityAxis);float y= Input.GetAxis(axisY.unityAxis);if (!isNoReturnThumb){thumb.localPosition = Vector2.zero;}isOnDrag = false;//如果水平距离 大于0 ,则判断为 Dragif (x!=0){isOnDrag = true;//更新 拇指的  局部信息, 获取半径再*xthumb.localPosition = new Vector2(GetRadius()*x, thumb.localPosition.y);}//如果垂直距离 大于0 ,则判断为 Dragif (y!=0){isOnDrag = true;//更新 拇指的  局部信息, 获取半径再*ythumb.localPosition = new Vector2(thumb.localPosition.x,GetRadius()*y );}//保存 局部位置 thumbPosition = thumb.localPosition;}#endregion// Computejoystick value     计算    虚拟 摇杆 值//存上一针的 值OldTmpAxis.x = axisX.axisValue; OldTmpAxis.y = axisY.axisValue;//Tmp轴 计算为 拇指的位置除以半径tmpAxis = thumbPosition / GetRadius();//更新  轴axisX.UpdateAxis( tmpAxis.x,isOnDrag, ETCBase.ControlType.Joystick,true);axisY.UpdateAxis( tmpAxis.y,isOnDrag, ETCBase.ControlType.Joystick,true);//移动 事件  #region Move event//如果x  y  值 不为0 并且上次 轴 不为0if ((axisX.axisValue!=0 ||  axisY.axisValue!=0 ) && OldTmpAxis == Vector2.zero){//调用  移动开始的 事件onMoveStart.Invoke();}if (axisX.axisValue!=0 ||  axisY.axisValue!=0 ){//如果不允许 移动和旋转if (!isTurnAndMove){// 如果 按下,并且状态是左或者是右if (axisX.actionOn == ETCAxis.ActionOn.Down && (axisX.axisState == ETCAxis.AxisState.DownLeft || axisX.axisState == ETCAxis.AxisState.DownRight)){//做 方向 运动axisX.DoDirectAction();}//x轴 按下else if (axisX.actionOn == ETCAxis.ActionOn.Press){axisX.DoDirectAction();}// Y axisif( axisY.actionOn == ETCAxis.ActionOn.Down && (axisY.axisState == ETCAxis.AxisState.DownUp || axisY.axisState == ETCAxis.AxisState.DownDown)){axisY.DoDirectAction();}//Y 轴 按下else if (axisY.actionOn == ETCAxis.ActionOn.Press){axisY.DoDirectAction();}}else{//否则  旋转和移动DoTurnAndMove();}//调用 在移动的时候 的 事件onMove.Invoke( new Vector2(axisX.axisValue,axisY.axisValue));//调用移动 速度的 事件onMoveSpeed.Invoke( new Vector2(axisX.axisSpeedValue,axisY.axisSpeedValue));}else if (axisX.axisValue==0 &&  axisY.axisValue==0  && OldTmpAxis!=Vector2.zero) {//调用 移动结束  的事件onMoveEnd.Invoke();}        if (!isTurnAndMove){if (axisX.axisValue==0 &&  axisX.directCharacterController ){if (!axisX.directCharacterController.isGrounded && axisX.isLockinJump)axisX.DoDirectAction();} if (axisY.axisValue==0 &&  axisY.directCharacterController ){if (!axisY.directCharacterController.isGrounded && axisY.isLockinJump)axisY.DoDirectAction();}}else{ //! tmLockif ((axisX.axisValue==0 && axisY.axisValue==0) &&  axisX.directCharacterController ){if (!axisX.directCharacterController.isGrounded ){if (!tmLockInJump){DoTurnAndMove();}else{tmLastMove = Vector3.zero;}}}}#endregion#region Down & press eventfloat coef =1;if (axisX.invertedAxis) coef = -1;if (Mathf.Abs(OldTmpAxis.x)< axisX.axisThreshold && Mathf.Abs(axisX.axisValue)>=axisX.axisThreshold){if (axisX.axisValue*coef >0){axisX.axisState = ETCAxis.AxisState.DownRight;OnDownRight.Invoke();}else if (axisX.axisValue*coef<0){axisX.axisState = ETCAxis.AxisState.DownLeft;OnDownLeft.Invoke();}else{axisX.axisState = ETCAxis.AxisState.None;}}else if (axisX.axisState!= ETCAxis.AxisState.None) {if (axisX.axisValue*coef>0){axisX.axisState = ETCAxis.AxisState.PressRight;OnPressRight.Invoke();}else if (axisX.axisValue*coef<0){axisX.axisState = ETCAxis.AxisState.PressLeft;OnPressLeft.Invoke();}else{axisX.axisState = ETCAxis.AxisState.None;}}coef =1;if (axisY.invertedAxis) coef = -1;if (Mathf.Abs(OldTmpAxis.y)< axisY.axisThreshold && Mathf.Abs(axisY.axisValue)>=axisY.axisThreshold  ){if (axisY.axisValue*coef>0){axisY.axisState = ETCAxis.AxisState.DownUp;OnDownUp.Invoke();}else if (axisY.axisValue*coef<0){axisY.axisState = ETCAxis.AxisState.DownDown;OnDownDown.Invoke();}else{axisY.axisState = ETCAxis.AxisState.None;}}else if (axisY.axisState!= ETCAxis.AxisState.None) {if (axisY.axisValue*coef>0){axisY.axisState = ETCAxis.AxisState.PressUp;OnPressUp.Invoke();}else if (axisY.axisValue*coef<0){axisY.axisState = ETCAxis.AxisState.PressDown;OnPressDown.Invoke();}else{axisY.axisState = ETCAxis.AxisState.None;}}#endregion}       #endregion//是否 触摸 覆盖了  虚拟摇杆区域#region Touch managerprivate bool isTouchOverJoystickArea(ref Vector2 localPosition, ref Vector2 screenPosition){bool touchOverArea = false;bool doTest = false;screenPosition = Vector2.zero;int count = GetTouchCount();int i=0;//获取 触摸 计数, 遍历 while (i<count && !touchOverArea){#if ((UNITY_ANDROID || UNITY_IOS || UNITY_WINRT || UNITY_BLACKBERRY) && !UNITY_EDITOR) if (Input.GetTouch(i).phase == TouchPhase.Began){screenPosition = Input.GetTouch(i).position;doTest = true;}#elseif (Input.GetMouseButtonDown(0)){screenPosition = Input.mousePosition;doTest = true;}#endif//如果 屏幕 点 覆盖 了 区域 ,就判断 为 trueif (doTest && isScreenPointOverArea(screenPosition, ref localPosition) ){touchOverArea = true;}i++;}return touchOverArea;}//是否 屏幕的点 覆盖了 区域private bool isScreenPointOverArea(Vector2 screenPosition, ref Vector2 localPosition){bool returnValue = false;if (joystickArea != JoystickArea.UserDefined){//将 屏幕坐标 转换为  UI 坐标if (RectTransformUtility.ScreenPointToLocalPointInRectangle( cachedRootCanvas.rectTransform(),screenPosition,null,out localPosition)){switch (joystickArea){case JoystickArea.Left: //对比 坐标 判断 是否 覆盖  左边  小于0 为覆盖if (localPosition.x<0){returnValue=true;}break;case JoystickArea.Right:// 右边 大于0 为覆盖if (localPosition.x>0){returnValue = true;}break;case JoystickArea.FullScreen: //全屏 覆盖truereturnValue = true;break;case JoystickArea.TopLeft:if (localPosition.y>0 && localPosition.x<0){ // 左上, Y>0 X<0returnValue = true;}break;case JoystickArea.Top:if (localPosition.y>0){ //上Y>0returnValue = true;}break;case JoystickArea.TopRight: //右上  y>0 X>0if (localPosition.y>0 && localPosition.x>0){returnValue=true;}break;case JoystickArea.BottomLeft: //左下 Y<0  X<0if (localPosition.y<0 && localPosition.x<0){returnValue = true;}break;case JoystickArea.Bottom:  //下 y<0if (localPosition.y<0){returnValue = true;}break;case JoystickArea.BottomRight: //右下 y<0  x>0 if (localPosition.y<0 && localPosition.x>0){returnValue = true;}break;}}}else{           // 从指定摄像机中观看该矩形变换是否包含屏幕点?if (RectTransformUtility.RectangleContainsScreenPoint( userArea, screenPosition, cachedRootCanvas.worldCamera )){//再将屏幕位置 转换为UI 坐标RectTransformUtility.ScreenPointToLocalPointInRectangle( cachedRootCanvas.rectTransform(),screenPosition,cachedRootCanvas.worldCamera,out localPosition);returnValue = true;}}return returnValue;}//获取 触摸的计数private int GetTouchCount(){#if ((UNITY_ANDROID || UNITY_IOS || UNITY_WINRT || UNITY_BLACKBERRY) && !UNITY_EDITOR) return Input.touchCount;#elseif (Input.GetMouseButton(0) || Input.GetMouseButtonUp(0)){//左键或者右键返回1return 1;}else{return 0;}#endif}#endregion#region Other private method//半径计算 方式 获取半径public float GetRadius(){float radius =0;switch (radiusBase){case RadiusBase.Width:radius = cachedRectTransform.sizeDelta.x * 0.5f;break;case RadiusBase.Height:radius = cachedRectTransform.sizeDelta.y * 0.5f;break;case RadiusBase.UserDefined:radius = radiusBaseValue;break;}return radius;}//设置   是否 启用protected override void SetActivated (){GetComponent<CanvasGroup>().blocksRaycasts = _activated;if (!_activated){OnUp(false);}}//设置  是否 可见  默认可见protected override void SetVisible (bool visible=true){bool localVisible = _visible;if (!visible){localVisible = visible;}GetComponent<Image>().enabled = localVisible;thumb.GetComponent<Image>().enabled = localVisible;GetComponent<CanvasGroup>().blocksRaycasts = _activated;}#endregion//移动 和 旋转 的 计算   方法private void DoTurnAndMove(){//通过反正切  获取角度 返回是弧度, 再乘以57.2957float angle =Mathf.Atan2( axisX.axisValue,axisY.axisValue ) * Mathf.Rad2Deg;// 从 tm移动曲线 中取得 二维向量的长度  再 乘以tm速度float speed = tmMoveCurve.Evaluate( new Vector2(axisX.axisValue,axisY.axisValue).magnitude) * tmSpeed;if (axisX.directTransform != null){axisX.directTransform.rotation = Quaternion.Euler(new Vector3(0,  angle + tmAdditionnalRotation,0));if (axisX.directCharacterController != null){if (axisX.directCharacterController.isGrounded || !tmLockInJump){// 世界的 CC向前的方向*speed   得到move 向量Vector3 move = axisX.directCharacterController.transform.TransformDirection(Vector3.forward) *  speed;//移动 axisX.directCharacterController.Move(move* Time.deltaTime);    }else{//  如果锁跳, 就用tmLastMove*Time.delTimeaxisX.directCharacterController.Move(tmLastMove* Time.deltaTime);}}else{// 局部的  向前 位移axisX.directTransform.Translate(Vector3.forward *  speed * Time.deltaTime,Space.Self);}}}// 初始 化  曲线,public void InitCurve(){axisX.InitDeadCurve();axisY.InitDeadCurve();InitTurnMoveCurve();}//初始 化 旋转 移动曲线public void InitTurnMoveCurve(){tmMoveCurve = AnimationCurve.EaseInOut(0,0,1,1);tmMoveCurve.postWrapMode = WrapMode.PingPong;tmMoveCurve.preWrapMode = WrapMode.PingPong;}
}

EasyTouch 学习之——ETCJoystick 虚拟摇杆相关推荐

  1. EasyTouch中虚拟摇杆的使用EasyJoystick

    unity3d自带的虚拟摇杆显然没有EasyTouch好用 首先下载这个插件 http://pan.baidu.com/s/1hqJAbTa 下载完成后.导入到unity,可以看看里面的案例 找到这个 ...

  2. cocos2dx游戏开发学习——虚拟摇杆(8方向)讲解

    写这篇博客的目的主要是记录一下 虚拟摇杆的实现过程.虚拟摇杆一般分文四方向和八方向,也主要根据项目需求来决定.直接进入主题吧. 先上效果图: 方向的思路分析 看图,说先我们可以将8个方向在坐标系中画出 ...

  3. Unity3D学习日记(二)使用UGUI制作虚拟摇杆控制摄像机

    前天撸了一个简单的UGUI虚拟摇杆,今天我就利用前天做的虚拟摇杆做了一个简单的摄像机控制器,主要看看UGUI虚拟摇杆是否可以完美的控制移动和旋转.(PS:主要是为接下来的项目做技术测试),手游版的CF ...

  4. EasyTouch5 之 Joystick 虚拟摇杆

    一.EasyTouch 资源结构 EasyTouchBundle [插件的根目录] |-EasyTouch [插件核心,核心功能的实现,偏向底层] |-EasyTouchControls [插件控制器 ...

  5. 【Unity3D插件】EasyTouch插件分享《手机摇杆插件》

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 QQ群:1040082875 一.前言 这篇文章参考了很多博客,然后加入了一些自己的理解,从了解到深入都有 ...

  6. Unity插件EasyTouch学习笔记

    前言 EasyTouch是一款非常好用识别手机操作的插件,比如各种手势.摇杆等等,熟悉之后可以节约大量造轮子的时间. 我是在2019版本的Unity上进行测试的. 4.x用法 注意事项: 代码需要引用 ...

  7. Unity3d项目入门之虚拟摇杆

    Unity本身不提供摇杆的组件,开发者可以使用牛逼的EasyTouch插件或者应用NGUI实现相关的需求,下面本文通过Unity自身的UGUI属性,实现虚拟摇杆的功能. 主参考 <Unity:使 ...

  8. Easy Touch虚拟摇杆的用法

    安装好Easy Touch插件之后直接在Hierarchy面板直接创建. 创建完成你就会看见一个EasyTouchControlsCanvas 这样就代表成功了 接下来就是如何用脚本控制虚拟摇杆如何控 ...

  9. 使用EasyTouch一分钟简单制作摇杆

    使用EasyTouch一分钟简单制作摇杆<一> 1.效果: 2.过程 (1)..首先把EasyTouch这个插件导入到新建的工程里,我用的是Easy Touch5.0.12. (2).创建 ...

最新文章

  1. 让你的数据离CPU更近一些
  2. java安装_快速提示:Java中的ISO 8601持续时间
  3. CKPT进程工作机制
  4. Ionic系列——环境配置和项目搭建
  5. [react] React怎样引入svg的文件?
  6. java implements interface_java接口(interface)与现实(implements)
  7. 代码实现:给一个不多于5位的正整数,要求:一、求它是几位数,二、逆序打印出各位数字。...
  8. selenium安装包_??《手把手教你》系列基础篇之1-python+ selenium自动化测试-环境搭建(详细)...
  9. Atitti.软件的一些理论补充 Atitti.软件的原理原则定律法则补充 目录 1.1. 分布式领域CAP理论, 1 1.2. 关系数据库的ACID模型拥有 高一致性 + 可用性 很难进行分区:
  10. [数据仓库]基础理论笔记
  11. java可以编辑 cad吗_MiniCAD 简单的java画图,能画圆、直线、矩形,还能移动,修改颜色等 Develop 238万源代码下载- www.pudn.com...
  12. iperf 服务端发送数据_iperf网络测试工具
  13. Latex中使用实心圆点列表
  14. java jimi_Java开源工具Jimi处理图片大小及格式转换
  15. java之简易生成彩色二维码实践
  16. Gateway网关简介及使用
  17. MATLAB的使用(二) help命令全解
  18. Python中Tkinter模块的Canvas控件绘制jpg图片到指定区域
  19. Linux 时间、时区设置
  20. python解锁电脑屏幕_怎样解除电脑屏幕锁定_教你解除电脑屏幕锁定的方法-系统城...

热门文章

  1. X线DR医学图像 --- DR医用滤线栅及摩尔纹详解 (四) 摩尔纹的频点计算
  2. RaphaelJS一些细节的学习
  3. 高德地图点击获取经纬度并标记
  4. 计算机播放声音时进行模数转换,音频的基础知识.ppt
  5. 软件魔方制作系统启动盘并安装win10系统
  6. 自动控制系统和计算机控制系统的关系,自动控制系统.ppt
  7. 双十一数码产品排名,2022年双十一数码产品推荐
  8. 软件工程与计算机科学的关系及区别
  9. 微信小程序报错:navigateTo:fail can not navigateTo a tabbar page的解决方法
  10. [学习笔记]UserInterface/Layouts