init uniWindowController 0.9.8

This commit is contained in:
2026-06-14 22:49:28 +08:00
commit bfce70eb6f
95 changed files with 30126 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
using UnityEngine;
namespace Kirurobo {
/// <summary>
/// 使附加的对象以恒定速度进行偏航旋转
/// </summary>
public class AutoRotator : MonoBehaviour {
/// <summary>
/// 旋转速度 [度/秒]
/// </summary>
public float angularVelocity = 90f;
/// <summary>
/// 旋转轴(偏航旋转,方向向上)
/// </summary>
Vector3 rotationAxis = Vector3.up;
/// <summary>
/// 初始姿态
/// </summary>
Quaternion initialLocalRotation;
// 用于初始化
void Start () {
// 记录初始姿态
initialLocalRotation = transform.localRotation;
}
// 每帧调用 Update
void Update () {
var rotation = Quaternion.Euler(0f, Time.time * angularVelocity, 0f);
transform.localRotation = initialLocalRotation * rotation;
}
}
}
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: f985bf036f5416a45b9dd4e31bc85075
timeCreated: 1545989238
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.

After

Width:  |  Height:  |  Size: 452 B

+88
View File
@@ -0,0 +1,88 @@
fileFormatVersion: 2
guid: 2b5d2690e20d6584e909fd2bdfd93579
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 0
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 8, y: 8, z: 8, w: 8}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 533df9bf30503d349b91598d325d5fcd
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.

After

Width:  |  Height:  |  Size: 451 B

