GQ_Communicate/GQ_TongXin/Assets/Obi/Editor/ObiPinConstraintsEditor.cs

195 lines
5.7 KiB
C#

using UnityEditor;
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Obi{
/**
* Custom inspector for ObiPinConstraints component.
*/
[CustomEditor(typeof(ObiPinConstraints)), CanEditMultipleObjects]
public class ObiPinConstraintsEditor : Editor
{
ObiPinConstraints constraints;
public void OnEnable(){
constraints = (ObiPinConstraints)target;
}
public override void OnInspectorGUI() {
serializedObject.UpdateIfRequiredOrScript();
Editor.DrawPropertiesExcluding(serializedObject,"m_Script");
// Get the particle actor editor to retrieve selected particles:
ObiParticleActorEditor[] editors = (ObiParticleActorEditor[])Resources.FindObjectsOfTypeAll(typeof(ObiParticleActorEditor));
// If there's any particle actor editor active, we can show pin constraints:
if (editors.Length >0)
{
List<int> selectedPins = new List<int>();
List<int> removedPins = new List<int>();
if (constraints.GetBatches().Count > 0){
ObiPinConstraintBatch batch = (ObiPinConstraintBatch)constraints.GetBatches()[0];
// Get the list of pin constraints from the selected particles:
for (int i = 0; i < batch.ConstraintCount; i++){
int particleIndex = batch.pinIndices[i];
if (particleIndex >= 0 && particleIndex < ObiParticleActorEditor.selectionStatus.Length &&
ObiParticleActorEditor.selectionStatus[particleIndex]){
selectedPins.Add(i);
}
}
if (selectedPins.Count > 0){
//Iterate over all constraints:
foreach (int i in selectedPins){
GUILayout.BeginVertical("box");
GUILayout.BeginHorizontal();
EditorGUI.BeginChangeCheck();
bool allowSceneObjects = !EditorUtility.IsPersistent(target);
batch.pinBodies[i] = EditorGUILayout.ObjectField("Pinned to:",batch.pinBodies[i],typeof(ObiCollider),allowSceneObjects) as ObiCollider;
// Calculate initial pin offset value after changing the rigidbody.
if (EditorGUI.EndChangeCheck() && batch.pinBodies[i] != null){
batch.pinOffsets[i] = batch.pinBodies[i].transform.InverseTransformPoint(constraints.Actor.GetParticlePosition(batch.pinIndices[i]));
}
Color oldColor = GUI.color;
GUI.color = Color.red;
if (GUILayout.Button("X",GUILayout.Width(30))){
// Mark this constraint to be removed outside of the loop.
removedPins.Add(i);
continue;
}
GUI.color = oldColor;
GUILayout.EndHorizontal();
batch.pinOffsets[i] = EditorGUILayout.Vector3Field("Offset:",batch.pinOffsets[i]);
batch.pinBreakResistance[i] = EditorGUILayout.DelayedFloatField("Break Resistance:",batch.pinBreakResistance[i]);
GUILayout.EndVertical();
}
}else{
EditorGUILayout.HelpBox("No pin constraints for the selected particles.",MessageType.Info);
}
if (GUILayout.Button("Remove selected")){
for (int i = 0; i < batch.ConstraintCount; i++){
int particleIndex = batch.pinIndices[i];
if (particleIndex >= 0 && particleIndex < ObiParticleActorEditor.selectionStatus.Length &&
ObiParticleActorEditor.selectionStatus[particleIndex]){
removedPins.Add(i);
}
}
}
if (GUILayout.Button("Add Pin Constraint")){
Undo.RecordObject(constraints, "Add pin constraints");
bool wasInSolver = constraints.InSolver;
constraints.RemoveFromSolver(null);
for(int i = 0; i < ObiParticleActorEditor.selectionStatus.Length; i++){
if (ObiParticleActorEditor.selectionStatus[i]){
batch.AddConstraint(i,null,Vector3.zero,0);
}
}
if (wasInSolver)
constraints.AddToSolver(null);
}
// Remove selected constraint outside of constraint listing loop:
if (removedPins.Count > 0){
Undo.RecordObject(constraints, "Remove pin constraints");
bool wasInSolver = constraints.InSolver;
constraints.RemoveFromSolver(null);
// Remove from last to first, to avoid throwing off subsequent indices:
foreach(int i in removedPins.OrderByDescending(i => i)){
batch.RemoveConstraint(i);
}
if (wasInSolver)
constraints.AddToSolver(null);
}
}
}
// Apply changes to the serializedProperty
if (GUI.changed){
serializedObject.ApplyModifiedProperties();
constraints.PushDataToSolver();
}
}
/**
* Draws selected pin constraints in the scene view.
*/
public void OnSceneGUI(){
if (Event.current.type != EventType.Repaint || !ObiParticleActorEditor.editMode) return;
// Get the particle actor editor to retrieve selected particles:
ObiParticleActorEditor[] editors = (ObiParticleActorEditor[])Resources.FindObjectsOfTypeAll(typeof(ObiParticleActorEditor));
// If there's any particle actor editor active, we can show pin constraints:
if (editors.Length >0 && constraints.GetBatches().Count > 0)
{
Handles.color = Color.cyan;
ObiPinConstraintBatch batch = (ObiPinConstraintBatch)constraints.GetBatches()[0];
// Get the list of pin constraints from the selected particles:
foreach (int i in batch.ActiveConstraints){
if (batch.pinBodies[i] != null){
Vector3 pinPosition = batch.pinBodies[i].transform.TransformPoint(batch.pinOffsets[i]);
Handles.DrawDottedLine(constraints.Actor.GetParticlePosition(batch.pinIndices[i]),pinPosition,5);
Handles.SphereHandleCap(0,pinPosition,Quaternion.identity,HandleUtility.GetHandleSize(pinPosition)*0.1f,EventType.Repaint);
}
}
}
}
}
}