- Home /
GUI splitter control
How can I make a GUI splitter control, similar to the splitter the console has?
Answer by ricardo_arango · May 22, 2013 at 03:17 PM
You can create a splitter using UnityGUI with BeginScrollView or BeginArea and changing the Rects of those areas using mouse events.
You can use the EventType.MouseMove event to see if the mouse is over your splitter object, the EventType.MouseDown event to check when the mouse was pressed over the splitter and the EventType.MouseDrag event to change the Rects and move the splitter as it is dragged.
Try the following code, by creating a C# script named "GUISplitter" inside a folder named "Editor". After the script is compiled a "GUI" menu with a "GUISplitter" menu item will appear in the top menu. Click on it to open the example EditorWindow with the vertical splitter control.
using UnityEngine;
using UnityEditor;
public class GUISplitter : EditorWindow {
Vector2 posLeft;
Vector2 posRight;
GUIStyle styleLeftView;
GUIStyle styleRightView;
float splitterPos;
Rect splitterRect;
Vector2 dragStartPos;
bool dragging;
float splitterWidth = 5;
// Add menu named "My Window" to the Window menu
[MenuItem ("GUI/GUISplitter")]
static void Init () {
GUISplitter window = (GUISplitter)EditorWindow.GetWindow (
typeof (GUISplitter));
window.position = new Rect(200, 200, 200,200);
window.splitterPos = 100;
}
void OnGUI (){
if (styleLeftView == null)
styleLeftView = new GUIStyle(GUI.skin.box);
if (styleRightView == null)
styleRightView = new GUIStyle(GUI.skin.button);
GUILayout.BeginHorizontal ();
// Left view
posLeft = GUILayout.BeginScrollView (posLeft,
GUILayout.Width (splitterPos),
GUILayout.MaxWidth(splitterPos),
GUILayout.MinWidth(splitterPos));
GUILayout.Box ("Left View",
styleLeftView,
GUILayout.ExpandWidth(true),
GUILayout.ExpandHeight(true));
GUILayout.EndScrollView ();
// Splitter
GUILayout.Box ("",
GUILayout.Width(splitterWidth),
GUILayout.MaxWidth (splitterWidth),
GUILayout.MinWidth(splitterWidth),
GUILayout.ExpandHeight(true));
splitterRect = GUILayoutUtility.GetLastRect ();
// Right view
posRight = GUILayout.BeginScrollView (posRight,
GUILayout.ExpandWidth(true));
GUILayout.Box ("Right View",
styleRightView,
GUILayout.ExpandWidth(true),
GUILayout.ExpandHeight(true));
GUILayout.EndScrollView ();
GUILayout.EndHorizontal ();
// Splitter events
if (Event.current != null) {
switch (Event.current.rawType) {
case EventType.MouseDown:
if (splitterRect.Contains (Event.current.mousePosition)) {
Debug.Log ("Start dragging");
dragging = true;
}
break;
case EventType.MouseDrag:
if (dragging){
Debug.Log ("moving splitter");
splitterPos += Event.current.delta.x;
Repaint ();
}
break;
case EventType.MouseUp:
if (dragging){
Debug.Log ("Done dragging");
dragging = false;
}
break;
}
}
}
}
Answer by Sky-Slider · Aug 30, 2017 at 03:02 PM
This solution does not work correctly if MouseUp event occurs outside the window. You need to use RawType Event like this: Event.current.rawType == EventType.mouseUp.
Answer by littledove · Oct 25, 2018 at 02:50 AM
if right area can move,then the children on it will above left.
Answer by codestage · Jul 11, 2019 at 09:13 PM
Or, you can use Unity's internal SplitterGUILayout. It is used in the standard Console and can be easily used in a similar way via reflection.
Take a look at these MIT-licensed wrappers to figure out how to reach it via reflection (no need to wrap it like there for the simple usage btw): https://github.com/steve3003/unity-profiler-data-exporter/tree/master/UnityWrappers
Do you have a more modern version of this code? I get "InvalidCastException" trying to use it in 2021 :)
You might try pinging code author (Stefano) or fix it yourself looking at what's exactly got broken. More likely some reflected APIs changed and reflection code needs to be synced.