+88
View File
@@ -0,0 +1,88 @@
fileFormatVersion: 2
guid: 4713fc586389c694f9e384c7f3a02289
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 9
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -100
wrapU: 1
wrapV: 1
wrapW: -1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 0
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 8, y: 8, z: 8, w: 8}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
singleChannelComponent: 0
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- serializedVersion: 2
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
androidETC2FallbackOverride: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID: 47fdf1b4c9bb7764d916b229e9a2d98c
vertices: []
indices:
edges: []
weights: []
spritePackingTag:
pSDRemoveMatte: 0
pSDShowRemoveMatteOption: 0
userData:
assetBundleName:
assetBundleVariant:
+27
View File
@@ -0,0 +1,27 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if ENABLE_LEGACY_INPUT_MANAGER
#elif ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif
namespace Kirurobo {
/// <summary>
/// 为快速兼容 Legacy InputManager 和 InputSystem 而准备的类
/// </summary>
#if ENABLE_LEGACY_INPUT_MANAGER
public class InputModuleProxy : UnityEngine.EventSystems.StandaloneInputModule
{
}
#elif ENABLE_INPUT_SYSTEM
public class InputModuleProxy : UnityEngine.InputSystem.UI.InputSystemUIInputModule
{
}
#else
public class InputModuleProxy
{
}
#endif
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ce6b387a66b0e654d9eb8712d70fff48
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+138
View File
@@ -0,0 +1,138 @@
/**
* UniWindowController 的示例脚本
*
* 作者: Kirurobo http://twitter.com/kirurobo
* 许可证: MIT
*/
using System;
using UnityEngine;
#if ENABLE_LEGACY_INPUT_MANAGER
// Don't use InputSystem in this script to prevent TouchPhase duplication
#elif ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif
namespace Kirurobo {
/// <summary>
/// Input System と Input Manager の違いを吸収するためのプロキシ
/// </summary>
public class InputProxy
{
public static Vector3 mousePosition {
get {
return GetMousePosition();
}
}
/// <summary>
/// Input System の利用に合わせてキーアップを取得
/// </summary>
/// <returns></returns>
public static bool GetKeyUp(String key)
{
#if ENABLE_LEGACY_INPUT_MANAGER
return Input.GetKeyUp(key);
#elif ENABLE_INPUT_SYSTEM
// 簡易的な実装。keyが1文字で、かつアルファベットか数字に対応
// 1文字以外は escape, space のみ対応
if (key.Length == 1) {
Key k = Key.None;
char c = key[0];
if (c >= '0' && c <= '9') {
// 数字の場合はDigit0~Digit9とNumpad0~Numpad9の両方に反応
k = (Key)Enum.ToObject(typeof(Key), (int)Key.Numpad0 + (int)(c - '0'));
if (Keyboard.current[k].wasReleasedThisFrame) return true;
// 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;
}
} else if (key == "escape") {
return Keyboard.current.escapeKey.wasReleasedThisFrame;
} else if (key == "space") {
return Keyboard.current.spaceKey.wasReleasedThisFrame;
}
return false;
#else
return false;
#endif
}
/// <summary>
/// Input System の利用に合わせてマウス座標を取得
/// </summary>
/// <returns></returns>
private static Vector3 GetMousePosition()
{
#if ENABLE_LEGACY_INPUT_MANAGER
return Input.mousePosition;
#elif ENABLE_INPUT_SYSTEM
return Mouse.current.position.ReadValue();
#else
return Vector3.zero;
#endif
}
/// <summary>
/// 判断鼠标按钮当前是否被按下
/// </summary>
/// <param name="button"></param>
/// <returns></returns>
public static bool GetMouseButton(int button)
{
#if ENABLE_LEGACY_INPUT_MANAGER
return Input.GetMouseButton(button);
#elif ENABLE_INPUT_SYSTEM
if (button == 0) return Mouse.current.leftButton.isPressed;
if (button == 1) return Mouse.current.rightButton.isPressed;
if (button == 2) return Mouse.current.middleButton.isPressed;
return false;
#else
return false;
#endif
}
/// <summary>
/// このフレームでマウスボタンが押されたか判定
/// </summary>
/// <param name="button"></param>
/// <returns></returns>
public static bool GetMouseButtonDown(int button)
{
#if ENABLE_LEGACY_INPUT_MANAGER
return Input.GetMouseButtonDown(button);
#elif ENABLE_INPUT_SYSTEM
if (button == 0) return Mouse.current.leftButton.wasPressedThisFrame;
if (button == 1) return Mouse.current.rightButton.wasPressedThisFrame;
if (button == 2) return Mouse.current.middleButton.wasPressedThisFrame;
return false;
#else
return false;
#endif
}
/// <summary>
/// 判断本帧是否松开了鼠标按钮
/// </summary>
/// <param name="button"></param>
/// <returns></returns>
public static bool GetMouseButtonUp(int button) {
#if ENABLE_LEGACY_INPUT_MANAGER
return Input.GetMouseButtonUp(button);
#elif ENABLE_INPUT_SYSTEM
if (button == 0) return Mouse.current.leftButton.wasReleasedThisFrame;
if (button == 1) return Mouse.current.rightButton.wasReleasedThisFrame;
if (button == 2) return Mouse.current.middleButton.wasReleasedThisFrame;
return false;
#else
return false;
#endif
}
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 93a3055c4733041a1a83f6c90996f3ee
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+282
View File
@@ -0,0 +1,282 @@
/*
* ModelController
*
* 旋转、平移和缩放对象
*
* 作者: Kirurobo http://twitter.com/kirurobo
* 许可证: MIT
*/
using System;
using UnityEngine;
namespace Kirurobo
{
public class ModelController : MonoBehaviour
{
[Flags]
public enum RotationAxes : int
{
None = 0,
Pitch = 1,
Yaw = 2,
PitchAndYaw = 3
}
[Flags]
public enum DragState
{
None,
Rotating,
Translating,
}
public RotationAxes axes = RotationAxes.PitchAndYaw;
public float yawSensitivity = 1f;
public float pitchSensitvity = 1f;
public float scaleSensitivity = 0.5f;
public Vector2 minimumAngles = new Vector2(-90f, -360f);
public Vector2 maximumAngles = new Vector2(90f, 360f);
[Tooltip("Restrict to move out from screen")]
public bool confineTranslation = true; // 並進移動をウィンドウ(Screen)の範囲に制限するか
[Tooltip("Default is the parent transform")]
public Transform centerTransform; // 回転中心
[Tooltip("Default is the main camera")]
public Camera currentCamera;
internal GameObject centerObject = null; // 当未指定旋转中心Transform时创建的对象
internal Vector3 rotation;
internal Vector3 translation;
internal Vector3 lastMousePosition; // 上一帧的鼠标坐标
internal DragState dragState; // 拖动时根据开始时的按钮设置对应状态
internal Vector3 relativePosition;
internal Quaternion relativeRotation;
internal Vector3 originalLocalScale;
internal float zoom;
void Start()
{
Initialize();
SetupTransform();
}
void OnDestroy()
{
// 回転中心を独自に作成していれば、削除
if (centerObject) GameObject.Destroy(centerObject);
}
void Update()
{
if (!currentCamera.isActiveAndEnabled) return;
{
HandleMouse();
}
}
/// <summary>
/// 必要なオブジェクトを取得・準備
/// </summary>
internal void Initialize()
{
if (!centerTransform)
{
centerTransform = this.transform.parent;
if (!centerTransform || centerTransform == this.transform)
{
centerObject = new GameObject();
centerTransform = centerObject.transform;
centerTransform.position = Vector3.zero;
}
}
if (!currentCamera)
{
currentCamera = Camera.main;
}
lastMousePosition = InputProxy.mousePosition;
}
/// <summary>
/// 初期位置・姿勢の設定
/// 対象となるオブジェクトがそろった後で実行する
/// </summary>
internal void SetupTransform()
{
relativePosition = transform.position- centerTransform.position; // 从对象到中心坐标的向量
relativeRotation = transform.rotation * Quaternion.Inverse(centerTransform.rotation);
originalLocalScale = transform.localScale;
ResetTransform();
}
/// <summary>
/// Reset rotation and translation.
/// </summary>
public void ResetTransform()
{
rotation = relativeRotation.eulerAngles;
translation = relativePosition;
zoom = 0f;
UpdateTransform();
}
/// <summary>
/// 应用旋转和平移
/// </summary>
internal void UpdateTransform()
{
Quaternion rot = Quaternion.Euler(rotation);
transform.rotation = rot;
transform.position = centerTransform.position + translation;
transform.localScale = originalLocalScale * Mathf.Pow(10f, zoom);
}
internal virtual void HandleMouse()
{
Vector3 mousePos = InputProxy.mousePosition;
if (InputProxy.GetMouseButtonDown(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; // ドラッグ開始時にはリセット
}
}
else if (InputProxy.GetMouseButtonDown(1))
{
// 右ボタン(1)ドラッグでは回転を行う
if (dragState == DragState.None && IsHit(mousePos))
{
dragState = DragState.Rotating;
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;
rotation.y = ClampAngle(rotation.y, minimumAngles.y, maximumAngles.y);
}
if ((axes & RotationAxes.Pitch) > RotationAxes.None)
{
rotation.x += (mousePos.y - lastMousePosition.y) * 360f / Screen.height * pitchSensitvity;
rotation.x = ClampAngle(rotation.x, minimumAngles.x, maximumAngles.x);
}
UpdateTransform();
}
else
{
// 如果右键已松开则结束旋转
dragState = DragState.None;
}
}
// 通过拖动平移
if (dragState == DragState.Translating)
{
// 仅在按下按钮时操作
if (InputProxy.GetMouseButton(0))
{
// 限制在屏幕范围内
if (confineTranslation)
{
Vector3 screenMax = new Vector3(Screen.width, Screen.height);
mousePos = Vector3.Max(Vector3.Min(mousePos, screenMax), Vector3.zero);
}
Vector3 screenPos = currentCamera.WorldToScreenPoint(transform.position);
Vector3 deltaPos = mousePos - lastMousePosition;
deltaPos.z = 0f;
Vector3 worldPos = currentCamera.ScreenToWorldPoint(screenPos + deltaPos);
translation = worldPos - centerTransform.position;
UpdateTransform();
}
else
{
// ボタンが離されていれば並進は終了
dragState = DragState.None;
}
}
// 暂时仅在使用 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); // 视场角的对数范围 [度]
UpdateTransform();
}
#endif
lastMousePosition = mousePos;
}
/// <summary>
/// 判断鼠标操作时是否点击到对象
/// </summary>
/// <returns></returns>
internal bool IsHit(Vector3 screenPosition)
{
RaycastHit hit;
Ray ray = currentCamera.ScreenPointToRay(screenPosition);
if (Physics.Raycast(ray, out hit))
{
if (hit.transform.IsChildOf(transform)) return true;
}
return false;
}
/// <summary>
/// 若角度超出指定范围,则进行修正
/// </summary>
/// <param name="angle"></param>
/// <param name="min"></param>
/// <param name="max"></param>
/// <returns></returns>
public static float ClampAngle(float angle, float min, float max)
{
if (angle < -min) angle = -((-angle) % 360f);
if (angle > max) angle = angle % 360f;
return Mathf.Clamp(angle, min, max);
}
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 035ad1913e9c28f4492641ca36127790
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+84
View File
@@ -0,0 +1,84 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: UiMaterial
m_Shader: {fileID: 10760, guid: 0000000000000000f000000000000000, type: 0}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _BumpScale: 1
- _ColorMask: 15
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _Stencil: 0
- _StencilComp: 8
- _StencilOp: 0
- _StencilReadMask: 255
- _StencilWriteMask: 255
- _UVSec: 0
- _UseUIAlphaClip: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 0.78431374}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 57c048a21c6552643bb464f9bcd0cf1a
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant: