6 Commits
Author SHA1 Message Date
lrss3 8a57080868 修改了源码,支持了半透明以及半透明类型 2026-07-27 10:43:49 +08:00
lrss3 6f07df5ded 调整shader为urp 2026-07-27 10:43:11 +08:00
lrss3 07bb4c7c9c 补充示例 2026-07-25 15:42:00 +08:00
lrss3 d4ae58193d 修复inputsystem引用 2026-07-12 12:15:27 +08:00
lrss3 ad9c111de3 Merge branch 'Dev' 2026-07-10 12:28:42 +08:00
lrss3 90debbdc70 移除32位部分,因为这会导致冲突。 2026-07-10 12:28:34 +08:00
61 changed files with 692 additions and 411 deletions
@@ -1,10 +1,19 @@
{
"name": "Lrss3.Xuniwindowcontroller.Editor",
"rootNamespace": "",
"references": [
"Lrss3.Xuniwindowcontroller"
"Lrss3.Xuniwindowcontroller",
"Unity.InputSystem"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": []
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
+12 -2
View File
@@ -1,6 +1,16 @@
{
"name": "Lrss3.Xuniwindowcontroller",
"references": [],
"rootNamespace": "",
"references": [
"Unity.InputSystem"
],
"includePlatforms": [],
"excludePlatforms": []
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
+1 -1
View File
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: b9161ad40887a5746afa1d4eb780f60a
guid: 1b2fb2965b4b647beb75e5d55e9c8d6b
folderAsset: yes
DefaultImporter:
externalObjects: {}
Binary file not shown.
@@ -11,17 +11,59 @@ PluginImporter:
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Editor: 0
Exclude Linux64: 0
Exclude OSXUniversal: 0
Exclude WebGL: 1
Exclude Win: 1
Exclude Win64: 0
- first:
Any:
second:
enabled: 1
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
CPU: x86_64
DefaultValueInitialized: true
OS: Windows
- first:
Standalone: Linux64
second:
enabled: 1
settings:
CPU: AnyCPU
- first:
Standalone: OSXUniversal
second:
enabled: 1
settings:
CPU: None
- first:
Standalone: Win
second:
enabled: 0
settings:
DefaultValueInitialized: true
CPU: None
- first:
Standalone: Win64
second:
enabled: 1
settings:
CPU: x86_64
- first:
WebGL: WebGL
second:
enabled: 0
settings: {}
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.
@@ -1,27 +0,0 @@
fileFormatVersion: 2
guid: 94d4ed4ccee04184c93f70e00c6f442c
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
userData:
assetBundleName:
assetBundleVariant:
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 1afe0de787d9c9b419c0083741340611
guid: e224aeabe6945c54e845bf690e104015
folderAsset: yes
DefaultImporter:
externalObjects: {}
+193
View File
@@ -0,0 +1,193 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &9167954367597434767
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 9167954367597434766}
- component: {fileID: 9167954367597434803}
- component: {fileID: 9167954367597434764}
- component: {fileID: 9167954367597434765}
m_Layer: 2
m_Name: WindowMoveHandle
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &9167954367597434766
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9167954367597434767}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 9167954367673589915}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &9167954367597434803
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9167954367597434767}
m_CullTransparentMesh: 0
--- !u!114 &9167954367597434764
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9167954367597434767}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0, g: 0, b: 0, a: 0}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0}
m_Type: 1
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!114 &9167954367597434765
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9167954367597434767}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: dd641513c2924f7488734c8cac43310f, type: 3}
m_Name:
m_EditorClassIdentifier:
disableOnZoomed: 1
--- !u!1 &9167954367673589911
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 9167954367673589915}
- component: {fileID: 9167954367673589908}
- component: {fileID: 9167954367673589909}
- component: {fileID: 9167954367673589910}
m_Layer: 5
m_Name: DragMoveCanvas
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &9167954367673589915
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9167954367673589911}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0, y: 0, z: 0}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 9167954367597434766}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 0}
--- !u!223 &9167954367673589908
Canvas:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9167954367673589911}
m_Enabled: 1
serializedVersion: 3
m_RenderMode: 0
m_Camera: {fileID: 0}
m_PlaneDistance: 100
m_PixelPerfect: 1
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_AdditionalShaderChannelsFlag: 0
m_SortingLayerID: 0
m_SortingOrder: -99
m_TargetDisplay: 0
--- !u!114 &9167954367673589909
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9167954367673589911}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
m_Name:
m_EditorClassIdentifier:
m_UiScaleMode: 0
m_ReferencePixelsPerUnit: 100
m_ScaleFactor: 1
m_ReferenceResolution: {x: 800, y: 600}
m_ScreenMatchMode: 0
m_MatchWidthOrHeight: 0
m_PhysicalUnit: 3
m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1
m_PresetInfoIsWorld: 0
--- !u!114 &9167954367673589910
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9167954367673589911}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreReversedGraphics: 1
m_BlockingObjects: 0
m_BlockingMask:
serializedVersion: 2
m_Bits: 4294967295
@@ -1,6 +1,6 @@
fileFormatVersion: 2
guid: 9cdd0222c2019eb4f984a69d349fa385
AssemblyDefinitionImporter:
guid: d7dcf50428b152040847878685fe0746
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
@@ -0,0 +1,66 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &2416199871598626844
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2416199871598626842}
- component: {fileID: 2416199871598626845}
m_Layer: 0
m_Name: UniWindowController
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &2416199871598626842
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2416199871598626844}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &2416199871598626845
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2416199871598626844}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d327b245537480646bd85e511002d6ce, type: 3}
m_Name:
m_EditorClassIdentifier:
_isTransparent: 0
_alphaValue: 1
_isTopmost: 0
_isBottommost: 0
_isZoomed: 0
_shouldFitMonitor: 0
_allowDropFiles: 0
isHitTestEnabled: 1
hitTestType: 1
opacityThreshold: 0.1
autoSwitchCameraBackground: 1
forceWindowed: 0
currentCamera: {fileID: 0}
transparentType: 1
keyColor:
serializedVersion: 2
rgba: 65537
_isFreePositioningEnabled: 0
onObject: 1
pickedColor: {r: 0, g: 0, b: 0, a: 0}
@@ -1,6 +1,6 @@
fileFormatVersion: 2
guid: 536bc02f6b95d694cbf83ddcac597970
AssemblyDefinitionImporter:
guid: e893aefd93740714b999573b02916984
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
@@ -15,7 +15,7 @@ namespace Kirurobo
private void Awake()
{
// 设为单例。若已有实例则销毁自身
// シングルトンとする。既にインスタンスがあれば自分を破棄
if (this != Instance)
{
Destroy(this.gameObject);
@@ -29,7 +29,7 @@ namespace Kirurobo
}
/// <summary>
/// 场景加载时记录主相机
/// シーンロード時にメインカメラを記憶
/// </summary>
/// <param name="arg0"></param>
/// <param name="arg1"></param>
@@ -39,19 +39,19 @@ namespace Kirurobo
}
/// <summary>
/// 打开指定名称的场景
/// 指定の名前のシーンを開く
/// </summary>
/// <param name="name">场景名</param>
/// <param name="name">シーン名</param>
public void LoadScene(string name)
{
if (name == "SimpleSample")
{
// SimpleSample 时无脚本控制,在此处设置透明
// SimpleSample の場合はスクリプトでの制御がないため、ここで透明
UniWindowController.current.isTransparent = true;
}
else if (name == "FullScreenSample")
{
// FullScreenSample 时强制最大化
// FullScreenSample の場合は強制的に最大化
UniWindowController.current.shouldFitMonitor = true;
}
@@ -59,7 +59,7 @@ namespace Kirurobo
}
/// <summary>
/// 退出
/// 終了
/// </summary>
public void Quit()
{
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 7b16c3acbffcdc7478199eacc7ec8497
guid: c83c7f09afe53854b909aed0ea55a3cd
MonoImporter:
externalObjects: {}
serializedVersion: 2
@@ -1,6 +1,5 @@
fileFormatVersion: 2
guid: 4f4b26af82054284b89cba410c27b75d
folderAsset: yes
guid: bca881472b6085049ad37ab0ad8fe61e
DefaultImporter:
externalObjects: {}
userData:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 970bccad986844364a272b0245fed77e
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 4890085278179872738
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b650a883366376446b7db29169c59420
timeCreated: 1545989238
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c4f4adeee10bff845b320d93a6b82f54
timeCreated: 1545989238
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 38b9db02f63429f49bd117e7f988d985
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,5 +1,5 @@
/**
* UniWindowController
* A sample script of UniWindowContoller
*
* Author: Kirurobo http://twitter.com/kirurobo
* License: MIT
@@ -13,7 +13,7 @@ using UnityEngine.UI;
namespace Kirurobo
{
/// <summary>
/// 使用 Toggle 开关 WindowController 设置的示例
/// WindowControllerの設定をToggleでオン/オフするサンプル
/// </summary>
public class UiSampleController : MonoBehaviour
{
@@ -21,14 +21,14 @@ namespace Kirurobo
private UniWindowMoveHandle uniWinMoveHandle;
private RectTransform canvasRect;
private float mouseMoveSS = 0f; // 鼠标轨迹平方和。[px^2]
private float mouseMoveSSThreshold = 36f; // 点击(非拖拽)阈值。[px^2]
private Vector3 lastMousePosition; // 右键点击位置。
private float lastEventOccurredTime = -5f; // 上次事件发生的时间戳 [s]
private float eventMessageTimeout = 1f; // 在此时间段内显示事件消息 [s]
private float mouseMoveSS = 0f; // Sum of mouse trajectory squares. [px^2]
private float mouseMoveSSThreshold = 36f; // Click (not dragging) threshold. [px^2]
private Vector3 lastMousePosition; // Right clicked position.
private float lastEventOccurredTime = -5f; // Timestamp the last event occurred [s]
private float eventMessageTimeout = 1f; // Show event message while this period [s]
#if ENABLE_LEGACY_INPUT_MANAGER
private float touchDuration = 0f;
private float touchDurationThreshold = 0.5f; // 长按时间阈值。[s]
private float touchDurationThreshold = 0.5f; // Long tap time threshold. [s]
#endif
public Toggle transparentToggle;
public Slider alphaSlider;
@@ -55,28 +55,28 @@ namespace Kirurobo
public RectTransform borderlinePanel;
/// <summary>
/// 初
/// 初
/// </summary>
void Start()
{
// 查找 UniWindowController
// UniWindowController を探す
uniwinc = UniWindowController.current;
// 查找 UniWindowDragMove
// UniWindowDragMove を探す
uniWinMoveHandle = GameObject.FindAnyObjectByType<UniWindowMoveHandle>();
// 获取 CanvasRectTransform
// CanvasRectTransform取得
if (menuPanel) canvasRect = menuPanel.GetComponentInParent<Canvas>().GetComponent<RectTransform>();
// 根据有效显示器数量创建选项
// 有効なモニタ数に合わせて選択肢を作成
UpdateMonitorDropdown();
// Toggle 的选中状态与当前状态同步
// Toggleのチェック状態を、現在の状態に合わせる
UpdateUI();
if (uniwinc)
{
// 操作 UI 时将其反映到窗口
// UIを操作された際にはウィンドウに反映されるようにする
transparentToggle?.onValueChanged.AddListener(val => uniwinc.isTransparent = val);
alphaSlider?.onValueChanged.AddListener(val => uniwinc.alphaValue = val);
topmostToggle?.onValueChanged.AddListener(val => uniwinc.isTopmost = val);
@@ -100,25 +100,25 @@ namespace Kirurobo
if (uniWinMoveHandle) dragMoveToggle?.onValueChanged.AddListener(val => uniWinMoveHandle.enabled = val);
#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX
// 如果不是 Windows,则禁用透明方式选择
// Windows でなければ、透過方法の選択は無効とする
//if (transparentTypeDropdown) transparentTypeDropdown.interactable = false;
//if (transparentTypeDropdown) transparentTypeDropdown.enabled = false;
if (transparentTypeDropdown) transparentTypeDropdown.gameObject.SetActive(false);
#endif
// 添加事件
// Add events
uniwinc.OnStateChanged += (type) =>
{
UpdateUI();
//Debug.Log("Window state changed: " + type);
ShowEventMessage("状态改变: " + type);
ShowEventMessage("State changed: " + type);
//ShowEventMessage("State changed: " + type + "4:isKey 2:canBecomeKey, 1:canBecomeMain : " + uniwinc.GetDebugInfo().ToString());
ShowClientSize();
};
uniwinc.OnMonitorChanged += () => {
UpdateMonitorDropdown();
UpdateUI();
ShowEventMessage("分辨率已改变!");
ShowEventMessage("Resolution changed!");
ShowClientSize();
};
uniwinc.OnDropFiles += files =>
@@ -127,12 +127,12 @@ namespace Kirurobo
};
}
// 即使 UinWinC 未就绪也能运行的 Listener
// UinWinCが準備できてなくても動くListener
showBorderlineToggle?.onValueChanged.AddListener(val => borderlinePanel.gameObject.SetActive(val));
}
/// <summary>
/// 显示带超时功能的消息
/// Show the message with timeout
/// </summary>
/// <param name="message"></param>
private void ShowEventMessage(string message)
@@ -144,20 +144,20 @@ namespace Kirurobo
}
/// <summary>
/// 每帧执行的处
/// 毎フレーム行う処
/// </summary>
private void Update()
{
// 更新点击测试相关的显示
// ヒットテスト関連の表示を更新
UpdateHitTestUI();
// 显示窗口位置和大小以确认运行状态
// 動作確認のためウィンドウ位置・サイズを表示
if ((lastEventOccurredTime + eventMessageTimeout) < Time.time)
{
ShowWindowMetrics();
}
// 鼠标右键点击显示菜单。移动距离在阈值以下视为点击
// マウス右ボタンクリックでメニューを表示させる。閾値以下の移動ならクリックとみなす
if (InputProxy.GetMouseButtonDown(1))
{
lastMousePosition = InputProxy.mousePosition;
@@ -178,7 +178,7 @@ namespace Kirurobo
}
#if ENABLE_LEGACY_INPUT_MANAGER
// 长按也可显示菜单
// ロングタッチでもメニューを表示させる
if (Input.touchSupported && (Input.touchCount > 0))
{
Touch touch = Input.GetTouch(0);
@@ -203,38 +203,38 @@ namespace Kirurobo
}
}
#elif ENABLE_INPUT_SYSTEM
// 目前 New Input System 不支持触摸
// EnhancedTouch 不能与 InputAction 同时使用
// 現状、New Input System ではタッチ対応は無し
// EnhancedTouch InputAction と併用不可
#endif
// 按键也可更改设置
// キーでも設定変更
if (uniwinc)
{
// 切换透明模式
// Toggle transparent
if (InputProxy.GetKeyUp("t"))
{
uniwinc.isTransparent = !uniwinc.isTransparent;
}
// 切换始终置顶
// Toggle always on the front
if (InputProxy.GetKeyUp("f"))
{
uniwinc.isTopmost = !uniwinc.isTopmost;
}
// 切换始终置底
// Toggle always on the bottom
if (InputProxy.GetKeyUp("b"))
{
uniwinc.isBottommost = !uniwinc.isBottommost;
}
// 切换最大化
// Toggle zoom
if (InputProxy.GetKeyUp("z"))
{
uniwinc.isZoomed = !uniwinc.isZoomed;
}
// 切换自由定位
// Toggle free positioning
if (InputProxy.GetKeyUp("p"))
{
uniwinc.isFreePositioningEnabled = !uniwinc.isFreePositioningEnabled;
@@ -242,13 +242,13 @@ namespace Kirurobo
}
// 测试打开文件面板
// Test for OpenFilePanel
if (InputProxy.GetKeyUp("o"))
{
FilePanel.Settings ds = new FilePanel.Settings
{
flags = FilePanel.Flag.AllowMultipleSelection,
title = "打开!",
title = "Open!",
filters = new FilePanel.Filter[]{
new FilePanel.Filter("Image files", "png", "jpg", "jpeg"),
new FilePanel.Filter("All files", "*"),
@@ -259,17 +259,17 @@ namespace Kirurobo
FilePanel.OpenFilePanel(ds, (files) => ShowEventMessage(string.Join(Environment.NewLine, files)));
}
// 测试保存文件面板
// Test for SaveFilePanel
if (InputProxy.GetKeyUp("s"))
{
FilePanel.Settings ds = new FilePanel.Settings
{
flags = FilePanel.Flag.AllowMultipleSelection,
title = "保存!",
title = "Save!",
filters = new FilePanel.Filter[]{
//// TODO: 指定文件类型时,macOS 保存对话框打开会失败
//// NSSavePanel.accessoryView 指定内容时会发生此问题
//// NSOpenPanel 继承自它,但不会发生此问题
//// TODO: ファイル種類指定があると、macOS保存ダイアログを開くことに失敗する
//// NSSavePanel.accessoryView に何か指定すると発生する
//// それが継承された NSOpenPanel では発生しない
// new FilePanel.Filter("Shell script", "sh"),
// new FilePanel.Filter("Log", "log"),
// new FilePanel.Filter("Plain text", "txt"),
@@ -281,7 +281,7 @@ namespace Kirurobo
FilePanel.SaveFilePanel(ds, (files) => ShowEventMessage(string.Join(Environment.NewLine, files)));
}
// 按下 [ESC] 时退出或停止播放
// Quit or stop playing when pressed [ESC]
if (InputProxy.GetKeyUp("escape"))
{
#if UNITY_EDITOR
@@ -293,8 +293,8 @@ namespace Kirurobo
}
/// <summary>
/// 重置持续触摸时间的记录
/// 仅在 Legacy Input Manager 中处理以避免警告
/// タッチされ続けている時間の記録をリセット
/// 警告が出ないように Legacy Input Manager でのみ処理している
/// </summary>
void ResetTouchDuration() {
#if ENABLE_LEGACY_INPUT_MANAGER
@@ -303,7 +303,7 @@ namespace Kirurobo
}
/// <summary>
/// 适配显示器下拉列表更改时的处
/// フィット対象モニタドロップダウンが変更された時の処
/// </summary>
/// <param name="val"></param>
void SetFitToMonitor(int val)
@@ -312,25 +312,25 @@ namespace Kirurobo
if (val < 1)
{
// 下拉列表第一项为不适配
// ドロップダウンの先頭は、フィット無し
uniwinc.shouldFitMonitor = false;
// 允许更改最大化状态
// 最大化を変更できるようにする
if (zoomedToggle) zoomedToggle.interactable = true;
}
else
{
// 由于从第二项开始,显示器编号减1
// 次からなので、モニタ番号は1を引く
uniwinc.monitorToFit = val - 1;
uniwinc.shouldFitMonitor = true; // false变为true时才会移动窗口,因此先指定显示器编号再更改
uniwinc.shouldFitMonitor = true; // これがfalseからtrueにしたタイミングで移動されるため、モニタ番号を指定してから変更
// 禁止更改最大化状态
// 最大化を変更不可にする
if (zoomedToggle) zoomedToggle.interactable = false;
}
}
/// <summary>
/// 显示窗口位置和坐标
/// ウィンドウ位置と座標を表示
/// </summary>
void ShowWindowMetrics()
{
@@ -339,18 +339,18 @@ namespace Kirurobo
var winPos = uniwinc.windowPosition;
//var curPos = uniwinc.GetClientCursorPosition();
OutputMessage(
"位置: " + winPos
+ "\n大小: " + uniwinc.windowSize
+ "\n相对鼠标:" + (uniwinc.cursorPosition - winPos)
"Pos.: " + winPos
+ "\nSize: " + uniwinc.windowSize
+ "\nRel. Cur.:" + (uniwinc.cursorPosition - winPos)
//+ "\nScr. Cur.:" + curPos
+ "\nUnity鼠标:" + (Vector2)InputProxy.mousePosition
+ "\nUnity Cur.:" + (Vector2)InputProxy.mousePosition
);
ShowClientSize();
}
}
/// <summary>
/// 聚焦时刷新 UI
/// Refresh UI on focused
/// </summary>
/// <param name="hasFocus"></param>
private void OnApplicationFocus(bool hasFocus)
@@ -361,20 +361,20 @@ namespace Kirurobo
if (uniwinc)
{
OutputMessage("已聚焦");
OutputMessage("Focused");
}
else
{
OutputMessage("未找到 UniWindowController");
OutputMessage("No UniWindowController");
}
}
}
/// <summary>
/// 指定坐标显示上下文菜单
/// 指定した座標にコンテキストメニューを表示する
/// </summary>
/// <param name="position">指定中心坐标</param>
/// <param name="position">中心座標指定</param>
private void ShowMenu(Vector2 position)
{
if (menuPanel)
@@ -383,11 +383,11 @@ namespace Kirurobo
float w = menuPanel.rect.width;
float h = menuPanel.rect.height;
// 指定坐标为中心进行位置
pos.y = Mathf.Max(Mathf.Min(pos.y, Screen.height - h / 2f), h / 2f); // 如果超出则向上移动
pos.x = Mathf.Max(Mathf.Min(pos.x, Screen.width - w / 2f), w / 2f); // 如果超出右侧则向左移动
// 指定座標に中心が来る前提で位置調
pos.y = Mathf.Max(Mathf.Min(pos.y, Screen.height - h / 2f), h / 2f); // はみ出していれば上に寄せる
pos.x = Mathf.Max(Mathf.Min(pos.x, Screen.width - w / 2f), w / 2f); // 右にはみ出していれば左に寄せる
menuPanel.pivot = Vector2.one * 0.5f; // 设置为中心
menuPanel.pivot = Vector2.one * 0.5f; // Set the center
menuPanel.anchorMin = Vector2.zero;
menuPanel.anchorMax = Vector2.zero;
menuPanel.anchoredPosition = pos;
@@ -396,7 +396,7 @@ namespace Kirurobo
}
/// <summary>
/// 关闭上下文菜单
/// コンテキストメニューを閉じる
/// </summary>
private void CloseMenu()
{
@@ -407,7 +407,7 @@ namespace Kirurobo
}
/// <summary>
/// 将实际状态反映到 UI 显示
/// 実際の状態をUI表示に反映
/// </summary>
private void UpdateUI()
{
@@ -476,11 +476,11 @@ namespace Kirurobo
hitTestTypeDropdown.RefreshShownValue();
}
// 同时更新点击测试部分的显示
// ヒットテスト部分の表示も更新
UpdateHitTestUI();
}
// 即使没有 UniWinC 也能运行的部分
// UniWinC 無しでも動作する部分
if (showBorderlineToggle && borderlinePanel)
{
borderlinePanel.gameObject.SetActive(showBorderlineToggle.isOn);
@@ -488,8 +488,8 @@ namespace Kirurobo
}
/// <summary>
/// 更新点击测试相关的 UI
/// 由于会自动变化,需要比 UpdateUI() 更频繁地更新
/// ヒットテスト関連のUI更新
/// 自動で変化するため UpdateUI() よりも高頻度で更新の必要がある
/// </summary>
public void UpdateHitTestUI()
{
@@ -530,7 +530,7 @@ namespace Kirurobo
if (pickedColorText)
{
pickedColorText.text = $"颜色拾取器已禁用";
pickedColorText.text = $"Color picker is disabled";
pickedColorText.color = Color.gray;
}
}
@@ -538,14 +538,14 @@ namespace Kirurobo
}
/// <summary>
/// 更新显示器选择下拉列表的选项
/// 之后需要调用 UpdateUI()
/// モニタ選択ドロップダウンの選択肢を更新
/// この後にUpdateUI()を呼ぶこと
/// </summary>
void UpdateMonitorDropdown()
{
if (!fitWindowDropdown) return;
// 删除除第一项以外的选项
// 先頭以外の選択肢を削除
fitWindowDropdown.options.RemoveRange(1, fitWindowDropdown.options.Count - 1);
if (!uniwinc)
@@ -557,7 +557,7 @@ namespace Kirurobo
int count = UniWindowController.GetMonitorCount();
for (int i = 0; i < count; i++)
{
fitWindowDropdown.options.Add(new Dropdown.OptionData("适配显示器 " + i));
fitWindowDropdown.options.Add(new Dropdown.OptionData("Fit to Monitor " + i));
}
if (uniwinc.monitorToFit >= count)
{
@@ -567,7 +567,7 @@ namespace Kirurobo
}
/// <summary>
/// 如果 UI 中有文本框,则显示消息。否则输出到控制台
/// テキスト枠がUIにあれば、そこにメッセージを出す。無ければコンソールに出力
/// </summary>
/// <param name="text"></param>
public void OutputMessage(string text)
@@ -583,7 +583,7 @@ namespace Kirurobo
}
/// <summary>
/// 如果 UI 中有客户端大小文本框,则显示消息。否则输出到控制台
/// クライアントサイズ用テキスト枠がUIにあれば、そこにメッセージを出す。無ければコンソールに出力
/// </summary>
public void ShowClientSize()
{
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 3b335a5bc9945c9469568d1aba1b14e8
timeCreated: 1545989238
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,5 +1,5 @@
 /**
* UI
/**
* UI controller for the fullscreen sample
*
* Author: Kirurobo http://twitter.com/kirurobo
* License: MIT
@@ -11,18 +11,18 @@ using UnityEngine.UI;
namespace Kirurobo
{
/// <summary>
/// 使用 Toggle 开关 WindowController 设置的示例
/// WindowControllerの設定をToggleでオン/オフするサンプル
/// </summary>
public class FullscreenSample : MonoBehaviour
{
private UniWindowController uniwinc;
private RectTransform canvasRect;
private float mouseMoveSS = 0f; // 鼠标轨迹平方和。[px^2]
private float mouseMoveSSThreshold = 36f; // 点击(非拖拽)阈值。[px^2]
private Vector3 lastMousePosition; // 右键点击位置。
private float mouseMoveSS = 0f; // Sum of mouse trajectory squares. [px^2]
private float mouseMoveSSThreshold = 36f; // Click (not dragging) threshold. [px^2]
private Vector3 lastMousePosition; // Right clicked position.
private float touchDuration = 0f;
private float touchDurationThreshold = 0.5f; // 长按时间阈值。[s]
private float touchDurationThreshold = 0.5f; // Long tap time threshold. [s]
public Toggle transparentToggle;
public Toggle topmostToggle;
@@ -33,28 +33,28 @@ namespace Kirurobo
public RectTransform menuPanel;
/// <summary>
/// 设置
/// Setup
/// </summary>
void Start()
{
// 查找 UniWindowController
// UniWindowController を探す
uniwinc = GameObject.FindAnyObjectByType<UniWindowController>();
// 获取 CanvasRectTransform
// CanvasRectTransform取得
if (menuPanel) canvasRect = menuPanel.GetComponentInParent<Canvas>().GetComponent<RectTransform>();
// 根据有效显示器数量创建选项
// 有効なモニタ数に合わせて選択肢を作成
UpdateMonitorDropdown();
// Toggle 的选中状态与当前状态同步
// Toggleのチェック状態を、現在の状態に合わせる
UpdateUI();
// 初始状态下关闭菜单
// 初期状態ではメニューを閉じておく
CloseMenu();
if (uniwinc)
{
// 操作 UI 时将其反映到窗口
// UIを操作された際にはウィンドウに反映されるようにする
transparentToggle?.onValueChanged.AddListener(val => uniwinc.isTransparent = val);
topmostToggle?.onValueChanged.AddListener(val => uniwinc.isTopmost = val);
bottommostToggle?.onValueChanged.AddListener(val => uniwinc.isBottommost = val);
@@ -77,12 +77,12 @@ namespace Kirurobo
}
/// <summary>
/// 每帧执行
/// Perform every frame
/// </summary>
private void Update()
{
// 鼠标右键点击时显示上下文菜单。
// 如果鼠标移动距离在阈值以下,则视为点击
// Show the context menu when right clicked.
// If mouse movement is closer than a threshold, it is considered a click
if (InputProxy.GetMouseButtonDown(1))
{
lastMousePosition = InputProxy.mousePosition;
@@ -102,9 +102,9 @@ namespace Kirurobo
touchDuration = 0f;
}
// 暂时仅在 Legacy Input Manager 中处理触摸
// ひとまず Legacy Input Manager でのみタッチ処理を扱う
#if ENABLE_LEGACY_INPUT_MANAGER
// 长按也可显示菜单
// Show the menu also when long touched
if (Input.touchSupported && (Input.touchCount > 0))
{
Touch touch = Input.GetTouch(0);
@@ -130,7 +130,7 @@ namespace Kirurobo
}
#endif
// 按下 [Space] 键也可显示菜单
// Show the menu also when pressed [Space] key
if (InputProxy.GetKeyUp("space"))
{
if (menuPanel)
@@ -144,7 +144,7 @@ namespace Kirurobo
}
}
// 按下 [ESC] 时退出或停止播放
// Quit or stop playing when pressed [ESC]
if (InputProxy.GetKeyUp("escape"))
{
Quit();
@@ -161,7 +161,7 @@ namespace Kirurobo
}
/// <summary>
/// 适配显示器下拉列表更改时的处
/// フィット対象モニタドロップダウンが変更された時の処
/// </summary>
/// <param name="val"></param>
void SetFitToMonitor(int val)
@@ -170,21 +170,21 @@ namespace Kirurobo
if (val < 1)
{
// 下拉列表第一项为不适配
// ドロップダウンの先頭は、フィット無し
uniwinc.shouldFitMonitor = false;
}
else
{
// 由于从第二项开始,显示器编号减1
// 次からなので、モニタ番号は1を引く
uniwinc.monitorToFit = val - 1;
uniwinc.shouldFitMonitor = true; // false变为true时才会移动窗口,因此先指定显示器编号再更改
uniwinc.shouldFitMonitor = true; // これがfalseからtrueにしたタイミングで移動されるため、モニタ番号を指定してから変更
}
}
/// <summary>
/// 指定坐标显示上下文菜单
/// 指定した座標にコンテキストメニューを表示する
/// </summary>
/// <param name="position">指定中心坐标</param>
/// <param name="position">中心座標指定</param>
private void ShowMenu(Vector2 position)
{
if (menuPanel)
@@ -193,11 +193,11 @@ namespace Kirurobo
float w = menuPanel.rect.width;
float h = menuPanel.rect.height;
// 指定坐标为中心进行位置
pos.y = Mathf.Max(Mathf.Min(pos.y, Screen.height - h / 2f), h / 2f); // 如果超出则向上移动
pos.x = Mathf.Max(Mathf.Min(pos.x, Screen.width - w / 2f), w / 2f); // 如果超出右侧则向左移动
// 指定座標に中心が来る前提で位置調
pos.y = Mathf.Max(Mathf.Min(pos.y, Screen.height - h / 2f), h / 2f); // はみ出していれば上に寄せる
pos.x = Mathf.Max(Mathf.Min(pos.x, Screen.width - w / 2f), w / 2f); // 右にはみ出していれば左に寄せる
menuPanel.pivot = Vector2.one * 0.5f; // 设置为中心
menuPanel.pivot = Vector2.one * 0.5f; // Set the center
menuPanel.anchorMin = Vector2.zero;
menuPanel.anchorMax = Vector2.zero;
menuPanel.anchoredPosition = pos;
@@ -207,7 +207,7 @@ namespace Kirurobo
}
/// <summary>
/// 关闭上下文菜单
/// コンテキストメニューを閉じる
/// </summary>
private void CloseMenu()
{
@@ -218,7 +218,7 @@ namespace Kirurobo
}
/// <summary>
/// 将实际状态反映到 UI 显示
/// 実際の状態をUI表示に反映
/// </summary>
private void UpdateUI()
{
@@ -255,14 +255,14 @@ namespace Kirurobo
}
/// <summary>
/// 更新显示器选择下拉列表的选项
/// 之后需要调用 UpdateUI()
/// モニタ選択ドロップダウンの選択肢を更新
/// この後にUpdateUI()を呼ぶこと
/// </summary>
void UpdateMonitorDropdown()
{
if (!fitWindowDropdown) return;
// 删除除第一项以外的选项
// 先頭以外の選択肢を削除
fitWindowDropdown.options.RemoveRange(1, fitWindowDropdown.options.Count - 1);
if (!uniwinc)
@@ -274,7 +274,7 @@ namespace Kirurobo
int count = UniWindowController.GetMonitorCount();
for (int i = 0; i < count; i++)
{
fitWindowDropdown.options.Add(new Dropdown.OptionData("适配显示器 " + i));
fitWindowDropdown.options.Add(new Dropdown.OptionData("Fit to Monitor " + i));
}
if (uniwinc.monitorToFit >= count)
{
@@ -284,7 +284,7 @@ namespace Kirurobo
}
/// <summary>
/// 显示带超时功能的消息
/// Show the message with timeout
/// </summary>
/// <param name="message"></param>
private void ShowEventMessage(string message)
@@ -293,7 +293,7 @@ namespace Kirurobo
}
/// <summary>
/// 如果 UI 中有文本框,则显示消息。否则输出到控制台
/// テキスト枠がUIにあれば、そこにメッセージを出す。無ければコンソールに出力
/// </summary>
/// <param name="text"></param>
public void OutputMessage(string text)
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 7f5802e9dd8c9bf4fb15aa0be21a95fc
guid: d027a988a73c645949379ea67c528652
MonoImporter:
externalObjects: {}
serializedVersion: 2
@@ -1,6 +1,5 @@
fileFormatVersion: 2
guid: 8878429ebc524544d849c1bc8884262a
folderAsset: yes
guid: cc8dc9342a8c4436397f75a2389ffc1a
DefaultImporter:
externalObjects: {}
userData:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b5563f201a09e4d65a6987f796daf7ac
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 4890085278179872738
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6fcffb6aae595400e8ee042864de7ccb
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0208720e8ee7e413abe0abd9e4497fba
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4184b0617c337434892dafbd45a3e5ce
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b9e9365bee95a4312b88783e135b628c
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
@@ -6,7 +6,7 @@ using UnityEngine.UI;
namespace Kirurobo
{
/// <summary>
/// 基础文件面板示例
/// Basic filepanel sample
/// </summary>
public class FileDialogSample : MonoBehaviour
{
@@ -15,82 +15,82 @@ namespace Kirurobo
public Button saveFileButton;
public Text messageText;
// 首次更新前调用 Start
// Start is called before the first frame update
void Start()
{
openFileButton.onClick.AddListener(OpenSingleFile);
openMultipleFilesButton.onClick.AddListener(OpenMultipleFiles);
saveFileButton.onClick.AddListener(OpenSaveFile);
messageText.text = "点击按钮!";
messageText.text = "Click a button!";
}
// 每帧调用 Update
// Update is called once per frame
void Update()
{
}
/// <summary>
/// 打开单个文件的对话框。
/// Open the open file dialog to select single file.
/// </summary>
private void OpenSingleFile() {
FilePanel.Settings settings = new FilePanel.Settings();
settings.filters = new FilePanel.Filter[]
{
new FilePanel.Filter("所有文件", "*"),
new FilePanel.Filter("图片文件 (*.png;*.jpg;*.jpeg;*.tiff;*.gif;*.tga)", "png", "jpg", "jpeg", "tiff", "gif", "tga"),
new FilePanel.Filter("文档 (*.txt;*.rtf;*.doc;*.docx)", "txt", "rtf", "doc", "docx"),
new FilePanel.Filter("All files", "*"),
new FilePanel.Filter("Image files (*.png;*.jpg;*.jpeg;*.tiff;*.gif;*.tga)", "png", "jpg", "jpeg", "tiff", "gif", "tga"),
new FilePanel.Filter("Documents (*.txt;*.rtf;*.doc;*.docx)", "txt", "rtf", "doc", "docx"),
};
settings.title = "打开文件!";
settings.title = "Open a file!";
settings.initialDirectory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyPictures);
messageText.text = "";
FilePanel.OpenFilePanel(settings, (files) =>
{
messageText.text = "打开文件\n" + string.Join("\n", files);
messageText.text = "Open a file\n" + string.Join("\n", files);
});
}
/// <summary>
/// 打开多个文件的对话框。
/// Open the open file dialog to select multiple files.
/// </summary>
private void OpenMultipleFiles() {
FilePanel.Settings settings = new FilePanel.Settings();
settings.filters = new FilePanel.Filter[]
{
new FilePanel.Filter("图片文件 (*.png;*.jpg;*.jpeg;*.tiff;*.gif;*.tga)", "png", "jpg", "jpeg", "tiff", "gif", "tga"),
new FilePanel.Filter("文档 (*.txt;*.rtf;*.doc;*.docx)", "txt", "rtf", "doc", "docx"),
new FilePanel.Filter("所有文件", "*"),
new FilePanel.Filter("Image files (*.png;*.jpg;*.jpeg;*.tiff;*.gif;*.tga)", "png", "jpg", "jpeg", "tiff", "gif", "tga"),
new FilePanel.Filter("Documents (*.txt;*.rtf;*.doc;*.docx)", "txt", "rtf", "doc", "docx"),
new FilePanel.Filter("All files", "*"),
};
settings.flags = FilePanel.Flag.AllowMultipleSelection;
settings.title = "打开多个文件!";
settings.title = "Open multiple files!";
settings.initialDirectory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments);
messageText.text = "";
FilePanel.OpenFilePanel(settings, (files) =>
{
messageText.text = "打开多个文件\n" + string.Join("\n", files);
messageText.text = "Open multiple files\n" + string.Join("\n", files);
});
}
/// <summary>
/// 打开保存文件对话框。
/// Open the save file dialog.
/// </summary>
private void OpenSaveFile() {
FilePanel.Settings settings = new FilePanel.Settings();
settings.filters = new FilePanel.Filter[]
{
new FilePanel.Filter("文本文件 (*.txt;*.log)", "txt", "log"),
new FilePanel.Filter("图片文件 (*.png;*.jpg;*.jpeg;*.tiff;*.gif;*.tga)", "png", "jpg", "jpeg", "tiff", "gif", "tga"),
new FilePanel.Filter("所有文件", "*"),
new FilePanel.Filter("Text file (*.txt;*.log)", "txt", "log"),
new FilePanel.Filter("Image files (*.png;*.jpg;*.jpeg;*.tiff;*.gif;*.tga)", "png", "jpg", "jpeg", "tiff", "gif", "tga"),
new FilePanel.Filter("All files", "*"),
};
settings.title = "实际上不会执行保存操作";
settings.title = "No save is actually performed";
settings.initialFile = "Test.txt";
messageText.text = "";
FilePanel.SaveFilePanel(settings, (files) =>
{
messageText.text = "选中的文件\n" + string.Join("\n", files);
messageText.text = "Selected file\n" + string.Join("\n", files);
});
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: eb6dba400744842c1b9025c020a1dd4e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,6 +1,5 @@
fileFormatVersion: 2
guid: 326ddcba926f5e849bde9a0e0fb87ee1
folderAsset: yes
guid: 48a0f5141a4d64ffd86a58d24b841e0c
DefaultImporter:
externalObjects: {}
userData:
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 24c3b38da5d7645cca546e4a61bf8980
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 4890085278179872738
userData:
assetBundleName:
assetBundleVariant:
+7 -7
View File
@@ -2,31 +2,31 @@ using UnityEngine;
namespace Kirurobo {
/// <summary>
/// 使附加的对象以恒定速度进行偏航旋转
/// アタッチしたオブジェクトを一定速度でヨー回転させる
/// </summary>
public class AutoRotator : MonoBehaviour {
/// <summary>
/// 旋转速度 [度/秒]
/// 回転速度 [deg/s]
/// </summary>
public float angularVelocity = 90f;
/// <summary>
/// 旋转轴(偏航旋转,方向向上
/// 回転軸(ヨー回転のため上向き
/// </summary>
Vector3 rotationAxis = Vector3.up;
/// <summary>
/// 初始姿态
/// 初期姿勢
/// </summary>
Quaternion initialLocalRotation;
// 用于初始化
// Use this for initialization
void Start () {
// 记录初始姿态
// 初期姿勢を記憶
initialLocalRotation = transform.localRotation;
}
// 每帧调用 Update
// Update is called once per frame
void Update () {
var rotation = Quaternion.Euler(0f, Time.time * angularVelocity, 0f);
transform.localRotation = initialLocalRotation * rotation;
+1 -1
View File
@@ -9,7 +9,7 @@ using UnityEngine.InputSystem;
namespace Kirurobo {
/// <summary>
/// 为快速兼容 Legacy InputManager InputSystem 而准备的类
/// Legacy InputManager InputSystem の両方に取り急ぎ対応するために用意したクラスです
/// </summary>
#if ENABLE_LEGACY_INPUT_MANAGER
public class InputModuleProxy : UnityEngine.EventSystems.StandaloneInputModule
+15 -15
View File
@@ -1,8 +1,8 @@
/**
* UniWindowController 的示例脚本
* A sample script of UniWindowContoller
*
* 作者: Kirurobo http://twitter.com/kirurobo
* 许可证: MIT
* Author: Kirurobo http://twitter.com/kirurobo
* License: MIT
*/
using System;
@@ -15,8 +15,8 @@ using UnityEngine.InputSystem;
namespace Kirurobo {
/// <summary>
/// 用于消除 Input System Input Manager 差异的代理
/// </summary>
/// Input System Input Manager の違いを吸収するためのプロキシ
/// </summary>
public class InputProxy
{
public static Vector3 mousePosition {
@@ -26,7 +26,7 @@ namespace Kirurobo {
}
/// <summary>
/// 配合 Input System 获取按键抬起
/// Input System の利用に合わせてキーアップを取得
/// </summary>
/// <returns></returns>
public static bool GetKeyUp(String key)
@@ -34,22 +34,22 @@ namespace Kirurobo {
#if ENABLE_LEGACY_INPUT_MANAGER
return Input.GetKeyUp(key);
#elif ENABLE_INPUT_SYSTEM
// 简易实现。仅支持单字母字符或数字
// 非单字符的仅支持 escape, space
// 簡易的な実装。keyが1文字で、かつアルファベットか数字に対応
// 1文字以外は escape, space のみ対応
if (key.Length == 1) {
Key k = Key.None;
char c = key[0];
if (c >= '0' && c <= '9') {
// 数字时同时响应 Digit0~Digit9Numpad0~Numpad9
// 数字の場合はDigit0Digit9Numpad0Numpad9の両方に反応
k = (Key)Enum.ToObject(typeof(Key), (int)Key.Numpad0 + (int)(c - '0'));
if (Keyboard.current[k].wasReleasedThisFrame) return true;
// Digit 键中 Digit0 的数值最大
// Digitの場合はDigit0の値が最大
k = (Key)Enum.ToObject(typeof(Key), (int)Key.Digit1 + (int)((c == '0' ? 9 : c - '1')));
if (Keyboard.current[k].wasReleasedThisFrame) return true;
}
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
// 字母时大小写均可
// アルファベットの場合は大文字・小文字どちらでも可とする
k = (Key)Enum.ToObject(typeof(Key), (int)Key.A + (int)(Char.ToUpper(c) - 'A'));
if (Keyboard.current[k].wasReleasedThisFrame) return true;
}
@@ -65,7 +65,7 @@ namespace Kirurobo {
}
/// <summary>
/// 配合 Input System 获取鼠标坐标
/// Input System の利用に合わせてマウス座標を取得
/// </summary>
/// <returns></returns>
private static Vector3 GetMousePosition()
@@ -80,7 +80,7 @@ namespace Kirurobo {
}
/// <summary>
/// 判断鼠标按钮当前是否被按下
/// マウスボタンが現在押されているか判定
/// </summary>
/// <param name="button"></param>
/// <returns></returns>
@@ -99,7 +99,7 @@ namespace Kirurobo {
}
/// <summary>
/// 判断本帧是否按下了鼠标按钮
/// このフレームでマウスボタンが押されたか判定
/// </summary>
/// <param name="button"></param>
/// <returns></returns>
@@ -118,7 +118,7 @@ namespace Kirurobo {
}
/// <summary>
/// 判断本帧是否松开了鼠标按钮
/// このフレームでマウスボタンが離されたか判定
/// </summary>
/// <param name="button"></param>
/// <returns></returns>
+34 -34
View File
@@ -1,10 +1,10 @@
/*
/*
* ModelController
*
* 旋转、平移和缩放对象
* Rotate, translate and scale the object
*
* 作者: Kirurobo http://twitter.com/kirurobo
* 许可证: MIT
* Author: Kirurobo http://twitter.com/kirurobo
* License: MIT
*/
using System;
@@ -40,7 +40,7 @@ namespace Kirurobo
public Vector2 maximumAngles = new Vector2(90f, 360f);
[Tooltip("Restrict to move out from screen")]
public bool confineTranslation = true; // 是否将位移限制在窗口(屏幕)范围内
public bool confineTranslation = true; // 並進移動をウィンドウ(Screen)の範囲に制限するか
[Tooltip("Default is the parent transform")]
public Transform centerTransform; // 回転中心
@@ -48,12 +48,12 @@ namespace Kirurobo
[Tooltip("Default is the main camera")]
public Camera currentCamera;
internal GameObject centerObject = null; // 当未指定旋转中心Transform时创建的对象
internal GameObject centerObject = null; // 回転中心Transformが指定されなかった場合に作成される
internal Vector3 rotation;
internal Vector3 translation;
internal Vector3 lastMousePosition; // 上一帧的鼠标坐标
internal DragState dragState; // 拖动时根据开始时的按钮设置对应状态
internal Vector3 lastMousePosition; // 直前フレームでのマウス座標
internal DragState dragState; // ドラッグ中は開始時のボタンに合わせた内容にする
internal Vector3 relativePosition;
internal Quaternion relativeRotation;
@@ -69,7 +69,7 @@ namespace Kirurobo
void OnDestroy()
{
// 如果旋转中心是独立创建的,则删
// 回転中心を独自に作成していれば、削
if (centerObject) GameObject.Destroy(centerObject);
}
@@ -82,7 +82,7 @@ namespace Kirurobo
}
/// <summary>
/// 获取并准备所需对象
/// 必要なオブジェクトを取得・準備
/// </summary>
internal void Initialize()
{
@@ -106,12 +106,12 @@ namespace Kirurobo
}
/// <summary>
/// 设置初始位置和姿态
/// 在目标对象就绪后执行
/// 初期位置・姿勢の設定
/// 対象となるオブジェクトがそろった後で実行する
/// </summary>
internal void SetupTransform()
{
relativePosition = transform.position- centerTransform.position; // 从对象到中心坐标的向量
relativePosition = transform.position- centerTransform.position; // オブジェクトから中心座標へのベクトル
relativeRotation = transform.rotation * Quaternion.Inverse(centerTransform.rotation);
originalLocalScale = transform.localScale;
@@ -131,7 +131,7 @@ namespace Kirurobo
}
/// <summary>
/// 应用旋转和平移
/// Apply rotation and translation
/// </summary>
internal void UpdateTransform()
{
@@ -148,38 +148,38 @@ namespace Kirurobo
if (InputProxy.GetMouseButtonDown(0))
{
// 左键(0)拖动时进行平移
// 左ボタン(0)ドラッグでは並進移動を行う
if (dragState == DragState.None && IsHit(mousePos))
{
dragState = DragState.Translating;
// 限制在屏幕范围内
// 画面範囲に制限する
if (confineTranslation)
{
Vector3 screenMax = new Vector3(Screen.width, Screen.height);
mousePos = Vector3.Max(Vector3.Min(mousePos, screenMax), Vector3.zero);
}
lastMousePosition = mousePos; // 拖动开始时重置
lastMousePosition = mousePos; // ドラッグ開始時にはリセット
}
}
else if (InputProxy.GetMouseButtonDown(1))
{
// 右键(1)拖动时进行旋转
// 右ボタン(1)ドラッグでは回転を行う
if (dragState == DragState.None && IsHit(mousePos))
{
dragState = DragState.Rotating;
lastMousePosition = mousePos; // 拖动开始时重置
lastMousePosition = mousePos; // ドラッグ開始時にはリセット
}
}
// 通过拖动旋转
// ドラッグで回転
if (dragState == DragState.Rotating)
{
// 仅在按下按钮时操作
// ボタンが押されている間のみ操作
if (InputProxy.GetMouseButton(1))
{
// 通过拖动旋转
// ドラッグで回転
if ((axes & RotationAxes.Yaw) > RotationAxes.None)
{
rotation.y -= (mousePos.x - lastMousePosition.x) * 360f / Screen.width * yawSensitivity;
@@ -196,18 +196,18 @@ namespace Kirurobo
}
else
{
// 如果右键已松开则结束旋转
// 右ボタンが離されていれば回転は終了
dragState = DragState.None;
}
}
// 通过拖动平移
// ドラッグで並進移動
if (dragState == DragState.Translating)
{
// 仅在按下按钮时操作
// ボタンが押されている間のみ操作
if (InputProxy.GetMouseButton(0))
{
// 限制在屏幕范围内
// 画面範囲に制限する
if (confineTranslation)
{
Vector3 screenMax = new Vector3(Screen.width, Screen.height);
@@ -224,22 +224,22 @@ namespace Kirurobo
}
else
{
// 如果按钮已松开则结束位移
// ボタンが離されていれば並進は終了
dragState = DragState.None;
}
}
// 暂时仅在使用 Legacy Input Manager 时接受滚轮操作
// ひとまず Legacy Input Manager でのみホイール操作を受け付けるものとしてリリース
#if ENABLE_LEGACY_INPUT_MANAGER
// 如果滚轮转动,则进行缩放
// ホイールが回転されれば、拡大縮小
if (!Mathf.Approximately(Input.GetAxis("Mouse ScrollWheel"), 0f) && IsHit(mousePos))
{
// 滚轮操作量
// ホイールによる操作量
float wheelDelta = Input.GetAxis("Mouse ScrollWheel") * scaleSensitivity;
// 更改缩放倍率
// 倍率を変更
zoom -= wheelDelta;
zoom = Mathf.Clamp(zoom, -1f, 2f); // 视场角的对数范围 [度]
zoom = Mathf.Clamp(zoom, -1f, 2f); // Logarithm of field-of-view [deg] range
UpdateTransform();
}
@@ -249,7 +249,7 @@ namespace Kirurobo
}
/// <summary>
/// 判断鼠标操作时是否点击到对象
/// マウスでの操作時、オブジェクトにヒットしたか判定
/// </summary>
/// <returns></returns>
internal bool IsHit(Vector3 screenPosition)
@@ -266,7 +266,7 @@ namespace Kirurobo
}
/// <summary>
/// 若角度超出指定范围,则进行修正
/// 指定範囲から外れる角度の場合、補正する
/// </summary>
/// <param name="angle"></param>
/// <param name="min"></param>
-5
View File
@@ -1,5 +0,0 @@
{
"displayName": "FileDialog",
"description": "Demonstrates native file open/save dialog integration.",
"createSeparatePackage": false
}
-5
View File
@@ -1,5 +0,0 @@
{
"displayName": "Fullscreen",
"description": "Fullscreen mode example with right-click context menu and 3D snowman scene.",
"createSeparatePackage": false
}
-5
View File
@@ -1,5 +0,0 @@
{
"displayName": "Menu",
"description": "Sample menu scene for navigating between different example scenes.",
"createSeparatePackage": false
}
-5
View File
@@ -1,5 +0,0 @@
{
"displayName": "SimpleSample",
"description": "A minimal example demonstrating basic window control setup.",
"createSeparatePackage": false
}
-5
View File
@@ -1,5 +0,0 @@
{
"displayName": "UiSample",
"description": "Complete UI demonstration with toggles and sliders for controlling window properties (transparency, topmost, click-through, etc.).",
"createSeparatePackage": false
}
-29
View File
@@ -1,29 +0,0 @@
using UnityEngine;
using UnityEditor;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;
namespace Lrss3.Xuniwindowcontroller.Editor.Tests
{
class EditorExampleTest
{
[Test]
public void EditorSampleTestSimplePasses()
{
// Use the Assert class to test conditions.
}
// A UnityTest behaves like a coroutine in PlayMode
// and allows you to yield null to skip a frame in EditMode
[UnityTest]
public IEnumerator EditorSampleTestWithEnumeratorPasses()
{
// Use the Assert class to test conditions.
// yield to skip a frame
yield return null;
}
}
}
@@ -1,14 +0,0 @@
{
"name": "Lrss3.Xuniwindowcontroller.Editor.Tests",
"references": [
"Lrss3.Xuniwindowcontroller.Editor",
"Lrss3.Xuniwindowcontroller"
],
"optionalUnityReferences": [
"TestAssemblies"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": []
}
-8
View File
@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: e6602e0b6b65ef7438c1a83bcf07d1b2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,11 +0,0 @@
{
"name": "Lrss3.Xuniwindowcontroller.Tests",
"references": [
"Lrss3.Xuniwindowcontroller"
],
"optionalUnityReferences": [
"TestAssemblies"
],
"includePlatforms": [],
"excludePlatforms": []
}
-28
View File
@@ -1,28 +0,0 @@
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;
namespace Lrss3.Xuniwindowcontroller.Tests
{
class RuntimeExampleTest
{
[Test]
public void PlayModeSampleTestSimplePasses()
{
// Use the Assert class to test conditions.
}
// A UnityTest behaves like a coroutine in PlayMode
// and allows you to yield null to skip a frame in EditMode
[UnityTest]
public IEnumerator PlayModeSampleTestWithEnumeratorPasses()
{
// Use the Assert class to test conditions.
// yield to skip a frame
yield return null;
}
}
}
+51 -47
View File
@@ -1,49 +1,53 @@
{
"name": "com.lrss3.xuniwindowcontroller",
"displayName": "XUniWindowController",
"version": "0.1.0",
"unity": "2022.3",
"description": "A Unity native plugin for controlling standalone application windows on Windows and macOS. \nSupports transparency, click-through, topmost/bottommost, maximize, file drop, native file dialogs, and multi-monitor window fitting.",
"author": {
"name": "Lrss3",
"url": "https://github.com/Lrss3"
},
"keywords": [
"window",
"transparent",
"click-through",
"native",
"plugin",
"windows",
"macos"
],
"category": "library",
"dependencies": {},
"samples": [
{
"displayName": "Menu",
"description": "Sample menu scene for navigating between different example scenes.",
"path": "Samples~/Menu"
},
{
"displayName": "SimpleSample",
"description": "A minimal example demonstrating basic window control setup.",
"path": "Samples~/SimpleSample"
},
{
"displayName": "UiSample",
"description": "Complete UI demonstration with toggles and sliders for controlling window properties (transparency, topmost, click-through, etc.).",
"path": "Samples~/UiSample"
},
{
"displayName": "Fullscreen",
"description": "Fullscreen mode example with right-click context menu and 3D snowman scene.",
"path": "Samples~/Fullscreen"
},
{
"displayName": "FileDialog",
"description": "Demonstrates native file open/save dialog integration.",
"path": "Samples~/FileDialog"
}
]
"name": "com.lrss3.xuniwindowcontroller",
"displayName": "XUniWindowController",
"version": "1.0.0",
"unity": "2022.3",
"description": "A Unity native plugin for controlling standalone application windows on Windows and macOS. \nSupports transparency, click-through, topmost/bottommost, maximize, file drop, native file dialogs, and multi-monitor window fitting.",
"author": {
"name": "Lrss3",
"url": "https://github.com/Lrss3"
},
"keywords": [
"window",
"transparent",
"click-through",
"native",
"plugin",
"windows",
"macos"
],
"category": "library",
"samples": [
{
"displayName": "Menu",
"description": "Sample menu scene for navigating between different example scenes.",
"path": "Samples~/00_Menu"
},
{
"displayName": "SimpleSample",
"description": "A minimal example demonstrating basic window control setup.",
"path": "Samples~/01_SimpleSample"
},
{
"displayName": "UiSample",
"description": "Complete UI demonstration with toggles and sliders for controlling window properties (transparency, topmost, click-through, etc.).",
"path": "Samples~/02_UiSample"
},
{
"displayName": "Fullscreen",
"description": "Fullscreen mode example with right-click context menu and 3D snowman scene.",
"path": "Samples~/03_Fullscreen"
},
{
"displayName": "FileDialog",
"description": "Demonstrates native file open/save dialog integration.",
"path": "Samples~/04_FileDialog"
},
{
"displayName": "Common",
"description": "",
"path": "Samples~/Common"
}
]
}