代码参考如下:
using UnityEditor;
using UnityEditor.EditorTools;
using UnityEngine;
[EditorTool("Roaming View Tool", typeof(SetRoamingViewCtrl))]
public class RoamingViewTool : EditorTool
{
public override GUIContent toolbarIcon => EditorGUIUtility.IconContent("EditCollider");
public override void OnToolGUI(EditorWindow window)
{
if (window is not SceneView) return;
//
foreach (var obj in targets)
{
if (obj is not SetRoamingViewCtrl setRoamingViewCtrl) continue;
//
Vector3[] nodes = setRoamingViewCtrl.nodes;
//
Handles.color = new Color(0, 1, 0, 0.5f);
//
for (int i = 0; i < nodes.Length; i++)
{
Vector3 node = setRoamingViewCtrl.nodes[i];
EditorGUI.BeginChangeCheck();
node = Handles.PositionHandle(node, Quaternion.identity);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(setRoamingViewCtrl, "Moved roaming node");
setRoamingViewCtrl.nodes[i] = node;
}
//
int next = i + 1;
next %= setRoamingViewCtrl.nodes.Length;
Handles.DrawLine(setRoamingViewCtrl.nodes[i], setRoamingViewCtrl.nodes[next]);
}
}
}
}
[EditorTool("Fixed View Tool", typeof(SetFixedViewCtrl))]
public class FixedViewTool : EditorTool
{
public override GUIContent toolbarIcon => EditorGUIUtility.IconContent("AvatarPivot");
public override void OnToolGUI(EditorWindow window)
{
if (window is not SceneView) return;
//
foreach (var obj in targets)
{
if (obj is not SetFixedViewCtrl setFixedViewCtrl) continue;
//
for (int i = 0; i < setFixedViewCtrl.nodes.Length; i++)
{
Tran node = setFixedViewCtrl.nodes[i];
EditorGUI.BeginChangeCheck();
Quaternion rotation = node.rotation;
Handles.TransformHandle(ref node.position, ref rotation);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(setFixedViewCtrl, "Tran fixed node");
Vector3 euler = rotation.eulerAngles;
euler.z = 0;
node.euler = euler;
}
}
for (int i = 0; i < setFixedViewCtrl.nodes.Length; i++)
{
Tran node = setFixedViewCtrl.nodes[i];
HandlesFrustum.Draw(node.position, node.rotation, 60, 3, 1.78f);
}
}
}
public class HandlesFrustum
{
static public void Draw(Vector3 center, Quaternion rotation, float fov, float range, float aspect)
{
Handles.matrix = Matrix4x4.TRS(center, rotation, Vector3.one);
float z = Mathf.Abs(range);
z = Mathf.Clamp(z, 0.1f, 100);
fov = Mathf.Abs(fov * 0.5f);
fov = Mathf.Clamp(fov, 1, 178);
float y = z * Mathf.Tan(fov * Mathf.Deg2Rad);
aspect = Mathf.Abs(aspect);
aspect = Mathf.Clamp(aspect, 0.1f, 10);
float x = y * aspect;
Vector3 p0 = new Vector3(-x, -y, z);
Vector3 p1 = new Vector3(-x, y, z);
Vector3 p2 = new Vector3(x, y, z);
Vector3 p3 = new Vector3(x, -y, z);
Handles.DrawLine(Vector3.zero, p0);
Handles.DrawLine(Vector3.zero, p1);
Handles.DrawLine(Vector3.zero, p2);
Handles.DrawLine(Vector3.zero, p3);
Handles.DrawLine(p0, p1);
Handles.DrawLine(p1, p2);
Handles.DrawLine(p2, p3);
Handles.DrawLine(p3, p0);
}
}
}
第8行中工具图标设置的字符串可参照下图:
或者参考链接: