public static string SaveAsset <T>(T asset, string fileName, string path) where T : ScriptableObject { if (path == "") { path = TutorialEditorUtils.GetActiveFolderPath(); } else if (Path.GetExtension(path) != "") { path = path.Replace(Path.GetFileName(AssetDatabase.GetAssetPath(Selection.activeObject)), ""); } if (string.IsNullOrEmpty(fileName)) { fileName = "New " + typeof(T).ToString(); } string assetPathAndName = AssetDatabase.GenerateUniqueAssetPath(string.Format("{0}/{1}.asset", path, fileName)); AssetDatabase.CreateAsset(asset, assetPathAndName); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); EditorUtility.FocusProjectWindow(); Selection.activeObject = asset; return(assetPathAndName); }
/// <summary> /// Saves an asset if it doesn't exists already /// </summary> /// <typeparam name="T"></typeparam> /// <param name="asset"></param> /// <param name="fileName"></param> /// <returns>The newly created asset or its existing instance (and its path)</returns> public static (T, string) GetOrSaveUniqueAsset <T>(T asset, string fileName) where T : ScriptableObject { string path = AssetDatabase.GetAssetPath(Selection.activeObject); if (path == "") { path = TutorialEditorUtils.GetActiveFolderPath(); } else if (Path.GetExtension(path) != "") { path = path.Replace(Path.GetFileName(AssetDatabase.GetAssetPath(Selection.activeObject)), ""); } if (string.IsNullOrEmpty(fileName)) { fileName = "New " + typeof(T).ToString(); } string assetPathAndName = string.Format("{0}/{1}.asset", path, fileName); T existingAsset = AssetDatabase.LoadAssetAtPath <T>(assetPathAndName); if (existingAsset) { return(existingAsset, assetPathAndName); } assetPathAndName = SaveAsset <T>(asset, fileName, path); return(asset, assetPathAndName); }
public override void OnInspectorGUI() { serializedObject.Update(); if (GUILayout.Button(Localization.Tr("Show Welcome Dialog"))) { TutorialModalWindow.TryToShow(Target, null); } if (k_IsAuthoringMode) { GUILayout.Space(10); //base.OnInspectorGUI(); DrawPropertiesExcluding(serializedObject, k_PropsToIgnore); } bool eventOffOrRuntimeOnlyExists = false; for (int i = 0; i < m_Buttons.arraySize; i++) { m_CurrentEvent = m_Buttons.GetArrayElementAtIndex(i).FindPropertyRelative(k_OnClickEventPropertyPath); if (!TutorialEditorUtils.EventIsNotInState(m_CurrentEvent, UnityEngine.Events.UnityEventCallState.EditorAndRuntime)) { continue; } eventOffOrRuntimeOnlyExists = true; break; } if (eventOffOrRuntimeOnlyExists) { TutorialEditorUtils.RenderEventStateWarning(); } serializedObject.ApplyModifiedProperties(); }
/// <summary> /// Renders an event property in the inspector /// </summary> /// <param name="nameAndTooltip"></param> /// <param name="property">The property to render</param> /// <param name="spaceAfterProperty">The amount of EditorGUILayout Space to render after the property field</param> static void RenderEventProperty(GUIContent nameAndTooltip, SerializedProperty property, float spaceAfterProperty) { if (property == null) { return; } if (TutorialEditorUtils.EventIsNotInState(property, UnityEngine.Events.UnityEventCallState.EditorAndRuntime)) { TutorialEditorUtils.RenderEventStateWarning(); EditorGUILayout.Space(8); } EditorGUILayout.LabelField(nameAndTooltip); EditorGUILayout.Space(5); EditorGUILayout.PropertyField(property); EditorGUILayout.Space(spaceAfterProperty); }
/// <summary> /// Opens the URL Of the section, if any /// </summary> public void OpenUrl() { TutorialEditorUtils.OpenUrl(Url); AnalyticsHelper.SendExternalReferenceEvent(Url, Heading.Untranslated, LinkText, Tutorial?.lessonId); }
void DrawSimplifiedInspector() { EditorGUILayout.BeginVertical(); if (m_Type != null) { EditorGUILayout.LabelField(Localization.Tr("Header Media Type")); m_HeaderMediaType = (HeaderMediaType)EditorGUILayout.EnumPopup(GUIContent.none, m_HeaderMediaType); m_Type.intValue = (int)m_HeaderMediaType; EditorGUILayout.Space(10); } RenderProperty(Localization.Tr("Media"), m_HeaderMediaType == HeaderMediaType.Image ? m_Image : m_Video); EditorGUILayout.Space(10); RenderProperty(Localization.Tr("Narrative Title"), m_NarrativeTitle); EditorGUILayout.Space(10); RenderProperty(Localization.Tr("Narrative Description"), m_NarrativeDescription); EditorGUILayout.Space(10); RenderProperty(Localization.Tr("Instruction Title"), m_InstructionTitle); EditorGUILayout.Space(10); RenderProperty(Localization.Tr("Instruction Description"), m_InstructionDescription); if (m_CriteriaCompletion != null) { EditorGUILayout.Space(10); EditorGUILayout.LabelField(Localization.Tr("Completion Criteria")); EditorGUILayout.PropertyField(m_CriteriaCompletion, GUIContent.none); EditorGUILayout.PropertyField(m_Criteria, GUIContent.none); } if (m_NextTutorial != null) { EditorGUILayout.Space(10); RenderProperty(Localization.Tr("Next Tutorial"), m_NextTutorial); RenderProperty(Localization.Tr("Next Tutorial button text"), m_TutorialButtonText); } EditorStyles.label.wordWrap = true; //DrawLabelWithImage(Localization.Tr("Custom Callbacks"); EditorGUILayout.BeginHorizontal(); s_ShowEvents = EditorGUILayout.Foldout(s_ShowEvents, s_EventsSectionTitle); if (k_IsAuthoringMode && GUILayout.Button(Localization.Tr("Create Callback Handler"))) { CreateCallbackHandlerScript("TutorialCallbacks.cs"); InitializeEventWithDefaultData(m_OnBeforePageShown); InitializeEventWithDefaultData(m_OnAfterPageShown); GUIUtility.ExitGUI(); } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(10); if (s_ShowEvents) { if (TutorialEditorUtils.EventIsNotInState(m_OnBeforePageShown, UnityEngine.Events.UnityEventCallState.EditorAndRuntime)) { TutorialEditorUtils.RenderEventStateWarning(); EditorGUILayout.Space(8); } RenderEventProperty(s_OnBeforeEventsTitle, m_OnBeforePageShown); EditorGUILayout.Space(5); if (TutorialEditorUtils.EventIsNotInState(m_OnAfterPageShown, UnityEngine.Events.UnityEventCallState.EditorAndRuntime)) { TutorialEditorUtils.RenderEventStateWarning(); EditorGUILayout.Space(8); } RenderEventProperty(s_OnAfterEventsTitle, m_OnAfterPageShown); EditorGUILayout.Space(10); } RenderProperty(Localization.Tr("Enable Masking"), m_MaskingSettings); EditorGUILayout.EndVertical(); DrawPropertiesExcluding(serializedObject, k_PropertiesToHide); serializedObject.ApplyModifiedProperties(); }
/// <summary> /// Transforms HTML tags to word element labels with different styles to enable rich text. /// </summary> /// <param name="htmlText"></param> /// <param name="targetContainer"> /// The following need to set for the container's style: /// flex-direction: row; /// flex-wrap: wrap; /// </param> public static void RichTextToVisualElements(string htmlText, VisualElement targetContainer) { bool addError = false; string errorText = ""; try { XDocument.Parse("<content>" + htmlText + "</content>"); } catch (Exception e) { targetContainer.Clear(); errorText = e.Message; htmlText = ShowContentWithError(htmlText); addError = true; } // TODO should translation be a responsibility of the caller of this function instead? htmlText = Localization.Tr(htmlText); targetContainer.Clear(); bool boldOn = false; // <b> sets this on </b> sets off bool italicOn = false; // <i> </i> bool linkOn = false; string linkURL = ""; bool firstLine = true; bool lastLineHadText = false; // start streaming text per word to elements while retaining current style for each word block string[] lines = htmlText.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None); foreach (string line in lines) { string[] words = line.Split(new[] { " " }, StringSplitOptions.None); if (!firstLine && !lastLineHadText) { AddParagraphToElement(targetContainer); } if (!firstLine && lastLineHadText) { AddLinebreakToElement(targetContainer); //AddParagraphToElement(targetContainer); lastLineHadText = false; } foreach (string word in words) { if (word == "" || word == " " || word == " ") { continue; } lastLineHadText = true; string strippedWord = word; bool removeBold = false; bool removeItalic = false; bool addParagraph = false; bool removeLink = false; if (strippedWord.Contains("<b>")) { strippedWord = strippedWord.Replace("<b>", ""); boldOn = true; } if (strippedWord.Contains("<i>")) { strippedWord = strippedWord.Replace("<i>", ""); italicOn = true; } if (strippedWord.Contains("<a")) { strippedWord = strippedWord.Replace("<a", ""); linkOn = true; } if (linkOn && strippedWord.Contains("href=")) { strippedWord = strippedWord.Replace("href=", ""); int linkFrom = strippedWord.IndexOf("\"", StringComparison.Ordinal) + 1; int linkTo = strippedWord.LastIndexOf("\"", StringComparison.Ordinal); linkURL = strippedWord.Substring(linkFrom, linkTo - linkFrom); strippedWord = strippedWord.Substring(linkTo + 2, (strippedWord.Length - 2) - linkTo); strippedWord.Replace("\">", ""); } if (strippedWord.Contains("</a>")) { strippedWord = strippedWord.Replace("</a>", ""); // TODO </a>text -> also text part is still blue. Parse - for now we can take care when authoring. removeLink = true; } if (strippedWord.Contains("<br/>")) { strippedWord = strippedWord.Replace("<br/>", ""); addParagraph = true; } if (strippedWord.Contains("</b>")) { strippedWord = strippedWord.Replace("</b>", ""); removeBold = true; } if (strippedWord.Contains("</i>")) { strippedWord = strippedWord.Replace("</i>", ""); removeItalic = true; } if (boldOn) { Label wordLabel = new Label(strippedWord); wordLabel.style.unityFontStyleAndWeight = new StyleEnum <FontStyle>(FontStyle.Bold); targetContainer.Add(wordLabel); } else if (italicOn) { Label wordLabel = new Label(strippedWord); wordLabel.style.unityFontStyleAndWeight = new StyleEnum <FontStyle>(FontStyle.Italic); targetContainer.Add(wordLabel); } else if (addParagraph) { AddParagraphToElement(targetContainer); } else if (linkOn && !string.IsNullOrEmpty(linkURL)) { var label = new HyperlinkLabel { text = strippedWord, tooltip = linkURL }; label.RegisterCallback <MouseUpEvent, string>( (evt, linkurl) => { TutorialEditorUtils.OpenUrl(linkurl); }, linkURL ); targetContainer.Add(label); } else { Label newlabel = new Label(strippedWord); targetContainer.Add(newlabel); } if (removeBold) { boldOn = false; } if (removeItalic) { italicOn = false; } if (removeLink) { linkOn = false; linkURL = ""; } } firstLine = false; } if (addError) { var label = new ParseErrorLabel() { text = Localization.Tr("PARSE ERROR"), tooltip = Localization.Tr("Click here to see more information in the console.") }; label.RegisterCallback <MouseUpEvent>((e) => Debug.LogError(errorText)); targetContainer.Add(label); } }