| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385 |
- using LightGlue.Unity.Game;
- using LightGlue.Unity.Networking;
- using LightGlue.Unity.Config;
- using LightGlue.Unity.Runtime;
- using LightGlue.Unity.UI;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- using Object = UnityEngine.Object;
- namespace LightGlue.Unity.Custom
- {
- public class LightGlueGameManager : MonoBehaviour
- {
- [Header("参考图像尺寸(必须与 Python --resize 一致)")]
- [Tooltip("参考图像宽度(像素)")]
- public int referenceImageWidth = 320;
- [Tooltip("参考图像高度(像素)")]
- public int referenceImageHeight = 240;
- private void OnEnable()
- {
- ReferenceImageResizeService.EnsureInitialized();
- ApplyReferenceResize(ReferenceImageResizeService.Width, ReferenceImageResizeService.Height);
- ReferenceImageResizeService.OnResizeChanged += ApplyReferenceResize;
- }
- private void OnDisable()
- {
- ReferenceImageResizeService.OnResizeChanged -= ApplyReferenceResize;
- }
- private void ApplyReferenceResize(int w, int h)
- {
- referenceImageWidth = w;
- referenceImageHeight = h;
- }
- [Header("平滑参数来源(唯一来源,无本地参数)")]
- [Tooltip("留空则使用 LightGlueCursorSettings.Instance;所有平滑参数均由此引用读取,UI 修改后即时生效")]
- public LightGlueCursorSettings cursorSettings;
- private Quaternion _currentRotation;
- private bool _hasCurrentRotation;
- private Quaternion _smoothStartRot;
- private Quaternion _smoothTargetRot;
- private float _smoothProgress;
- private LightGluePositionUpdate _latestUpdate;
- private bool _hasLatestUpdate;
- [Tooltip("X轴偏移(像素,如果autoCalculateOffset=false则使用此值)")]
- public float offsetX = 0f;
- [Tooltip("Y轴偏移(像素,如果autoCalculateOffset=false则使用此值)")]
- public float offsetY = 0f;
- private RectTransform _markerRect;
- private Canvas _canvas;
- private Vector2 _currentScreenPos;
- private bool _hasCurrentScreenPos;
- private Vector2 _smoothStartPos;
- private Vector2 _smoothTargetPos;
- private float _smoothUIProgress;
- public static LightGlueGameManager _ins;
- public static void Create()
- {
- if (_ins != null) return;
- // 这里按你项目资源路径调整
- GameObject o = Object.Instantiate(Resources.Load<GameObject>("LightGlueGameManager"));
- Object.DontDestroyOnLoad(o);
- _ins = o.GetComponent<LightGlueGameManager>();
- // 挂到你们 ViewMgr 层级(按你实际节点修改)
- //if (ViewMgr.Instance != null)
- //{
- // var parent = ViewMgr.Instance.transform.Find("1");
- // if (parent != null) o.transform.SetParent(parent, false);
- //}
- _ins.OnCreated();
- }
- // 初始化运行时
- private void OnCreated()
- {
- }
- private void Awake()
- {
- if (cursorSettings == null)
- cursorSettings = LightGlueCursorSettings.Instance;
- //摄像头设备
- LightGlueRuntimeFacade.Ensure();
- LightGlueRuntimeFacade.OnPositionUpdate += HandleLatestUpdate;
- }
- void Start()
- {
-
- }
- private void OnDestroy()
- {
- LightGlueRuntimeFacade.OnPositionUpdate -= HandleLatestUpdate;
- }
- /// <summary>
- /// 单点更新事件
- /// </summary>
- public OnPositionUpdateEvent OnPositionUpdate;
- public delegate void OnPositionUpdateEvent(Vector2 position, Vector2 cameraLocation);
- public void InvokeOnPositionUpdate(Vector2 position, Vector2 cameraLocation)
- {
- try
- {
- OnPositionUpdate?.Invoke(position, cameraLocation);
- }
- catch (Exception e)
- {
- Debug.LogError(e);
- }
- }
- private LightGlueCursorSettings GetCursorSettings()
- {
- if (cursorSettings != null) return cursorSettings;
- return LightGlueCursorSettings.Instance;
- }
- private void HandleLatestUpdate(LightGluePositionUpdate update)
- {
- _latestUpdate = update;
- _hasLatestUpdate = true;
- if (!_latestUpdate.IsValid) return;
- var settings = GetCursorSettings();
- if (settings == null) return;
- // 构造 LightGlueResult(参考图坐标:左上原点、Y向下)
- Vector2 p = _latestUpdate.CameraLocation != default ? _latestUpdate.CameraLocation : _latestUpdate.Position;
- var result = new LightGlueResult(
- isValid: _latestUpdate.IsValid,
- numMatches: _latestUpdate.NumMatches,
- inliersRatio: _latestUpdate.InliersRatio,
- cameraX: p.x,
- cameraY: p.y);
- if (!result.IsValid) return;
- // -------- 1) Screen 坐标(用于射线/鼠标/业务)--------
- Vector2 gameScreenPos = result.GetMappedPosition(
- referenceWidth: referenceImageWidth,
- referenceHeight: referenceImageHeight,
- targetWidth: Screen.width,
- targetHeight: Screen.height,
- type: LightGlueResult.MappedCoordinateType.GameScreen);
- Vector3 screenPoint = new Vector3(gameScreenPos.x, gameScreenPos.y, 0f);
- // -------- 2) UI anchored 坐标 + 平滑/抖动(用于 UI)--------
- Vector2 targetUiPos = result.GetMappedPosition(
- referenceWidth: referenceImageWidth,
- referenceHeight: referenceImageHeight,
- targetWidth: Screen.width,
- targetHeight: Screen.height,
- type: LightGlueResult.MappedCoordinateType.UIAnchored,
- offset: new Vector2(offsetX, offsetY));
- bool useUISmooth = settings.markerEnableSmoothFollow;
- float lerpUISpeed = settings.markerPositionLerpSpeed;
- float jitterUI = settings.markerJitterThresholdPixels;
- AnimationCurve curveUI = settings.markerSmoothCurve;
- if (!useUISmooth || !_hasCurrentScreenPos)
- {
- _currentScreenPos = targetUiPos;
- _hasCurrentScreenPos = true;
- _smoothStartPos = targetUiPos;
- _smoothTargetPos = targetUiPos;
- _smoothUIProgress = 1f;
- }
- else
- {
- if (jitterUI > 0f && Vector2.Distance(_currentScreenPos, targetUiPos) < jitterUI)
- targetUiPos = _currentScreenPos;
- _smoothTargetPos = targetUiPos;
- if (_smoothUIProgress >= 1f)
- {
- _smoothStartPos = _currentScreenPos;
- _smoothUIProgress = 0f;
- }
- _smoothUIProgress += Time.unscaledDeltaTime * lerpUISpeed;
- _smoothUIProgress = Mathf.Clamp01(_smoothUIProgress);
- float t = (curveUI != null && curveUI.keys.Length > 0)
- ? curveUI.Evaluate(_smoothUIProgress)
- : _smoothUIProgress;
- t = Mathf.Clamp01(t);
- _currentScreenPos = Vector2.Lerp(_smoothStartPos, _smoothTargetPos, t);
- }
- // -------- 4) 鼠标/射击:统一用 Screen 坐标--------
- if (SB_EventSystem.ins) SB_EventSystem.ins.MoveSimulateMouseByInfrared(_currentScreenPos);
- if (GeneratingTarget.gm != null) GeneratingTarget.gm.shootingEvent.OnPositionUpdate(_currentScreenPos);
- // UI/业务事件:position=UI(anchored),cameraLocation=Screen(屏幕坐标)
- InvokeOnPositionUpdate(_currentScreenPos, gameScreenPos);
- // -------- 3) Camera 朝向--------
- if (Camera.main == null || CameraToLook.ins == null) return;
- Ray ray = Camera.main.ScreenPointToRay(screenPoint);
- Vector3 rayEndPoint = ray.GetPoint(200f);
- Quaternion targetRotation = Quaternion.LookRotation(rayEndPoint - Camera.main.transform.position);
- // 仅挑战场景额外换算(只做一次)
- if (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name == "GameChallenge")
- targetRotation = Quaternion.AngleAxis(-180f, Vector3.up) * targetRotation;
- // 3.1 开镜:只用 GameAssistUI 的平滑(不再叠加 CursorSettings 平滑)
- if (GameAssistUI.ins && GameAssistUI.ins.scaleAimOn)
- {
- float dt = Mathf.Min(Time.unscaledDeltaTime, 0.05f); // 避免低帧率造成旋转跳跃
- float smoothingFactor = GameMgr.gameType == 1 ? 12f : 7f;
- float k = dt * GameAssistUI.ins.currentSensitivity * smoothingFactor;
- CameraToLook.ins.localRotation = Quaternion.Slerp(
- CameraToLook.ins.localRotation,
- targetRotation,
- k
- );
- }
- else
- {
- // 3.2 非开镜:用 CursorSettings 的平滑+抖动(与 LightGlueCameraAimController 一致)
- bool useSmooth = settings.cameraAimEnableSmoothRotation;
- float lerpSpeed = settings.cameraAimRotationLerpSpeed;
- float jitterDeg = settings.cameraAimRotationJitterThresholdDeg;
- AnimationCurve curve = settings.cameraAimSmoothCurve;
- if (!useSmooth || !_hasCurrentRotation)
- {
- _currentRotation = targetRotation;
- _hasCurrentRotation = true;
- _smoothStartRot = targetRotation;
- _smoothTargetRot = targetRotation;
- _smoothProgress = 1f;
- }
- else
- {
- if (jitterDeg > 0f)
- {
- float angle = Quaternion.Angle(_currentRotation, targetRotation);
- if (angle < jitterDeg)
- {
- CameraToLook.ins.localRotation = _currentRotation;
- if (SB_EventSystem.ins) SB_EventSystem.ins.MoveSimulateMouseByInfrared(screenPoint);
- if (GeneratingTarget.gm != null) GeneratingTarget.gm.shootingEvent.OnPositionUpdate(screenPoint);
- return;
- }
- }
- _smoothTargetRot = targetRotation;
- if (_smoothProgress >= 1f)
- {
- _smoothStartRot = _currentRotation;
- _smoothProgress = 0f;
- }
- _smoothProgress += Time.unscaledDeltaTime * lerpSpeed;
- _smoothProgress = Mathf.Clamp01(_smoothProgress);
- float t = (curve != null && curve.keys.Length > 0) ? curve.Evaluate(_smoothProgress) : _smoothProgress;
- t = Mathf.Clamp01(t);
- _currentRotation = Quaternion.Slerp(_smoothStartRot, _smoothTargetRot, t);
- }
- CameraToLook.ins.localRotation = _currentRotation;
- }
-
- }
- private void HandlePositionUpdate(LightGluePositionUpdate update)
- {
- // Debug.Log($"[LightGlueGameManager] Received position update: Valid={update.IsValid}, Matches={update.NumMatches}, InliersRatio={update.InliersRatio}, CameraLocation=({update.CameraLocation.x}, {update.CameraLocation.y}), Position=({update.Position.x}, {update.Position.y})");
-
- _latestUpdate = update;
- _hasLatestUpdate = true;
- LightGlueResult result;
- if (!_hasLatestUpdate) return;
- if (!_latestUpdate.IsValid) return;
-
- // Position/CameraLocation 均为参考图坐标(左上原点、Y向下)
- Vector2 p = _latestUpdate.CameraLocation != default ? _latestUpdate.CameraLocation : _latestUpdate.Position;
- result = new LightGlueResult(
- isValid: _latestUpdate.IsValid,
- numMatches: _latestUpdate.NumMatches,
- inliersRatio: _latestUpdate.InliersRatio,
- cameraX: p.x,
- cameraY: p.y);
- if (!result.IsValid) return;
- Vector2 gameScreenPos = result.GetMappedPosition(
- referenceWidth: referenceImageWidth,
- referenceHeight: referenceImageHeight,
- targetWidth: Screen.width,
- targetHeight: Screen.height,
- type: LightGlueResult.MappedCoordinateType.GameScreen);
- Vector2 gameUIPos = result.GetMappedPosition(
- referenceWidth: referenceImageWidth,
- referenceHeight: referenceImageHeight,
- targetWidth: Screen.width,
- targetHeight: Screen.height,
- type: LightGlueResult.MappedCoordinateType.UIAnchored);
- Vector3 screenPoint = new Vector3(gameScreenPos.x, gameScreenPos.y, 0f);
- InvokeOnPositionUpdate(gameUIPos, gameScreenPos);
- //跑九轴时候,不处理这里位置
- //if (AimHandler.ins && AimHandler.ins.bRuning9Axis()) return;
- if (Camera.main == null)
- return;
- Ray ray = Camera.main.ScreenPointToRay(screenPoint);
- Vector3 rayEndPoint = ray.GetPoint(200);
- Quaternion quat = Quaternion.LookRotation(rayEndPoint - Camera.main.transform.position);
- // 挑战场景中其相机的父级有旋转,需要换算
- if (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name == "GameChallenge")
- {
- quat = Quaternion.AngleAxis(-180, Vector3.up) * quat;
- }
- if (GameAssistUI.ins && GameAssistUI.ins.scaleAimOn)
- {
- if (CameraToLook.ins != null)
- {
- // 平滑旋转逻辑
- float dt = Mathf.Min(Time.unscaledDeltaTime, 0.05f); // 避免低帧率造成旋转跳跃
- float smoothingFactor = GameMgr.gameType == 1 ? 12 : 7f; // 原始未开镜的FOV,可调节,数值越大越“跟手”
- CameraToLook.ins.localRotation = Quaternion.Slerp(
- CameraToLook.ins.localRotation,
- quat,
- dt * GameAssistUI.ins.currentSensitivity * smoothingFactor
- );
- }
- }
- else
- {
- if (CameraToLook.ins != null) CameraToLook.ins.localRotation = quat;
- }
- if (SB_EventSystem.ins) SB_EventSystem.ins.MoveSimulateMouseByInfrared(screenPoint);
- //移动目标游戏
- if (GeneratingTarget.gm != null) GeneratingTarget.gm.shootingEvent.OnPositionUpdate(screenPoint);
- }
-
-
- // Update is called once per frame
- void Update()
- {
- }
- }
- }
|