您现在的位置:首页 >> 前端 >> 内容

Unity学习之利用UGUIScrollRect组件制作手游摇杆控件

时间:2018/5/9 14:20:07 点击:

  核心提示:Unity学习之利用UGUIScrollRect组件制作手游摇杆控件今天和朋友聊天的时候听说某大厂做手游摇杆是用UGUI实现的,想想自己以前做手游的时候都是用的Easy Tocuh插件,于是很好奇是如...

Unity学习之利用UGUIScrollRect组件制作手游摇杆控件

今天和朋友聊天的时候听说某大厂做手游摇杆是用UGUI实现的,想想自己以前做手游的时候都是用的Easy Tocuh插件,于是很好奇是如何实现的。于是在大佬的协助下缕清了思路,如何用UGUI的ScrollRect组件制作手游的摇杆控件。

首先创建一个空项目,在场景内创建一个Scroll View并移动至Canvas的左下角:

Unity学习之利用UGUIScrollRect组件制作手游摇杆控件

我是将Scroll View的锚点定在Canvas的左下角并给PosX和PosY均赋值为150,如下图:

Unity学习之利用UGUIScrollRect组件制作手游摇杆控件

选中Scroll View,在Inspector面板找到Scroll Rect组件,将HZ喎?/kf/ware/vc/" target="_blank" class="keylink">vcml6b250YWwgU2Nyb2xsYmFyPC9zdHJvbmc+us08c3Ryb25nPlZlcnRpY2FsIFNjcm9sbGJhcjwvc3Ryb25nPs/Cw+a1xDxzdHJvbmc+VmlzaWJsaXR5PC9zdHJvbmc+vvnJ6NbDzqo8c3Ryb25nPkF1dG8gSGlkZTwvc3Ryb25nPjwvcD4NCjxwPjxpbWcgYWx0PQ=="" src="/uploadfile/Collfiles/20180505/20180505091217359.png" title="\" />

选中Viewport,将锚点设置在左上角,给PosX和PosY赋值为0,给Width和Height赋值为200(和Scroll Rect的Width、Height相同),再选中Content,重复操作

Unity学习之利用UGUIScrollRect组件制作手游摇杆控件

Unity学习之利用UGUIScrollRect组件制作手游摇杆控件

顺带一提,我还将右边和下边的拖拽条隐藏掉并且不接收射线,并且去掉了Viewport的Mask组件,具体操作各位道友们可以自行实现。

创建脚本,我命名为MobileRockerController,拖拽脚本给Content,现添加代码如下:

// MobileRockerController.cs written by Fumiki at 2018-05-04
using UnityEngine;
using UnityEngine.UI;

namespace Com.MobileRocker.Fumiki
{
    public class MobileRockerController : MonoBehaviour
    {
        /// 
        /// 手机摇杆
        /// 
        [SerializeField] private RectTransform rocker;

        private void Awake()
        {
            if (rocker == null)
                rocker = gameObject.GetComponent();

        private void Update()
        {
            Debug.Log(rocker.anchoredPosition);
        }
    }
}

这时已经可以看到有手柄的效果了,Console输出的就是拖拽Content后Update方法中反馈回来的Content的二维锚点坐标值:

Unity学习之利用UGUIScrollRect组件制作手游摇杆控件

为了美化,我还顺手设置了一下Scroll View的Image组件的颜色,也给Content添加了一个Image组件,使用了UGUI的圆形贴图并设置了一下颜色(暂时先不上图了,有点Low)。

删除Content上的MobileRockerController脚本,并将脚本重新绑定给Scroll View,改写脚本如下:

using System;
using UnityEngine;
using UnityEngine.UI;

namespace Com.MobileRocker.Fumiki
{
    public class MobileRockerController : MonoBehaviour
    {
        #region 将手机摇杆类设置为单例类
        private MobileRockerController() { }
        private MobileRockerController(ref MobileRockerController reference) { }
        private static MobileRockerController instance = null;
        public static MobileRockerController Instance
        {
            get { return instance; }
        }
        #endregion

        /// 
        /// 手机摇杆基座
        /// 
        [SerializeField] private RectTransform rockerBase = null;

