static void DrawAngleWidget(Vector2 center, float radius, float angleDegrees, float offset, Color sectionColor, bool enabled) { Vector2 originPosition = center + new Vector2( Mathf.Cos(offset * Mathf.Deg2Rad), Mathf.Sin(offset * Mathf.Deg2Rad)) * radius; Vector2 toOrigin = originPosition - center; Vector2 handlePosition = center + new Vector2( Mathf.Cos((angleDegrees + offset) * Mathf.Deg2Rad), Mathf.Sin((angleDegrees + offset) * Mathf.Deg2Rad)) * radius; Color backupColor = Handles.color; Handles.color = LightAnchorStyles.DiskBackgroundAngleColor(); Handles.DrawSolidDisc(center, Vector3.forward, radius); Handles.color = LightAnchorStyles.angleDiskBorderColor; Handles.DrawWireDisc(center, Vector3.forward, radius); Handles.color = sectionColor; Handles.DrawSolidArc(center, Vector3.forward, Quaternion.AngleAxis(offset, Vector3.forward) * Vector3.right, angleDegrees, radius); Handles.color = LightAnchorStyles.WireDiskAngleColor(); Handles.DrawLine(center + toOrigin * 0.75f, center + toOrigin * 0.9f); Handles.DrawLine(center, handlePosition); Handles.DrawSolidDisc(handlePosition, Vector3.forward, 5f); Handles.color = backupColor; }
/// <summary> /// Calls the methods in its invocation list when show the Inspector /// </summary> public override void OnInspectorGUI() { var camera = Camera.main; if (camera == null) { Debug.LogError("Light Anchor: At least one camera must be tagged as MainCamera"); return; } if (IsCacheInvalid(manipulator)) { manipulator.SynchronizeOnTransform(camera); UpdateCache(); } // anchor is cached for it cannot be changed from the inspector, // we have a dedicated editor tool to move the anchor var anchor = manipulator.anchorPosition; bool yawChanged = false; bool pitchChanged = false; bool rollChanged = false; bool distanceChanged = false; bool frameChanged = false; bool upChanged = false; using (var change = new EditorGUI.ChangeCheckScope()) { EditorGUILayout.Space(); float widgetHeight = EditorGUIUtility.singleLineHeight * 5f; float oldValue; using (new EditorGUILayout.HorizontalScope()) { Color usedColor; { var localRect = EditorGUILayout.GetControlRect(false, widgetHeight); oldValue = m_Yaw; usedColor = Color.green; usedColor.a = 0.2f; m_Yaw = AngleField(localRect, "Yaw", m_Yaw, 90, usedColor, true); } yawChanged = oldValue != m_Yaw; { var localRect = EditorGUILayout.GetControlRect(false, widgetHeight); oldValue = m_Pitch; usedColor = Color.blue; usedColor.a = 0.2f; m_Pitch = AngleField(localRect, "Pitch", m_Pitch, 180, usedColor, true); } pitchChanged = oldValue != m_Pitch; { var localRect = EditorGUILayout.GetControlRect(false, widgetHeight); oldValue = m_Roll; usedColor = Color.grey; usedColor.a = 0.2f; bool enabledKnob = true; m_Roll = AngleField(localRect, "Roll", m_Roll, -90, usedColor, enabledKnob); } rollChanged = oldValue != m_Roll; } EditorGUILayout.Space(); Rect angleRect = EditorGUILayout.GetControlRect(true, EditorGUI.GetPropertyHeight(SerializedPropertyType.Vector3, EditorGUIUtility.TrTextContent(""))); float[] angles = new float[3] { m_Yaw, m_Pitch, m_Roll }; EditorGUI.BeginChangeCheck(); EditorGUI.MultiFloatField(angleRect, LightAnchorStyles.angleSubContent, angles); const float eps = 1e-4f; if (EditorGUI.EndChangeCheck()) { if (Mathf.Abs(angles[0] - m_Yaw) > eps) { m_Yaw = angles[0]; yawChanged = true; } if (Mathf.Abs(angles[1] - m_Pitch) > eps) { m_Pitch = angles[1]; pitchChanged = true; } if (Mathf.Abs(angles[2] - m_Roll) > eps) { m_Roll = angles[2]; rollChanged = true; } } EditorGUILayout.Space(); oldValue = manipulator.distance; m_Distance = EditorGUILayout.FloatField(LightAnchorStyles.distanceProperty, manipulator.distance); distanceChanged = oldValue != m_Distance; var dropRect = EditorGUILayout.GetControlRect(false, EditorGUIUtility.singleLineHeight); LightAnchor.UpDirection newSpace = (LightAnchor.UpDirection)EditorGUI.EnumPopup(dropRect, LightAnchorStyles.upDirectionProperty, manipulator.frameSpace); upChanged = manipulator.frameSpace != newSpace; manipulator.frameSpace = newSpace; if (upChanged) { manipulator.SynchronizeOnTransform(camera); UpdateCache(); } frameChanged = yawChanged || pitchChanged || rollChanged || distanceChanged; if (m_FoldoutPreset = EditorGUILayout.Foldout(m_FoldoutPreset, "Common")) { Color cachedColor = GUI.backgroundColor; GUI.backgroundColor = LightAnchorStyles.BackgroundIconColor(); var inspectorWidth = EditorGUIUtility.currentViewWidth - LightAnchorStyles.inspectorWidthPadding; var presetButtonWidth = GUILayout.Width(inspectorWidth / LightAnchorStyles.presetButtonCount); var presetButtonHeight = GUILayout.Height(inspectorWidth / LightAnchorStyles.presetButtonCount); using (new EditorGUILayout.HorizontalScope()) { bool rectFound = false; Rect rect = new Rect(); if (GUILayout.Button(LightAnchorStyles.presetTextureRimLeft, presetButtonWidth, presetButtonHeight)) { m_Yaw = 135; m_Pitch = 0; yawChanged = true; pitchChanged = true; frameChanged = true; } if (Mathf.Abs(m_Yaw - 135.0f) < eps && Mathf.Abs(m_Pitch - 0.0f) < eps) { rect = GUILayoutUtility.GetLastRect(); rectFound = true; } if (GUILayout.Button(LightAnchorStyles.presetTextureKickLeft, presetButtonWidth, presetButtonHeight)) { m_Yaw = 100; m_Pitch = 10; yawChanged = true; pitchChanged = true; frameChanged = true; } if (Mathf.Abs(m_Yaw - 100.0f) < eps && Mathf.Abs(m_Pitch - 10.0f) < eps) { rect = GUILayoutUtility.GetLastRect(); rectFound = true; } if (GUILayout.Button(LightAnchorStyles.presetTextureBounceLeft, presetButtonWidth, presetButtonHeight)) { m_Yaw = 30; m_Pitch = -30; yawChanged = true; pitchChanged = true; frameChanged = true; } if (Mathf.Abs(m_Yaw - 30.0f) < eps && Mathf.Abs(m_Pitch + 30.0f) < eps) { rect = GUILayoutUtility.GetLastRect(); rectFound = true; } if (GUILayout.Button(LightAnchorStyles.presetTextureFillLeft, presetButtonWidth, presetButtonHeight)) { m_Yaw = 35; m_Pitch = 35; yawChanged = true; pitchChanged = true; frameChanged = true; } if (Mathf.Abs(m_Yaw - 35.0f) < eps && Mathf.Abs(m_Pitch - 35.0f) < eps) { rect = GUILayoutUtility.GetLastRect(); rectFound = true; } if (GUILayout.Button(LightAnchorStyles.presetTextureHair, presetButtonWidth, presetButtonHeight)) { m_Yaw = 0; m_Pitch = 110; yawChanged = true; pitchChanged = true; frameChanged = true; } if (Mathf.Abs(m_Yaw - 0.0f) < eps && Mathf.Abs(m_Pitch - 110.0f) < eps) { rect = GUILayoutUtility.GetLastRect(); rectFound = true; } if (GUILayout.Button(LightAnchorStyles.presetTextureFillRight, presetButtonWidth, presetButtonHeight)) { m_Yaw = -35; m_Pitch = 35; yawChanged = true; pitchChanged = true; frameChanged = true; } if (Mathf.Abs(m_Yaw + 35.0f) < eps && Mathf.Abs(m_Pitch - 35.0f) < eps) { rect = GUILayoutUtility.GetLastRect(); rectFound = true; } if (GUILayout.Button(LightAnchorStyles.presetTextureBounceRight, presetButtonWidth, presetButtonHeight)) { m_Yaw = -30; m_Pitch = -30; yawChanged = true; pitchChanged = true; frameChanged = true; } if (Mathf.Abs(m_Yaw + 30.0f) < eps && Mathf.Abs(m_Pitch + 30.0f) < eps) { rect = GUILayoutUtility.GetLastRect(); rectFound = true; } if (GUILayout.Button(LightAnchorStyles.presetTextureKickRight, presetButtonWidth, presetButtonHeight)) { m_Yaw = -100; m_Pitch = 10; yawChanged = true; pitchChanged = true; frameChanged = true; } if (Mathf.Abs(m_Yaw + 100.0f) < eps && Mathf.Abs(m_Pitch - 10.0f) < eps) { rect = GUILayoutUtility.GetLastRect(); rectFound = true; } if (GUILayout.Button(LightAnchorStyles.presetTextureRimRight, presetButtonWidth, presetButtonHeight)) { m_Yaw = -135; m_Pitch = 0; yawChanged = true; pitchChanged = true; frameChanged = true; } if (Mathf.Abs(m_Yaw + 135.0f) < eps && Mathf.Abs(m_Pitch - 0.0f) < eps) { rect = GUILayoutUtility.GetLastRect(); rectFound = true; } if (rectFound) { Handles.DrawSolidRectangleWithOutline(rect, LightAnchorStyles.totalTransparentColor, LightAnchorStyles.hoverColor); } GUILayout.FlexibleSpace(); } GUI.backgroundColor = cachedColor; } if (frameChanged) { LightAnchor manipulator = target as LightAnchor; if (upChanged) { manipulator.SynchronizeOnTransform(camera); } Undo.RecordObjects(new UnityEngine.Object[] { manipulator.transform }, "Reset Light Anchor Transform"); if (yawChanged) { manipulator.yaw = m_Yaw; } if (pitchChanged) { manipulator.pitch = m_Pitch; } if (rollChanged) { manipulator.roll = m_Roll; } if (distanceChanged) { manipulator.distance = m_Distance; } manipulator.UpdateTransform(camera, anchor); IsCacheInvalid(manipulator); } } }
/// <summary> /// Calls the methods in its invocation list when show the Inspector /// </summary> public override void OnInspectorGUI() { var camera = Camera.main; if (camera == null) { EditorGUILayout.HelpBox("Light Anchor: At least one camera must be tagged as MainCamera", MessageType.Error); return; } if (IsCacheInvalid(manipulator)) { manipulator.SynchronizeOnTransform(camera); UpdateCache(); } // anchor is cached for it cannot be changed from the inspector, // we have a dedicated editor tool to move the anchor var anchor = manipulator.anchorPosition; bool yawChanged = false; bool pitchChanged = false; bool rollChanged = false; bool distanceChanged = false; bool positionOverrideChanged = false; bool upChanged = false; using (var change = new EditorGUI.ChangeCheckScope()) { EditorGUILayout.Space(); float widgetHeight = EditorGUIUtility.singleLineHeight * 5f; using (new EditorGUILayout.HorizontalScope()) { Color usedColor; EditorGUI.BeginChangeCheck(); { var localRect = EditorGUILayout.GetControlRect(false, widgetHeight); usedColor = Color.green; usedColor.a = 0.2f; m_Yaw = AngleField(localRect, "Yaw", m_Yaw, 90, usedColor, true); } yawChanged = EditorGUI.EndChangeCheck(); EditorGUI.BeginChangeCheck(); { var localRect = EditorGUILayout.GetControlRect(false, widgetHeight); usedColor = Color.blue; usedColor.a = 0.2f; m_Pitch = AngleField(localRect, "Pitch", m_Pitch, 180, usedColor, true); } pitchChanged = EditorGUI.EndChangeCheck(); EditorGUI.BeginChangeCheck(); { var localRect = EditorGUILayout.GetControlRect(false, widgetHeight); usedColor = Color.grey; usedColor.a = 0.2f; bool enabledKnob = true; m_Roll = AngleField(localRect, "Roll", m_Roll, -90, usedColor, enabledKnob); } rollChanged = EditorGUI.EndChangeCheck(); } EditorGUILayout.Space(); Rect angleRect = EditorGUILayout.GetControlRect(true, EditorGUI.GetPropertyHeight(SerializedPropertyType.Vector3, EditorGUIUtility.TrTextContent(""))); float[] angles = new float[3] { m_Yaw, m_Pitch, m_Roll }; EditorGUI.BeginChangeCheck(); EditorGUI.MultiFloatField(angleRect, LightAnchorStyles.angleSubContent, angles); const float eps = 1e-4f; if (EditorGUI.EndChangeCheck()) { if (Mathf.Abs(angles[0] - m_Yaw) > eps) { m_Yaw = angles[0]; yawChanged = true; } if (Mathf.Abs(angles[1] - m_Pitch) > eps) { m_Pitch = angles[1]; pitchChanged = true; } if (Mathf.Abs(angles[2] - m_Roll) > eps) { m_Roll = angles[2]; rollChanged = true; } } EditorGUILayout.Space(); EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_DistanceProperty, LightAnchorStyles.distanceProperty); if (distanceChanged = EditorGUI.EndChangeCheck()) { m_DistanceProperty.floatValue = Mathf.Min(m_DistanceProperty.floatValue, LightAnchor.k_MaxDistance); } EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_FrameSpaceProperty, LightAnchorStyles.upDirectionProperty); upChanged = EditorGUI.EndChangeCheck(); EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_AnchorPositionOverrideProperty, LightAnchorStyles.anchorPositionOverrideProperty); positionOverrideChanged = EditorGUI.EndChangeCheck(); if (m_AnchorPositionOverrideProperty.objectReferenceValue != null) { EditorGUI.indentLevel++; EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(m_AnchorPositionOffsetProperty, LightAnchorStyles.anchorPositionOffsetProperty); positionOverrideChanged |= EditorGUI.EndChangeCheck(); EditorGUI.indentLevel--; } if (m_FoldoutPreset = EditorGUILayout.Foldout(m_FoldoutPreset, "Common")) { Color cachedColor = GUI.backgroundColor; GUI.backgroundColor = LightAnchorStyles.BackgroundIconColor(); var inspectorWidth = EditorGUIUtility.currentViewWidth - LightAnchorStyles.inspectorWidthPadding; var presetButtonWidth = GUILayout.Width(inspectorWidth / LightAnchorStyles.presetButtonCount); var presetButtonHeight = GUILayout.Height(inspectorWidth / LightAnchorStyles.presetButtonCount); using (new EditorGUILayout.HorizontalScope()) { bool rectFound = false; Rect rect = new Rect(); if (GUILayout.Button(LightAnchorStyles.presetTextureRimLeft, presetButtonWidth, presetButtonHeight)) { m_Yaw = 135; m_Pitch = 0; yawChanged = true; pitchChanged = true; } if (Mathf.Abs(m_Yaw - 135.0f) < eps && Mathf.Abs(m_Pitch - 0.0f) < eps) { rect = GUILayoutUtility.GetLastRect(); rectFound = true; } if (GUILayout.Button(LightAnchorStyles.presetTextureKickLeft, presetButtonWidth, presetButtonHeight)) { m_Yaw = 100; m_Pitch = 10; yawChanged = true; pitchChanged = true; } if (Mathf.Abs(m_Yaw - 100.0f) < eps && Mathf.Abs(m_Pitch - 10.0f) < eps) { rect = GUILayoutUtility.GetLastRect(); rectFound = true; } if (GUILayout.Button(LightAnchorStyles.presetTextureBounceLeft, presetButtonWidth, presetButtonHeight)) { m_Yaw = 30; m_Pitch = -30; yawChanged = true; pitchChanged = true; } if (Mathf.Abs(m_Yaw - 30.0f) < eps && Mathf.Abs(m_Pitch + 30.0f) < eps) { rect = GUILayoutUtility.GetLastRect(); rectFound = true; } if (GUILayout.Button(LightAnchorStyles.presetTextureFillLeft, presetButtonWidth, presetButtonHeight)) { m_Yaw = 35; m_Pitch = 35; yawChanged = true; pitchChanged = true; } if (Mathf.Abs(m_Yaw - 35.0f) < eps && Mathf.Abs(m_Pitch - 35.0f) < eps) { rect = GUILayoutUtility.GetLastRect(); rectFound = true; } if (GUILayout.Button(LightAnchorStyles.presetTextureHair, presetButtonWidth, presetButtonHeight)) { m_Yaw = 0; m_Pitch = 110; yawChanged = true; pitchChanged = true; } if (Mathf.Abs(m_Yaw - 0.0f) < eps && Mathf.Abs(m_Pitch - 110.0f) < eps) { rect = GUILayoutUtility.GetLastRect(); rectFound = true; } if (GUILayout.Button(LightAnchorStyles.presetTextureFillRight, presetButtonWidth, presetButtonHeight)) { m_Yaw = -35; m_Pitch = 35; yawChanged = true; pitchChanged = true; } if (Mathf.Abs(m_Yaw + 35.0f) < eps && Mathf.Abs(m_Pitch - 35.0f) < eps) { rect = GUILayoutUtility.GetLastRect(); rectFound = true; } if (GUILayout.Button(LightAnchorStyles.presetTextureBounceRight, presetButtonWidth, presetButtonHeight)) { m_Yaw = -30; m_Pitch = -30; yawChanged = true; pitchChanged = true; } if (Mathf.Abs(m_Yaw + 30.0f) < eps && Mathf.Abs(m_Pitch + 30.0f) < eps) { rect = GUILayoutUtility.GetLastRect(); rectFound = true; } if (GUILayout.Button(LightAnchorStyles.presetTextureKickRight, presetButtonWidth, presetButtonHeight)) { m_Yaw = -100; m_Pitch = 10; yawChanged = true; pitchChanged = true; } if (Mathf.Abs(m_Yaw + 100.0f) < eps && Mathf.Abs(m_Pitch - 10.0f) < eps) { rect = GUILayoutUtility.GetLastRect(); rectFound = true; } if (GUILayout.Button(LightAnchorStyles.presetTextureRimRight, presetButtonWidth, presetButtonHeight)) { m_Yaw = -135; m_Pitch = 0; yawChanged = true; pitchChanged = true; } if (Mathf.Abs(m_Yaw + 135.0f) < eps && Mathf.Abs(m_Pitch - 0.0f) < eps) { rect = GUILayoutUtility.GetLastRect(); rectFound = true; } if (rectFound) { Handles.DrawSolidRectangleWithOutline(rect, LightAnchorStyles.totalTransparentColor, LightAnchorStyles.hoverColor); } GUILayout.FlexibleSpace(); } GUI.backgroundColor = cachedColor; } if (upChanged) { Undo.RecordObjects(new UnityEngine.Object[] { target, manipulator.transform }, "Light Anchor Change"); manipulator.frameSpace = (LightAnchor.UpDirection)m_FrameSpaceProperty.intValue; manipulator.SynchronizeOnTransform(camera); UpdateCache(); } if (yawChanged || pitchChanged || rollChanged || distanceChanged || positionOverrideChanged) { Undo.RecordObjects(new UnityEngine.Object[] { target, manipulator.transform }, "Light Anchor Change"); if (yawChanged) { manipulator.yaw = m_Yaw; } if (pitchChanged) { manipulator.pitch = m_Pitch; } if (rollChanged) { manipulator.roll = m_Roll; } if (distanceChanged) { manipulator.distance = m_DistanceProperty.floatValue; } if (positionOverrideChanged) { var newTransform = m_AnchorPositionOverrideProperty.objectReferenceValue as Transform; if (newTransform != null) { // Check that the assigned transform is not child of the light anchor, otherwise it would cause problems when moving the light position if (newTransform.IsChildOf(manipulator.transform)) { Debug.LogError($"Can't assign '{newTransform.name}' because it's a child of the Light Anchor component"); } else { manipulator.anchorPositionOverride = newTransform; manipulator.anchorPositionOffset = m_AnchorPositionOffsetProperty.vector3Value; float newDistance = Vector3.Distance(manipulator.transform.position, manipulator.anchorPosition); // Orient the object to face the new override position manipulator.SynchronizeOnTransform(camera); // And adjust it's distance to avoid modifying it's position. manipulator.distance = newDistance; } } else { manipulator.anchorPositionOverride = newTransform; } } if (manipulator.anchorPositionOverride != null) { anchor = manipulator.anchorPosition; } manipulator.UpdateTransform(camera, anchor); IsCacheInvalid(manipulator); } } }