/// <summary> /// Used to set a specified zone from a preset context asset. /// </summary> /// <param name="zone"> The zone to set.</param> /// <param name="ctx"> The context to load the preset from.</param> public static void SetZoneFromContextPreset(DS_HazeZone zone, DS_HazeContextAsset ctx) { if (!zone) { Debug.LogError("DeepSky::DS_HazeZoneEditor:SetZoneFromContextPreset - null zone passed!"); return; } if (!ctx) { Debug.LogError("DeepSky::DS_HazeZoneEditor:SetZoneFromContextPreset - null ctx passed!"); return; } zone.Context.CopyFrom(ctx.Context); }
/// <summary> /// Save a new context preset from the context currently displayed /// in the editor. /// </summary> public void CreateNewHazeContextPreset(string name) { DS_HazeZone editingObject = (DS_HazeZone)target; DS_HazeContextAsset asset = editingObject.Context.GetContextAsset(); if (!AssetDatabase.IsValidFolder(kPresetsPath)) { AssetDatabase.CreateFolder(kPresetsFolderPath, kPresetsFolder); } AssetDatabase.CreateAsset(asset, kPresetsPath + "/" + name + ".asset"); AssetDatabase.SaveAssets(); EditorGUIUtility.PingObject(asset); }
/// <summary> /// Custom Inspector drawing for DS_HazeCore components. /// </summary> public override void OnInspectorGUI() { // Make the foldout text bold. GUIStyle foldoutStyle = new GUIStyle(EditorStyles.foldout); GUIStyle headerLabelStyle = new GUIStyle(EditorStyles.boldLabel); headerLabelStyle.alignment = TextAnchor.MiddleLeft; // Get the styles for the mini buttons and 'solo' toggle. GUIStyle variantStyle = new GUIStyle(EditorStyles.helpBox); variantStyle.padding = new RectOffset(0, 2, 3, 3); GUIStyle buttonLeft = GUI.skin.FindStyle("ButtonLeft"); GUIStyle buttonRight = GUI.skin.FindStyle("ButtonRight"); GUIStyle miniButtonStyleL = new GUIStyle(EditorStyles.miniButtonLeft); GUIStyle miniButtonStyleM = new GUIStyle(EditorStyles.miniButtonMid); GUIStyle miniButtonStyleR = new GUIStyle(EditorStyles.miniButtonRight); // Style for expandable help text. GUIStyle helpBoxStyle = new GUIStyle(EditorStyles.helpBox); helpBoxStyle.richText = true; Texture2D helpIconImage = EditorGUIUtility.FindTexture("console.infoicon.sml"); GUIStyle helpIconStyle = new GUIStyle(); helpIconStyle.normal.background = helpIconImage; helpIconStyle.onNormal.background = helpIconImage; helpIconStyle.active.background = helpIconImage; helpIconStyle.onActive.background = helpIconImage; helpIconStyle.focused.background = helpIconImage; helpIconStyle.onFocused.background = helpIconImage; serializedObject.Update(); DS_HazeZone hazeZone = target as DS_HazeZone; SerializedProperty soloIndexProp = m_ContextProp.FindPropertyRelative("m_SoloItem"); // Handle the object picker for selecting a preset. Note that the actual loading happens at the end of // this function and only after a Repaint event. EditorGUILayout.BeginVertical(); { EditorGUILayout.Space(); EditorGUILayout.LabelField("Zone Parameters:", headerLabelStyle); EditorGUILayout.PropertyField(serializedObject.FindProperty("m_Priority")); EditorGUILayout.PropertyField(serializedObject.FindProperty("m_BlendRange")); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); { if (GUILayout.Button("Create Preset", buttonLeft)) { PopupWindow.Show(m_SavePresetRect, m_PresetNamePopup); } if (Event.current.type == EventType.Repaint) { m_SavePresetRect = GUILayoutUtility.GetLastRect(); } if (GUILayout.Button("Load Preset", buttonRight)) { int ctrlID = EditorGUIUtility.GetControlID(FocusType.Passive); EditorGUIUtility.ShowObjectPicker <DS_HazeContextAsset>(null, false, "", ctrlID); } m_HelpTxtExpanded = EditorGUILayout.Toggle(m_HelpTxtExpanded, helpIconStyle, GUILayout.Width(helpIconImage.width)); } EditorGUILayout.EndHorizontal(); if (m_HelpTxtExpanded) { EditorGUILayout.TextArea(kHelpTxt, helpBoxStyle); } // Check for messages returned by the object picker. if (Event.current.commandName == "ObjectSelectorClosed") { m_WaitingToLoad = EditorGUIUtility.GetObjectPickerObject() as DS_HazeContextAsset; } EditorGUILayout.Space(); // Manually calculate a scaling factor based on the current width of the Inspector and a fixed minimum width. float maxLabelWidth = EditorGUIUtility.labelWidth; if (EditorGUIUtility.currentViewWidth < 350) { maxLabelWidth = Mathf.Lerp(50, EditorGUIUtility.labelWidth, (1.0f / (350.0f - 275.0f)) * (EditorGUIUtility.currentViewWidth - 275.0f)); } EditorGUILayout.LabelField("Time-Of-Day Variants:", EditorStyles.boldLabel); SerializedProperty ctxVariants = m_ContextProp.FindPropertyRelative("m_ContextItems"); for (int cv = 0; cv < ctxVariants.arraySize; cv++) { SerializedProperty cvElem = ctxVariants.GetArrayElementAtIndex(cv); SerializedProperty cvName = cvElem.FindPropertyRelative("m_Name"); SerializedProperty cvWeightProp = cvElem.FindPropertyRelative("m_Weight"); Rect cvRect = EditorGUILayout.BeginHorizontal(variantStyle); { cvRect.y += 5; cvRect.width = 50; // Draw the foldout and get the expanded state of this variant. cvElem.isExpanded = EditorGUI.Foldout(cvRect, cvElem.isExpanded, GUIContent.none, true, foldoutStyle); EditorGUILayout.LabelField(cvName.stringValue, headerLabelStyle, GUILayout.Width(maxLabelWidth)); // Draw the 'solo' button. EditorGUI.BeginChangeCheck(); EditorGUILayout.Toggle(cv == soloIndexProp.intValue, GUILayout.Width(12)); if (EditorGUI.EndChangeCheck()) { soloIndexProp.intValue = soloIndexProp.intValue != cv ? cv : -1; } // Draw the weight curve as part of the header, so we can edit the weighting without having to expand the whole context. cvWeightProp.animationCurveValue = EditorGUILayout.CurveField(cvWeightProp.animationCurveValue, Color.green, new Rect(0, 0, 1, 1)); // Add, move up/down and delete buttons. if (GUILayout.Button("+", miniButtonStyleL)) { hazeZone.Context.DuplicateContextItem(cv); } if (GUILayout.Button('\u25B2'.ToString(), miniButtonStyleM)) { hazeZone.Context.MoveContextItemUp(cv); } if (GUILayout.Button('\u25BC'.ToString(), miniButtonStyleM)) { hazeZone.Context.MoveContextItemDown(cv); } if (GUILayout.Button("-", miniButtonStyleR)) { hazeZone.Context.RemoveContextItem(cv); } } EditorGUILayout.EndHorizontal(); // If the context variant is expanded, draw its actual property below the header. if (cvElem.isExpanded) { EditorGUILayout.PropertyField(cvElem); } } } EditorGUILayout.EndVertical(); serializedObject.ApplyModifiedProperties(); // Check if there's a context waiting to be loaded. We need to wait until // after a repaint event as it will probably modify the size of the context variants // list. This can cause a mis-match between what was setup during the Layout event and // what we're now drawing during a Repaint. if (Event.current.type == EventType.Repaint && m_WaitingToLoad != null) { LoadFromContextPreset(m_WaitingToLoad); m_WaitingToLoad = null; } }
public static void DS_HazeZoneDrawGizmo(DS_HazeZone src, GizmoType gizmoType) { Transform xForm = src.GetComponent <Transform>(); float dT; Vector3 sizes; Gizmos.matrix = xForm.localToWorldMatrix; if ((gizmoType & GizmoType.Active) != GizmoType.Active) { dT = Mathf.Min(xForm.localScale.x, xForm.localScale.y, xForm.localScale.z) * src.BlendRange; sizes = xForm.localScale; sizes.x = (sizes.x - dT) / sizes.x; sizes.y = (sizes.y - dT) / sizes.y; sizes.z = (sizes.z - dT) / sizes.z; sizes *= 0.5f; Vector3[] vtxs = { new Vector3(sizes.x, sizes.y, sizes.z), new Vector3(-sizes.x, sizes.y, sizes.z), new Vector3(-sizes.x, sizes.y, sizes.z), new Vector3(-sizes.x, sizes.y, -sizes.z), new Vector3(-sizes.x, sizes.y, -sizes.z), new Vector3(sizes.x, sizes.y, -sizes.z), new Vector3(sizes.x, sizes.y, -sizes.z), new Vector3(sizes.x, sizes.y, sizes.z), new Vector3(sizes.x, -sizes.y, sizes.z), new Vector3(-sizes.x, -sizes.y, sizes.z), new Vector3(-sizes.x, -sizes.y, sizes.z), new Vector3(-sizes.x, -sizes.y, -sizes.z), new Vector3(-sizes.x, -sizes.y, -sizes.z), new Vector3(sizes.x, -sizes.y, -sizes.z), new Vector3(sizes.x, -sizes.y, -sizes.z), new Vector3(sizes.x, -sizes.y, sizes.z), new Vector3(sizes.x, sizes.y, sizes.z), new Vector3(sizes.x, -sizes.y, sizes.z), new Vector3(-sizes.x, sizes.y, sizes.z), new Vector3(-sizes.x, -sizes.y, sizes.z), new Vector3(-sizes.x, sizes.y, -sizes.z), new Vector3(-sizes.x, -sizes.y, -sizes.z), new Vector3(sizes.x, sizes.y, -sizes.z), new Vector3(sizes.x, -sizes.y, -sizes.z), }; Matrix4x4 handleM = Handles.matrix; Handles.matrix = xForm.localToWorldMatrix; #if UNITY_5_0 || UNITY_5_1 || UNITY_5_2 Handles.color = Color.yellow; for (int vi = 0; vi < vtxs.Length; vi += 2) { Handles.DrawLine(vtxs[vi], vtxs[vi + 1]); } #else Handles.color = Color.yellow; Handles.DrawDottedLines(vtxs, 5); #endif Handles.matrix = handleM; Gizmos.color = kUnselectedColour; } else { Gizmos.color = Color.green; dT = Mathf.Min(xForm.localScale.x, xForm.localScale.y, xForm.localScale.z) * src.BlendRange; sizes = xForm.localScale; sizes.x = (sizes.x - dT) / sizes.x; sizes.y = (sizes.y - dT) / sizes.y; sizes.z = (sizes.z - dT) / sizes.z; Gizmos.DrawWireCube(Vector3.zero, sizes); Gizmos.color = kSelectedColour; } Gizmos.DrawWireCube(Vector3.zero, Vector3.one); }
/// <summary> /// Set the context from the preset context asset. /// </summary> /// <param name="cxt"></param> private void LoadFromContextPreset(DS_HazeContextAsset ctx) { DS_HazeZone editingObject = (DS_HazeZone)target; editingObject.Context.CopyFrom(ctx.Context); }
/// <summary> /// Create the Controller, Zone and View needed to see DeepSky effects, fitting /// the zone around the passed terrain or object (if supplied) and applying the /// selected preset. /// </summary> /// <param name="boundsObject"> The Zone will be scaled to surround this object/terrain. </param> /// <param name="presetPath"> Asset path to preset Context to load settings from. </param> private void AddQuickSetupToScene(GameObject boundsObject, string presetPath) { DS_HazeCore core = DS_HazeCore.Instance; GameObject cont; if (core == null) { cont = new GameObject("DS_HazeController", typeof(DS_HazeCore)); cont.transform.position = new Vector3(0, 0, 0); } else { cont = core.gameObject; Debug.Log("DeepSky::AddQuickSetupToScene - There is already a Haze Controller in this scene! Skipping adding a new one."); } GameObject zone = new GameObject("DS_HazeZone", typeof(DS_HazeZone)); DS_HazeContextAsset ctxAsset = AssetDatabase.LoadAssetAtPath <DS_HazeContextAsset>(presetPath); if (ctxAsset == null) { Debug.LogWarning("DeepSky::AddQuickSetupToScene - Unable to load preset " + presetPath); } else { DS_HazeZone zoneComp = zone.GetComponent <DS_HazeZone>(); DS_HazeZoneEditor.SetZoneFromContextPreset(zoneComp, ctxAsset); } Vector3 zoneSize = new Vector3(250, 100, 250); Vector3 zoneLocation = Vector3.zero; if (boundsObject) { zoneLocation = boundsObject.transform.position; bool useDefault = false; Vector3 objSize = zoneSize; Terrain ter = boundsObject.GetComponent <Terrain>(); if (ter) { // This is a terrain, get the size from the terrain data and scale zone to default inner blend zone. objSize = ter.terrainData.size; zoneLocation += ter.terrainData.size * 0.5f; } else { // Normal object, fit to mesh renderer bounds (if there is a mesh renderer). MeshRenderer mr = boundsObject.GetComponent <MeshRenderer>(); if (mr) { objSize = mr.bounds.size; zoneLocation = mr.bounds.center; } else { Debug.Log("DeepSky::AddQuickSetupToScene - Supplied object has no Mesh Renderer to get bounds from! Using default size."); useDefault = true; } } if (!useDefault) { // Make sure there is at least some size. if (objSize.x < 10) { objSize.x = 10; } if (objSize.y < 10) { objSize.y = 10; } if (objSize.z < 10) { objSize.z = 10; } zoneSize = objSize; float dT = Mathf.Min(zoneSize.x, zoneSize.y, zoneSize.z) * 0.1f; Vector3 scale = new Vector3(zoneSize.x / (zoneSize.x - dT), zoneSize.y / (zoneSize.y - dT), zoneSize.z / (zoneSize.z - dT)); zoneSize.Scale(scale); zoneSize.y += objSize.y * 0.1f; // Scale up by 10% in Y to give a little extra room at the top/bottom of the terrain/mesh. } } zone.transform.localScale = zoneSize; zone.transform.position = zoneLocation; zone.transform.SetParent(cont.transform); DS_HazeView view = m_Camera.GetComponent <DS_HazeView>(); if (view) { Debug.Log("DeepSky::AddQuickSetupToScene - The camera already has a Haze View! Skipping adding a new one."); return; } else { view = m_Camera.gameObject.AddComponent <DS_HazeView>(); view.DirectLight = m_DirectionalLight; } }