-
-
Save ProGM/226204b2a7f99998d84d755ffa1fb39a to your computer and use it in GitHub Desktop.
using System; | |
using UnityEngine; | |
#if UNITY_EDITOR | |
using UnityEditor; | |
#endif | |
public class DraggablePoint : PropertyAttribute {} | |
#if UNITY_EDITOR | |
[CustomEditor(typeof(MonoBehaviour), true)] | |
public class DraggablePointDrawer : Editor { | |
readonly GUIStyle style = new GUIStyle(); | |
void OnEnable(){ | |
style.fontStyle = FontStyle.Bold; | |
style.normal.textColor = Color.white; | |
} | |
public void OnSceneGUI () { | |
var property = serializedObject.GetIterator (); | |
while (property.Next (true)) { | |
if (property.propertyType == SerializedPropertyType.Vector3) { | |
var field = serializedObject.targetObject.GetType ().GetField (property.name); | |
if (field == null) { | |
continue; | |
} | |
var draggablePoints = field.GetCustomAttributes (typeof(DraggablePoint), false); | |
if (draggablePoints.Length > 0) { | |
Handles.Label(property.vector3Value, property.name); | |
property.vector3Value = Handles.PositionHandle (property.vector3Value, Quaternion.identity); | |
serializedObject.ApplyModifiedProperties (); | |
} | |
} | |
} | |
} | |
} | |
#endif |
using UnityEngine; | |
using System.Collections; | |
public class ExampleBehavior : MonoBehaviour { | |
[DraggablePoint] public Vector3 SpawnPosition; | |
public GameObject SpawnableObject; | |
public void Spawn() { | |
Instantiate(SpawnableObject, SpawnPosition, Quaternion.identity); | |
} | |
} |
Soooo back again.... Made another version that puts handles relative to the parent. So if you move the game object around the handles will move relative to the parent rather than being in world space.
using System;
using UnityEngine;
using System.Reflection;
#if UNITY_EDITOR
using UnityEditor;
#endif
///Handles relative to game object
public class DraggablePointRelative : PropertyAttribute { }
#if UNITY_EDITOR
[CustomEditor(typeof(MonoBehaviour), true)]
public class DraggablePointDrawer : Editor
{
readonly GUIStyle style = new GUIStyle();
void OnEnable()
{
style.fontStyle = FontStyle.Bold;
style.normal.textColor = Color.white;
}
public void OnSceneGUI()
{
SerializedProperty property = serializedObject.GetIterator();
while (property.Next(true))
{
if (property.propertyType == SerializedPropertyType.Vector3)
{
handleVectorProperty(property);
}
else if (property.isArray)
{
for (int x = 0; x < property.arraySize; x++)
{
SerializedProperty element = property.GetArrayElementAtIndex(x);
if (element.propertyType != SerializedPropertyType.Vector3)
{
//Break early if we're not an array of Vector3
break;
}
handleVectorPropertyInArray(element, property, x);
}
}
}
}
void handleVectorProperty(SerializedProperty property)
{
FieldInfo field = serializedObject.targetObject.GetType().GetField(property.name);
if (field == null)
{
return;
}
var draggablePoints = field.GetCustomAttributes(typeof(DraggablePoint), false);
if (draggablePoints.Length > 0)
{
Handles.Label(property.vector3Value + ((MonoBehaviour)target).transform.position, property.name);
property.vector3Value = Handles.PositionHandle(property.vector3Value + ((MonoBehaviour)target).transform.position, Quaternion.identity) - ((MonoBehaviour)target).transform.position;
serializedObject.ApplyModifiedProperties();
}
}
void handleVectorPropertyInArray(SerializedProperty property, SerializedProperty parent, int index)
{
FieldInfo parentfield = serializedObject.targetObject.GetType().GetField(parent.name);
if (parentfield == null)
{
return;
}
var draggablePoints = parentfield.GetCustomAttributes(typeof(DraggablePoint), false);
if (draggablePoints.Length > 0)
{
Handles.Label(property.vector3Value + ((MonoBehaviour)target).transform.position, parent.name + "[" + index + "]");
property.vector3Value = Handles.PositionHandle(property.vector3Value + ((MonoBehaviour)target).transform.position, Quaternion.identity) - ((MonoBehaviour)target).transform.position;
serializedObject.ApplyModifiedProperties();
}
}
}
#endif
public class DraggablePoint : PropertyAttribute {}
should not be defined in a script inside the Editor
folder but somewhere inside a Script
or Assets
folder. Otherwise you'll be forced to place all the script using this inside the Editor
folder
I realise I'm replying a year and a half later, but I'm trying to adapt this to be able to edit Vector3 arrays in scriptable objects. I'm using SOs to generate spawn points for a mobile game and being able to edit them quickly in the scene view would be useful, rather than doing so in the inspector.
I'm assuming I need to use the OnOpenAsset to access assets as opposed to game objects but I keep hitting brick walls. Anybody managed to do this?
Sorry accidentally didn't comment to you directly but have a look at my comment:
https://gist.github.com/ProGM/226204b2a7f99998d84d755ffa1fb39a#gistcomment-3266712