float AngleField(Rect knobRect, string label, float angle, float offset, Color sectionColor, bool enabled) { var id = GUIUtility.GetControlID("AngleSlider".GetHashCode(), FocusType.Passive); var state = GetAngleFieldState(id); if (Event.current.type == EventType.Repaint) { state.radius = Mathf.Min(knobRect.width, knobRect.height) * 0.5f; state.position = knobRect.center; } // state object not populated yet, we'll wait for repaint, abort if (Math.Abs(state.radius) < Mathf.Epsilon) { return(angle); } var newAngle = 0f; // reset on right click var didReset = GUIUtility.hotControl == 0 && Event.current.type == EventType.MouseDown && Event.current.button == 1 && knobRect.Contains(Event.current.mousePosition); if (didReset) { newAngle = 0f; Event.current.Use(); GUI.changed = true; } else if (enabled) { var srcPos = new Vector2( Mathf.Cos((angle + offset) * Mathf.Deg2Rad), Mathf.Sin((angle + offset) * Mathf.Deg2Rad)) * state.radius + state.position; var dstPos = Slider2DCircular(id, srcPos, 5f, Handles.CircleHandleCap); dstPos -= state.position; dstPos.Normalize(); newAngle = LightAnchor.NormalizeAngleDegree(Mathf.Atan2(dstPos.y, dstPos.x) * Mathf.Rad2Deg - offset); newAngle = Mathf.Round(newAngle * 100.0f) / 100.0f; } else { newAngle = 0; } if (Event.current.type == EventType.Repaint) { DrawAngleWidget(state.position, state.radius, newAngle, offset, sectionColor, enabled); } return(newAngle); }
bool IsCacheInvalid(LightAnchor manipulator) { var camera = Camera.main; Assert.IsNotNull(camera, "Light Anchor: Main Camera is NULL"); var cameraTransform = camera.transform; var manipulatorTransform = manipulator.transform; var camToLight = manipulatorTransform.position - cameraTransform.position; var camLightForwardDot = Vector3.Dot(manipulatorTransform.forward, cameraTransform.forward); var camLightRightDot = Vector3.Dot(manipulatorTransform.right, cameraTransform.right); var dirty = camToLight != m_CamToLight || Math.Abs(camLightForwardDot - m_CamLightForwardDot) > float.Epsilon || Math.Abs(camLightRightDot - m_CamLightRightDot) > float.Epsilon; m_CamToLight = camToLight; m_CamLightForwardDot = camLightForwardDot; m_CamLightRightDot = camLightRightDot; return(dirty); }
/// <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> /// Initializes and returns an instance of LightAnchorHandles /// </summary> /// <param name="target">Target object</param> public LightAnchorHandles(LightAnchor target) { this.target = target; }