        /// 
        /// 手机摇杆
        /// 
        [SerializeField] private RectTransform rocker = null;

        /// 
        /// 手机摇杆横纵偏移量
        /// 
        [SerializeField] private Vector2 rockerOffset = Vector2.zero;

        /// 
        /// 外部获取手机摇杆横纵偏移量的接口属性[只读]
        /// 
        public Vector2 RockerOffset
        {
            get { return rockerOffset; }
        }

        private void Awake()
        {
            if (instance == null)
                instance = this;
            if (rockerBase == null)
                rockerBase = gameObject.GetComponent();
            if (rocker == null)
                rocker = gameObject.GetComponent().content;
        }

        private void Update()
        {
            SetAnchoredPosToRockerOffset();
        }


        /// 
        /// 将摇杆的锚点坐标转换为偏移量
        /// 
        private void SetAnchoredPosToRockerOffset()
        {
            // 分别获取摇杆基座宽高的一般用以后面的判断
            float halfBaseX = rockerBase.sizeDelta.x / 2.0f;
            float halfBaseY = rockerBase.sizeDelta.y / 2.0f;
            // 判断以设定边界
            if (rocker.anchoredPosition.x > halfBaseX)
            {
                if (rocker.anchoredPosition.y > halfBaseY)
                    rockerOffset = new Vector2(1.0f, 1.0f);
                else if (rocker.anchoredPosition.y < -halfBaseY)
                    rockerOffset = new Vector2(1.0f, -1.0f);
                else
                    rockerOffset = new Vector2(1.0f, rocker.anchoredPosition.y / 100.0f);
            }
            else if (rocker.anchoredPosition.x < -halfBaseX)
            {
                if (rocker.anchoredPosition.y > halfBaseY)
                    rockerOffset = new Vector2(-1.0f, 1.0f);
                else if (rocker.anchoredPosition.y < -halfBaseY)
                    rockerOffset = new Vector2(-1.0f, -1.0f);
                else
                    rockerOffset = new Vector2(-1.0f, rocker.anchoredPosition.y / 100.0f);
            }
            else
            {
                if (rocker.anchoredPosition.y > halfBaseY)
                    rockerOffset = new Vector2(rocker.anchoredPosition.x / 100.0f, 1.0f);
                else if (rocker.anchoredPosition.y < -halfBaseY)
                    rockerOffset = new Vector2(rocker.anchoredPosition.x / 100.0f, -1.0f);
                else
                    rockerOffset = new Vector2(rocker.anchoredPosition.x / 100.0f, rocker.anchoredPosition.y / 100.0f);
            }
            // 设定偏移量的精度
            rockerOffset = new Vector2(Convert.ToSingle(Math.Round(rockerOffset.x, 2)), 
                                       Convert.ToSingle(Math.Round(rockerOffset.y, 2)));
        } 
    }
}

这样其他需要和摇杆挂钩的GameObject就可以调用MobileRockerController.Instance.RockerOffset获取手柄的偏移量并根据自己的需求编写逻辑了。

最后上一张效果图,庆祝一下我第一次用UGUI做出的简易手柄:

Unity学习之利用UGUIScrollRect组件制作手游摇杆控件

简单介绍一下,这是用通过手柄的偏移量给小球增加扭力使小球滚动的一个小demo,虽然粗糙了一些,不过证明了手柄确实可用。

顺带附上没有注释的小球脚本(小球绑定了刚体):

using UnityEngine;

namespace Com.MobileRocker.Fumiki
{
    public class PlayerController : MonoBehaviour
    {
        private Vector3 forceOffset = Vector3.zero;

        void Update()
        {
            forceOffset = new Vector3(MobileRockerController.Instance.RockerOffset.y, 0, 
                -MobileRockerController.Instance.RockerOffset.x);
            gameObject.GetComponent().AddTorque(forceOffset * 50, ForceMode.Force);
        }
    }
}

Tags:UN NI IT TY 
作者:网络 来源:Fumiki的填坑日
  • 易笔记(art.yibiji.com) © 2025 版权所有 All Rights Reserved.
  • 本站部分内容收集于互联网若有侵权请联系站长删除 鄂ICP备18030946号-1