Unity 之 使用原生UGUI实现随手移动摇杆功能经典实例

这篇具有很好参考价值的文章主要介绍了Unity 之 使用原生UGUI实现随手移动摇杆功能经典实例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

unity ugui 遥感,ジ﹋★☆『 经典示例 』,unity,ui,c#

实现效果

本文最终实现效果:
unity ugui 遥感,ジ﹋★☆『 经典示例 』,unity,ui,c#


一,实现思路

1.1 原理解析

做一个实验看一下使用ScrollRect组件实现摇杆的原理。

  1. Hierarchy面板右键 UI -> Scroll View 创建一个滚动视图,这个组件经常被应用于排行榜,选角色之类的可滑动的界面。
    unity ugui 遥感,ジ﹋★☆『 经典示例 』,unity,ui,c#

  2. Scroll View -> Viewport -> Content 添加一个Image组件
    unity ugui 遥感,ジ﹋★☆『 经典示例 』,unity,ui,c#

  3. 运行场景,鼠标点击并拖动中间部分,即可看到如下效果:
    unity ugui 遥感,ジ﹋★☆『 经典示例 』,unity,ui,c#

看到这里基本了解实现思路了吧,其实就是通过Scroll Rect组件的Context和Viewport的关系来进行模拟的。
unity ugui 遥感,ジ﹋★☆『 经典示例 』,unity,ui,c#

更多关于ScrollRect的使用方法和实战应用,可以查看:Unity 之 UGUI Scroll Rect滚动矩形组件详解


1.2 思路概述

  1. 随手指落下位置
    思路:其实就是根据手指第一次落下的屏幕坐标,修改摇杆的初始位置;手抬起时再将摇杆位置还原
    知识点:获取手指按下和抬起的回调,将手指落下坐标转换为屏幕UI坐标

  2. 摇杆移动
    思路:使用Scroll Rect的移动回调,来控制中间的虚拟摇杆进行位置变化
    注意的点:使用OnDrag进行回调,并来控制虚拟摇杆的标移动位置不要超出背景

  3. 移动回调
    思路:当使用摇杆时使用Update进行实时回调
    注意的点:使用OnEndDrag进行回调,还原要个位置


二,实现代码

2.1 随手落下

通过锚点和RectTransformUtility坐标转换方法进行位置设置。

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

[RequireComponent(typeof(EventTrigger))]
public class JoystickTouch : ScrollRect
{    
    protected override void Start()
    {            
        EventTrigger trigger = GetComponent<EventTrigger>();
        EventTrigger.Entry entryPointerUp = new EventTrigger.Entry();
        entryPointerUp.eventID = EventTriggerType.PointerUp;
        entryPointerUp.callback.AddListener((data) => { OnPointerUp((PointerEventData)data); });
        trigger.triggers.Add(entryPointerUp);

        EventTrigger.Entry entryPointerDown = new EventTrigger.Entry();
        entryPointerDown.eventID = EventTriggerType.PointerDown;
        entryPointerDown.callback.AddListener((data) => { OnPointerDown((PointerEventData)data); });
        trigger.triggers.Add(entryPointerDown);
    }
    
    // 随手落下设置摇杆位置
    private void OnPointerDown(PointerEventData eventData)
    {
        Vector2 LocalPosition;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(this.GetComponent<RectTransform>(),
            eventData.position, eventData.pressEventCamera, out LocalPosition);
        this.viewport.localPosition = LocalPosition;
    }

    // 抬起还原位置
    private void OnPointerUp(PointerEventData eventData)
    {
        this.viewport.anchoredPosition3D = Vector3.zero;
    }

}

2.2 摇杆转动

还是在上面的类中重写OnDrag方法,进行虚拟摇杆中间位置的控制。

public class JoystickTouch : ScrollRect
{    
    // 半径 -- 控制拖拽区域
    private float mRadius;
    
    protected override void Start()
    {
        mRadius = this.content.sizeDelta.x * 0.5f;
    }
    
    public override void OnDrag(PointerEventData eventData)
    {
        base.OnDrag(eventData);
        joyIsCanUse = true;
        //虚拟摇杆移动
        Vector3 contentPosition = this.content.anchoredPosition;
        if (contentPosition.magnitude > mRadius)
        {
            contentPosition = contentPosition.normalized * mRadius;
            SetContentAnchoredPosition(contentPosition);
        }

        // 摇杆内部按钮旋转
        //if (content.anchoredPosition.y != 0)
        //{
        //    content.eulerAngles = new Vector3(0, 0,
        //        Vector3.Angle(Vector3.right, content.anchoredPosition) * content.anchoredPosition.y /
        //        Mathf.Abs(content.anchoredPosition.y) - 90);
        //}
    }
}

