Unity实现虚拟摇杆

 更新时间:2020年04月14日 10:42:23   作者:LLLLL__  
这篇文章主要为大家详细介绍了Unity实现虚拟摇杆,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Unity实现虚拟摇杆的具体代码,供大家参考,具体内容如下

面板上设置一些属性,比如摇杆拖拽的距离,是否始终可视,是否限制虚拟摇杆位置(我是把虚拟摇杆限制在了屏幕的左下区域)。
使用GetDirAndLength()方法去获得移动的方向和长度即可

using UnityEngine;
 
/// <summary>
/// 虚拟摇杆管理器
/// </summary>
public class VirtualJoystickManager : MonoBehaviour
{
  private static VirtualJoystickManager _instance;
  public static VirtualJoystickManager Instance
  {
    get
    {
      if (_instance == null)
      {
        _instance = FindObjectOfType<VirtualJoystickManager>();
      }
      return _instance;
    }
  }
 
  [Header("是否始终可视")]
  public bool alwaysVisible;//是否始终可视
  [Header("是否限制虚拟摇杆位置")]
  public bool restrictVirtualJoystickPos;//是否限制虚拟摇杆位置
 
  [Header("虚拟摇杆物体")]
  [Header("==========")]
  public GameObject virtualJoystick;//虚拟摇杆父物体
  public GameObject inside;//内环
  public GameObject outside;//外环
 
  [Header("最大拖拽距离")]
  [Header("==========")]
  public float maxDragLength;//最大拖拽距离
 
  private Vector3 virtualJoystickCenter;//虚拟轴中心
 
  private void Update()
  {
    //如果限制虚拟轴位置并且虚拟轴位置超出了限制范围则不进行任何操作
    if (restrictVirtualJoystickPos && JudgeIsValidRange() == false)
    {
      return;
    }
 
    //更新显示
    UpdateShow();
 
    //更新虚拟摇杆位置
    if (Input.GetMouseButtonDown(0))
    {
      UpdateVirtualJoystickPos();
    }
    else if (Input.GetMouseButtonUp(0))
    {
      inside.transform.position = virtualJoystickCenter;
    }
 
    //更新内环位置(限制拖拽范围)
    if (Input.GetMouseButton(0))
    {
      UpdateInsidePos();
    }
  }
 
  /// <summary>
  /// 更新显示
  /// </summary>
  private void UpdateShow()
  {
    if (alwaysVisible)
    {
      inside.SetActive(true);
      outside.SetActive(true);
    }
    else if (alwaysVisible == false)
    {
      if (Input.GetMouseButtonDown(0))
      {
        inside.SetActive(true);
        outside.SetActive(true);
      }
      if (Input.GetMouseButtonUp(0))
      {
        inside.SetActive(false);
        outside.SetActive(false);
      }
    }
  }
 
  /// <summary>
  /// 更新虚拟摇杆位置
  /// </summary>
  private void UpdateVirtualJoystickPos()
  {
    //得到虚拟轴的中心位置
    virtualJoystickCenter = ScreenToWorld(Input.mousePosition);
 
    //设置虚拟轴的位置
    virtualJoystick.transform.position = virtualJoystickCenter;
  }
 
  /// <summary>
  /// 更新内环位置
  /// </summary>
  private void UpdateInsidePos()
  {
    inside.transform.position = ScreenToWorld(Input.mousePosition);
    if (Vector3.Distance(inside.transform.position, virtualJoystickCenter) > maxDragLength)
    {
      Vector3 normalizedPos = (inside.transform.position - virtualJoystickCenter).normalized;
      inside.transform.position = normalizedPos * maxDragLength + virtualJoystickCenter;
    }
  }
 
  /// <summary>
  /// 判断是否为有效的范围
  /// </summary>
  /// <returns>是否为有效的范围</returns>
  private bool JudgeIsValidRange()
  {
    if (inside.activeInHierarchy)
    {
      return true;
    }
 
    Vector2 v = Input.mousePosition;
    if (v.x > Screen.width / 2 || v.x < 0)
    {
      return false;
    }
    else if (v.y > Screen.height / 2 || v.y < 0)
    {
      return false;
    }
    return true;
  }
 
  /// <summary>
  /// 屏幕坐标转世界坐标
  /// </summary>
  /// <param name="screenPos">屏幕坐标位置</param>
  /// <param name="camera">相机</param>
  /// <returns>转换后的世界坐标</returns>
  public static Vector3 ScreenToWorld(Vector3 screenPos, Camera camera = null)
  {
    if (camera == null)
    {
      camera = Camera.main;
    }
    Vector3 _screenPos = new Vector3(screenPos.x, screenPos.y, -camera.transform.position.z);
    Vector3 v = camera.ScreenToWorldPoint(_screenPos);
    return v;
  }
 
  /// <summary>
  /// 得到运动的方向和长度
  /// </summary>
  /// <returns>方向和长度</returns>
  public Vector3 GetDirAndLength()
  {
    return inside.transform.position - virtualJoystickCenter;
  }
}

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

相关文章

  • 基于C#实现员工IC卡的读写功能

    基于C#实现员工IC卡的读写功能

    这篇文章主要为大家详细介绍了C#如何实现读写员工IC卡的功能,文中的示例代码讲解详细,对我们学习C#有一定的帮助,感兴趣的小伙伴可以跟随小编一起了解一下
    2023-01-01
  • C# Socket编程实现简单的局域网聊天器的示例代码

    C# Socket编程实现简单的局域网聊天器的示例代码

    这篇文章主要介绍了C# Socket编程实现简单的局域网聊天器,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • C#微信开发之自定义菜单管理

    C#微信开发之自定义菜单管理

    本文主要介绍了C#微信开发中自定义菜单管理的相关知识,具有一定的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • 判断图片-判断位图是否是黑白图片的方法

    判断图片-判断位图是否是黑白图片的方法

    近来工作需要判断图片否是是彩色的,由于是十万张以上的大批量理处,所以通过序程来动自判断。
    2013-05-05
  • WPF利用ValueConverter实现值转换器

    WPF利用ValueConverter实现值转换器

    值转换器在WPF开发中是非常常见的,值转换器可以帮助我们很轻松地实现,界面数据展示的问题。本文将通过WPF ValueConverter实现简单的值转换器,希望对大家有所帮助
    2023-03-03
  • 用C#绘制九宫格形式的图片

    用C#绘制九宫格形式的图片

    大家好,本篇文章主要讲的是用C#绘制九宫格形式的图片,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • Ruby创建数组方法总结

    Ruby创建数组方法总结

    在本篇文章里小编给大家分享了关于Ruby创建数组方法的知识点内容,对戏有兴趣的朋友们学习下。
    2019-01-01
  • C#中的multipart/form-data提交文件和参数

    C#中的multipart/form-data提交文件和参数

    这篇文章主要介绍了C#中的multipart/form-data提交文件和参数,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • unity实现无限列表功能

    unity实现无限列表功能

    这篇文章主要介绍了unity实现无限列表功能,水平方向,竖直方向滑动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • C#实现让窗体获得焦点的方法示例

    C#实现让窗体获得焦点的方法示例

    这篇文章主要介绍了C#实现让窗体获得焦点的方法,涉及C#窗体事件相关操作技巧,需要的朋友可以参考下
    2017-06-06

最新评论