// Delete the version of the sky studio shader that uses global keywords if the // platform supports using local keywords. static void CheckAndDeleteGlobalShaderKeywordsFile() { if (!SkyEditorUtility.SupportsLocalKeywords()) { return; } Shader globalShader = Shader.Find(SkyProfile.DefaultLegacyShaderName); // Check if it's already been deleted. if (globalShader == null) { return; } string assetPath = AssetDatabase.GetAssetPath(globalShader); if (assetPath == null) { return; } if (!AssetDatabase.DeleteAsset(assetPath)) { Debug.LogWarning("Failed to delete legacy Sky Studio shader."); } AssetDatabase.SaveAssets(); }
private void RenderSectionTitle(string title, string iconName) { GUIStyle bgStyle = new GUIStyle(); bgStyle.normal.background = m_SectionHeaderBg; bgStyle.margin = new RectOffset(0, 0, 20, 7); bgStyle.padding = new RectOffset(0, 0, 0, 0); GUIStyle titleStyle = new GUIStyle(GUI.skin.label); titleStyle.normal.textColor = Color.black; titleStyle.fontStyle = FontStyle.Bold; titleStyle.fontSize = k_TitleSize; titleStyle.margin = new RectOffset(0, 0, 0, 0); titleStyle.padding = new RectOffset(0, 0, 3, 0); GUIStyle iconStyle = new GUIStyle(); iconStyle.margin = new RectOffset(0, 0, 0, 0); iconStyle.padding = new RectOffset(0, 0, 0, 0); EditorGUILayout.BeginHorizontal(bgStyle, GUILayout.Height(k_HeaderHeight)); // Default to a placeholder icon if we don't have one. string loadIconFile = iconName != null ? iconName : "UnknownSectionIcon"; Texture icon = SkyEditorUtility.LoadEditorResourceTexture(loadIconFile); EditorGUILayout.LabelField(new GUIContent(icon), iconStyle, GUILayout.Width(k_IconSize), GUILayout.Height(k_IconSize)); EditorGUILayout.LabelField(new GUIContent(title), titleStyle); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); }
static void RunFullMigration() { EditorPrefs.SetInt(migrationVersionKey, migrationVersion); EditorPrefs.SetString(migrationUnityVersionKey, Application.version); // No migration necessary since we're on an older version of Unity. if (!SkyEditorUtility.SupportsLocalKeywords()) { return; } // Upgrade all the skybox materials in the project. string[] guids = AssetDatabase.FindAssets("t:material"); foreach (string guid in guids) { string assetPath = AssetDatabase.GUIDToAssetPath(guid); if (assetPath == null) { continue; } // Upgrade the material if it's a legacy sky studio material. CheckAndRepairSkyStudioMaterial(assetPath); } // Delete the legacy shader since it's no longer being used by materials. CheckAndDeleteGlobalShaderKeywordsFile(); }
private void OnStarRenderingComplete(BaseStarDataRenderer renderer, Texture2D texture, bool success) { if (m_IsCancelled) { m_BusyRenderingCount = 0; return; } texture.name = TextureNameForStarLayer(renderer.layerId); SkyEditorUtility.AddSkyResource(profile, texture); AssetDatabase.Refresh(); if (renderer.layerId == "1") { profile.starLayer1DataTexture = texture; } else if (renderer.layerId == "2") { profile.starLayer2DataTexture = texture; } else if (renderer.layerId == "3") { profile.starLayer3DataTexture = texture; } m_BusyRenderingCount -= 1; if (completionCallback != null) { completionCallback(this, true); } }
public static void UpgradeSetupSkySystem() { TimeOfDayController oldTc = GameObject.FindObjectOfType <TimeOfDayController>(); if (oldTc == null) { EditorUtility.DisplayDialog("Sky Upgrade Failed", "There is no SkySystemController in your current scene to upgrade. Try using the Setup Sky tool to create a sky system instead.", "OK"); return; } GameObject skySystemPrefab = SkyEditorUtility.LoadEditorPrefab(SkySetupWindow.SKY_CONTROLLER_PREFAB); if (skySystemPrefab == null) { Debug.LogError("Failed to locate sky controller prefab"); EditorUtility.DisplayDialog("Sky Upgrade Failed", "Failed to locate SkySystemController prefab. Did you move the prefab or rename any Sky Studio folders? Delete FunlySkyStudio and reinstall the asset package.", "OK"); return; } TimeOfDayController tc = Instantiate(skySystemPrefab).GetComponent <TimeOfDayController>(); tc.name = SkySetupWindow.SKY_CONTROLLER_PREFAB; tc.skyProfile = oldTc.skyProfile; tc.skyTime = oldTc.skyTime; tc.automaticIncrementSpeed = oldTc.automaticIncrementSpeed; tc.automaticTimeIncrement = oldTc.automaticTimeIncrement; DestroyImmediate(oldTc.gameObject); EditorUtility.SetDirty(tc); EditorUtility.SetDirty(tc.gameObject); EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); EditorUtility.DisplayDialog("Sky Upgrade Complete", "The SkySystemController in your current scene has been upgraded, and is using the latest Sky Studio prefab.", "OK"); }
private bool RenderGroupButton(Rect rowRect, int buttonIndex, string iconName, string tooltip) { Texture2D texIcon = SkyEditorUtility.LoadEditorResourceTexture(iconName); if (texIcon == null) { Debug.LogError("Failed to load icon for group button."); return(false); } Color originalColor = GUI.color; GUI.contentColor = GUI.skin.label.normal.textColor; const float buttonPadding = 2.0f; const float buttonEndPadding = 5.0f; Rect btnRect = new Rect( NAME_COLUMN_WIDTH - buttonEndPadding - ((buttonIndex + 1) * ICON_BUTTON_SIZE) - ((buttonIndex) * buttonPadding), rowRect.y + (rowRect.height - ICON_BUTTON_SIZE) / 2.0f, ICON_BUTTON_SIZE, ICON_BUTTON_SIZE ); bool didClickButton = GUI.Button( btnRect, new GUIContent(null, texIcon, tooltip), m_ButtonStyle); GUI.contentColor = originalColor; return(didClickButton); }
// These are the buttons next to the current time of day at the top. private void RenderGlobalTimelineButtons(Rect rect, TimeOfDayController tc) { GUILayout.BeginArea(rect); GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); float buttonSize = 20.0f; Color originalContentColor = GUI.contentColor; GUI.contentColor = GUI.skin.label.normal.textColor; GUIStyle buttonStyle = new GUIStyle(GUI.skin.button); buttonStyle.padding = new RectOffset(2, 2, 2, 2); Texture2D addTexture = SkyEditorUtility.LoadEditorResourceTexture("AddIcon"); bool didClickAddButton = GUILayout.Button( new GUIContent(addTexture, "Add a sky property to the timeline."), buttonStyle, GUILayout.Width(buttonSize), GUILayout.Height(buttonSize)); GUILayout.Space(LEFT_INSET); if (didClickAddButton) { SkyGUITimelineMenu.ShowAddTimelinePropertyMenu(m_ActiveSkyProfile); } GUI.contentColor = originalContentColor; GUILayout.EndHorizontal(); GUILayout.EndArea(); }
// Use vertex shader to fix aspect ratio. public static void RenderNumberGroup(Rect rect, SkyProfile profile, NumberKeyframeGroup group) { lock (profile) { bool sortKeyFrames = false; RenderLinePath(rect, group); for (int i = 0; i < group.keyframes.Count; i++) { NumberKeyframe currentKey = group.GetKeyframe(i); int nextIndex = (i + 1) % group.keyframes.Count; NumberKeyframe nextKey = group.GetKeyframe(nextIndex); // Clamp time if we're wrapping around. float nextTime = nextKey.time; if (nextTime <= currentKey.time) { nextTime = 1.0f; } bool didSingleClick = false; bool isDragging = false; bool keyframeUpdated = false; SkyEditorUtility.DrawNumericKeyMarker(rect, currentKey, group, profile, out didSingleClick, out isDragging, out keyframeUpdated); if (keyframeUpdated) { sortKeyFrames = true; } if (didSingleClick || isDragging) { KeyframeInspectorWindow.SetKeyframeData( currentKey, group, KeyframeInspectorWindow.KeyType.Numeric, profile); if (didSingleClick && KeyframeInspectorWindow.inspectorEnabled == false) { KeyframeInspectorWindow.ShowWindow(); } } } if (sortKeyFrames) { group.SortKeyframes(); } } }
private void RenderTimelineCursor(Rect rect, TimeOfDayController timeController) { // Flag the start of a timeline drag. if (TimelineSelection.isDraggingTimeline == false && (Event.current.type == EventType.MouseDrag) && rect.Contains(Event.current.mousePosition)) { TimelineSelection.isDraggingTimeline = true; } if (TimelineSelection.isDraggingTimeline) { float percent = Mathf.Clamp((Event.current.mousePosition.x - rect.x) / rect.width, 0, MAX_TIME_VALUE); timeController.skyTime = percent; EditorUtility.SetDirty(timeController); } if (Event.current.type != EventType.Repaint) { return; } float playHeadHeight = PLAYHEAD_WIDTH / 2.0f; float xCursorPos = SkyEditorUtility.GetXPositionForPercent(rect, timeController.timeOfDay); // Draw the line that overlaps all the content rows. const float extensionSize = 5.0f; Rect lineRect = new Rect( xCursorPos - (CURSOR_LINE_WIDTH / 2.0f), rect.y + TIME_HEADER_HEIGHT - extensionSize, CURSOR_LINE_WIDTH, rect.height - TIME_HEADER_HEIGHT + extensionSize); GUI.DrawTexture(lineRect, SkyEditorUtility.LoadEditorResourceTexture("CursorLine")); // Draw the playhead arrow. if (m_PlayheadTexture == null) { m_PlayheadTexture = SkyEditorUtility.LoadEditorResourceTexture("PlayheadArrow"); } Rect headRect = new Rect( xCursorPos - (PLAYHEAD_WIDTH / 2.0f), rect.y + TIME_HEADER_HEIGHT - playHeadHeight, PLAYHEAD_WIDTH, playHeadHeight); GUI.DrawTexture(headRect, m_PlayheadTexture, ScaleMode.StretchToFill, true); }
private List <ProfilePreset> LoadListOfPresets() { List <ProfilePreset> presets = new List <ProfilePreset>(); string[] guids = AssetDatabase.FindAssets("t:SkyProfile"); if (guids == null || guids.Length == 0) { return(presets); } foreach (string guid in guids) { string presetPath = AssetDatabase.GUIDToAssetPath(guid); if (presetPath == null) { Debug.LogError("Failed to get name for profile GUID: " + guid); continue; } string presetName = ObjectNames.NicifyVariableName(Path.GetFileNameWithoutExtension(presetPath)); string menuName = Path.GetDirectoryName(presetPath) + "/" + presetName; menuName = SkyEditorUtility.WindowsPathToUnixPath(menuName); string presetDirPrefix = "Assets/" + SkyEditorUtility.PACKAGE_DIR_NAME + "/Internal/Presets/"; if (menuName.StartsWith(presetDirPrefix)) { menuName = menuName.Remove(0, presetDirPrefix.Length); } else { menuName = "Your Project/" + menuName; } presets.Add(new ProfilePreset(guid, presetPath, presetName, menuName)); } presets.Sort(delegate(ProfilePreset p1, ProfilePreset p2) { return(p1.menuName.CompareTo(p2.menuName)); }); return(presets); }
private void ShowSpherePointKeyframesInSkybox(SpherePointKeyframeGroup group) { int debugPoints = 0; for (int i = 0; i < group.keyframes.Count; i++) { SpherePointKeyframe keyframe = group.keyframes[i]; Vector3 direction = keyframe.spherePoint.GetWorldDirection(); float isActiveKeyframe = SkyEditorUtility.IsKeyframeActiveInInspector(keyframe) ? 1.0f : 0.0f; Vector4 pointData = new Vector4(direction.x, direction.y, direction.z, isActiveKeyframe); if (i < MAX_DEBUG_POINTS) { m_DebugPoints[i] = pointData; debugPoints += 1; } } ShowDebugPoints(m_DebugPoints, debugPoints); }
public static void RenderColorGroupRow(Rect rect, SkyProfile profile, ColorKeyframeGroup colors) { bool sortGroup = false; RenderColorGroupRow(rect, colors); for (int i = 0; i < colors.keyframes.Count; i++) { ColorKeyframe currentKey = colors.GetKeyframe(i); // Track key marker mouse events and render. bool didSingleClick = false; bool isDragging = false; bool keyframeUpdated = false; SkyEditorUtility.DrawHorizontalKeyMarker(rect, currentKey, profile, out didSingleClick, out isDragging, out keyframeUpdated); if (keyframeUpdated) { sortGroup = true; } // Show the color keyframe property window. if (didSingleClick || isDragging) { // Load info about this keyframe and show the editor window. KeyframeInspectorWindow.SetKeyframeData( currentKey, colors, KeyframeInspectorWindow.KeyType.Color, profile); if (didSingleClick) { KeyframeInspectorWindow.ShowWindow(); } } } if (sortGroup) { colors.SortKeyframes(); } }
private void ApplyDefaultSettings(SkyProfile profile) { // Lightning art. if (profile.lightningArtSet == null) { profile.lightningArtSet = GetDefaultArtStyleWithName <LightningArtSet>("DefaultLightningArtSet"); } // Splash art. if (profile.rainSplashArtSet == null) { profile.rainSplashArtSet = GetDefaultArtStyleWithName <RainSplashArtSet>("DefaultRainSplashArtSet"); } // Rain near texture. TextureKeyframeGroup group = profile.GetGroup <TextureKeyframeGroup>(ProfilePropertyKeys.RainNearTextureKey); if (group.keyframes.Count == 1 && group.keyframes[0].texture == null) { group.keyframes[0].texture = SkyEditorUtility.LoadEditorResourceTexture("RainDownfall-1"); if (group.keyframes[0].texture == null) { Debug.LogWarning("Failed to locate default near rain texture"); } } // Rain far texture. group = profile.GetGroup <TextureKeyframeGroup>(ProfilePropertyKeys.RainFarTextureKey); if (group.keyframes.Count == 1 && group.keyframes[0].texture == null) { group.keyframes[0].texture = SkyEditorUtility.LoadEditorResourceTexture("RainDownfall-3"); if (group.keyframes[0].texture == null) { Debug.LogWarning("Failed to locate default far rain texture"); } } }
// Sticks to bottom of rect, and can slide horizontally only. public static void DrawHorizontalKeyMarker( Rect fullSliderRect, BaseKeyframe keyFrame, UnityEngine.Object undoObject, out bool didSingleClick, out bool isDragging, out bool keyFrameTimeChanged) { Rect markerRect = new Rect( SkyEditorUtility.GetXPositionForPercent(fullSliderRect, keyFrame.time) - (KEY_GRIP_WIDTH / 2), fullSliderRect.y + fullSliderRect.height - (KEY_GRIP_HEIGHT) / 2.0f, KEY_GRIP_WIDTH, KEY_GRIP_HEIGHT); bool wasDragging = TimelineSelection.selectedControlUUID != null && TimelineSelection.selectedControlUUID == keyFrame.id; bool isMouseOverControl = markerRect.Contains(Event.current.mousePosition); didSingleClick = false; isDragging = wasDragging; keyFrameTimeChanged = false; // Single Click. if (Event.current.isMouse) { // Check for single click, with no drag. if (Event.current.type == EventType.MouseUp && TimelineSelection.selectedControlUUID == null && isMouseOverControl) { Event.current.Use(); didSingleClick = true; } // Start slide. if (TimelineSelection.selectedControlUUID == null && isMouseOverControl && Event.current.type == EventType.MouseDrag) { TimelineSelection.selectedControlUUID = keyFrame.id; Event.current.Use(); isDragging = true; } // End Slide. if (wasDragging && Event.current.type == EventType.MouseUp) { TimelineSelection.selectedControlUUID = null; Event.current.Use(); isDragging = false; } // If we're dragging this keyframe grip, move it's position. if (isDragging || wasDragging) { // Update key frame time value and reposition rectangle. Undo.RecordObject(undoObject, "Keyframe time position changed."); keyFrame.time = SkyEditorUtility.GetPercentForXPosition(fullSliderRect, Event.current.mousePosition.x); keyFrameTimeChanged = true; isDragging = true; // Position the marker rect. markerRect.x = SkyEditorUtility.GetXPositionForPercent(fullSliderRect, keyFrame.time) - (KEY_GRIP_WIDTH / 2); Event.current.Use(); } } bool showAsActive = IsKeyframeActiveInInspector(keyFrame) || isDragging; // Draw the marker at this location. SkyEditorUtility.DrawKeyMarker(markerRect, showAsActive); }
public static void DrawNumericKeyMarker(Rect fullSliderRect, NumberKeyframe keyFrame, NumberKeyframeGroup group, UnityEngine.Object undoObject, out bool didSingleClick, out bool isDragging, out bool keyFrameTimeChanged) { Rect markerRect = new Rect( SkyEditorUtility.GetXPositionForPercent(fullSliderRect, keyFrame.time) - (KEY_GRIP_WIDTH / 2), GetYPositionForPercent(fullSliderRect, 1 - group.ValueToPercent(keyFrame.value)), KEY_GRIP_WIDTH, KEY_GRIP_HEIGHT); bool wasDragging = TimelineSelection.selectedControlUUID != null && TimelineSelection.selectedControlUUID == keyFrame.id; bool isMouseOverControl = markerRect.Contains(Event.current.mousePosition); didSingleClick = false; keyFrameTimeChanged = false; isDragging = wasDragging; // Single Click. if (Event.current.isMouse) { // Check for single click, with no drag. if (Event.current.type == EventType.MouseUp && TimelineSelection.selectedControlUUID == null && isMouseOverControl) { didSingleClick = true; Event.current.Use(); } // Start slide. if (TimelineSelection.selectedControlUUID == null && isMouseOverControl && Event.current.type == EventType.MouseDrag) { TimelineSelection.selectedControlUUID = keyFrame.id; // Find the position of the current value and record the offset so we can drag the keygrip relative from here. Vector2 valuePosition = new Vector2( GetXPositionForPercent(fullSliderRect, keyFrame.time), GetYPositionForPercent(fullSliderRect, 1 - group.ValueToPercent(keyFrame.value))); TimelineSelection.startingMouseOffset = valuePosition - Event.current.mousePosition; isDragging = true; Event.current.Use(); } // End Slide. if (wasDragging && Event.current.type == EventType.MouseUp) { TimelineSelection.selectedControlUUID = null; isDragging = false; Event.current.Use(); } // If we're dragging this keyframe grip, move it's position. if (wasDragging || isDragging) { // Update key frame time value and reposition rectangle. Undo.RecordObject(undoObject, "Keyframe time and value changed."); Vector2 adjustedMousePosition = Event.current.mousePosition + TimelineSelection.startingMouseOffset; keyFrame.time = GetPercentForXPosition(fullSliderRect, adjustedMousePosition.x); float adjustedValuePercent = 1 - GetPercentForYPosition(fullSliderRect, adjustedMousePosition.y); keyFrame.value = group.PercentToValue(adjustedValuePercent); keyFrameTimeChanged = true; isDragging = true; // Position the marker rect. markerRect.x = SkyEditorUtility.GetXPositionForPercent(fullSliderRect, keyFrame.time) - (KEY_GRIP_WIDTH / 2); markerRect.y = GetYPositionForPercent(fullSliderRect, 1 - group.ValueToPercent(keyFrame.value)); Event.current.Use(); } } bool showAsActive = IsKeyframeActiveInInspector(keyFrame) || isDragging; // Draw the marker at this location. SkyEditorUtility.DrawKeyMarker(markerRect, showAsActive); }
// Returns the index public static bool RenderTableList( List <string> list, out int deleteIndex, out bool didSwapRows, out int swapIndex1, out int swapIndex2) { bool didModifyList = false; deleteIndex = -1; didSwapRows = false; swapIndex1 = -1; swapIndex2 = -1; EditorGUILayout.BeginVertical(GUI.skin.box); GUIStyle rowStyle = new GUIStyle(GUI.skin.label); const float buttonHeight = 15.0f; for (int i = 0; i < list.Count; i++) { string item = list[i]; EditorGUILayout.BeginVertical(); EditorGUILayout.BeginHorizontal(rowStyle); EditorGUILayout.LabelField(item, GUI.skin.label); GUILayout.FlexibleSpace(); if (_deleteRowIcon == null) { _deleteRowIcon = SkyEditorUtility.LoadEditorResourceTexture("RowDelete"); } if (_upRowIcon == null) { _upRowIcon = SkyEditorUtility.LoadEditorResourceTexture("RowUp"); } if (_downRowIcon == null) { _downRowIcon = SkyEditorUtility.LoadEditorResourceTexture("RowDown"); } // Tint our images to match the editor skin text. Color originalColor = GUI.contentColor; GUI.contentColor = GUI.skin.label.normal.textColor; // Move row up. if (i - 1 >= 0) { EditorGUI.BeginChangeCheck(); GUILayout.Button(new GUIContent(_upRowIcon), GUILayout.Height(buttonHeight)); if (EditorGUI.EndChangeCheck()) { // Swap with row above. swapIndex1 = i; swapIndex2 = i - 1; didSwapRows = true; didModifyList = true; } } // Move row down. if (i + 1 < list.Count) { EditorGUI.BeginChangeCheck(); GUILayout.Button(new GUIContent(_downRowIcon), GUILayout.Height(buttonHeight)); if (EditorGUI.EndChangeCheck()) { swapIndex1 = i; swapIndex2 = i + 1; didSwapRows = true; didModifyList = true; } } // Delete this row. EditorGUI.BeginChangeCheck(); GUILayout.Button(new GUIContent(_deleteRowIcon), GUILayout.Height(buttonHeight)); if (EditorGUI.EndChangeCheck()) { didModifyList = true; deleteIndex = i; } GUI.contentColor = originalColor; EditorGUILayout.EndHorizontal(); // Draw a divider between rows. if (i != list.Count - 1) { Rect dividerRect = EditorGUILayout.GetControlRect(false, 1.0f); EditorGUI.DrawRect(dividerRect, Color.gray); } EditorGUILayout.EndVertical(); } GUILayout.EndVertical(); GUI.changed = didModifyList; return(didModifyList); }
private void RenderVerticalDivider(Rect dividerRect, string imageName = "VerticalDividerOverlay") { Texture2D dividerTexture = SkyEditorUtility.LoadEditorResourceTexture(imageName); GUI.DrawTexture(dividerRect, dividerTexture); }
private Shader GetBestShaderForSkyProfile(SkyProfile profile) { string shaderName = SkyEditorUtility.GetBestDefaultShaderNameForUnityVersion(); return(Shader.Find(shaderName)); }
private void SetupSceneWithPreset(ProfilePreset preset) { ClearSkyControllers(); Scene currentScene = SceneManager.GetActiveScene(); string sceneDir = Path.GetDirectoryName(currentScene.path); string profileContainerName = currentScene.name + " - Sky Data"; string profileContainerDir = SkyEditorUtility.GenerateUniqueFolder(sceneDir, profileContainerName, true); // Create new sky controller. GameObject skySystemPrefab = SkyEditorUtility.LoadEditorPrefab(SKY_CONTROLLER_PREFAB); if (skySystemPrefab == null) { Debug.LogError("Failed to locate sky controller prefab"); return; } TimeOfDayController tc = Instantiate(skySystemPrefab).GetComponent <TimeOfDayController>(); tc.name = SKY_CONTROLLER_PREFAB; // Create a new sky profile. string profileAssetPath = SkyEditorUtility.GenerateUniqueFilename(profileContainerDir, "SkyProfile", ".asset"); AssetDatabase.CopyAsset(preset.assetPath, profileAssetPath); // Load the new SKy Profile. SkyProfile profile = AssetDatabase.LoadAssetAtPath(profileAssetPath, typeof(SkyProfile)) as SkyProfile; if (profile == null) { Debug.LogError("Failed to duplicate profile"); return; } // Create the skybox material. Material skyboxMaterial = new Material(GetBestShaderForSkyProfile(profile)); string skyboxPath = SkyEditorUtility.GenerateUniqueFilename(profileContainerDir, "SkyboxMaterial", ".mat"); AssetDatabase.CreateAsset(skyboxMaterial, skyboxPath); profile.skyboxMaterial = skyboxMaterial; // Link things together. tc.skyProfile = profile; tc.skyProfile.skyboxMaterial = skyboxMaterial; tc.skyTime = .22f; // Configure the profile a bit and setup in the current scene. SkyProfileEditor.ApplyKeywordsToMaterial(tc.skyProfile, skyboxMaterial); SkyProfileEditor.forceRebuildProfileId = profile.GetInstanceID(); RenderSettings.skybox = skyboxMaterial; ApplyDefaultSettings(profile); // Drop a lightning spawn area into the scene in case user enables the feature. if (!ContainsLightningSpawnArea()) { CreateLightningSpawnArea(); } EditorUtility.SetDirty(skyboxMaterial); EditorUtility.SetDirty(tc.skyProfile); EditorUtility.SetDirty(tc); EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene()); Selection.activeObject = tc.skyProfile; }
private void OnGUI() { LoadStyles(); TimeOfDayController timeController = FindObjectOfType <TimeOfDayController>() as TimeOfDayController; // Render a setup helper UI. if (timeController == null) { RenderNeedsSkySetupLayout(); return; } // Render a profile help message UI. if (timeController.skyProfile == null) { RenderNeedsProfileLayout(); return; } m_ActiveTimeController = timeController; m_ActiveSkyProfile = timeController ? timeController.skyProfile : null; RebuildTimelineDefinitions(timeController.skyProfile); float contentHeight = CalculateWindowContentHeight(timeController.skyProfile); float scrollbarInset = 0; // Select the first colorGroup if one isn't selected. if (TimelineSelection.selectedGroupUUID == null && timeController.skyProfile.timelineManagedKeys.Count > 0) { IKeyframeGroup group = timeController.skyProfile.GetGroup(timeController.skyProfile.timelineManagedKeys[0]); if (group != null) { TimelineSelection.selectedGroupUUID = group.id; } } // Inset content on the right to make room for scroll bar. if (contentHeight > position.height) { scrollbarInset = CONTENT_INSET; } // Timeline rect. Rect contentRect = new Rect( 0, 0, position.width - scrollbarInset, position.height); // Check if mouse left the window, and cancel drag operations. if (Event.current.type == EventType.MouseLeaveWindow || contentRect.Contains(Event.current.mousePosition) == false) { SkyEditorUtility.CancelTimelineDrags(); } // Loads the list of timeline groups to render. RenderTimelineEditor(contentRect, timeController, contentHeight); // Save the edits to the profile object. if (timeController != null) { EditorUtility.SetDirty(timeController.skyProfile); // Keep the scene view rendering in sync for live editing. timeController.UpdateSkyForCurrentTime(); } }
private bool RenderTimelineList() { bool didChangeProfile = false; RenderSectionTitle("Timeline Animated Properties", "TimelineSectionIcon"); EditorGUILayout.Space(); List <ProfileGroupDefinition> onTimeline = m_Profile.GetGroupDefinitionsManagedByTimeline(); List <ProfileGroupDefinition> offTimeline = m_Profile.GetGroupDefinitionsNotManagedByTimeline(); int deleteIndex = -1; bool didSwapRows = false; int swapIndex1 = -1; int swapIndex2 = -1; if (onTimeline.Count == 0) { // Show definition message if no items added yet. EditorGUILayout.HelpBox("You can animate properties by adding them to the timeline.", MessageType.None); } else { EditorGUI.BeginChangeCheck(); List <string> timelineTitles = GetTitlesForGroups(onTimeline); StringTableListGUI.RenderTableList( timelineTitles, out deleteIndex, out didSwapRows, out swapIndex1, out swapIndex2); // Check for table modification events (remove, reorder, etc.) if (EditorGUI.EndChangeCheck()) { didChangeProfile = true; if (deleteIndex != -1) { string deleteGroupKey = onTimeline[deleteIndex].propertyKey; IKeyframeGroup group = m_Profile.GetGroup(deleteGroupKey); if (SkyEditorUtility.IsGroupSelectedOnTimeline(group.id)) { TimelineSelection.Clear(); // If we deleted a sphere point group make sure to hide the debug dots. if (group is SpherePointKeyframeGroup && m_Profile.skyboxMaterial != null) { m_Profile.skyboxMaterial.DisableKeyword(ShaderKeywords.RenderDebugPoints); } } m_Profile.timelineManagedKeys.Remove(deleteGroupKey); m_Profile.TrimGroupToSingleKeyframe(deleteGroupKey); } else if (didSwapRows) { string tmp = m_Profile.timelineManagedKeys[swapIndex2]; m_Profile.timelineManagedKeys[swapIndex2] = m_Profile.timelineManagedKeys[swapIndex1]; m_Profile.timelineManagedKeys[swapIndex1] = tmp; } } } EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button(new GUIContent("Open Timeline"))) { SkyTimelineWindow.ShowWindow(); } if (GUILayout.Button(new GUIContent("Add to Timeline"))) { SkyGUITimelineMenu.ShowAddTimelinePropertyMenu(m_Profile, offTimeline); } EditorGUILayout.EndHorizontal(); return(didChangeProfile); }
private static void RenderLinePath(Rect rect, NumberKeyframeGroup group) { if ((int)rect.width <= 0 || (int)rect.height <= 0 || Event.current.type != EventType.Repaint) { return; } int squareSize = 2048; if (m_LineRenderTexture == null) { m_LineRenderTexture = new RenderTexture( squareSize, squareSize, 16, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB); m_LineRenderTexture.antiAliasing = 2; m_LineRenderTexture.filterMode = FilterMode.Bilinear; } if (!m_LineRenderTexture.IsCreated()) { m_LineRenderTexture.Create(); } if (m_LineMesh == null) { m_LineMesh = new Mesh() { hideFlags = HideFlags.HideAndDontSave }; m_LineMesh.MarkDynamic(); } List <Vector3> points = GetLinePoints(group); // Background color. Color bgColor = new Color(k_BackgroundShade, k_BackgroundShade, k_BackgroundShade); // Line shader. if (m_LineMaterial == null) { m_LineMaterial = new Material(Shader.Find("Hidden/Funly/Sky/SoftLine")) { hideFlags = HideFlags.HideInHierarchy }; } m_LineMaterial.SetColor("_LineColor", ColorHelper.ColorWithHexAlpha(0x2AFBFFFF)); m_LineMaterial.SetFloat("_EdgeFeathering", k_LineEdgeFeathering); m_LineMaterial.SetColor("_BackgroundColor", bgColor); m_LineMaterial.SetTexture("_MainTex", SkyEditorUtility.LoadEditorResourceTexture("NumberShadowLine", false)); if (m_LineShadowMaterial == null) { m_LineShadowMaterial = new Material(Shader.Find("Hidden/Funly/Sky/LineShadow")) { hideFlags = HideFlags.HideInHierarchy }; } Color shadowColor = new Color(k_ShadowShade, k_ShadowShade, k_ShadowShade, 1.0f); m_LineShadowMaterial.SetColor("_BackgroundColor", bgColor); m_LineShadowMaterial.SetColor("_ShadowColor", shadowColor); // Setup tmp texture to render into. RenderTexture oldRenderTexture = RenderTexture.active; RenderTexture.active = m_LineRenderTexture; GL.PushMatrix(); GL.LoadPixelMatrix(0, m_LineRenderTexture.width, 0, m_LineRenderTexture.height); GL.Clear(true, true, bgColor); float lineInset = 5.0f; float heightScale = rect.height / rect.width; float lineThickness = k_LineThickness * heightScale; BuildLineMesh( m_LineMesh, points, m_LineRenderTexture.width, m_LineRenderTexture.width * heightScale - (lineInset * 2), lineThickness); // Line shadow. m_LineShadowMaterial.SetPass(0); Graphics.DrawMeshNow(m_LineMesh, new Vector3(0, lineInset - 8, 0), Quaternion.identity); // Actual line. m_LineMaterial.SetPass(0); Graphics.DrawMeshNow(m_LineMesh, new Vector3(0, lineInset, 0), Quaternion.identity); GL.PopMatrix(); RenderTexture.active = oldRenderTexture; // Pull out just the snippet section we want to use. Rect textureRect = new Rect( 0, 0, 1, heightScale); GUI.DrawTextureWithTexCoords(rect, m_LineRenderTexture, textureRect); }
private Texture RenderCubemapToTexture(Cubemap cubemap, int faceSize, Color clearColor, TextureFormat textureFormat, bool exportFaces, string assetPathPrefix, bool alphaIsTransparency) { CubeFaceData[] faces = { new CubeFaceData(CubemapFace.NegativeX, new Vector2(0, faceSize)), new CubeFaceData(CubemapFace.PositiveX, new Vector2(faceSize * 2, faceSize)), new CubeFaceData(CubemapFace.PositiveY, new Vector2(faceSize, faceSize * 2)), new CubeFaceData(CubemapFace.NegativeY, new Vector2(faceSize, 0)), new CubeFaceData(CubemapFace.PositiveZ, new Vector2(faceSize, faceSize)), new CubeFaceData(CubemapFace.NegativeZ, new Vector2(faceSize * 3, faceSize)) }; RenderTexture oldRt = RenderTexture.active; Texture2D faceTex = new Texture2D(faceSize, faceSize, TextureFormat.RGBA32, false); RenderTexture faceRenderTex = new RenderTexture(faceSize, faceSize, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB); faceRenderTex.Create(); RenderTexture flatCubeTex = new RenderTexture(faceSize * 4, faceSize * 3, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB); flatCubeTex.Create(); Material flipMat = new Material(Shader.Find("Funly/Sky Studio/Utility/Flip Image")); Material blitMat = new Material(Shader.Find("Unlit/Transparent")); RenderTexture.active = flatCubeTex; GL.PushMatrix(); GL.LoadPixelMatrix(0, flatCubeTex.width, flatCubeTex.height, 0); GL.Clear(true, true, new Color(0.0f, 0.0f, 0.0f, 0.0f)); GL.PopMatrix(); RenderTexture.active = null; for (int i = 0; i < faces.Length; i++) { CubeFaceData data = faces[i]; // Pull a face texture out of the cubemap. Color[] pixels = cubemap.GetPixels(data.face); faceTex.SetPixels(pixels); faceTex.Apply(); // Flip the image. RenderTexture.active = faceRenderTex; GL.PushMatrix(); GL.LoadPixelMatrix(0, faceRenderTex.width, flatCubeTex.height, 0); Graphics.Blit(faceTex, faceRenderTex, flipMat, 0); GL.PopMatrix(); if (exportFaces) { string path = assetPathPrefix + data.face.ToString() + ".png"; SkyEditorUtility.WriteTextureToFile(faceRenderTex, path, textureFormat); RenderTexture.active = null; AssetDatabase.ImportAsset(path); } RenderTexture.active = null; // Target our cubemap, and render the flipped face into it. RenderTexture.active = flatCubeTex; GL.PushMatrix(); GL.LoadPixelMatrix(0, flatCubeTex.width, flatCubeTex.height, 0); Graphics.DrawTexture(new Rect(data.offset.x, data.offset.y, faceSize, faceSize), faceRenderTex, blitMat); // Write the final texture on last face. if (i == faces.Length - 1) { string path = assetPathPrefix + ".png"; Debug.Log("Exporting cubemap to compressed texture at path: " + path); SkyEditorUtility.WriteTextureToFile(flatCubeTex, path, textureFormat); RenderTexture.active = null; AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate); // Adjust texture settings. TextureImporter importer = TextureImporter.GetAtPath(path) as TextureImporter; importer.textureShape = TextureImporterShape.TextureCube; importer.alphaIsTransparency = alphaIsTransparency; AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate); } GL.PopMatrix(); RenderTexture.active = null; } RenderTexture.active = oldRt; return(flatCubeTex); }
// Color based on last edge speed. public static List <Vector4> GenerateColorSpeedPoints(SpherePointKeyframeGroup group) { List <Vector4> colorPoints = new List <Vector4>(); if (group.GetKeyFrameCount() <= 1) { colorPoints.Add(new Vector4(0.0f, m_AvgColor.r, m_AvgColor.g, m_AvgColor.b)); colorPoints.Add(new Vector4(1.0f, m_AvgColor.r, m_AvgColor.g, m_AvgColor.b)); return(colorPoints); } float gradientOffset = .02f; const float maxSpeed = 1200.0f; for (int i = 0; i < group.keyframes.Count; i++) { int nextIndex = (i + 1) % group.GetKeyFrameCount(); SpherePointKeyframe currentKeyframe = group.keyframes[i]; SpherePointKeyframe nextKeyframe = group.keyframes[nextIndex]; // Last keyframe has special rules if (i == group.keyframes.Count - 1) { float speed = GetSpeedBetweenKeyframes(currentKeyframe, nextKeyframe); Color speedColor = Color.Lerp(m_AvgColor, m_MaxColor, speed / maxSpeed); float gradientBeginTime = currentKeyframe.time + gradientOffset; float gradientEndTime = 1.0f; if (gradientBeginTime >= 1.0f) { gradientBeginTime = currentKeyframe.time; } colorPoints.Add( new Vector4(gradientBeginTime, speedColor.r, speedColor.g, speedColor.b)); colorPoints.Add( new Vector4(gradientEndTime, speedColor.r, speedColor.g, speedColor.b)); // Now bridge gap if any to first keyframe. if (!SkyEditorUtility.IsKeyFrameAtStart(nextKeyframe)) { gradientBeginTime = 0.0f; gradientEndTime = nextKeyframe.time - gradientOffset; if (gradientEndTime < 0) { gradientEndTime = nextKeyframe.time; } colorPoints.Insert(0, new Vector4(gradientEndTime, speedColor.r, speedColor.g, speedColor.b)); colorPoints.Insert(0, new Vector4(gradientBeginTime, speedColor.r, speedColor.g, speedColor.b)); } else { colorPoints.Insert( 0, new Vector4(0, speedColor.r, speedColor.g, speedColor.b)); } } else { float gradientBeginTime = currentKeyframe.time + gradientOffset; float gradientEndTime = nextKeyframe.time - gradientOffset; // Need to play with these to see how they look. Maybe use a percentage between them instead? if (gradientBeginTime >= nextKeyframe.time) { gradientBeginTime = currentKeyframe.time; } if (gradientEndTime <= currentKeyframe.time) { gradientEndTime = nextKeyframe.time; } float speed = GetSpeedBetweenKeyframes(currentKeyframe, nextKeyframe); Color speedColor = Color.Lerp(m_AvgColor, m_MaxColor, speed / maxSpeed); colorPoints.Add( new Vector4(gradientBeginTime, speedColor.r, speedColor.g, speedColor.b)); colorPoints.Add( new Vector4(gradientEndTime, speedColor.r, speedColor.g, speedColor.b)); } } return(colorPoints); }
private void RenderTimelineEditor(Rect rect, TimeOfDayController timeController, float contentHeight) { float nameColMinX = rect.x; float valueColMinX = nameColMinX + NAME_COLUMN_WIDTH; float valueColMaxX = rect.xMax; float valueColWidth = rect.width - NAME_COLUMN_WIDTH; // Check for the end of a timeline drag. if (TimelineSelection.isDraggingTimeline && Event.current.type == EventType.MouseUp) { TimelineSelection.isDraggingTimeline = false; } // If we're busy dragging the timeline, consume the events so child views don't see them. if (Event.current.type == EventType.MouseDrag && TimelineSelection.isDraggingTimeline) { Event.current.Use(); } // Check if user dragged in the time ruler so we don't click things behind it. if (DidDragTimeRuler()) { SkyEditorUtility.CancelTimelineDrags(); TimelineSelection.isDraggingTimeline = true; Event.current.Use(); } float fullContentHeight = Mathf.Max(position.height, contentHeight); // Background style. RenderBackground(); // Render timeline buttons at header. Rect toolbarRect = new Rect(nameColMinX, rect.y, NAME_COLUMN_WIDTH, TIME_HEADER_HEIGHT); RenderHeaderButtons(toolbarRect, timeController); // Render Scrubber. Rect timeScrubberRect = new Rect(valueColMinX, rect.y, valueColWidth - VALUE_COLUMN_INSET, TIME_HEADER_HEIGHT); RenderTimeRuler(timeScrubberRect, timeController.timeOfDay); // Show an empty content help message. if (timeController.skyProfile.timelineManagedKeys.Count == 0) { RenderEmptyTimelineMessage(); } Rect innerScrollViewContent = new Rect( 0, 0, rect.width, contentHeight - TIME_HEADER_HEIGHT); Rect scrollWindowPosition = new Rect(0, TIME_HEADER_HEIGHT, position.width, rect.height - TIME_HEADER_HEIGHT); m_ScrollPosition = GUI.BeginScrollView(scrollWindowPosition, m_ScrollPosition, innerScrollViewContent, false, false); // Render all the content rows. Rect rowsRect = new Rect(rect.x, 0, rect.width, 0); RenderAllRows(rowsRect, timeController.skyProfile); RenderSpherePointGroupDebugPointsIfSelected(); GUI.EndScrollView(); // Draw the cursor, which overlaps the other content. Rect cursorRect = new Rect( valueColMinX, rect.y, valueColWidth - VALUE_COLUMN_INSET, fullContentHeight); RenderTimelineCursor(cursorRect, timeController); }