• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • 【Unity】UGUI實現搖桿功能

    標簽: 功能Demo

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using System;
    using UnityEngine.EventSystems;
    
    public class InputJoystick : MonoBehaviour
    {
        //搖桿根節點
        [SerializeField] RectTransform joystickRoot;
        //搖桿節點
        [SerializeField] RectTransform joystickNode;
        //搖桿方向節點
        [SerializeField] RectTransform joystickDirection;
    
        //搖桿半徑
        [SerializeField] int joystickRadius = 200;
        //抬手搖桿復位速度
        [SerializeField, Range(0.01f, 1)] float revertPositionSpeed = 0.75f;
        //單擊判定時間范圍
        [SerializeField] float tapDuration = 0.1f;
    
        //搖桿事件回調
        public static Action OnJoystickMoveStart;
        public static Action<Vector2> OnJoystickMoving;
        public static Action OnJoystickMoveEnd;
        public static Action OnJoystickTap;
    
        //屏幕寬高
        private int screenWidth = Screen.width;
        private int screenHeight = Screen.height;
    
        //搖桿默認位置
        private Vector3 joystickDefaultPos;
        //按下時搖桿中心位置
        private Vector3 curJoystickOrigin;
        //按下時搖桿方向
        private Vector3 curJoystickDirection;
    
        private bool isInputing = false;        //是否按下搖桿
        private bool needToRevertRoot = false;  //根節點是否需要回位
        private bool needToRevertNode = false;  //遙感節點是否需要回位
        private bool isReadyToTap = false;      //是否判定單擊
        private bool isActived = true;          //是否**搖桿
    
        //搖桿按下時間
        private float startInputTime;
    
        private void Awake()
        {
            joystickDefaultPos = joystickRoot.anchoredPosition;
        }
        private void Start()
        {
            joystickDirection.gameObject.SetActive(false);
        }
    
        private void Update()
        {
            if (!isActived)
                return;
            if (Input.GetMouseButtonDown(0))
            {
                if (IsRaycastUI())
                    return;
                OnInputStart(Input.mousePosition);
                isInputing = true;
            }
            else if (Input.GetMouseButton(0))
            {
                if (isInputing)
                    OnInputIng(Input.mousePosition);
            }
            else if (Input.GetMouseButtonUp(0))
            {
                if (isInputing)
                {
                    OnInputEnd(Input.mousePosition);
                    isInputing = false;
                }
            }
            else if (!isInputing)
            {
                if (needToRevertRoot)
                {
                    RevertJoystickRootPos();
                }
                if (needToRevertNode)
                {
                    RevertJoystickNodePos();
                }
            }
        }
    
        private bool IsRaycastUI()
        {
            //鼠標點擊事件
            return (EventSystem.current != null && EventSystem.current.IsPointerOverGameObject());
        }
    
        //**/取消** 搖桿
        public void ActiveJoystick(bool active)
        {
            if (isActived == active)
                return;
    
            isActived = active;
    
            if (!isActived)
            {
                if (isInputing)
                    OnJoystickMoveEnd?.Invoke();
            }
    
            joystickRoot.gameObject.SetActive(active);
            joystickRoot.anchoredPosition = joystickDefaultPos;
            joystickNode.localPosition = Vector3.zero;
        }
    
        #region --- 輸入回調 ---
    
        private void OnInputStart(Vector3 point)
        {
            curJoystickOrigin = point;
    
            startInputTime = Time.unscaledTime;
            isReadyToTap = true;
    
            Vector3 joystickPos = Vector3.zero;
            joystickPos.x = -0.5f * screenWidth + point.x;
            joystickPos.y = -0.5f * screenHeight + point.y;
            joystickRoot.anchoredPosition = joystickPos;
            joystickNode.localPosition = Vector3.zero;
    
            joystickDirection.gameObject.SetActive(true);
    
            OnJoystickMoveStart?.Invoke();
        }
        float tempLength;
        private void OnInputIng(Vector3 point)
        {
            tempLength = (point - curJoystickOrigin).magnitude;
    
            if (tempLength < 0.01f)
            {
                curJoystickDirection = Vector3.zero;
                OnJoystickMoving?.Invoke(curJoystickDirection);
    
                if (isReadyToTap)
                {
                    if (Time.unscaledTime - startInputTime >= tapDuration)
                    {
                        isReadyToTap = false;
                    }
                }
            }
            else if (tempLength <= joystickRadius)
            {
                curJoystickDirection = (point - curJoystickOrigin).normalized * tempLength / joystickRadius;
                isReadyToTap = false;
            }
            else
            {
                curJoystickDirection = (point - curJoystickOrigin).normalized;
                isReadyToTap = false;
            }
    
            joystickNode.localPosition = curJoystickDirection * joystickRadius;
            if (curJoystickDirection == Vector3.zero)
                joystickDirection.up = Vector3.up;
            else
                joystickDirection.up = curJoystickDirection;
    
            OnJoystickMoving?.Invoke(curJoystickDirection);
        }
        private void OnInputEnd(Vector3 point)
        {
            curJoystickOrigin = joystickDefaultPos;
    
            needToRevertRoot = true;
            needToRevertNode = true;
    
            joystickDirection.gameObject.SetActive(false);
    
            if (isReadyToTap)
            {
                OnJoystickTap?.Invoke();
                isReadyToTap = false;
            }
    
            OnJoystickMoveEnd?.Invoke();
        }
    
        #endregion
    
        #region --- 搖桿復位 ---
    
        private void RevertJoystickRootPos()
        {
            if ((joystickRoot.position - joystickDefaultPos).sqrMagnitude > 0.1f)
            {
                joystickRoot.anchoredPosition = Vector3.Lerp(joystickRoot.anchoredPosition, joystickDefaultPos, revertPositionSpeed);
            }
            else
            {
                joystickRoot.anchoredPosition = joystickDefaultPos;
                needToRevertRoot = false;
            }
        }
        private void RevertJoystickNodePos()
        {
            if (joystickNode.localPosition.sqrMagnitude > 0.1f)
            {
                joystickNode.localPosition = Vector3.Lerp(joystickNode.localPosition, Vector3.zero, revertPositionSpeed);
            }
            else
            {
                joystickNode.localPosition = Vector3.zero;
                needToRevertNode = false;
            }
        }
    
        #endregion
    
    }

     

    版權聲明:本文為qq_39108767原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/qq_39108767/article/details/106454067

    智能推薦

    Unity3D UGUI 制作搖桿Joystick

    簡單的UI制作 其中的ImageBg的錨點 其中的ImagePoint的錨點 代碼 加一個回調,讓控制的物體移動起來。 UIBase,UIEvent等在我的其他文章里寫的,可以看看。...

    [Unity]關于UGUI拖拽備份克隆功能的簡單實現

    最近題主在做一個RPGDemo的技能拖拽到技能欄的功能時,遇到了UGUI中并沒有直接實現拖拽備份克隆的功能(PS:題主還是剛入門的新手),索性自己就寫了一下,邏輯算不上復雜,但剛開始也不太簡單。 之前的效果(沒有實現前) 在講ugui的實現之前我們來看看老版本的ngui如何實現拖拽備份克隆的功能。 就是直接繼承了UIDragDropItem接口直接實現 這個借口在面板提供了一個對象Clone On...

    unity開發UGUI實現記住密碼的功能

    之前我寫過好多關于UGUi的博客了 然后呢最近我寫的關于UGUI的博客都是針對于有基礎的小伙伴們 我所說的有基礎就是基本所有UGUI的用法都有初步的了解 然后我這里實現一些功能給大家作參考 這篇博客我給大家分享一下用UGUI實現記住密碼的選項 具體用法呢很簡單 我這里用到的是playerPrefs來實現的 我們還可以使用字典(Dictionary)來實現 這里給大家一篇我之前寫過的關于登錄和注冊的...

    神奇的Batch Normalization 如果一個模型僅訓練BN層會是什么樣的

    您可能會感到驚訝,但這是有效的。 ? 最近,我閱讀了arXiv平臺上的Jonathan Frankle,David J. Schwab和Ari S. Morcos撰寫的論文“Training BatchNorm and Only BatchNorm: On the Expressive Power of Random Features in CNNs”。 這個主意立刻引起了...

    用Python實現校園通知更新提醒

    前言 這個項目實已經在一個月前已經完成了,一直都想寫一篇博客來總結這個過程中遇到的一些問題。但最近一個月來都比較忙,所以一直拖到了現在。 首先說說起因吧,我沒事的時候,總喜歡依次點開學校主頁、教務處、圖書館以及學院的網站,看看有沒有什么新通知,雖然大多與我無關。恰逢最近正在學Python,經常聽到別人說用Python寫爬蟲很簡單,但自己尚未接觸過爬蟲。于是抱著試一試的心態看了幾篇關于Python爬...

    猜你喜歡

    spring_ioc相關_第一章

    1 spring是一站式框架,在javaee的三層結構中,每一層都提供不提并的解決技術 web層:springMVC service層:spring的ioc dao層:spring的jdbcTemplate 2 javaee為避免兩個類之間出現耦合,則把對象的創建交給spring進行管理,spring的ioc操作:(1)ioc的配置文件方式;(2)ioc注解方式 3 ioc的底層原理使用技術(1)...

    【Python+OpenCV】視頻流局部區域像素值處理-一種特征提取方法

    參考我之前寫的處理圖片的文章:Python+OpenCV實現【圖片】局部區域像素值處理(改進版) 開發環境:Python3.6.0 + OpenCV3.2.0 任務目標:攝像頭采集圖像(例如:480*640),并對視頻流每一幀(灰度圖)特定矩形區域(480*30)像素值進行行求和,得到一個480*1的數組,用這480個數據繪制條形圖,即在逐幀采集視頻流并處理后“實時”顯示采...

    JavaWeb——【前端】——注冊頁面

    頁面效果 實現代碼 注意事項 主要使用的bootstrap樣式 如果想引用,不要直接復制,沒用的。 先介紹下所引用的文件: boostrap的js、bootstrap的css、jquery的js、以及自己編寫的register.css。 因為博主用的thymeleaf語法,所以有th符號。 若要使用時,根據個人情況導入相應的依賴。...

    網站HTTP升級HTTPS完全配置手冊

    本文由葡萄城技術團隊于博客園原創并首發 轉載請注明出處:葡萄城官網,葡萄城為開發者提供專業的開發工具、解決方案和服務,賦能開發者。 今天,所有使用Google Chrome穩定版的用戶迎來了v68正式版首個版本的發布,詳細版本號為v68.0.3440.75,上一個正式版v67.0.3396.99發布于6月13日,自Chrome 68起,當在加載非HTTPS站點時,都會在地址欄上明確標記為&ldqu...

    echarts 自定義儀表盤設置背景圖片

    echarts儀表盤 使用插件 vue-echarts 代碼示例 HTML部分 js部分 效果圖...

    精品国产乱码久久久久久蜜桃不卡