Skip to content

Instantly share code, notes, and snippets.

@prime31
Last active August 23, 2018 20:27
Show Gist options
  • Save prime31/11bf6a13a75b175cdd35 to your computer and use it in GitHub Desktop.
Save prime31/11bf6a13a75b175cdd35 to your computer and use it in GitHub Desktop.
Ever get tired of creating piles of GameObjects just because you want a Vector3 position? Those days are over. The Vector3Editor will let you edit single Vector3 properties and arrays of Vector3's without having to create a plethora of GameObjects.
// Usage:
// - stick the Vector3Editor.cs file in the Editor folder of your project
// - create a class with a Vector3 or Vector3[] property (you probably already have plenty of them. The WarpZone class below is a simple example)
// - create an editor script for any the class that you want to be able to edit extending Vector3Editor (see WarpZoneEditor below)
// - in OnEnable simply call setup() with your property names and optional labels
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
public class Vector3Editor : Editor
{
private List<SerializedProperty> _singleValueProps = new List<SerializedProperty>();
private List<SerializedProperty> _arrayProps = new List<SerializedProperty>();
private List<string> _handleLabels = new List<string>();
protected void setup( string[] propertyNames, string[] handleLabels = null )
{
if( handleLabels != null && propertyNames.Length != handleLabels.Length )
{
Debug.LogWarning( "propertyNames and handleLabels should be the same length. Ignoring handleLabels" );
handleLabels = null;
}
// we need to sort out the labels so that when we loop through later we get the right ones
var singlePropLabels = new List<string>();
var arrayPropLabels = new List<string>();
var handleLabelIndex = 0;
foreach( var str in propertyNames )
{
var prop = serializedObject.FindProperty( str );
if( prop.isArray && prop.type == "vector" )
{
_arrayProps.Add( prop );
if( handleLabels != null )
arrayPropLabels.Add( handleLabels[handleLabelIndex++] );
}
else if( !prop.isArray && prop.type == "Vector3f" )
{
_singleValueProps.Add( prop );
if( handleLabels != null )
singlePropLabels.Add( handleLabels[handleLabelIndex++] );
}
}
if( handleLabels != null )
{
_handleLabels.AddRange( singlePropLabels );
_handleLabels.AddRange( arrayPropLabels );
}
}
protected virtual void OnSceneGUI()
{
var handleLabelIndex = 0;
// draw the single values props
foreach( var prop in _singleValueProps )
{
var label = _handleLabels.Count > 0 ? _handleLabels[handleLabelIndex++] : string.Empty;
Handles.Label( prop.vector3Value, label );
prop.vector3Value = Handles.PositionHandle( prop.vector3Value, Quaternion.identity );
}
foreach( var arr in _arrayProps )
{
var label = _handleLabels.Count > 0 ? _handleLabels[handleLabelIndex++] + ": " : string.Empty;
for( var i = 0; i < arr.arraySize; i++ )
{
var prop = arr.GetArrayElementAtIndex( i );
Handles.Label( prop.vector3Value, label + i );
prop.vector3Value = Handles.PositionHandle( prop.vector3Value, Quaternion.identity );
}
}
serializedObject.ApplyModifiedProperties();
}
}
// ##### ##### ##### ##### ##### #####
// ## Example implementation class
// ##### ##### ##### ##### ##### #####
public class WarpZone : MonoBehaviour
{
public Vector3 warpTarget;
public Vector3[] manyTargets;
}
// ##### ##### ##### ##### ##### #####
// ## Example implementation Editor
// ##### ##### ##### ##### ##### #####
[CustomEditor( typeof( WarpZone ) )]
public class WarpZoneEditor : Vector3Editor
{
void OnEnable()
{
// all you need to do here is call setup with the property names that you want to edit in the scene view. Note
// that only Vector3's are supported (both Vector3 and Vector3[] will work).
// use this variant if you want labels next to each handle
setup( new string[] { "warpTarget", "manyTargets" }, new string[] { "Warp Zone Target", "Warp Zone Target" } );
// use this variant if you dont want handles labeled
//setup( new string[] { "warpTarget", "manyTargets" } );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment