Unity如何实现简单摇杆的制作

利用UGUI制作一个简单摇杆效果图:

1、首先建立两个Image,然后将其中一个为父物体,另一个为子物体,并且调整好大小:

ps:将子物体的锚点设置为居中

2、在父物体上写个JoyStick.cs脚本:

using UnityEngine;
using UnityEngine.EventSystems;
using System.Collections;
public class JoyStick : MonoBehaviour, IDragHandler, IEndDragHandler, IBeginDragHandler
{
  public static float h, v;  //传出hv
  public float maxDis;    //最大距离

  private RectTransform childRectTrans;
  private Coroutine coroutine = null;

  void Start()
  {
      childRectTrans = transform.GetChild(0) as RectTransform;
  }
  public void OnBeginDrag(PointerEventData eventData)
  {
      if (coroutine != null)
      {
          StopCoroutine(coroutine);
          coroutine = null;
      }
  }
  public void OnDrag(PointerEventData eventData)
  {
      Vector3 outPos;
      if (RectTransformUtility.ScreenPointToWorldPointInRectangle(this.transform as RectTransform, eventData.position, eventData.pressEventCamera, out outPos))
      {
          childRectTrans.position = outPos;

          //限制拖拽距离
          childRectTrans.anchoredPosition = Vector2.ClampMagnitude(childRectTrans.anchoredPosition, maxDis);

          //或者利用子物体和父物体的距离判断是否超过最大距离,当距离大于等于最大的距离时候,
          //计算父物体和子物体的向量,然后利用向量*最大距离来限制拖拽距离
          //if (Vector2.Distance(childRectTrans.position, this.transform.position) > maxDis)
          //{
          //    Vector2 dir = (childRectTrans.position - this.transform.position).normalized;
          //    childRectTrans.anchoredPosition = dir * maxDis;
          //}
          GetHV();
      }
  }

  public void OnEndDrag(PointerEventData eventData)
  {
      //当结束拖动,要将物体归0,为了加一点缓冲效果
      //(1)可以使用dotween等补间动画插件,会减少很多
      //rectTransform.DoAnchoredPos(Vector2.zero,0.5f);
      //(2)或者使用携程 这里使用携程
      if (coroutine == null)
          coroutine = StartCoroutine(IEToZeroPos(childRectTrans, 0.1f));
  }
  private void GetHV()
  {
      h = childRectTrans.anchoredPosition.x / maxDis;
      v = childRectTrans.anchoredPosition.y / maxDis;
  }
  private IEnumerator IEToZeroPos(RectTransform rectTransform, float duartion)
  {
      if (duartion == 0f)
      {
          yield return null;
          rectTransform.anchoredPosition = Vector2.zero;
          GetHV();
          coroutine = null;
          yield break;
      }
      Vector2 currentpos = rectTransform.anchoredPosition;
      float offx = currentpos.x / duartion;
      float offy = currentpos.y / duartion;
      while (rectTransform.anchoredPosition != Vector2.zero)
      {
          yield return null;
          rectTransform.anchoredPosition = new Vector2(rectTransform.anchoredPosition.x - offx * Time.deltaTime, rectTransform.anchoredPosition.y - offy * Time.deltaTime);
          GetHV();
          if (rectTransform.anchoredPosition.sqrMagnitude < 8f)
          {
              rectTransform.anchoredPosition = Vector2.zero;
              GetHV();
              coroutine = null;
              break;
          }
      }
  }
}

另外附上Cube上面的脚本

private void Update()
  {
      Vector3 dir = new Vector3(JoyStick.h, 0, JoyStick.v);
      if (dir.sqrMagnitude > 0)
      {
          transform.Translate(dir * 3f * Time.deltaTime,Space.World);
          Quaternion targatRotate = Quaternion.LookRotation(dir, Vector3.up);
          transform.rotation = Quaternion.Slerp(transform.rotation, targatRotate, 3 * Time.deltaTime);
      }
  }

加个使用doTween的吧

using UnityEngine;
using UnityEngine.EventSystems;
using System.Collections; using DG.Tweening;
public class JoyStick : MonoBehaviour, IDragHandler, IEndDragHandler, IBeginDragHandler
{
  public static float h, v;  //传出hv
  public float maxDis;    //最大距离

  private RectTransform childRectTrans;
  private Coroutine coroutine = null;

  void Start()
  {
      childRectTrans = transform.GetChild(0) as RectTransform;
  }
  public void OnBeginDrag(PointerEventData eventData)
  {
      if (coroutine != null)
      {
          StopCoroutine(coroutine);
          coroutine = null;
      }
  }
  public void OnDrag(PointerEventData eventData)
  {
      Vector3 outPos;
      if (RectTransformUtility.ScreenPointToWorldPointInRectangle(this.transform as RectTransform, eventData.position, eventData.pressEventCamera, out outPos))
      {
          childRectTrans.position = outPos;

          //限制拖拽距离
          childRectTrans.anchoredPosition = Vector2.ClampMagnitude(childRectTrans.anchoredPosition, maxDis);

          //或者利用子物体和父物体的距离判断是否超过最大距离,当距离大于等于最大的距离时候,
          //计算父物体和子物体的向量,然后利用向量*最大距离来限制拖拽距离
          //if (Vector2.Distance(childRectTrans.position, this.transform.position) > maxDis)
          //{
          //    Vector2 dir = (childRectTrans.position - this.transform.position).normalized;
          //    childRectTrans.anchoredPosition = dir * maxDis;
          //}
          GetHV();
      }
  }

  public void OnEndDrag(PointerEventData eventData)
  {
      //当结束拖动,要将物体归0,为了加一点缓冲效果
      //(1)可以使用dotween等补间动画插件,会减少很多
      rectTransform.DoAnchoredPos(Vector2.zero,0.5f).OnUpdate(GetHV);     
  }
  private void GetHV()
  {
      h = childRectTrans.anchoredPosition.x / maxDis;
      v = childRectTrans.anchoredPosition.y / maxDis;
  }

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程教程

 一、对象的定义和创建定义类对象的方法为:类名 对象名;类是引用类型的,当定义了对象之后,系统会为数据引用分配存储空间,但是用来保存对象的实际数据的空间并没有分配。对象的创建创建对象时需要使用new运算符。ne ...