三,源码分享

3.1 场景搭建

创建三个Image一个作为一个的子物体,依次为:接收点击背景面积,摇杆背景板,摇杆中的虚拟按钮。
第一个Image挂载新建脚本JoystickTouch
场景搭建如下:
unity ugui 遥感,ジ﹋★☆『 经典示例 』,unity,ui,c#


3.2 完整代码

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

[RequireComponent(typeof(EventTrigger))]
public class JoystickTouch : ScrollRect
{
    /// <summary>
    /// 拖动差值
    /// </summary>
    public Vector2 offsetValue;
    
    // 半径 -- 控制拖拽区域
    private float mRadius;
    
    /// <summary>
    /// 移动中回调
    /// </summary>
    public System.Action<RectTransform> JoystickMoveHandle;
    /// <summary>
    /// 移动结束回调
    /// </summary>
    public System.Action<RectTransform> JoystickEndHandle;

    /// <summary>
    /// 摇杆是否处于可用状态
    /// </summary>
    public bool joyIsCanUse = false;
    
    protected override void Start()
    {
        mRadius = this.content.sizeDelta.x * 0.5f;
            
        EventTrigger trigger = GetComponent<EventTrigger>();
        EventTrigger.Entry entryPointerUp = new EventTrigger.Entry();
        entryPointerUp.eventID = EventTriggerType.PointerUp;
        entryPointerUp.callback.AddListener((data) => { OnPointerUp((PointerEventData)data); });
        trigger.triggers.Add(entryPointerUp);

        EventTrigger.Entry entryPointerDown = new EventTrigger.Entry();
        entryPointerDown.eventID = EventTriggerType.PointerDown;
        entryPointerDown.callback.AddListener((data) => { OnPointerDown((PointerEventData)data); });
        trigger.triggers.Add(entryPointerDown);
    }
    
    protected override void OnEnable()
    {
        joyIsCanUse = false;
        offsetValue = Vector2.zero;
    }
    
    public override void OnDrag(PointerEventData eventData)
    {
        base.OnDrag(eventData);
        joyIsCanUse = true;
        //虚拟摇杆移动
        Vector3 contentPosition = this.content.anchoredPosition;
        if (contentPosition.magnitude > mRadius)
        {
            contentPosition = contentPosition.normalized * mRadius;
            SetContentAnchoredPosition(contentPosition);
        }

        // 摇杆内部按钮旋转
        //if (content.anchoredPosition.y != 0)
        //{
        //    content.eulerAngles = new Vector3(0, 0,
        //        Vector3.Angle(Vector3.right, content.anchoredPosition) * content.anchoredPosition.y /
        //        Mathf.Abs(content.anchoredPosition.y) - 90);
        //}
    }

    private void FixedUpdate()
    {
        if (joyIsCanUse)
        {
            JoystickMoveHandle?.Invoke(this.content);
            offsetValue = this.content.anchoredPosition3D;
        }
    }

    public override void OnEndDrag(PointerEventData eventData)
    {
        base.OnEndDrag(eventData);
        joyIsCanUse = false;
        offsetValue = Vector2.zero;
        JoystickEndHandle?.Invoke(this.content);
    }
    
    // 随手落下设置摇杆位置
    private void OnPointerDown(PointerEventData eventData)
    {
        Vector2 LocalPosition;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(this.GetComponent<RectTransform>(),
            eventData.position, eventData.pressEventCamera, out LocalPosition);
        this.viewport.localPosition = LocalPosition;
    }

    // 抬起还原位置
    private void OnPointerUp(PointerEventData eventData)
    {
        this.viewport.anchoredPosition3D = Vector3.zero;
    }

}

3.3 实现效果

按钮素材图片:

unity ugui 遥感,ジ﹋★☆『 经典示例 』,unity,ui,c#

unity ugui 遥感,ジ﹋★☆『 经典示例 』,unity,ui,c#
实现效果:
unity ugui 遥感,ジ﹋★☆『 经典示例 』,unity,ui,c#


工程下载:源码和步骤都在上面分享过了,若还有什么不明白的,可以 点击链接下载 ,积分不够的童鞋关注下方卡片,回复:“摇杆” 即可获得开篇Demo源码~文章来源地址https://www.toymoban.com/news/detail-796342.html

