墙体碰撞器编辑插件脚本
2017-05-15 本文已影响75人
木心Sepith
airwalleditor.gif
[System.Serializable]
public class AirWallPoint
{
public int pointID;
public Vector3 position;
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[ExecuteInEditMode]
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer), typeof(MeshCollider))]
public class AirWallEditor : MonoBehaviour {
[HideInInspector]
public float wallHight = 10f;
[HideInInspector]
public Mesh wallMash ;
Material wallMat;
[HideInInspector]
public List<AirWallPoint> wallpoints = new List<AirWallPoint>()
{
new AirWallPoint { position = new Vector3(0, 0, 0) },
new AirWallPoint { position = new Vector3(5, 0, 0) },
new AirWallPoint { position = new Vector3(5, 0, 5) },
};
[HideInInspector]
public Vector3[] vertices;
[HideInInspector]
public int[] triangles;
[HideInInspector]
public int triangles_count = 1;
void OnEnable()
{
if (wallMat == null)
wallMat = new Material(Shader.Find("Transparent/Diffuse"));
GetComponent<MeshRenderer>().material = wallMat;
GetComponent<MeshRenderer>().enabled = false;
UpdateMesh();
}
public void UpdateMesh()
{
if (wallpoints.Count > 1)
{
if (wallMash == null)
{
GetComponent<MeshFilter>().mesh = wallMash = new Mesh();
wallMash.name = "airWall";
}
MeshCollider airWallCollider = GetComponent<MeshCollider>();
airWallCollider.sharedMesh = wallMash;
airWallCollider.enabled = false;
wallMash.Clear();
int vert = wallpoints.Count * 2;
vertices = new Vector3[vert];
triangles_count = vert;
triangles = new int[vert * 3];
for (int i = 0; i < vertices.Length; i++)
{
if (i % 2 == 0)
{
vertices[i] = wallpoints[i / 2].position;
}
else
{
vertices[i] = wallpoints[i / 2].position + new Vector3(0, wallHight, 0);
}
}
for (int i = 0; i < vert-2; i++)
{
for (int j = 0; j < 3; j++)
{
if (i % 2 == 0)
{
triangles[3 * i + j] = i + j;
}
else
{
triangles[3 * i + j] = i + 2 - j;
}
}
}
triangles[(vert - 2) * 3] = vert - 2;
triangles[(vert - 2) * 3 + 1] = vert - 1;
triangles[(vert - 2) * 3 + 2] = 0;
triangles[(vert - 1) * 3 ] = 1;
triangles[(vert - 1) * 3 + 1] = 0;
triangles[(vert - 1) * 3 + 2] = vert - 1;
wallMash.vertices = vertices;
wallMash.triangles = triangles;
wallMash.RecalculateNormals();
wallMash.RecalculateBounds();
airWallCollider.enabled = true;
}
}
void OnDisable()
{
if (Application.isEditor)
{
GetComponent<MeshCollider>().sharedMesh = null;
DestroyImmediate(wallMash);
}
}
void Reset()
{
UpdateMesh();
}
}
using UnityEngine;
using UnityEditor;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
[CustomEditor(typeof(AirWallEditor))]
public class AirWallEditorStyle : Editor
{
Tool toolType = Tool.Move;
Vector3 targetPos;
private bool m_isEditor;
private bool isEditor
{
get
{
return m_isEditor;
}
set {
if(m_isEditor == value)
return;
m_isEditor = value;
if (m_isEditor)
{
toolType = Tools.current;
}
else {
Tools.current = toolType;
}
}
}
AirWallEditor m_Target;
private SerializedObject star;
public void OnEnable()
{
m_Target = (AirWallEditor)target;
}
public override void OnInspectorGUI()
{
//DrawDefaultInspector();
GUILayout.Space(10);
GUIStyle boolBtnOn = new GUIStyle(GUI.skin.GetStyle("Button"));
GUILayout.BeginHorizontal();
GUILayout.Label("");
isEditor = GUILayout.Toggle(isEditor, EditorGUIUtility.IconContent("EditCollider"), boolBtnOn, GUILayout.Width(35), GUILayout.Height(25));
EditorGUILayout.TextField("Editor AirWall",EditorStyles.boldLabel, GUILayout.MaxWidth(100));
GUILayout.Label("");
GUILayout.EndHorizontal();
GUILayout.Space(10);
if (m_isEditor)
{
Tools.current = Tool.None;
}
DrawWallPointInspector();
}
void OnSceneGUI()
{
if (isEditor)
{
for (int i = 0; i < m_Target.wallpoints.Count; ++i)
{
DrawWallpointsHandles(i);
}
}
}
void DrawWallpointsHandles(int index)
{
//开始绘制GUI
Handles.BeginGUI();
//规定GUI显示区域
GUILayout.BeginArea(new Rect(100, 100, 150, 150));
GUILayout.Label("wallpoints:" + m_Target.wallpoints.Count.ToString());
GUILayout.Label("vertices:" + m_Target.vertices.Length.ToString());
GUILayout.Label("triangles_count:" + m_Target.triangles_count.ToString());
GUILayout.Label("triangles:" + m_Target.triangles.Length.ToString());
GUILayout.EndArea();
Handles.EndGUI();
EditorGUI.BeginChangeCheck();
//if (index < m_Target.wallpoints.Count-1)
//{
// nor = m_Target.wallMash.normals[index * 2 ].normalized - m_Target.wallpoints[index].position.normalized;
//}
//Debug.Log(m_Target.wallMash.normals[4]);
m_Target.wallpoints[index].position = Handles.DoPositionHandle(m_Target.wallpoints[index].position + m_Target.transform.position, Quaternion.identity) - m_Target.transform.position;
//Handles.SphereCap(1, m_Target.wallpoints[index].position + m_Target.transform.position, Quaternion.identity, 1f);
Handles.Label(m_Target.wallpoints[index].position + m_Target.transform.position,"wallPoint_" +index + " : " + (m_Target.wallpoints[index].position + m_Target.transform.position).ToString());
if (EditorGUI.EndChangeCheck())
{
m_Target.UpdateMesh();
}
}
void DrawWallPointInspector()
{
GUILayout.Space(5);
EditorGUI.BeginChangeCheck();
m_Target.wallHight = EditorGUILayout.FloatField("airWall Hight : ", m_Target.wallHight);
if (EditorGUI.EndChangeCheck())
{
m_Target.UpdateMesh();
}
GUILayout.Space(5);
GUILayout.Label("Wallpoints", EditorStyles.boldLabel);
for (int i = 0; i < m_Target.wallpoints.Count; ++i)
{
DrawWallpoints(i);
}
DrawAddWallpointButton();
}
void DrawWallpoints(int index)
{
if (index < 0 || index >= m_Target.wallpoints.Count)
{
return;
}
GUILayout.BeginHorizontal();
GUILayout.Label("WallPointID", EditorStyles.label, GUILayout.Width(50));
EditorGUI.BeginChangeCheck();
GUILayout.Label(index.ToString(), GUILayout.Width(15));
Vector3 newPosition = EditorGUILayout.Vector3Field("", m_Target.wallpoints[index].position ) ;
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(m_Target, "Modify State");
m_Target.wallpoints[index].pointID = index;
m_Target.wallpoints[index].position = newPosition;
m_Target.UpdateMesh();
EditorUtility.SetDirty(m_Target);
}
if (GUILayout.Button("Remove"))
{
EditorApplication.Beep();
Undo.RecordObject(m_Target, "Delete wallpoints");
m_Target.wallpoints.RemoveAt(index);
m_Target.UpdateMesh();
EditorUtility.SetDirty(m_Target);
}
GUILayout.EndHorizontal();
}
void DrawAddWallpointButton()
{
if (GUILayout.Button("Add new WallPoint", GUILayout.Height(30)))
{
Undo.RecordObject(m_Target, "Add new State");
if (m_Target.wallpoints.Count > 1)
{
Vector3 lastPos = m_Target.wallpoints[m_Target.wallpoints.Count - 1].position;
Vector3 lastPos2 = m_Target.wallpoints[m_Target.wallpoints.Count - 2].position;
m_Target.wallpoints.Add(new AirWallPoint { position = lastPos + (lastPos - lastPos2) });
}
else if (m_Target.wallpoints.Count == 1)
{
m_Target.wallpoints.Add(new AirWallPoint { position = m_Target.wallpoints[m_Target.wallpoints.Count - 1].position + new Vector3(5, 0, 0) });
}
else
{
m_Target.wallpoints.Add(new AirWallPoint { position = new Vector3(0, 0, 0) });
}
m_Target.UpdateMesh();
EditorUtility.SetDirty(m_Target);
}
}
}