unityzgy/.svn/pristine/e2/e2282b4f7f374fc1c8a45881b5d2a53e3b2b4158.svn-base
ayuan9957 bf12e02276 feat: 多语言本地化系统 - 支持中/英/法/俄实时切换
- LocalizationManager: 新增翻译表(SetFormatted/SetDuration/LocalizeOperateMsg)
- LoginPanel: InputField placeholder本地化、字体颜色保持
- HistoryPanel: 用时数据本地化、placeholder本地化
- RecordDetailPanel: 操作详情消息本地化(LanguageChanged重建)
- AppraiseWindowBase: 评价等级本地化、操作消息重建
- EditorAppraiser: 所有评估消息改用InjectOperateMsgLocalized
- StudentOperateRecorder: 新增InjectOperateMsgLocalized方法
- LocalizationLanguageTestBar: 单例模式、ScreenSpaceOverlay筛选
- 字体切换时保留颜色和verticalOverflow
2026-07-16 10:05:59 +08:00

613 lines
31 KiB
Plaintext

using UnityEngine;
using UnityEditor;
using System.Collections;
[CustomEditor(typeof(QuickRope2))]
public class QuickRope2Editor : Editor
{
QuickRope2 r;
private int currentActiveHandle = -1;
private float guiScale = 0.5f;
private Vector3 prevRopePos = Vector3.zero;
public const int MAX_CROSS_SEGMENTS = 24;
public const float MIN_RADIUS = 0.001f;
public const float MAX_RADIUS = 500;
private Vector2 aoScrollPosition = Vector2.zero;
void OnEnable()
{
r = (QuickRope2)target;
if (Application.isPlaying)
return;
CleanupObject();
r.ApplyRopeSettings(); //r.SetControlPoints(r.ControlPoints);
}
public override void OnInspectorGUI()
{
r.EDITOR_TAB_SELECTED = GUILayout.Toolbar(r.EDITOR_TAB_SELECTED, new string[] { "Basics", "Physics", "Attach", "Control" });
EditorGUILayout.Separator();
EditorGUILayout.Separator();
bool isCloth = (r.GetComponent<QuickRope2Cloth>() != null);
switch (r.EDITOR_TAB_SELECTED)
{
case 0:
r.ropeEnd = (GameObject)EditorGUILayout.ObjectField(new GUIContent("Rope End", "The defined end of this rope."), r.ropeEnd, typeof(GameObject), true);
r.jointSpacing = EditorGUILayout.FloatField(new GUIContent("Joint Spacing", "The amount of distance between each joint in the rope object.\n\n Max = " + QuickRope2.MAX_JOINT_SPACING + "\n Min = " + QuickRope2.MIN_JOINT_SPACING + "\n\nTo set a custom the min/max distance, alter the const value in the QuickRopes2.cs script."), r.jointSpacing);
r.showJoints = EditorGUILayout.Toggle(new GUIContent("Preview Joints", "If checked, all joints created will be shown in the Hierarchy. Useful if you are trying to debug custom scripts."), r.showJoints);
QuickRope2.EDITOR_GUI_SCALE = EditorGUILayout.Slider("Editor GUI Scale", QuickRope2.EDITOR_GUI_SCALE, 0.1f, 5f);
guiScale = QuickRope2.EDITOR_GUI_SCALE;
EditorGUILayout.Separator();
EditorGUILayout.PrefixLabel("Set Mesh Type");
EditorGUILayout.BeginHorizontal(); EditorGUILayout.Space(); int val = GUILayout.Toolbar(-1, new string[] { "None", "Line", "Prefab", "Mesh", "Cloth" }); EditorGUILayout.Space(); EditorGUILayout.EndHorizontal();
switch (val)
{
case 0:
ClearMeshTypes();
break;
case 1:
ClearMeshTypes();
r.gameObject.AddComponent<QuickRope2Line>();
break;
case 2:
ClearMeshTypes();
r.gameObject.AddComponent<QuickRope2Prefab>();
break;
case 3:
ClearMeshTypes();
r.gameObject.AddComponent<QuickRope2Mesh>();
break;
case 4:
ClearMeshTypes();
r.gameObject.AddComponent<QuickRope2Cloth>();
break;
}
EditorGUILayout.Separator();
EditorGUILayout.Separator();
EditorGUILayout.PrefixLabel("Mesh Type Settings");
if (r.GetComponent<QuickRope2Line>() != null)
{
EditorGUILayout.BeginHorizontal(); GUILayout.Space(35); EditorGUILayout.LabelField("Use \"Line Renderer\" component below."); EditorGUILayout.EndHorizontal();
}
if (r.GetComponent<QuickRope2Prefab>() != null)
{
QuickRope2Prefab t = r.GetComponent<QuickRope2Prefab>();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(35); t.prefab = (GameObject)EditorGUILayout.ObjectField("Prefab", t.prefab, typeof(GameObject), false); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(35); t.jointScale = EditorGUILayout.FloatField("Scale", t.jointScale); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(35); r.AlternateJoints = EditorGUILayout.Toggle("Alternate Joints", r.AlternateJoints); EditorGUILayout.EndHorizontal();
if (r.AlternateJoints)
{
EditorGUILayout.BeginHorizontal();
GUILayout.Space(35);
r.FirstJointAlternated = EditorGUILayout.Toggle("First Joint Alternated", r.FirstJointAlternated);
EditorGUILayout.EndHorizontal();
}
}
if(r.GetComponent<QuickRope2Mesh>()!=null)
{
QuickRope2Mesh t = r.GetComponent<QuickRope2Mesh>();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(35); t.meshStatic = EditorGUILayout.Toggle(new GUIContent("Mesh Static", "If checked, the mesh will not automatically update during the \"Update\" method."), t.meshStatic); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(35); t.crossSegments = (int)Mathf.Clamp(EditorGUILayout.IntField(new GUIContent("Sides", "The number of sides in your rope.\n\nMAX: " + MAX_CROSS_SEGMENTS), t.crossSegments), 3, MAX_CROSS_SEGMENTS); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(35); t.maxRadius = (int)Mathf.Clamp(EditorGUILayout.IntField(new GUIContent("Curve Scale", "The scale of the curve graph below."), t.maxRadius), 1, Mathf.Infinity); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(35); t.curve = EditorGUILayout.CurveField(new GUIContent("Radius Curve", "The ropes radius will be defined by the shape of this curve."), t.curve, Color.white, new Rect(0, 0, 1, t.maxRadius)); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(35); t.textureTiling = EditorGUILayout.FloatField(new GUIContent("Texture Tiling", "Sets the Y value of the texture loaded on this rope."), t.textureTiling); EditorGUILayout.EndHorizontal();
}
if (r.GetComponent<QuickRope2Cloth>() != null)
{
QuickRope2Cloth t = r.GetComponent<QuickRope2Cloth>();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(35); t.crossSegments = (int)Mathf.Clamp(t.crossSegments, 3, MAX_CROSS_SEGMENTS); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(35); t.maxRadius = (int)Mathf.Clamp(EditorGUILayout.IntField(new GUIContent("Max Radius", "The scale of the curve graph below."), t.maxRadius), 1, Mathf.Infinity); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(35); t.curve = EditorGUILayout.CurveField(new GUIContent("Radius Curve", "The ropes radius will be defined by the shape of this curve."), t.curve, Color.white, new Rect(0, 0, 1, t.maxRadius)); EditorGUILayout.EndHorizontal();
}
break;
case 1:
/* BEGIN PHYSICS REGION */
#region Physics
if (r.enablePhysics && isCloth)
r.enablePhysics = false;
if (isCloth)
{
GUILayout.Label("You cannot use traditional physics\non the Cloth type.");
EditorGUILayout.Separator();
GUI.enabled = false;
}
r.enablePhysics = EditorGUILayout.Toggle("Use Physics", r.enablePhysics);
GUI.enabled = r.enablePhysics;
if (r.EDITOR_SHOW_RIGIDBODY = EditorGUILayout.Foldout(r.EDITOR_SHOW_RIGIDBODY, "Rigidbody Settings"))
{
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); r.constraint = (RopeConstraint)EditorGUILayout.EnumPopup(new GUIContent("Constraints", ""), r.constraint); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); r.solverOverride = (int)Mathf.Clamp(EditorGUILayout.IntField(new GUIContent("Solver Override", ""), r.solverOverride), -1, 255); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); r.mass = Mathf.Clamp(EditorGUILayout.FloatField(new GUIContent("Mass", ""), r.mass), 0.0001f, Mathf.Infinity); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); r.drag = Mathf.Clamp(EditorGUILayout.FloatField(new GUIContent("Drag", ""), r.drag), 0, Mathf.Infinity); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); r.angDrag = Mathf.Clamp(EditorGUILayout.FloatField(new GUIContent("Angular Drag", ""), r.angDrag), 0, Mathf.Infinity); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); r.useGravity = EditorGUILayout.Toggle(new GUIContent("Use Gravity", ""), r.useGravity); EditorGUILayout.EndHorizontal();
}
EditorGUILayout.Separator();
if (r.EDITOR_SHOW_JOINTSETTINGS = EditorGUILayout.Foldout(r.EDITOR_SHOW_JOINTSETTINGS, "Joint Settings"))
{
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); r.LowAngXLimit = (r.AngYLimit = r.HighAngXLimit = Mathf.Clamp(EditorGUILayout.FloatField(new GUIContent("Swing Limit", ""), r.AngYLimit), 0, 180)) * -1; EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(40); r.LTLDamper = Mathf.Clamp(EditorGUILayout.FloatField(new GUIContent("Dampen", ""), r.LTLDamper), 0, 500); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(40); r.LTLSpring = Mathf.Clamp(EditorGUILayout.FloatField(new GUIContent("Spring", ""), r.LTLSpring), 0, 500); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(40); r.LTLBounce = Mathf.Clamp(EditorGUILayout.FloatField(new GUIContent("Bounce", ""), r.LTLBounce), 0, 500); EditorGUILayout.EndHorizontal();
EditorGUILayout.Separator();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); r.AngZLimit = Mathf.Clamp(EditorGUILayout.FloatField(new GUIContent("Twist Limit", ""), r.AngZLimit), 0, 180); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(40); r.S1LDamper = Mathf.Clamp(EditorGUILayout.FloatField(new GUIContent("Dampen", ""), r.S1LDamper), 0, 500); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(40); r.S1LSpring = Mathf.Clamp(EditorGUILayout.FloatField(new GUIContent("Spring", ""), r.S1LSpring), 0, 500); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(40); r.S1LBounce = Mathf.Clamp(EditorGUILayout.FloatField(new GUIContent("Bounce", ""), r.S1LBounce), 0, 500); EditorGUILayout.EndHorizontal();
EditorGUILayout.Separator();
GUI.enabled = ((r.GetComponent<QuickRope2Cloth>() == null) && (r.GetComponent<QuickRope2Mesh>() == null) && (r.GetComponent<QuickRope2Line>() == null));
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); r.breakForce = Mathf.Clamp(EditorGUILayout.FloatField(new GUIContent("Break Force", ""), r.breakForce), 0, Mathf.Infinity); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); r.breakTorque = Mathf.Clamp(EditorGUILayout.FloatField(new GUIContent("Break Torque", ""), r.breakTorque), 0, Mathf.Infinity); EditorGUILayout.EndHorizontal();
GUI.enabled = true;
}
EditorGUILayout.Separator();
if (r.EDITOR_SHOW_COLLIDERSETTINGS = EditorGUILayout.Foldout(r.EDITOR_SHOW_COLLIDERSETTINGS, "Collider Settings"))
{
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); r.colliderType = (RopeColliderType)EditorGUILayout.EnumPopup(new GUIContent("Collider Type", ""), r.colliderType); EditorGUILayout.EndHorizontal();
GUI.enabled = (r.colliderType != RopeColliderType.DEFAULT);
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); r.colliderRadius = Mathf.Clamp(EditorGUILayout.FloatField(new GUIContent("Collider Radius", ""), r.colliderRadius), 0, Mathf.Infinity); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); r.physicsMaterial = (PhysicMaterial)EditorGUILayout.ObjectField(new GUIContent("Physics Material", ""), r.physicsMaterial, typeof(PhysicMaterial), false); EditorGUILayout.EndHorizontal();
GUI.enabled = true;
}
GUI.enabled = true;
#endregion
break;
case 2:
if (isCloth)
{
GUILayout.Label("You must attach objects via the \n\"Interactive Cloth\" component below.");
EditorGUILayout.Separator();
GUI.enabled = false;
}
if (GUILayout.Button(new GUIContent("Attach GameObject", "Adds a new attachment variable. Assign the variable with the object you would like to attach and the joint index you would like your object to attach to. Attachment is represented by a blue arrow pointing from object to joint index in the scene.")))
{
r.attachedObjects.Add(new RopeAttachedObject());
}
EditorGUILayout.Separator();
if (r.attachedObjects.Count == 0)
{
EditorGUILayout.Separator();
EditorGUILayout.Separator();
EditorGUILayout.LabelField("No objects have been attached.\n\nPress \"Attach GameObject\" button above.", GUILayout.Height(55));
}
aoScrollPosition = GUILayout.BeginScrollView(aoScrollPosition, GUILayout.MaxHeight(200), GUILayout.MinHeight(200));
foreach (RopeAttachedObject ao in r.attachedObjects)
{
EditorGUILayout.BeginHorizontal(); GUILayout.Space(5); ao.go = (GameObject)EditorGUILayout.ObjectField((ao.go==null) ? "Object" : ao.go.name, ao.go, typeof(GameObject), true); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); ao.jointType = (RopeAttachmentJointType)EditorGUILayout.EnumPopup("Con. Type", ao.jointType); EditorGUILayout.EndHorizontal();
if (ao.jointType == RopeAttachmentJointType.Hinge)
{
EditorGUILayout.BeginHorizontal(); GUILayout.Space(35); ao.hingeAxis = EditorGUILayout.Vector3Field("Axis", ao.hingeAxis); EditorGUILayout.EndHorizontal();
}
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); ao.jointIndex = (int)Mathf.Clamp(EditorGUILayout.IntField("Index", ao.jointIndex), 0, r.Joints.Count-1); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
if (ao.go != null)
{
GUILayout.Space(Screen.width / 3f); if (GUILayout.Button("Center On Index")) { ao.go.transform.position = r.Joints[ao.jointIndex].transform.position; }
}
if (GUILayout.Button("Remove")) { r.attachedObjects.Remove(ao); r.attachedObjects.TrimExcess(); return; }
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
}
GUILayout.EndScrollView();
GUI.enabled = true;
break;
case 3:
if (r.enablePhysics && isCloth)
r.enablePhysics = false;
if (isCloth)
{
GUILayout.Label("You cannot use the controller\non the Cloth type.");
EditorGUILayout.Separator();
r.enableRopeController = false;
GUI.enabled = false;
}
r.enableRopeController = EditorGUILayout.Toggle(new GUIContent("Enable Conroller", ""), r.enableRopeController);
EditorGUILayout.Separator();
GUI.enabled = r.enableRopeController;
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); r.extendRopeKey = (KeyCode)EditorGUILayout.EnumPopup(new GUIContent("Extend Key", ""), r.extendRopeKey); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); r.retractRopeKey = (KeyCode)EditorGUILayout.EnumPopup(new GUIContent("Retract Key", ""), r.retractRopeKey); EditorGUILayout.EndHorizontal();
EditorGUILayout.Separator();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); EditorGUILayout.LabelField("Current Rope Length: " + r.RopeLength); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); r.maxRopeLength = Mathf.Clamp(EditorGUILayout.FloatField(new GUIContent("Max Length", ""), r.maxRopeLength), r.jointSpacing * 3f, Mathf.Infinity); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); r.minRopeLength = Mathf.Clamp(EditorGUILayout.FloatField(new GUIContent("Min Length", ""), r.minRopeLength), r.jointSpacing * 3f, Mathf.Infinity); EditorGUILayout.EndHorizontal();
EditorGUILayout.Separator();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); r.acceleration = Mathf.Clamp(EditorGUILayout.FloatField(new GUIContent("Acceleration", ""), r.acceleration), 0, Mathf.Infinity); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); r.dampening = Mathf.Clamp(EditorGUILayout.FloatField(new GUIContent("Dampening", ""), r.dampening), 0, 1); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); r.maxVelocity = Mathf.Clamp(EditorGUILayout.FloatField(new GUIContent("Max Velocity", ""), r.maxVelocity), 0, Mathf.Infinity); EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal(); GUILayout.Space(25); r.sleepVelocity = Mathf.Clamp(EditorGUILayout.FloatField(new GUIContent("Sleep Velocity", ""), r.sleepVelocity), 0, Mathf.Infinity); EditorGUILayout.EndHorizontal();
EditorGUILayout.Separator();
GUI.enabled = true;
break;
}
EditorGUILayout.Separator();
EditorGUILayout.Separator();
if (!Application.isPlaying && GUI.changed)
UpdateRope();
}
void CleanupObject()
{
if (r.ropeEnd == null)
return;
if (!r.enablePhysics)
{
DestroyImmediate(r.ropeEnd.GetComponent<ConfigurableJoint>());
DestroyImmediate(r.ropeEnd.GetComponent<Rigidbody>());
DestroyImmediate(r.GetComponent<ConfigurableJoint>());
DestroyImmediate(r.GetComponent<Rigidbody>());
}
if (r.GetComponent<QuickRope2Line>() == null)
{
DestroyImmediate(r.GetComponent<LineRenderer>());
}
if (r.GetComponent<QuickRope2Mesh>() == null)
{
//if(r.GetComponent<QuickRope2Cloth>()==null)
// DestroyImmediate(r.GetComponent<RopeTubeRenderer>());
DestroyImmediate(r.GetComponent<MeshFilter>());
DestroyImmediate(r.GetComponent<MeshRenderer>());
}
if (r.GetComponent<QuickRope2Cloth>() == null)
{
//if (r.GetComponent<QuickRope2Mesh>() == null)
// DestroyImmediate(r.GetComponent<RopeTubeRenderer>());
//DestroyImmediate(r.GetComponent<ClothRenderer>());
//DestroyImmediate(r.GetComponent<InteractiveCloth>());
}
}
void ClearMeshTypes()
{
if (r.GetComponent<QuickRope2Line>())
{
DestroyImmediate(r.GetComponent<QuickRope2Line>());
}
if (r.GetComponent<QuickRope2Mesh>())
{
DestroyImmediate(r.GetComponent<QuickRope2Mesh>());
}
if (r.GetComponent<QuickRope2Cloth>())
{
DestroyImmediate(r.GetComponent<QuickRope2Cloth>());
}
if (r.GetComponent<QuickRope2Prefab>())
{
DestroyImmediate(r.GetComponent<QuickRope2Prefab>());
}
}
bool rebuildAfterCompile = false;
void OnSceneGUI()
{
r = (QuickRope2)target;
if (Application.isPlaying || r.ropeEnd == null)
return;
if (EditorApplication.isCompiling)
{
rebuildAfterCompile = true;
}
else if (rebuildAfterCompile)
{
rebuildAfterCompile = false;
UpdateRope();
//return;
}
Quaternion camLookAt = SceneView.currentDrawingSceneView.camera.transform.rotation;
Vector3 camNormal = SceneView.currentDrawingSceneView.camera.transform.forward;
//============== Add Control Point Button ==================
if (r.ControlPoints.Count == 0 && PlusButton(r.transform.position + (r.ropeEnd.transform.position - r.transform.position) / 2, camLookAt))
{
r.ControlPoints.Add(r.transform.position + (r.ropeEnd.transform.position - r.transform.position) / 2);
}
if(r.ControlPoints.Count > 0)
{
// First Add Button
if (PlusButton(r.transform.position + (r.ControlPoints[0] - r.transform.position)/2, camLookAt))
{
r.ControlPoints.Insert(0, r.transform.position + (r.ControlPoints[0] - r.transform.position) / 2);
currentActiveHandle = 0;
}
// Last Add Button
if (PlusButton(r.ControlPoints[r.ControlPoints.Count - 1] + (r.ropeEnd.transform.position - r.ControlPoints[r.ControlPoints.Count-1])/2, camLookAt))
{
r.ControlPoints.Insert(r.ControlPoints.Count, r.ControlPoints[r.ControlPoints.Count - 1] + (r.ropeEnd.transform.position - r.ControlPoints[r.ControlPoints.Count - 1]) / 2);
currentActiveHandle = r.ControlPoints.Count - 1;
}
for (int i = 0; i < r.ControlPoints.Count - 1; i++)
{
Vector3 btnPos = r.ControlPoints[i] + ((r.ControlPoints[i + 1] - r.ControlPoints[i]) / 2);
if (PlusButton(btnPos, camLookAt))
{
r.ControlPoints.Insert(i + 1, btnPos);
currentActiveHandle = i + 1;
}
}
}
// ==================
if (r.ControlPoints == null)
{
UpdateRope();
return;
}
// =================
for (int i = 0; i < r.ControlPoints.Count; i++)
{
Handles.color = new Color(0, 0, 0, 1);
if (Handles.Button(r.ControlPoints[i], camLookAt, 0.5f * guiScale, 0.5f * guiScale, Handles.CircleCap))
currentActiveHandle = i;
if (i == currentActiveHandle)
{
Handles.color = new Color(0.3f, 0.3f, 0.8f);
Handles.DrawSolidDisc(r.ControlPoints[i], camNormal, 0.4f * guiScale);
Handles.color = Color.white;
r.ControlPoints[i] = Handles.PositionHandle(r.ControlPoints[i], Quaternion.identity);
if (Event.current.type == EventType.KeyDown)
{
if (Event.current.keyCode == KeyCode.P)
{
if (i > 0 && i < r.ControlPoints.Count - 2)
r.ControlPoints.Insert(i + 1, r.ControlPoints[i] + ((r.ControlPoints[i + 1] - r.ControlPoints[i]) / 2));
//UpdateRope();
}
if (Event.current.keyCode == KeyCode.Backspace)
{
r.ControlPoints.RemoveAt(currentActiveHandle);
currentActiveHandle--;
if (currentActiveHandle == -1 && r.ControlPoints.Count != 0)
currentActiveHandle = 0;
r.ControlPoints.TrimExcess();
UpdateRope();
return;
}
}
}
else
{
Handles.color = new Color(0.2f, 0.2f, 0.4f, 0.8f);
Handles.DrawSolidDisc(r.ControlPoints[i], camNormal, 0.4f * guiScale);
}
}
//Deal with rope end
{
Handles.color = new Color(0, 0, 0, 1);
if (Handles.Button(r.ropeEnd.transform.position, camLookAt, 0.5f * guiScale, 0.5f * guiScale, Handles.CircleCap))
currentActiveHandle = 5000;
if (currentActiveHandle == 5000)
{
Handles.color = new Color(0.3f, 0.3f, 0.8f);
Handles.DrawSolidDisc(r.ropeEnd.transform.position, camNormal, 0.4f * guiScale);
Handles.color = Color.white;
r.ropeEnd.transform.position = Handles.PositionHandle(r.ropeEnd.transform.position, Quaternion.identity);
}
else
{
Handles.color = new Color(0.2f, 0.2f, 0.4f, 0.8f);
Handles.DrawSolidDisc(r.ropeEnd.transform.position, camNormal, 0.4f * guiScale);
}
}
foreach (RopeAttachedObject ao in r.attachedObjects)
{
if (ao.go == null)
continue;
if (ao.jointIndex > r.Joints.Count - 1)
ao.jointIndex = r.Joints.Count - 1;
Handles.color = new Color(0.8f, 0.4f, 0f, 0.8f);
Handles.DrawSolidDisc(ao.go.transform.position, camNormal, 0.2f * guiScale);
Handles.DrawSolidDisc(r.Joints[ao.jointIndex].transform.position, camNormal, 0.2f * guiScale);
float dist = Vector3.Distance(r.Joints[ao.jointIndex].transform.position, ao.go.transform.position);
if (dist > 0.5f)
Handles.ArrowCap(0, ao.go.transform.position, Quaternion.LookRotation((r.Joints[ao.jointIndex].transform.position - ao.go.transform.position).normalized), dist * 0.8f);
Handles.color = new Color(0.8f, 0f, 0f, 0.8f);
if (ao.jointType == RopeAttachmentJointType.Hinge && (ao.hingeAxis != Vector3.zero))
Handles.ArrowCap(0, ao.go.transform.position, ao.go.transform.rotation * Quaternion.LookRotation(ao.hingeAxis), 1);
}
winRect = GUI.Window(0, winRect, EditWindowFunc, "Edit Selected Control Point");
if (GUI.changed)
{
EditorUtility.SetDirty(target);
UpdateRope();
}
else if (QuickRope2Helper.HasMoved(ref prevRopePos, r.transform.position))
UpdateRope();
}
void UpdateRope()
{
r.jointSpacing = Mathf.Clamp(r.jointSpacing, QuickRope2.MIN_JOINT_SPACING, QuickRope2.MAX_JOINT_SPACING);
if (r.jointSpacing >= QuickRope2.MIN_JOINT_SPACING)
{
r.ApplyRopeSettings(); //r.SetControlPoints(r.ControlPoints);
}
}
bool PlusButton(Vector3 position, Quaternion direction)
{
Handles.color = new Color(0, 0.8f, 0, 1f);
Handles.DotCap(0, position, direction, 0.2f * guiScale);
return Handles.Button(position, direction, 0.25f * guiScale, 0.25f * guiScale, Handles.RectangleCap);
}
Vector3 curSelVect = Vector3.zero;
static Rect winRect = new Rect(5, 25, 260, 125);
void EditWindowFunc(int winID)
{
if (currentActiveHandle < 0)
{
GUI.Label(new Rect(45, 55, 260, 125), "Add or select a control point!");
return;
}
if (currentActiveHandle == 5000)
curSelVect = r.ropeEnd.transform.position;
else
curSelVect = r.ControlPoints[currentActiveHandle];
EditorGUILayout.BeginHorizontal();
GUILayout.Space(30);
EditorGUILayout.LabelField("X: ", GUILayout.Width(50));
float x = EditorGUILayout.FloatField(curSelVect.x, GUILayout.Width(150));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
GUILayout.Space(30);
EditorGUILayout.LabelField("Y: ", GUILayout.Width(50));
float y = EditorGUILayout.FloatField(curSelVect.y, GUILayout.Width(150));
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
GUILayout.Space(30);
EditorGUILayout.LabelField("Z: ", GUILayout.Width(50));
float z = EditorGUILayout.FloatField(curSelVect.z, GUILayout.Width(150));
EditorGUILayout.EndHorizontal();
if (currentActiveHandle == 5000)
{
r.ropeEnd.transform.position = new Vector3(x, y, z);
GUI.enabled = false;
}
else
{
r.ControlPoints[currentActiveHandle] = new Vector3(x, y, z);
}
EditorGUILayout.Space();
GUILayout.BeginHorizontal();
if (GUILayout.Button("Average"))
{
if (r.ControlPoints.Count == 1)
{
r.ControlPoints[currentActiveHandle] = (r.ropeEnd.transform.position - r.transform.position) / 2f;
}
else
{
if (currentActiveHandle > 0 && currentActiveHandle < (r.ControlPoints.Count-1))
{
r.ControlPoints[currentActiveHandle] = (r.ControlPoints[currentActiveHandle - 1] + r.ControlPoints[currentActiveHandle + 1]) / 2f;
}
else if(currentActiveHandle == 0)
{
r.ControlPoints[currentActiveHandle] = (r.transform.position + r.ControlPoints[currentActiveHandle + 1]) / 2f;
}
else if(currentActiveHandle == (r.ControlPoints.Count-1))
{
r.ControlPoints[currentActiveHandle] = (r.ControlPoints[currentActiveHandle - 1] + r.ropeEnd.transform.position) / 2f;
}
}
UpdateRope();
}
if (GUILayout.Button("Zero Vector"))
{
r.ControlPoints[currentActiveHandle] = Vector3.zero;
UpdateRope();
}
GUILayout.EndHorizontal();
if (GUILayout.Button("Delete [Backspace]"))
{
r.ControlPoints.RemoveAt(currentActiveHandle);
currentActiveHandle--;
if (currentActiveHandle == -1 && r.ControlPoints.Count != 0)
currentActiveHandle = 0;
r.ControlPoints.TrimExcess();
UpdateRope();
}
if (GUI.changed)
UpdateRope();
GUI.enabled = true;
GUI.DragWindow();
}
}