| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353 |
- local UINavigator = {}
- local INPUT_TYPE = {
- REMOTE = "REMOTE", -- 遥控
- MOUSE = "MOUSE", -- 鼠标
- GESTURE = "GESTURE" -- 手势
- }
- local nGestureScale = 1.2
- local nFrameCount = 10
- local nRemoteInputTime = 5
- local nGestureInputTime = 0.2
- local lastMousePos
- local nLastGestureInputTime
- local nLastRemoteInputTime
- local lastSelectedObj
- local originalScale
- local currentInputType
- local function ChangeInputType(INPUT_TYPE)
- currentInputType = INPUT_TYPE
- end
- local function UpdateLastRemoteTime()
- nLastRemoteInputTime = CS.UnityEngine.Time.unscaledTime
- end
- local function UpdateLastGestureTime()
- nLastGestureInputTime = CS.UnityEngine.Time.unscaledTime
- end
- local function SelectButton(selectable)
- if nil == selectable then
- CS.UnityEngine.EventSystems.EventSystem.current:SetSelectedGameObject(nil)
- return
- end
- selectable.gameObject:SetActive(true)
- selectable.transform:GetComponent("Selectable"):Select()
- end
- local function SetEntryButton(button)
- ChangeInputType(INPUT_TYPE.REMOTE)
- UpdateLastRemoteTime()
- SelectButton(button)
- end
- local function SetGestureInputType()
- UpdateLastGestureTime()
- if currentInputType == INPUT_TYPE.GESTURE then return end
- ChangeInputType(INPUT_TYPE.GESTURE)
- -- 手势输入时 ui从缩放动画变成放大效果
- if lastSelectedObj
- and not lastSelectedObj:IsDestroyed()
- and not lastSelectedObj.transform:CompareTag("CommonUtilsMenu") then
- lastSelectedObj.transform:DOKill()
- lastSelectedObj.transform.localScale = nGestureScale * originalScale
- end
- end
- local function CheckInput()
- local Input = CS.UnityEngine.Input
- local KeyCode = CS.UnityEngine.KeyCode
- if Input.GetKeyDown(KeyCode.Escape) then
- local eventManager = require('Base/ZEventDispatchCenter.lua')
- eventManager:DispatchEvent(eventManager.EventType.COMMON_REMOTE_RETURN)
- end
- end
- local function GetSelected()
- local selected = CS.UnityEngine.EventSystems.EventSystem.current.currentSelectedGameObject
- if selected and not selected:Equals(nil) and selected.activeInHierarchy then
- return selected:GetComponent("Selectable")
- end
- return nil
- end
- local function ResetLastSelectedTransform()
- if lastSelectedObj and not lastSelectedObj:IsDestroyed() then
- lastSelectedObj.transform:DOKill()
- lastSelectedObj.transform.localScale = originalScale
- end
- end
- local function DispatchEventSelectBtn(selected)
- local eventManager = require('Base/ZEventDispatchCenter.lua')
- eventManager:DispatchEvent(eventManager.EventType.COMMON_SELECT_BUTTON, lastSelectedObj, selected)
- end
- local function MakeButtonFlash(selected)
- selected.transform:DOKill()
- selected.transform.localScale = originalScale
- selected.transform:DOScale(1.2, 1):SetLoops(-1, CS.DG.Tweening.LoopType.Yoyo)
- end
- local function SetSelectData(selected)
- if not selected then return end
- originalScale = selected.transform.localScale
- if selected.transform:CompareTag("CommonUtilsMenu") then
- local eventManager = require('Base/ZEventDispatchCenter.lua')
- eventManager:DispatchEvent(eventManager.EventType.COMMON_UI_NAVIGATOR_SELECT_MENU, selected)
- return
- end
- MakeButtonFlash(selected)
- end
- local function IsRemoteKeyDown()
- local Input = CS.UnityEngine.Input
- local KeyCode = CS.UnityEngine.KeyCode
- return Input.GetKeyDown(KeyCode.LeftArrow)
- or Input.GetKeyDown(KeyCode.RightArrow)
- or Input.GetKeyDown(KeyCode.UpArrow)
- or Input.GetKeyDown(KeyCode.DownArrow)
- or Input.GetKeyDown(KeyCode.Return)
- or Input.GetKeyDown(KeyCode.Joystick1Button0)
- end
- local function UpdateSelectableBehaviour()
- local selected = GetSelected()
- if selected ~= lastSelectedObj then
- ResetLastSelectedTransform()
- DispatchEventSelectBtn(selected)
- SetSelectData(selected)
- lastSelectedObj = selected
- return
- end
- end
- local function CheckRemoteKeyDown()
- if IsRemoteKeyDown() then
- ChangeInputType(INPUT_TYPE.REMOTE)
- return
- end
- local Time = CS.UnityEngine.Time
- local Input = CS.UnityEngine.Input
- local mouseMove = CS.UnityEngine.Vector3.SqrMagnitude(Input.mousePosition - lastMousePos)
- if Time.frameCount > nFrameCount
- and (mouseMove > 0.1 or Input.GetMouseButtonDown(0)) then
- ChangeInputType(INPUT_TYPE.MOUSE)
- end
- lastMousePos = Input.mousePosition
- end
- local function Select(selected)
- if selected then
- selected.gameObject:SetActive(true)
- selected:Select()
- return
- end
- CS.UnityEngine.EventSystems.EventSystem.current:SetSelectedGameObject(nil)
- end
- local function GetKeyCode()
- local KeyCode = CS.UnityEngine.KeyCode
- local Input = CS.UnityEngine.Input
- if Input.GetKeyDown(KeyCode.LeftArrow) then
- return KeyCode.LeftArrow
- end
- if Input.GetKeyDown(KeyCode.RightArrow) then
- return KeyCode.RightArrow
- end
- if Input.GetKeyDown(KeyCode.UpArrow) then
- return KeyCode.UpArrow
- end
- if Input.GetKeyDown(KeyCode.DownArrow) then
- return KeyCode.DownArrow
- end
- return KeyCode.None
- end
- local function SetKeyboardSelected(selected)
- -- 没有选中的UI 寻找第一个
- if nil == selected
- or not selected.isActiveAndEnabled
- then
- local Navigation = CS.UnityEngine.UI.Navigation
- local allSelectablesArray = CS.UnityEngine.UI.Selectable.allSelectablesArray
- local nLen = allSelectablesArray.Length
- for nIndex = 0, nLen - 1, 1 do
- if nil ~= allSelectablesArray[nIndex]:IsDestroyed()
- and Navigation.Mode.None ~= allSelectablesArray[nIndex].navigation.mode
- then
- Select(allSelectablesArray[nIndex])
- break
- end
- end
- return
- end
- if 1 == CS.UnityEngine.Selectable.allSelectableCount
- and CS.UnityEngine.EventSystems.EventSystem.current.currentSelectedGameObject
- then
- Select(nil)
- end
- end
- local function UpdateKeyboardSelection()
- local selected = GetSelected()
- local Navigation = CS.UnityEngine.UI.Navigation
- if selected and selected.navigation.mode == Navigation.Mode.None then
- Select(nil)
- return
- end
- local KeyCode = CS.UnityEngine.KeyCode
- local currentKeyCode = GetKeyCode()
- if KeyCode.None ~= currentKeyCode then
- SetKeyboardSelected(selected)
- UpdateLastRemoteTime()
- return
- end
- if 1 == CS.UnityEngine.Selectable.allSelectableCount
- and CS.UnityEngine.EventSystems.EventSystem.current.currentSelectedGameObject
- and CS.UnityEngine.Time.unscaledTime - nLastRemoteInputTime > nRemoteInputTime
- then
- Select(nil)
- end
- end
- local function UpdateMouseSelection()
- local EventSystems = CS.UnityEngine.EventSystems
- if not EventSystems.EventSystem.current:IsPointerOverGameObject() then
- Select(nil)
- return
- end
- local pointerEventData = EventSystems.PointerEventData(EventSystems.EventSystem.current)
- local mousePosition = CS.UnityEngine.Input.mousePosition
- local mousePos = CS.UnityEngine.Vector2(mousePosition.x, mousePosition.y)
- pointerEventData.position = mousePos
- local listRaycast = CS.System.Collections.Generic.List(CS.UnityEngine.EventSystems.RaycastResult)()
- EventSystems.EventSystem.current:RaycastAll(pointerEventData, listRaycast)
- local tPointSelect = {}
- for _, tRaycast in pairs(listRaycast) do
- local selectable = tRaycast.gameObject:GetComponent("Selectable")
- if selectable and selectable.navigation.mode ~= CS.UnityEngine.UI.Navigation.Mode.None then
- table.insert(tPointSelect, selectable)
- end
- end
- if 0 == #tPointSelect then
- Select(nil)
- return
- end
- local firstSeleted = tPointSelect[1]
- if EventSystems.EventSystem.current.currentSelectedGameObject == firstSeleted.gameObject then
- return
- end
- Select(firstSeleted)
- end
- local function UpdateGestureSelection()
- if CS.UnityEngine.Time.unscaledTime - nLastGestureInputTime > nGestureInputTime then
- ChangeInputType(INPUT_TYPE.GESTURE)
- if lastSelectedObj
- and not lastSelectedObj:IsDestroyed()
- and not lastSelectedObj.transform:CompareTag("CommonUtilsMenu") then
- MakeButtonFlash(lastSelectedObj)
- end
- end
- end
- local function SwitchInputType()
- if INPUT_TYPE.REMOTE == currentInputType then
- UpdateKeyboardSelection()
- return
- end
- if INPUT_TYPE.MOUSE == currentInputType then
- UpdateMouseSelection()
- return
- end
- if INPUT_TYPE.GESTURE == currentInputType then
- UpdateGestureSelection()
- return
- end
- end
- local function RegisterEvent()
- local eventManager = require('Base/ZEventDispatchCenter.lua')
- eventManager:RegisterEvent(eventManager.EventType.COMMON_SET_ENTRY_BUTTON, SetEntryButton)
- eventManager:RegisterEvent(eventManager.EventType.COMMON_SET_GESTUREINPUT, SetGestureInputType)
- eventManager:RegisterEvent(eventManager.EventType.COMMON_UI_NAVIGATOR_ANIM, MakeButtonFlash)
- eventManager:RegisterEvent(eventManager.EventType.COMMON_UI_NAVIGATOR_SELECT, Select)
- end
- local function UnregisterEvent()
- local eventManager = require('Base/ZEventDispatchCenter.lua')
- eventManager:UnregisterEvent(eventManager.EventType.COMMON_UI_NAVIGATOR_SELECT, Select)
- eventManager:UnregisterEvent(eventManager.EventType.COMMON_UI_NAVIGATOR_ANIM, MakeButtonFlash)
- eventManager:UnregisterEvent(eventManager.EventType.COMMON_SET_GESTUREINPUT, SetGestureInputType)
- eventManager:UnregisterEvent(eventManager.EventType.COMMON_SET_ENTRY_BUTTON, SetEntryButton)
- end
- function UINavigator.Awake(luaRoot)
- UINavigator.luaRoot = luaRoot
- local canvas = CS.UnityEngine.GameObject.Find('Canvas')
- UINavigator._rootCanvas = canvas
- lastMousePos = CS.UnityEngine.Input.mousePosition
- end
- function UINavigator.Start()
- RegisterEvent()
- end
- function UINavigator.Update()
- CheckInput()
- UpdateSelectableBehaviour()
- CheckRemoteKeyDown()
- SwitchInputType()
- end
- function UINavigator.OnDestroy()
- UnregisterEvent()
- CS.UnityEngine.GameObject.Destroy(UINavigator.rootPanel)
- end
- return UINavigator
|