Unity Editor Window Zooming
来源:互联网 发布:跳舞毯哪款最好 知乎 编辑:程序博客网 时间:2024/06/04 08:25
参考:
http://martinecker.com/martincodes/unity-editor-window-zooming/
http://answers.unity3d.com/questions/38224/how-can-i-zoom-out-properly-within-a-editorwindow.html
方法1:
using UnityEngine;using System.Collections;public class Test : MonoBehaviour{ private Vector2 scale = new Vector2(1, 1); private Vector2 pivotPoint; void OnGUI() { Matrix4x4 oldMatrix = GUI.matrix; pivotPoint = new Vector2(Screen.width / 2, Screen.height / 2); GUIUtility.ScaleAroundPivot(scale, pivotPoint); if (GUI.Button(new Rect(Screen.width / 2 - 25, Screen.height / 2 - 25, 50, 50), "Big!")) scale += new Vector2(0.5F, 0.5F); GUI.matrix = oldMatrix; if (GUI.Button(new Rect(Screen.width / 2 + 25, Screen.height / 2 - 25, 50, 50), "Big!")) scale += new Vector2(0.5F, 0.5F); }}
方法2:
using System;using System.Collections.Generic;using UnityEngine;using UnityEditor;public class ZoomTestWindow : EditorWindow{ [MenuItem("Window/Zoom Test")] private static void Init() { ZoomTestWindow window = EditorWindow.GetWindow<ZoomTestWindow>(false, "Zoom Test"); window.minSize = new Vector2(600.0f, 300.0f); window.wantsMouseMove = true; window.Show(); //EditorWindow.FocusWindowIfItsOpen(); } private const float kZoomMin = 0.1f; private const float kZoomMax = 10.0f; private readonly Rect _zoomArea = new Rect(0.0f, 75.0f, 600.0f, 300.0f - 100.0f); private float _zoom = 1.0f; private Vector2 _zoomCoordsOrigin = Vector2.zero; private Vector2 ConvertScreenCoordsToZoomCoords(Vector2 screenCoords) { return (screenCoords - _zoomArea.TopLeft()) / _zoom + _zoomCoordsOrigin; } private void DrawZoomArea() { // Within the zoom area all coordinates are relative to the top left corner of the zoom area // with the width and height being scaled versions of the original/unzoomed area's width and height. EditorZoomArea.Begin(_zoom, _zoomArea); GUI.Box(new Rect(0.0f - _zoomCoordsOrigin.x, 0.0f - _zoomCoordsOrigin.y, 100.0f, 25.0f), "Zoomed Box"); // You can also use GUILayout inside the zoomed area. GUILayout.BeginArea(new Rect(300.0f - _zoomCoordsOrigin.x, 70.0f - _zoomCoordsOrigin.y, 130.0f, 50.0f)); GUILayout.Button("Zoomed Button 1"); GUILayout.Button("Zoomed Button 2"); GUILayout.EndArea(); EditorZoomArea.End(); } private void DrawNonZoomArea() { GUI.Box(new Rect(0.0f, 0.0f, 600.0f, 50.0f), "Adjust zoom of middle box with slider or mouse wheel.\nMove zoom area dragging with middle mouse button or Alt+left mouse button."); _zoom = EditorGUI.Slider(new Rect(0.0f, 50.0f, 600.0f, 25.0f), _zoom, kZoomMin, kZoomMax); GUI.Box(new Rect(0.0f, 300.0f - 25.0f, 600.0f, 25.0f), "Unzoomed Box"); } private void HandleEvents() { // Allow adjusting the zoom with the mouse wheel as well. In this case, use the mouse coordinates // as the zoom center instead of the top left corner of the zoom area. This is achieved by // maintaining an origin that is used as offset when drawing any GUI elements in the zoom area. if (Event.current.type == EventType.ScrollWheel) { Vector2 screenCoordsMousePos = Event.current.mousePosition; Vector2 delta = Event.current.delta; Vector2 zoomCoordsMousePos = ConvertScreenCoordsToZoomCoords(screenCoordsMousePos); float zoomDelta = -delta.y / 150.0f; float oldZoom = _zoom; _zoom += zoomDelta; _zoom = Mathf.Clamp(_zoom, kZoomMin, kZoomMax); _zoomCoordsOrigin += (zoomCoordsMousePos - _zoomCoordsOrigin) - (oldZoom / _zoom) * (zoomCoordsMousePos - _zoomCoordsOrigin); Event.current.Use(); } // Allow moving the zoom area's origin by dragging with the middle mouse button or dragging // with the left mouse button with Alt pressed. if (Event.current.type == EventType.MouseDrag && (Event.current.button == 0 && Event.current.modifiers == EventModifiers.Alt) || Event.current.button == 2) { Vector2 delta = Event.current.delta; delta /= _zoom; _zoomCoordsOrigin += delta; Event.current.Use(); } } public void OnGUI() { HandleEvents(); // The zoom area clipping is sometimes not fully confined to the passed in rectangle. At certain // zoom levels you will get a line of pixels rendered outside of the passed in area because of // floating point imprecision in the scaling. Therefore, it is recommended to draw the zoom // area first and then draw everything else so that there is no undesired overlap. DrawZoomArea(); DrawNonZoomArea(); }}
using UnityEngine;using System;// Helper Rect extension methodspublic static class RectExtensions{ public static Vector2 TopLeft(this Rect rect) { return new Vector2(rect.xMin, rect.yMin); } public static Rect ScaleSizeBy(this Rect rect, float scale) { return rect.ScaleSizeBy(scale, rect.center); } public static Rect ScaleSizeBy(this Rect rect, float scale, Vector2 pivotPoint) { Rect result = rect; result.x -= pivotPoint.x; result.y -= pivotPoint.y; result.xMin *= scale; result.xMax *= scale; result.yMin *= scale; result.yMax *= scale; result.x += pivotPoint.x; result.y += pivotPoint.y; return result; } public static Rect ScaleSizeBy(this Rect rect, Vector2 scale) { return rect.ScaleSizeBy(scale, rect.center); } public static Rect ScaleSizeBy(this Rect rect, Vector2 scale, Vector2 pivotPoint) { Rect result = rect; result.x -= pivotPoint.x; result.y -= pivotPoint.y; result.xMin *= scale.x; result.xMax *= scale.x; result.yMin *= scale.y; result.yMax *= scale.y; result.x += pivotPoint.x; result.y += pivotPoint.y; return result; }}public class EditorZoomArea{ private const float kEditorWindowTabHeight = 21.0f; private static Matrix4x4 _prevGuiMatrix; public static Rect Begin(float zoomScale, Rect screenCoordsArea) { GUI.EndGroup(); // End the group Unity begins automatically for an EditorWindow to clip out the window tab. This allows us to draw outside of the size of the EditorWindow. Rect clippedArea = screenCoordsArea.ScaleSizeBy(1.0f / zoomScale, screenCoordsArea.TopLeft()); clippedArea.y += kEditorWindowTabHeight; GUI.BeginGroup(clippedArea); _prevGuiMatrix = GUI.matrix; Matrix4x4 translation = Matrix4x4.TRS(clippedArea.TopLeft(), Quaternion.identity, Vector3.one); Matrix4x4 scale = Matrix4x4.Scale(new Vector3(zoomScale, zoomScale, 1.0f)); GUI.matrix = translation * scale * translation.inverse * GUI.matrix; return clippedArea; } public static void End() { GUI.matrix = _prevGuiMatrix; GUI.EndGroup(); GUI.BeginGroup(new Rect(0.0f, kEditorWindowTabHeight, Screen.width, Screen.height)); }}
理解:
algorithm for scaling an image from a given pivot point:http://stackoverflow.com/questions/3598538/algorithm-for-scaling-an-image-from-a-given-pivot-point
Well, I don't know what framework/library you're using but you can think of it as:
- translation to make your pivot point the center point
- standard scaling
- opposite transalation to make the center point the original pivot point
Translation and scaling are isomorphismes so you can represent them as matrix. Each transformation is a matrix and you can multiply them for find the combined transformation matrix. So:
- T = transformation
- S = scalling
- T' = opposite transformation
If you apply T.x being x a point vector it gives you the new coordinates. The same for S.x.
So if you want to do that operations you have to do: T'. (S. (T.x))
I think you can associate operations so it's the same as (T'.S.T).x
If you are using a framework apply three operations (or combine operations and apply). If you are using crude math... go the matrix way :)
- Unity Editor Window Zooming
- 【Unity】Unity Editor Tips
- 【Unity 插件】 Shader Editor
- Unity学习 - Editor扩张
- Unity Editor编程杂记
- Unity Editor扩展
- Unity GUID替换Editor
- Unity Editor Scripting
- Unity Editor Scripting 2
- Unity Editor 常用类
- Unity Editor编译顺序
- Unity Editor编辑器(MenuItem)
- Unity Editor(二)C#特性与Editor
- [Editor]Unity Editor类常用方法
- powercenter sql-editor window issue
- Unity Editor下 修改 Prefab
- Unity Editor 深拷贝 组件
- Unity Editor GUI 编辑器入门教程
- [产品经理]产品管理职位的级别
- linux将本目录下的大小为0的文件移除
- DTD约束
- ServerSocket+Swing+SQL Server2008聊天系统(好友私聊,聊天室群聊)
- addEventListener()解决传统事件绑定中去除冗余同名函数但也存在问题
- Unity Editor Window Zooming
- S4.1_Struts2_ActionAdvance 在action动作类里定义增删改方法,在struts.xml中的action method属性如何设置?
- MPI—统计完数的个数
- <sstream>—istringstream、ostringstream、stringstream类
- 字母点击滚动条跳转事件
- Nexus私服与Maven配置
- 将数据流链接到加密转换的流CryptoStream 类
- 构造数组的MaxTree
- 去除inline-block元素间间距的N种方法