添加插件
This commit is contained in:
110
Assets/Obi/Editor/Common/Collisions/ObiColliderEditor.cs
Normal file
110
Assets/Obi/Editor/Common/Collisions/ObiColliderEditor.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
|
||||
[CustomEditor(typeof(ObiColliderBase), true), CanEditMultipleObjects]
|
||||
public class ObiColliderEditor : Editor
|
||||
{
|
||||
|
||||
ObiColliderBase collider;
|
||||
SerializedProperty collisionFilter;
|
||||
|
||||
public void OnEnable()
|
||||
{
|
||||
collider = (ObiColliderBase)target;
|
||||
collisionFilter = serializedObject.FindProperty("filter");
|
||||
}
|
||||
|
||||
protected void NonReadableMeshWarning(Mesh mesh)
|
||||
{
|
||||
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
|
||||
Texture2D icon = EditorGUIUtility.Load("icons/console.erroricon.png") as Texture2D;
|
||||
EditorGUILayout.LabelField(new GUIContent("The input mesh is not readable. Read/Write must be enabled in the mesh import settings.", icon), EditorStyles.wordWrappedMiniLabel);
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button("Fix now", GUILayout.MaxWidth(100), GUILayout.MinHeight(32)))
|
||||
{
|
||||
string assetPath = AssetDatabase.GetAssetPath(mesh);
|
||||
ModelImporter modelImporter = AssetImporter.GetAtPath(assetPath) as ModelImporter;
|
||||
if (modelImporter != null)
|
||||
{
|
||||
modelImporter.isReadable = true;
|
||||
}
|
||||
modelImporter.SaveAndReimport();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
|
||||
serializedObject.UpdateIfRequiredOrScript();
|
||||
|
||||
foreach (ObiColliderBase t in targets)
|
||||
{
|
||||
ObiMeshShapeTracker meshTracker = t.Tracker as ObiMeshShapeTracker;
|
||||
if (meshTracker != null)
|
||||
{
|
||||
if (meshTracker.targetMesh != null && !meshTracker.targetMesh.isReadable)
|
||||
NonReadableMeshWarning(meshTracker.targetMesh);
|
||||
}
|
||||
}
|
||||
|
||||
var rect = EditorGUILayout.GetControlRect();
|
||||
var label = EditorGUI.BeginProperty(rect, new GUIContent("Collision category"), collisionFilter);
|
||||
rect = EditorGUI.PrefixLabel(rect, label);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var newCategory = EditorGUI.Popup(rect, ObiUtils.GetCategoryFromFilter(collider.Filter), ObiUtils.categoryNames);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
foreach (ObiColliderBase t in targets)
|
||||
{
|
||||
Undo.RecordObject(t, "Set collision category");
|
||||
t.Filter = ObiUtils.MakeFilter(ObiUtils.GetMaskFromFilter(t.Filter), newCategory);
|
||||
PrefabUtility.RecordPrefabInstancePropertyModifications(t);
|
||||
}
|
||||
}
|
||||
EditorGUI.EndProperty();
|
||||
|
||||
rect = EditorGUILayout.GetControlRect();
|
||||
label = EditorGUI.BeginProperty(rect, new GUIContent("Collides with"), collisionFilter);
|
||||
rect = EditorGUI.PrefixLabel(rect, label);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var newMask = EditorGUI.MaskField(rect, ObiUtils.GetMaskFromFilter(collider.Filter), ObiUtils.categoryNames);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
foreach (ObiColliderBase t in targets)
|
||||
{
|
||||
Undo.RecordObject(t, "Set collision mask");
|
||||
t.Filter = ObiUtils.MakeFilter(newMask, ObiUtils.GetCategoryFromFilter(t.Filter));
|
||||
PrefabUtility.RecordPrefabInstancePropertyModifications(t);
|
||||
}
|
||||
}
|
||||
EditorGUI.EndProperty();
|
||||
|
||||
DrawPropertiesExcluding(serializedObject, "m_Script", "CollisionMaterial", "filter", "Thickness", "Inverted");
|
||||
|
||||
foreach (ObiColliderBase t in targets)
|
||||
{
|
||||
if (!t.gameObject.isStatic)
|
||||
t.ForceUpdate();
|
||||
}
|
||||
|
||||
// Apply changes to the serializedProperty
|
||||
if (GUI.changed)
|
||||
{
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c99a0a8358754501b3c8089185b0e6f
|
||||
timeCreated: 1502034385
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
178
Assets/Obi/Editor/Common/Collisions/ObiDistanceFieldEditor.cs
Normal file
178
Assets/Obi/Editor/Common/Collisions/ObiDistanceFieldEditor.cs
Normal file
@@ -0,0 +1,178 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
|
||||
namespace Obi{
|
||||
[CustomEditor(typeof(ObiDistanceField))]
|
||||
public class ObiDistanceFieldEditor : Editor
|
||||
{
|
||||
|
||||
ObiDistanceField distanceField;
|
||||
|
||||
PreviewHelpers previewHelper;
|
||||
Vector2 previewDir;
|
||||
Material previewMaterial;
|
||||
|
||||
Mesh previewMesh;
|
||||
Texture3D volumeTexture;
|
||||
|
||||
protected IEnumerator routine;
|
||||
|
||||
private void UpdatePreview(){
|
||||
|
||||
CleanupPreview();
|
||||
|
||||
if (distanceField.InputMesh != null){
|
||||
|
||||
previewMesh = CreateMeshForBounds(distanceField.FieldBounds);
|
||||
previewMesh.hideFlags = HideFlags.HideAndDontSave;
|
||||
|
||||
volumeTexture = distanceField.GetVolumeTexture(64);
|
||||
volumeTexture.hideFlags = HideFlags.HideAndDontSave;
|
||||
|
||||
previewMaterial = Resources.Load<Material>("DistanceFieldPreview");
|
||||
previewMaterial.SetTexture("_Volume",volumeTexture);
|
||||
previewMaterial.SetVector("_AABBMin",-distanceField.FieldBounds.extents);
|
||||
previewMaterial.SetVector("_AABBMax",distanceField.FieldBounds.extents);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void CleanupPreview(){
|
||||
GameObject.DestroyImmediate(previewMesh);
|
||||
GameObject.DestroyImmediate(volumeTexture);
|
||||
}
|
||||
|
||||
public void OnEnable(){
|
||||
distanceField = (ObiDistanceField) target;
|
||||
previewHelper = new PreviewHelpers();
|
||||
UpdatePreview();
|
||||
}
|
||||
|
||||
public void OnDisable(){
|
||||
EditorUtility.ClearProgressBar();
|
||||
previewHelper.Cleanup();
|
||||
CleanupPreview();
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI() {
|
||||
|
||||
serializedObject.UpdateIfRequiredOrScript();
|
||||
|
||||
Editor.DrawPropertiesExcluding(serializedObject,"m_Script");
|
||||
|
||||
GUI.enabled = (distanceField.InputMesh != null);
|
||||
if (GUILayout.Button("Generate")){
|
||||
// Start a coroutine job in the editor.
|
||||
EditorUtility.SetDirty(target);
|
||||
CoroutineJob job = new CoroutineJob();
|
||||
routine = job.Start( distanceField.Generate());
|
||||
EditorCoroutine.ShowCoroutineProgressBar("Generating distance field", routine);
|
||||
UpdatePreview();
|
||||
EditorGUIUtility.ExitGUI();
|
||||
}
|
||||
GUI.enabled = true;
|
||||
|
||||
int nodeCount = (distanceField.nodes != null ? distanceField.nodes.Count : 0);
|
||||
float resolution = distanceField.FieldBounds.size.x / distanceField.EffectiveSampleSize;
|
||||
EditorGUILayout.HelpBox("Nodes: "+ nodeCount+"\n"+
|
||||
"Size in memory: "+ (nodeCount * 0.062f).ToString("0.#") +" kB\n"+
|
||||
"Compressed to: " + (nodeCount / Mathf.Pow(resolution,3) * 100).ToString("0.##") + "%",MessageType.Info);
|
||||
|
||||
if (GUI.changed)
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
}
|
||||
|
||||
public override bool HasPreviewGUI(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnInteractivePreviewGUI(Rect region, GUIStyle background)
|
||||
{
|
||||
previewDir = PreviewHelpers.Drag2D(previewDir, region);
|
||||
|
||||
if (Event.current.type != EventType.Repaint || previewMesh == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Quaternion quaternion = Quaternion.Euler(this.previewDir.y, 0f, 0f) * Quaternion.Euler(0f, this.previewDir.x, 0f) * Quaternion.Euler(0, 120, -20f);
|
||||
|
||||
previewHelper.BeginPreview(region, background);
|
||||
|
||||
Bounds bounds = previewMesh.bounds;
|
||||
float magnitude = Mathf.Sqrt(bounds.extents.sqrMagnitude);
|
||||
float num = 4f * magnitude;
|
||||
previewHelper.m_Camera.transform.position = -Vector3.forward * num;
|
||||
previewHelper.m_Camera.transform.rotation = Quaternion.identity;
|
||||
previewHelper.m_Camera.nearClipPlane = num - magnitude * 1.1f;
|
||||
previewHelper.m_Camera.farClipPlane = num + magnitude * 1.1f;
|
||||
|
||||
// Compute matrix to rotate the mesh around the center of its bounds:
|
||||
Matrix4x4 matrix = Matrix4x4.TRS(Vector3.zero,quaternion,Vector3.one) * Matrix4x4.TRS(-bounds.center,Quaternion.identity,Vector3.one);
|
||||
|
||||
Graphics.DrawMesh(previewMesh, matrix, previewMaterial,1, previewHelper.m_Camera, 0);
|
||||
|
||||
Texture texture = previewHelper.EndPreview();
|
||||
GUI.DrawTexture(region, texture, ScaleMode.StretchToFill, true);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a solid mesh from some Bounds. This is used to display the distance field volumetric preview.
|
||||
*/
|
||||
private Mesh CreateMeshForBounds(Bounds b){
|
||||
Mesh m = new Mesh();
|
||||
|
||||
/** Indices of bounds corners:
|
||||
|
||||
Y
|
||||
2 6
|
||||
+------+
|
||||
3 .'| 7 .'|
|
||||
+---+--+' |
|
||||
| | | |
|
||||
| +--+---+ X
|
||||
| .' 0 | .' 4
|
||||
+------+'
|
||||
Z 1 5
|
||||
|
||||
*/
|
||||
Vector3[] vertices = new Vector3[8]{
|
||||
b.center + new Vector3(-b.extents.x,-b.extents.y,-b.extents.z), //0
|
||||
b.center + new Vector3(-b.extents.x,-b.extents.y,b.extents.z), //1
|
||||
b.center + new Vector3(-b.extents.x,b.extents.y,-b.extents.z), //2
|
||||
b.center + new Vector3(-b.extents.x,b.extents.y,b.extents.z), //3
|
||||
b.center + new Vector3(b.extents.x,-b.extents.y,-b.extents.z), //4
|
||||
b.center + new Vector3(b.extents.x,-b.extents.y,b.extents.z), //5
|
||||
b.center + new Vector3(b.extents.x,b.extents.y,-b.extents.z), //6
|
||||
b.center + new Vector3(b.extents.x,b.extents.y,b.extents.z) //7
|
||||
};
|
||||
int[] triangles = new int[36]{
|
||||
2,3,7,
|
||||
6,2,7,
|
||||
|
||||
7,5,4,
|
||||
6,7,4,
|
||||
|
||||
3,1,5,
|
||||
7,3,5,
|
||||
|
||||
2,0,3,
|
||||
3,0,1,
|
||||
|
||||
6,4,2,
|
||||
2,4,0,
|
||||
|
||||
4,5,0,
|
||||
5,1,0
|
||||
};
|
||||
|
||||
m.vertices = vertices;
|
||||
m.triangles = triangles;
|
||||
return m;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d47dd3a8215841aca1fe5b272cb24f2
|
||||
timeCreated: 1507046737
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
30
Assets/Obi/Editor/Common/Collisions/ObiForceZoneEditor.cs
Normal file
30
Assets/Obi/Editor/Common/Collisions/ObiForceZoneEditor.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Obi
|
||||
{
|
||||
|
||||
/**
|
||||
* Custom inspector for ObiForceZone component.
|
||||
*/
|
||||
|
||||
[CustomEditor(typeof(ObiForceZone)), CanEditMultipleObjects]
|
||||
public class ObiForceZoneEditor : Editor
|
||||
{
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
|
||||
serializedObject.UpdateIfRequiredOrScript();
|
||||
|
||||
DrawPropertiesExcluding(serializedObject, "m_Script");
|
||||
|
||||
// Apply changes to the serializedProperty
|
||||
if (GUI.changed)
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 724435a7a84154b27bb0c8ea49b611df
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user