- Home /
How to choose the transform tool from script ?
Is it possible to control the current transform tool (Pan, translate, rotate or scale) with a simple line like
Editor.transformTool = TransformTool.Rotate;
The reason I want to do this is I'm doing a custom editor script where you can click a button in the inspector, then an object in the scene view, which will affect the object to some variable. If the transform tool is different from pan, the click is ignored by my script and the object is simply selected. I hear there is the function Event.current.Use();, but it doesn't seems to help.
[ EDIT ] Just to be clear, here is the code I'm talking about, without useless stuff :
class ObjectEditor extends Editor { private var pick = false; private var selection : GameObject = null;
function OnInspectorGUI ()
{
var str : String = selection ? selection.name : "null";
// Create a button in the inspector with the name f the selection displayed in it.
// If you click it, you enter the picking mode and the next click in the scene view will pick an object.
GUILayout.BeginHorizontal ();
var r : Rect = EditorGUILayout.BeginHorizontal ("Button");
if (GUI.Button (r, GUIContent.none))
pick = !pick;
GUILayout.Label (str);
EditorGUILayout.EndHorizontal ();
GUILayout.EndHorizontal ();
}
function OnSceneGUI()
{
// If this is a click and if we are in picking mode
// The problem is that if you click in the scene view, you loose
// the focus on your object, so this code isn't executed.
if( Event.current.type == EventType.MouseUp && pick )
{
// We are going to cast a ray through the scene to pick an object.
var R : Ray = HandleUtility.GUIPointToWorldRay( Event.current.mousePosition );
var H : RaycastHit;
if( Physics.Raycast( R, H, Mathf.Infinity ) )
{
pick = false;
selection = H.collider.gameObject;
Repaint(); // Display the name right now.
}
// Supposed to "eat" the event, prenting it to do something else. I guess the selection by Unity occurs before.
Event.current.Use();
}
}
}
[ EDIT 2 ] To be thorough, OnSceneGUI is executed once with a MouseDown in any cases. But then, the focus is lost.
Do you really need 1 button to do all that? you simply could add 3 buttons, 1 for each transformation, and the associate the button to the transformation you want into the object you selected.
You get me wrong. I just want to be able to click in the scene view without loosing my selection. It appears that, in pan mode and only that one, the click doesn't select objects, which is convenient for me. I want to say "Ok, my next click won't be a selection, so unity, put yourself in pan mode and don't do anything stupid !"
I've come across a similar problem, i just want to know the current mode of transformation. The local/global or pivot/center setting would also be nice to "get"/"set".
How did you try using Event.current.Use? You would need to get mouse input in OnSceneGUI and handle your own picking logic, then call Event.current.Use() so Unity doesn't use the mouse click again to select the object.
Answer by yoyo · Jan 18, 2011 at 05:20 PM
By digging into the UnityEditor DLL with MonoDevelop, I came up with the following.
DISCLAIMER: The following script uses Reflection to call a private API. It is not documented or supported by Unity and may change in a future release. (Some may consider this evil; you have been warned.)
Put this C# script into your Editor folder ...
using System.Reflection;
using UnityEngine; using UnityEditor;
// SceneToolHacker uses diabolical reflection technique to set the // active tool. Note that this may well break with future Unity releases!! public static class SceneToolHacker { public enum Tool { DragCamera = 0, Translate = 1, Rotate = 2, Scale = 3 }
public static Tool CurrentTool
{
get { return (Tool)mTools_current.GetValue(null, null); }
set { mTools_current.SetValue(null, (int)value, null); }
}
// "Sorry Virginia, there is no private."
private static PropertyInfo mTools_current = typeof(Tools).GetProperty("current", BindingFlags.Static | BindingFlags.NonPublic);
}
You can either take it from there, or give this menu demo a whirl to see it in action ...
using System;
using UnityEngine; using UnityEditor;
// Quick menu-driven demonstration. public static class SceneToolHackerMenu { [MenuItem("Hack/Scene Tool/Get")] public static void GetSceneTool() { Debug.Log(String.Format("{0} tool is active.", SceneToolHacker.CurrentTool)); }
[MenuItem("Hack/Scene Tool/Set/Translate")]
public static void SetSceneToolTranslate()
{
SceneToolHacker.CurrentTool = SceneToolHacker.Tool.Translate;
}
[MenuItem("Hack/Scene Tool/Set/Rotate")]
public static void SetSceneToolRotate()
{
SceneToolHacker.CurrentTool = SceneToolHacker.Tool.Rotate;
}
[MenuItem("Hack/Scene Tool/Set/Scale")]
public static void SetSceneToolScale()
{
SceneToolHacker.CurrentTool = SceneToolHacker.Tool.Scale;
}
}
Evil is fun!
Wahou, it works perfectly (with the current version at least) ! I wanted to use those function in a monobehaviour (well, in it's custom editor) and for those who are interested, you can call them with EditorApplication.Execute$$anonymous$$enuItem ("Hack/Scene Tool/Set/..."). Thanks a lot :)
Or you can use "SceneToolHacker.CurrentTool = SceneToolHacker.Tool.Translate;"
As of 3.2 the property was made public, so now there is no need to use reflection. You can access it directly as Tools.current
Answer by yoyo · Jan 13, 2011 at 10:04 AM
Try setting ...
gameObj.hideFlags = HideFlags.NotEditable;
This should make the object non-selectable in the scene view, which could solve your problem. (Though I'm not quite clear if the object being selected is the problem you're having, so this may not help.)
Not really, my problem is that I loose the focus when you click an object in the scene view. I want to remain in the same object (which have the script I care about) and just point out other objects to store in an array.
Answer by Berenger · Jan 17, 2011 at 09:02 AM
So, I didn't find out the solution, but I found an other way for my problem (and actually a better way). It's pretty simple, just need to use the right click instead of the left ...
Answer by Linphency · Dec 22, 2011 at 08:03 AM
This script works for me in 3.4
Tools.current = Tool.View;
Tool enum class can be found here
http://unity3d.com/support/documentation/ScriptReference/Tool.html
Your answer
Follow this Question
Related Questions
[Custom Inspector] Selecting Gizmo in Scene View and issues 1 Answer
Scripting a Click event in the Unity Editor 1 Answer
Triangles Index always zero - Custom Editor 1 Answer
Display OnSceneGUI without selecting the object 0 Answers
OnSceneGUI has odd behaviour with multiple objects selected 1 Answer