- Home /
[Answered]How to instantly draw rect in editor GUI for 2D tilemapper
I have written a custom editor script that displays a sprite map texture on the inspector and I am attempting to have this tool allow the user to click and drag over portions of the sprite map he wants to use for an object to speed up the level creation for my 2D game.
As such I have the editorGUI draw a rect over the texture. My problem is that I want it to draw during a mouse drag event yet it will only draw the rectangle 2-3 seconds after I let go of the button.
I created a portion of the script that drew a rectangle of increasing size that reset itself and even that had large latency problems. But I started quickly clicking on the editor in a gray area and it started drawing the aforementioned growing rectangle every time I clicked. I am unsure how to interpret this behavior.
Here is how my script currently gets the coordinates:
private void DrawCropAreaGUI() {
//Cache the event
Event evt = Event.current;
switch(evt.type){
case EventType.MouseDown:
case EventType.MouseDrag:
case EventType.MouseUp:
//If the click is outside of the sprite sheet
if(!spriteSheetRect.Contains( evt.mousePosition ))
break;
//We're working with the initial click
if(evt.type == EventType.MouseDown) {
mouseDown = evt.mousePosition;
}
//We haven't finished yet we're just drawing the outline
if(evt.type == EventType.MouseDrag || evt.type == EventType.MouseUp) {
int left, top, right, bottom; //The extents of our rectangle of selection
//The drag is moving to the left
if(mouseDown.x > evt.mousePosition.x){
left = (int)evt.mousePosition.x;
right = (int)mouseDown.x;
}
//The drag is moving to the right
else{
left = (int)mouseDown.x;
right = (int)evt.mousePosition.x;
}
//The drag is moving up
if(mouseDown.y > evt.mousePosition.y){
top = (int)evt.mousePosition.y;
bottom = (int)mouseDown.y;
}
//The drag is going down
else{
top = (int)mouseDown.y;
bottom = (int)evt.mousePosition.y;
}
selectionRect = new Rect( left, top , right - left, bottom - top );
}
break;
}
}
Then this is the OnInspectorGUI function:
public override void OnInspectorGUI() {
//Grab the attributes from the object
m_Object.Update();
//Overall settings label
GUILayout.Label("Selection Settings", EditorStyles.boldLabel);
//Set up the fields
EditorGUILayout.PropertyField( t_width );
EditorGUILayout.PropertyField( t_height );
//If the width value is less than 0
if(t_width.intValue < 0)
//We can't select less than 0 pixels
t_width.intValue = 0;
//If the height value is less than 0
if(t_height.intValue < 0)
//We can't select less than 0 pixels
t_height.intValue = 0;
//The sprite map label
GUILayout.Label( "Sprite Map", EditorStyles.boldLabel );
Color c = new Color(200, 200, 0, 0.5f);
if(t_texture.objectReferenceValue != null) {
spriteSheetRect = GUILayoutUtility.GetRect( 0.0f, 100.0f, GUILayout.ExpandWidth( true ), GUILayout.ExpandHeight(true) );
DrawCropAreaGUI();
//Draw our texturefor the user to eselect from
EditorGUI.DrawTextureTransparent(spriteSheetRect , (Texture2D) t_texture.objectReferenceValue );
Debug.Log( "spriteshseet " + spriteSheetRect + " selection " + selectionRect );
EditorGUI.DrawRect( selectionRect, c );
//ShadowAndOutline.DrawOutline( selectionRect, "", new GUIStyle(), Color.red, Color.gray, 10 );
}
DropAreaGUI();
//Apply the attributes to the object once done
m_Object.ApplyModifiedProperties();
}
Answer by yveris · Nov 18, 2013 at 04:10 AM
I figured it out.
Apparently, when creating event handler functions the programmer is required to end the function with Event.current.Use(). So as to notify unity the current event has been used and change the event.type. This will cause other gui elements to ignore this event. If you don't do this manually then I assume Unity has some sort of clock that handles the functions that does this but you won't get the response time you're looking for.Reference for event.use and the Unity GUI event class