到了这里,关于Unity 之 使用原生UGUI实现随手移动摇杆功能经典实例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【学习笔记】Unity基础(七)【uGUI基础、利用render Texture实现小地图功能】

    转载请注明出处:🔗https://blog.csdn.net/weixin_44013533/article/details/130808689 本篇基本是大纲性质,参考价值不大,只有最后一小节“利用render Texture实现小地图功能”花了点时间,可以看看,不过也用到了上面的canvas、UI image等知识、以及input等脚本功能,也算一个小练手吧 倒是

    2024年02月08日
    浏览(47)
  • Unity中Shader测试常用的UGUI可交互功能的脚本基本使用

    我们在上篇文章简单介绍了一下Shader测试时常用的UGUI功能。 Unity中Shader测试常用的UGUI功能简介 我们在这篇文章中,简单看一下 可交互的UGUI的脚本怎么使用。 public Button _Button; void OnButtonClick() { Debug.Log(“你点击了按钮”); } _Button.onClick.AddListener(OnButtonClick); public Button _Button

    2024年02月04日
    浏览(41)
  • 【Unity InputSystem】实用教程-实现角色移动跳跃功能(Input System在PC端鼠键!手机端触摸屏!主机手柄!三端使用教程)

    在上一篇文章当中我们手把手的跟大家分享了InputSystem的基础操作(如何使用5种不同的方式获取到InputSystem种的输入检查信息)。那么接下来我们继续分享一下在我们获取到InputSystem输入信息后,如何使用检测到的信息实现我们对应的输入功能。 本次我们使用的Unity编辑器版本为

    2024年02月11日
    浏览(59)
  • 使用U3D、pico开发VR(二)——添加手柄摇杆控制移动

    1System: 2Move Speed:注意速度过小会导致看起来没有移动 3RightHandMoveAction(right loco move):个人采用右手柄实现移动 1System: 2Turn Speed:注意旋转速度过小会导致看起来没有移动 3RightHandMoveAction:个人采用右手柄实现旋转 至此,初步的移动功能就实现了

    2024年02月08日
    浏览(67)
  • 【Unity2022】Unity实现手机游戏操控摇杆(实现操控轮盘)

    首先展示一下本文章实现的效果: 创建两个UI图像,一个用于表示背景,作为父物体,命名为JoyStick,一个表示摇杆,命名为Center。 背景图像选择一个圆,最好加点半透明的属性,最终完成图如下图所示。 创建一个脚本,命名为Joystick,然后将脚本挂载到JoyStick物体上,我们

    2024年02月07日
    浏览(43)
  • 【Unity】Joystick Pack摇杆插件实现锁四向操作

    ​ 简介:一款Unity摇杆插件,非常轻量化 ​ 摇杆移动类型:圆形、横向、竖向 ​ 摇杆类型: Joystick 描述 Fixed 固定位置 Floating 浮动操纵杆从用户触碰的地方开始,一直固定到触碰被释放。 Dynamic 动态操纵杆从用户触摸的地方开始,然后随着触摸在屏幕上移动。 Variable 可变

    2024年01月16日
    浏览(38)
  • Unity中Shader测试常用的UGUI功能简介

    我们在测试Shader效果时,可能会使用到一些简单的UGUI功能。在这篇文章我们大概的介绍一下UGUI的基础功能。 Unity的UGUI帮助文档 锚点是针对父级进行变换的。 锚点的作用是让UI适配不同设备的屏幕变换 需要修改为中心点模式 可以实现子对象 跟随 父对象 缩放的功能 我们在创

    2024年02月04日
    浏览(39)
  • Unity UGUI的Outline(描边实现事务的原子性)组件的介绍及使用

    Outline(描边)组件是Unity UGUI中的一种特效组件,用于给UI元素添加描边效果。通过设置描边的颜色、宽度和模糊程度,可以使UI元素在视觉上更加突出。 Outline(描边)组件通过在UI元素周围绘制多个相同的UI元素,并设置不同的颜色和大小,从而实现描边的效果。描边的宽度和模糊

    2024年02月22日
    浏览(57)
  • unity通过脚本实现漫游功能 wasd控制玩家移动,空格跳跃,鼠标控制视野旋转,滑轮控制镜头伸缩

    将场景中的摄像机删除,在玩家的控制面板中添加Camera组件,和rigibody组件   using System.Collections; using System.Collections.Generic; using UnityEngine; public class move : MonoBehaviour {     public float speed;     Rigidbody rigid;     void Start()     {                 rigid = GetComponentRigidbody();     }  

    2024年02月10日
    浏览(46)
  • PICO 推摇杆移动

    SDK版本 Pico UnityXR SDK v2.0.5   推摇杆,根据摇杆的偏移量,每帧进行移动和旋转 右手的摇杆,如果要想左手,第17行代码改成XRNode.LeftHand

    2024年02月14日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包