修复 2021.3.2f1 工程中出现的api缺失问题

This commit is contained in:
2026-06-25 14:50:57 +08:00
parent bfce70eb6f
commit af50f72656
2 changed files with 100 additions and 70 deletions

View File

@@ -1,6 +1,6 @@
/*
* UniWindowController.cs
*
*
* Author: Kirurobo http://twitter.com/kirurobo
* License: MIT
*/
@@ -17,6 +17,7 @@ using UnityEngine.Events;
using System.Linq;
#endif
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif
@@ -24,22 +25,23 @@ using UnityEngine.InputSystem;
namespace Kirurobo
{
/// @cond DOXYGEN_SHOW_INTERNAL_CLASSES
/// <summary>
/// 使布尔属性可编辑
/// </summary>
[System.AttributeUsage(System.AttributeTargets.Field, Inherited = true, AllowMultiple = false)]
public class EditablePropertyAttribute : UnityEngine.PropertyAttribute { }
public class EditablePropertyAttribute : UnityEngine.PropertyAttribute
{
}
/// <summary>
/// 将属性设置为只读
/// </summary>
[System.AttributeUsage(System.AttributeTargets.Field, Inherited = true, AllowMultiple = false)]
public class ReadOnlyAttribute : UnityEngine.PropertyAttribute { }
public class ReadOnlyAttribute : UnityEngine.PropertyAttribute
{
}
/// @endcond
/// <summary>
/// Windows/Mac 统一窗口控制器
/// </summary>
@@ -113,6 +115,7 @@ namespace Kirurobo
/// 获取当前 UniWindowController 实例
/// </summary>
public static UniWindowController current => _current ? _current : FindOrCreateInstance();
private static UniWindowController _current;
/// <summary>
@@ -128,6 +131,7 @@ namespace Kirurobo
get { return _isClickThrough; }
set { SetClickThrough(value); }
}
private bool _isClickThrough = false;
/// <summary>
@@ -138,6 +142,7 @@ namespace Kirurobo
get { return _isTransparent; }
set { SetTransparent(value); }
}
[SerializeField, EditableProperty, Tooltip("选中后启动时设置为透明")]
private bool _isTransparent = false;
@@ -149,6 +154,7 @@ namespace Kirurobo
get { return _alphaValue; }
set { SetAlphaValue(value); }
}
[SerializeField, EditableProperty, Tooltip("窗口透明度"), Range(0f, 1f)]
private float _alphaValue = 1.0f;
@@ -160,6 +166,7 @@ namespace Kirurobo
get { return ((_uniWinCore == null) ? _isTopmost : _isTopmost = _uniWinCore.IsTopmost); }
set { SetTopmost(value); }
}
[SerializeField, EditableProperty, Tooltip("选中后启动时置顶")]
private bool _isTopmost = false;
@@ -171,6 +178,7 @@ namespace Kirurobo
get { return ((_uniWinCore == null) ? _isBottommost : _isBottommost = _uniWinCore.IsBottommost); }
set { SetBottommost(value); }
}
[SerializeField, EditableProperty, Tooltip("选中后启动时置底")]
private bool _isBottommost = false;
@@ -182,6 +190,7 @@ namespace Kirurobo
get { return ((_uniWinCore == null) ? _isZoomed : _isZoomed = _uniWinCore.GetZoomed()); }
set { SetZoomed(value); }
}
[SerializeField, EditableProperty, Tooltip("选中后启动时最大化")]
private bool _isZoomed = false;
@@ -193,6 +202,7 @@ namespace Kirurobo
get { return _shouldFitMonitor; }
set { FitToMonitor(value, _monitorToFit); }
}
[SerializeField, EditableProperty, Tooltip("选中后将窗口适配到显示器")]
private bool _shouldFitMonitor = false;
@@ -204,6 +214,7 @@ namespace Kirurobo
get { return _monitorToFit; }
set { FitToMonitor(_shouldFitMonitor, value); }
}
private int _monitorToFit = 0;
/// <summary>
@@ -214,6 +225,7 @@ namespace Kirurobo
get { return _allowDropFiles; }
set { SetAllowDrop(value); }
}
[SerializeField, EditableProperty, Tooltip("启用文件或文件夹拖放")]
private bool _allowDropFiles = false;
@@ -226,8 +238,7 @@ namespace Kirurobo
/// <summary>
/// 点击穿透自动判定的方法
/// </summary>
[Tooltip("选择方法")]
public HitTestType hitTestType = HitTestType.Opacity;
[Tooltip("选择方法")] public HitTestType hitTestType = HitTestType.Opacity;
/// <summary>
/// 点击穿透判定方法为不透明度时使用的阈值
@@ -244,8 +255,7 @@ namespace Kirurobo
/// <summary>
/// 启用后,窗口透明时会自动将相机背景改为单色黑色透明
/// </summary>
[Header("高级设置")]
[Tooltip("窗口透明时更改相机背景")]
[Header("高级设置")] [Tooltip("窗口透明时更改相机背景")]
public bool autoSwitchCameraBackground = true;
/// <summary>
@@ -255,54 +265,53 @@ namespace Kirurobo
/// 仅在启动时生效
/// 在 Mac 上,即使强制退出全屏,似乎仍会变成另一个画面,效果不大
/// </summary>
[Tooltip("启动时强制窗口模式")]
public bool forceWindowed = false;
[Tooltip("启动时强制窗口模式")] public bool forceWindowed = false;
/// <summary>
/// 相机实例
/// </summary>
[Tooltip("未设置时使用主相机")]
public Camera currentCamera;
[Tooltip("未设置时使用主相机")] public Camera currentCamera;
/// <summary>
/// 透明方式的指定
/// </summary>
[Header("仅限 Windows")]
[Tooltip("选择透明方式。*仅 Windows 可用")]
[Header("仅限 Windows")] [Tooltip("选择透明方式。*仅 Windows 可用")]
public TransparentType transparentType = TransparentType.Alpha;
/// <summary>
/// 当透明类型为 ColorKey 时使用的键色
/// </summary>
[Tooltip("将在窗口下次变为透明时使用")]
public Color32 keyColor = new Color32(0x01, 0x00, 0x01, 0x00);
[Tooltip("将在窗口下次变为透明时使用")] public Color32 keyColor = new Color32(0x01, 0x00, 0x01, 0x00);
/// <summary>
/// 在 macOS 上,是否允许将窗口放置在菜单栏上方
/// </summary>
public bool isFreePositioningEnabled
{
get { return ((_uniWinCore == null) ? _isFreePositioningEnabled : _isFreePositioningEnabled = _uniWinCore.IsFreePositioningEnabled); }
get
{
return ((_uniWinCore == null)
? _isFreePositioningEnabled
: _isFreePositioningEnabled = _uniWinCore.IsFreePositioningEnabled);
}
set { SetFreePositioning(value); }
}
[Header("仅限 macOS")]
[Tooltip("禁用 constrainFrameRect() *仅 macOS 可用")]
[SerializeField, EditableProperty]
[Header("仅限 macOS")] [Tooltip("禁用 constrainFrameRect() *仅 macOS 可用")] [SerializeField, EditableProperty]
private bool _isFreePositioningEnabled = false;
/// <summary>
/// 鼠标指针是否在不透明像素或物体上
/// </summary>
[Header("状态")]
[SerializeField, ReadOnly, Tooltip("鼠标指针是否在不透明像素上?(只读)")]
[Header("状态")] [SerializeField, ReadOnly, Tooltip("鼠标指针是否在不透明像素上?(只读)")]
private bool onObject = true;
/// <summary>
/// 鼠标指针下方的像素颜色。(只读)
/// </summary>
[SerializeField, ReadOnly, Tooltip("鼠标指针下方的像素颜色。(只读)")]
public Color pickedColor;
/// <summary>
/// 获取/设置窗口坐标
/// </summary>
@@ -361,11 +370,12 @@ namespace Kirurobo
/// Raycast 时的图层遮罩
/// </summary>
private int hitTestLayerMask;
/// <summary>
/// 窗口样式改变时发生
/// </summary>
public event OnStateChangedDelegate OnStateChanged;
public delegate void OnStateChangedDelegate(WindowStateEventType type);
public delegate void FilesDelegate(string[] files);
@@ -379,6 +389,7 @@ namespace Kirurobo
/// 显示器设置或分辨率改变时发生
/// </summary>
public event OnMonitorChangedDelegate OnMonitorChanged;
public delegate void OnMonitorChangedDelegate();
@@ -421,12 +432,11 @@ namespace Kirurobo
{
originalCameraClearFlags = currentCamera.clearFlags;
originalCameraBackground = currentCamera.backgroundColor;
}
// 鼠标事件信息
pointerEventData = new PointerEventData(EventSystem.current);
// 使用 Ignore Raycast 之外的图层作为有效遮罩
hitTestLayerMask = ~LayerMask.GetMask("Ignore Raycast");
@@ -451,6 +461,7 @@ namespace Kirurobo
{
targetMonitorIndex = 0;
}
if (monitors <= targetMonitorIndex)
{
targetMonitorIndex = monitors - 1;
@@ -468,8 +479,12 @@ namespace Kirurobo
/// <returns></returns>
private static UniWindowController FindOrCreateInstance()
{
#if UNITY_2022_1_OR_NEWER
var instance = GameObject.FindAnyObjectByType<UniWindowController>();
#else
var instance = GameObject.FindObjectOfType<UniWindowController>();
#endif
// 目前禁止自动创建
// // 场景中未找到时创建新实例
// if (!instance)
@@ -480,7 +495,7 @@ namespace Kirurobo
return instance;
}
void Start()
{
//// New Input System 存在兼容性问题,用于验证输出
@@ -535,11 +550,12 @@ namespace Kirurobo
if (_uniWinCore == null || !_uniWinCore.IsActive)
{
UpdateTargetWindow();
} else
}
else
{
_uniWinCore.Update();
}
// 处理事件
UpdateEvents();
@@ -574,7 +590,7 @@ namespace Kirurobo
// //shouldFitMonitor = false; // 禁用适配
// }
if (_shouldFitMonitor) StartCoroutine("ForceZoomed"); // 延迟强制最大化
OnStateChanged?.Invoke((WindowStateEventType)type);
}
}
@@ -627,7 +643,7 @@ namespace Kirurobo
{
// 没有自动点击测试则结束
if (!isHitTestEnabled || hitTestType == HitTestType.None) return;
// 鼠标光标隐藏状态视为在透明像素上
bool hit = (onObject);
@@ -682,6 +698,7 @@ namespace Kirurobo
onObject = true;
}
}
yield return null;
}
@@ -690,7 +707,6 @@ namespace Kirurobo
/// </summary>
private Vector2 GetClientCursorPosition()
{
// New Input System 在没有焦点时无法获取鼠标坐标,因此自行计算
Vector2 mousePos = UniWinCore.GetCursorPosition();
Vector2 winPos = windowPosition;
@@ -698,7 +714,7 @@ namespace Kirurobo
Vector2 unityPos = new Vector2(
(mousePos.x - winPos.x - clientRect.x) * Screen.width / clientRect.width,
(mousePos.y - winPos.y - clientRect.y) * Screen.height / clientRect.height
);
);
// // 调试用
// // 与 Unity 获取的值进行比较
@@ -714,14 +730,14 @@ namespace Kirurobo
// 在编辑器中始终使用 Unity 功能获取鼠标坐标
// Game 窗口可能不是唯一窗口,或 Scale 不同,无法简单计算
#if UNITY_EDITOR
#if ENABLE_LEGACY_INPUT_MANAGER
#if UNITY_EDITOR
#if ENABLE_LEGACY_INPUT_MANAGER
return Input.mousePosition;
#elif UNITY_EDITOR && ENABLE_INPUT_SYSTEM
#elif UNITY_EDITOR && ENABLE_INPUT_SYSTEM
return Mouse.current.position.ReadValue();
#else
#else
return unityPos;
#endif
#endif
#else
return unityPos;
#endif
@@ -762,8 +778,8 @@ namespace Kirurobo
// 在屏幕外则视为透明
if (
mousePos.x < 0 || mousePos.x >= w
|| mousePos.y < 0 || mousePos.y >= h
)
|| mousePos.y < 0 || mousePos.y >= h
)
{
return false;
}
@@ -775,14 +791,14 @@ namespace Kirurobo
if (transparentType == TransparentType.ColorKey) return true;
// 根据指定坐标的绘制结果进行判断
try // 在 WaitForEndOfFrame 时机执行的话,不需要 try 应该也没问题
try // 在 WaitForEndOfFrame 时机执行的话,不需要 try 应该也没问题
{
// 参考 http://tsubakit1.hateblo.jp/entry/20131203/1386000440
colorPickerTexture.ReadPixels(new Rect(mousePos, Vector2.one), 0, 0);
Color color = colorPickerTexture.GetPixels32()[0];
pickedColor = color;
return (color.a >= opacityThreshold); // alpha 达到阈值则视为不透明
return (color.a >= opacityThreshold); // alpha 达到阈值则视为不透明
}
catch (System.Exception ex)
{
@@ -797,7 +813,7 @@ namespace Kirurobo
private void HitTestByRaycast()
{
Vector2 position = GetClientCursorPosition();
// // 判断是否在 uGUI 上
var raycastResults = new List<RaycastResult>();
pointerEventData.position = position;
@@ -838,7 +854,8 @@ namespace Kirurobo
onObject = true;
return;
}
} else
}
else
{
// 如果相机无效,则获取主相机
currentCamera = Camera.main;
@@ -878,6 +895,7 @@ namespace Kirurobo
{
SetTopmost(_isTopmost);
}
SetZoomed(_isZoomed);
SetClickThrough(_isClickThrough);
SetAllowDrop(_allowDropFiles);
@@ -889,11 +907,11 @@ namespace Kirurobo
}
else
{
#if UNITY_EDITOR
#if UNITY_EDITOR
// 在编辑器中,由于 Game 视图可能被关闭或停靠,如果发生变化则更改目标窗口
// 如果活动窗口与当前目标相同,则不执行任何操作
_uniWinCore.AttachMyActiveWindow();
#endif
#endif
}
}
@@ -974,7 +992,8 @@ namespace Kirurobo
/// <param name="type"></param>
public void SetTransparentType(TransparentType type)
{
if (_uniWinCore != null) {
if (_uniWinCore != null)
{
// 如果正在透明中,则先解除再重新透明
if (_isTransparent)
{
@@ -1081,6 +1100,7 @@ namespace Kirurobo
{
return new Rect(position, size);
}
return Rect.zero;
}
@@ -1115,7 +1135,7 @@ namespace Kirurobo
UpdateMonitorFitting();
}
}
}
}
else
{
if (_shouldFitMonitor)
@@ -1147,7 +1167,7 @@ namespace Kirurobo
{
return UniWinCore.GetCursorPosition();
}
/// <summary>
/// 设置鼠标光标位置
/// </summary>
@@ -1218,10 +1238,12 @@ namespace Kirurobo
[Obsolete]
public int GetDebugInfo()
{
if (_uniWinCore != null) {
if (_uniWinCore != null)
{
return UniWinCore.GetDebugInfo();
}
return 0;
}
}
}
}

