iTweenPath.cs [pyg language="csharp" s="monokai" ] //Slight additions for a cleaner interface by Jacob Pennock //source by Bob Berkebile : Pixelplacement : http://www.pixelplacement.com using UnityEngine; using System.Collections.Generic; public enum iTweenPathCap {Default, Sphere, Cube, Dot, Circle,Square} public class iTweenPath : MonoBehaviour { public string pathName =””; public Color pathColor = Color.cyan; public iTweenPathCap capType; public float capSize; public List nodes = new List(){Vector3.zero, Vector3.zero}; public int nodeCount; public static Dictionary paths = new Dictionary(); public bool initialized = false; public string initialName = “”; void OnEnable(){ paths.Add(pathName.ToLower(), this); } void OnDrawGizmosSelected(){ if(enabled) { // dkoontz if(nodes.Count > 0){ iTween.DrawPath(nodes.ToArray(), pathColor); } } // dkoontz } public static Vector3[] GetPath(string requestedName){ requestedName = requestedName.ToLower(); if(paths.ContainsKey(requestedName)){ return paths[requestedName].nodes.ToArray(); }else{ Debug.Log(“No path with that name exists! Are you sure you wrote it correctly?”); return null; } } } [/pyg] iTweenPathEditor.cs [pyg language="csharp" s="monokai" ] //Slight additions for a cleaner interface by Jacob Pennock //source by Bob Berkebile : Pixelplacement : http://www.pixelplacement.com using UnityEngine; using UnityEditor; using System.Collections; [CustomEditor(typeof(iTweenPath))] public class iTweenPathEditor : Editor { iTweenPath _target; GUIStyle style = new GUIStyle(); public static int count = 0; void OnEnable(){ //i like bold handle labels since I’m getting old: style.fontStyle = FontStyle.Bold; style.normal.textColor = Color.white; _target = (iTweenPath)target; //lock in a default path name: if(!_target.initialized){ _target.initialized = true; _target.pathName = “New Path ” + ++count; _target.initialName = _target.pathName; } } public override void OnInspectorGUI(){ //path name: EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel(“Path Name”); _target.pathName = EditorGUILayout.TextField(_target.pathName); EditorGUILayout.EndHorizontal(); if(_target.pathName == “”){ _target.pathName = _target.initialName; } //path color: EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel(“Path Color”); _target.pathColor = EditorGUILayout.ColorField(_target.pathColor); EditorGUILayout.EndHorizontal(); //Node Type _target.capType = (iTweenPathCap)EditorGUILayout.EnumPopup(“Node Type”,_target.capType); //Node size if(_target.capType != iTweenPathCap.Default) { _target.capSize = EditorGUILayout.Slider(“Node Size”,_target.capSize, 0.5f, 5.0f); } //exploration segment count control: EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel(“Node Count”); _target.nodeCount = Mathf.Clamp(EditorGUILayout.IntSlider(_target.nodeCount, 0, 25), 2,100); EditorGUILayout.EndHorizontal(); //add node? if(_target.nodeCount > _target.nodes.Count){ for (int i = 0; i < _target.nodeCount - _target.nodes.Count; i++) { _target.nodes.Add(Vector3.zero); } } //remove node? if(_target.nodeCount < _target.nodes.Count){ if(EditorUtility.DisplayDialog("Remove path node?","Shortening the node list will permantently destory parts of your path. This operation cannot be undone.", "OK", "Cancel")){ int removeCount = _target.nodes.Count - _target.nodeCount; _target.nodes.RemoveRange(_target.nodes.Count-removeCount,removeCount); }else{ _target.nodeCount = _target.nodes.Count; } } //node display: EditorGUI.indentLevel = 4; for (int i = 0; i < _target.nodes.Count; i++) { _target.nodes[i] = EditorGUILayout.Vector3Field("Node " + (i+1), _target.nodes[i]); } //update and redraw: if(GUI.changed){ EditorUtility.SetDirty(_target); } } void OnSceneGUI(){ if(_target.enabled) { // dkoontz if(_target.nodes.Count > 0){ //allow path adjustment undo: Undo.SetSnapshotTarget(_target,”Adjust iTween Path”); //path begin and end labels: Handles.Label(_target.nodes[0], “‘” + _target.pathName + “‘ Begin”, style); Handles.Label(_target.nodes[_target.nodes.Count-1], “‘” + _target.pathName + “‘ End”, style); //node handle display: DrawPathCaps(); } } // dkoontz } void DrawPathCaps() { switch(_target.capType) { case iTweenPathCap.Default: for (int i = 0; i < _target.nodes.Count; i++) { _target.nodes[i] = Handles.PositionHandle(_target.nodes[i], Quaternion.identity); } break; case iTweenPathCap.Sphere: Handles.color = _target.pathColor; for (int i = 0; i < _target.nodes.Count; i++) { _target.nodes[i] = Handles.FreeMoveHandle(_target.nodes[i],Quaternion.identity,_target.capSize,Vector3.zero,Handles.SphereCap); } break; case iTweenPathCap.Cube: Handles.color = _target.pathColor; for (int i = 0; i < _target.nodes.Count; i++) { _target.nodes[i] = Handles.FreeMoveHandle(_target.nodes[i],Quaternion.identity,_target.capSize,Vector3.zero,Handles.CubeCap); } break; case iTweenPathCap.Dot: Handles.color = _target.pathColor; for (int i = 0; i < _target.nodes.Count; i++) { _target.nodes[i] = Handles.FreeMoveHandle(_target.nodes[i],Quaternion.identity,_target.capSize,Vector3.zero,Handles.DotCap); } break; case iTweenPathCap.Circle: Handles.color = _target.pathColor; for (int i = 0; i < _target.nodes.Count; i++) { _target.nodes[i] = Handles.FreeMoveHandle(_target.nodes[i],Quaternion.identity,_target.capSize,Vector3.zero,Handles.CircleCap); } break; case iTweenPathCap.Square: Handles.color = _target.pathColor; for (int i = 0; i < _target.nodes.Count; i++) { _target.nodes[i] = Handles.FreeMoveHandle(_target.nodes[i],Quaternion.identity,_target.capSize,Vector3.zero,Handles.RectangleCap); } break; } } } [/pyg]