View File

@@ -1,6 +1,6 @@
/*
* UniWindowDragMove.cs
*
*
* 作者: Kirurobo http://twitter.com/kirurobo
* 许可证: MIT
*/
@@ -10,22 +10,23 @@ using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.EventSystems;
#if ENABLE_LEGACY_INPUT_MANAGER
#elif ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif
namespace Kirurobo
namespace Kirurobo
{
public class UniWindowMoveHandle : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler, IPointerUpHandler
public class UniWindowMoveHandle : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler,
IPointerUpHandler
{
private UniWindowController _uniwinc;
/// <summary>
/// 窗口最大化时是否禁用移动
/// </summary>
[Tooltip("窗口已最大化(缩放)时禁用拖拽移动。")]
public bool disableOnZoomed = true;
[Tooltip("窗口已最大化(缩放)时禁用拖拽移动。")] public bool disableOnZoomed = true;
/// <summary>
/// 拖动中则为 true
@@ -34,6 +35,7 @@ namespace Kirurobo
{
get { return _isDragging; }
}
private bool _isDragging = false;
/// <summary>
@@ -56,17 +58,21 @@ namespace Kirurobo
/// 记录拖动前自动命中测试是否启用
/// </summary>
private bool _isHitTestEnabled;
/// <summary>
/// 拖动开始时窗口内坐标[像素]
/// </summary>
private Vector2 _dragStartedPosition;
// 首次帧更新前调用 Start
void Start()
{
// 获取场景中的 UniWindowController
#if UNITY_2022_1_OR_NEWER
_uniwinc = GameObject.FindAnyObjectByType<UniWindowController>();
#else
_uniwinc = GameObject.FindObjectOfType<UniWindowController>();
#endif
if (_uniwinc) _isHitTestEnabled = _uniwinc.isHitTestEnabled;
//// 下面的代码似乎不需要,所以注释掉以免擅自更改
@@ -85,7 +91,7 @@ namespace Kirurobo
// 仅通过鼠标左键拖动
if (eventData.button != PointerEventData.InputButton.Left) return;
// Mac 上行为会有所不同
// 实际上仅在 Retina 支持启用时,但 eventData.position 的坐标系与窗口坐标系的缩放会不一致
#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX
@@ -93,7 +99,7 @@ namespace Kirurobo
#else
_dragStartedPosition = eventData.position;
#endif
// 如果 _isDragging 为 false则判断即将开始拖动
if (!_isDragging)
{
@@ -102,7 +108,7 @@ namespace Kirurobo
_uniwinc.isHitTestEnabled = false;
_uniwinc.isClickThrough = false;
}
_isDragging = true;
}
@@ -130,11 +136,12 @@ namespace Kirurobo
{
if (_isDragging)
{
_uniwinc.isHitTestEnabled = _isHitTestEnabled;
_uniwinc.isHitTestEnabled = _isHitTestEnabled;
}
_isDragging = false;
}
/// <summary>
/// 非最大化时,通过鼠标拖动移动窗口
/// </summary>
@@ -158,7 +165,8 @@ namespace Kirurobo
// 如果鼠标按钮已松开,则结束拖动
var buttons = UniWindowController.GetMouseButtons();
if ((buttons & UniWindowController.MouseButton.Left) == UniWindowController.MouseButton.None) {
if ((buttons & UniWindowController.MouseButton.Left) == UniWindowController.MouseButton.None)
{
EndDragging();
return;
}
@@ -203,4 +211,4 @@ namespace Kirurobo
#endif
}
}
}
}