This commit is contained in:
CortexCore
2025-03-14 21:04:19 +08:00
parent ff8670c453
commit 757ffe79ee
1282 changed files with 104378 additions and 3 deletions

View File

@@ -0,0 +1,9 @@
#if GRIFFIN
namespace Pinwheel.Griffin.HelpTool
{
public enum GCategory
{
General, TipsTricks, GroupTool, BackupTool, BillboardTool, PaintTool, SplineTool, StampTool, HelpTool, DataTool
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 52ce0eedf69921342a0bfbe4d81cbccb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,15 @@
#if GRIFFIN
using UnityEditor;
namespace Pinwheel.Griffin.HelpTool
{
[CustomEditor(typeof(GHelpComponent))]
public class GHelpComponentInspector : Editor
{
public override void OnInspectorGUI()
{
GHelpToolDrawer.DrawGUI();
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1a1a8a9b3a0d1404bb4e4e6551bb2950
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,47 @@
#if GRIFFIN
using UnityEngine;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Pinwheel.Griffin.HelpTool
{
//[CreateAssetMenu(fileName ="HelpDatabase", menuName ="Griffin/Help Database")]
public class GHelpDatabase : ScriptableObject
{
private static GHelpDatabase instance;
public static GHelpDatabase Instance
{
get
{
if (instance == null)
{
#if UNITY_EDITOR
instance = Resources.Load<GHelpDatabase>("HelpDatabase");
#endif
if (instance == null)
{
instance = ScriptableObject.CreateInstance<GHelpDatabase>();
}
}
return instance;
}
}
[SerializeField]
private List<GHelpEntry> entries;
public List<GHelpEntry> Entries
{
get
{
if (entries == null)
{
entries = new List<GHelpEntry>();
}
return entries;
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f091f3fad6bf06a4d87c19bde9953ea5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,157 @@
#if GRIFFIN
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace Pinwheel.Griffin.HelpTool
{
[CustomEditor(typeof(GHelpDatabase))]
public class GHelpDatabaseInspector : Editor
{
private GHelpDatabase instance;
private bool onlyShowLastTenItems = true;
private GUIStyle textAreaStyle;
private GUIStyle TextAreaStyle
{
get
{
if (textAreaStyle == null)
{
textAreaStyle = new GUIStyle(EditorStyles.textArea);
}
textAreaStyle.wordWrap = true;
return textAreaStyle;
}
}
private void OnEnable()
{
instance = target as GHelpDatabase;
}
public override void OnInspectorGUI()
{
DrawStatistic();
string prefPrefix = "helpdb" + instance.GetInstanceID();
List<GHelpEntry> entries = instance.Entries;
int startIndex = 0;
if (onlyShowLastTenItems)
{
startIndex = Mathf.Max(0, entries.Count - 10);
}
for (int i = startIndex; i < entries.Count; ++i)
{
GHelpEntry e = entries[i];
e.Id = i + 1;
string label = string.IsNullOrEmpty(e.Question) ?
"[" + e.Id.ToString("000") + "]" :
GEditorCommon.Ellipsis(string.Format("[{0}] {1}", e.Id.ToString("000"), e.Question), 100);
bool expanded = GEditorCommon.Foldout(label, prefPrefix + i, false);
if (expanded)
{
EditorGUI.indentLevel += 1;
EditorGUILayout.LabelField("Id: " + e.Id.ToString("000"));
EditorGUILayout.PrefixLabel("Category");
e.Category = (GCategory)EditorGUILayout.EnumPopup(e.Category);
EditorGUILayout.PrefixLabel("Question");
e.Question = EditorGUILayout.TextField(e.Question);
EditorGUILayout.PrefixLabel("Answer");
e.Answer = EditorGUILayout.TextArea(e.Answer, TextAreaStyle, GUILayout.Height(EditorGUIUtility.singleLineHeight * 5));
for (int j = 0; j < e.Links.Count; ++j)
{
EditorGUILayout.PrefixLabel("Link " + j + " (Text>URL)");
GHelpLink link = e.Links[j];
EditorGUILayout.BeginHorizontal();
link.DisplayText = EditorGUILayout.TextField(link.DisplayText);
link.Link = EditorGUILayout.TextField(link.Link);
EditorGUILayout.EndHorizontal();
e.Links[j] = link;
}
EditorGUI.indentLevel -= 1;
EditorGUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if (GUILayout.Button("L+", GUILayout.Width(30)))
{
e.Links.Add(new GHelpLink());
}
GUI.enabled = e.Links.Count > 0;
if (GUILayout.Button("L-", GUILayout.Width(30)))
{
e.Links.RemoveAt(e.Links.Count - 1);
}
GUI.enabled = true;
if (GUILayout.Button("Delete Entry"))
{
if (EditorUtility.DisplayDialog(
"Confirm",
"Delete this entry?",
"OK", "Cancel"))
{
entries.RemoveAt(i);
Event.current.Use();
continue;
}
}
if (GUILayout.Button("Duplicate"))
{
GHelpEntry newEntry = entries[i];
newEntry.Links = new List<GHelpLink>(entries[i].Links);
entries.Add(newEntry);
string prefKey = GEditorCommon.GetProjectRelatedEditorPrefsKey("foldout", prefPrefix + (entries.Count - 1));
EditorPrefs.SetBool(prefKey, true);
Event.current.Use();
continue;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.Space();
}
entries[i] = e;
}
if (GEditorCommon.RightAnchoredButton("Add"))
{
entries.Add(new GHelpEntry());
}
EditorUtility.SetDirty(instance);
}
private void DrawStatistic()
{
List<GHelpEntry> entries = instance.Entries;
int total = entries.Count;
Dictionary<GCategory, int> countPerCategory = new Dictionary<GCategory, int>();
foreach (GCategory c in Enum.GetValues(typeof(GCategory)))
{
int count = entries.FindAll(e => e.Category == c).Count;
countPerCategory.Add(c, count);
}
EditorGUILayout.LabelField("Total", total.ToString());
EditorGUI.indentLevel += 1;
foreach (GCategory c in Enum.GetValues(typeof(GCategory)))
{
int count = countPerCategory[c];
EditorGUILayout.LabelField(c.ToString(), count.ToString());
}
EditorGUI.indentLevel -= 1;
onlyShowLastTenItems = EditorGUILayout.Toggle("Only Show Last 10 Items", onlyShowLastTenItems);
GEditorCommon.Separator();
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 41a48e5ccf2bac944879c2d914592198
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,35 @@
#if GRIFFIN
using UnityEditor;
using UnityEngine;
namespace Pinwheel.Griffin.HelpTool
{
public class GHelpEditor : EditorWindow
{
public static GHelpEditor Instance { get; set; }
public static void ShowWindow()
{
GHelpEditor window = EditorWindow.GetWindow<GHelpEditor>();
window.minSize = new Vector2(300, 300);
window.titleContent = new GUIContent("Help");
window.Show();
}
private void OnEnable()
{
Instance = this;
}
private void OnDisable()
{
Instance = null;
}
private void OnGUI()
{
GHelpToolDrawer.DrawGUI();
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9e432a392a937a64082043cede84a028
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,85 @@
#if GRIFFIN
using System.Collections.Generic;
using UnityEngine;
namespace Pinwheel.Griffin.HelpTool
{
[System.Serializable]
public struct GHelpEntry
{
[SerializeField]
private int id;
public int Id
{
get
{
return id;
}
set
{
id = Mathf.Max(1, value);
}
}
[SerializeField]
private GCategory category;
public GCategory Category
{
get
{
return category;
}
set
{
category = value;
}
}
[SerializeField]
private string question;
public string Question
{
get
{
return question;
}
set
{
question = value;
}
}
[SerializeField]
private string answer;
public string Answer
{
get
{
return answer;
}
set
{
answer = value;
}
}
[SerializeField]
private List<GHelpLink> links;
public List<GHelpLink> Links
{
get
{
if (links == null)
{
links = new List<GHelpLink>();
}
return links;
}
set
{
links = value;
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cb6d9a7e4e422814998cac4f66477b65
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,38 @@
#if GRIFFIN
using UnityEngine;
namespace Pinwheel.Griffin.HelpTool
{
[System.Serializable]
public struct GHelpLink
{
[SerializeField]
private string displayText;
public string DisplayText
{
get
{
return displayText;
}
set
{
displayText = value;
}
}
[SerializeField]
private string link;
public string Link
{
get
{
return link;
}
set
{
link = value;
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c8f337b66e1f63e4e8968c547911ae95
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,292 @@
#if GRIFFIN
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace Pinwheel.Griffin.HelpTool
{
public static class GHelpToolDrawer
{
private static string searchText;
private static Vector2 scrollPos;
private static int suggestionIndex;
private static string[] searchSuggestions = new string[]
{
"Create a new terrain",
"Paint texture on terrain",
"Convert Unity Terrain to low poly",
"Paint tree and grass on terrain",
"Upgrade to LWRP",
"Create ramp, path, river using Spline Creator",
"Using stamper tools",
"Baking nav mesh",
"Import and export data",
"What's new in this version"
};
private static List<int> searchResult;
private static List<int> SearchResult
{
get
{
if (searchResult == null)
{
searchResult = new List<int>();
}
return searchResult;
}
set
{
searchResult = value;
}
}
private static List<float> hitCount;
private static List<float> HitCount
{
get
{
if (hitCount == null)
{
hitCount = new List<float>();
}
return hitCount;
}
set
{
hitCount = value;
}
}
private static bool[] expandedFlags;
private static GUIStyle linkButtonStyle;
private static GUIStyle LinkButtonStyle
{
get
{
if (linkButtonStyle == null)
{
linkButtonStyle = new GUIStyle(EditorStyles.label);
}
linkButtonStyle.normal.textColor = GEditorCommon.selectedItemColor;
linkButtonStyle.alignment = TextAnchor.UpperLeft;
return linkButtonStyle;
}
}
private static GUIStyle richTextStyle;
private static GUIStyle RichTextStyle
{
get
{
if (richTextStyle == null)
{
richTextStyle = new GUIStyle(EditorStyles.label);
}
richTextStyle.richText = true;
richTextStyle.wordWrap = true;
return richTextStyle;
}
}
public static void DrawGUI()
{
try
{
DrawIcon();
DrawSearchBox();
DrawSearchResult();
}
catch
{
searchText = string.Empty;
suggestionIndex = 0;
SearchResult.Clear();
HitCount.Clear();
expandedFlags = null;
OnSearchTextChanged();
}
}
private static void DrawIcon()
{
string iconName = EditorGUIUtility.isProSkin ? "IconWhite" : "IconBlack";
Texture2D icon = GEditorSkin.Instance.GetTexture(iconName);
if (icon == null)
return;
EditorGUILayout.Space();
Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(64));
GUI.DrawTexture(r, icon, ScaleMode.ScaleToFit, true, 1);
GEditorCommon.Space();
}
private static void DrawSearchBox()
{
EditorGUI.BeginChangeCheck();
searchText = EditorGUILayout.TextField(searchText);
if (EditorGUI.EndChangeCheck())
{
OnSearchTextChanged();
}
GEditorCommon.Separator();
}
private static void OnSearchTextChanged()
{
suggestionIndex = Random.Range(0, searchSuggestions.Length);
Search();
}
private static void Search()
{
SearchResult.Clear();
HitCount.Clear();
if (searchText.Equals("?"))
{
for (int i = 0; i < GHelpDatabase.Instance.Entries.Count; ++i)
{
SearchResult.Add(i);
HitCount.Add(1);
expandedFlags = new bool[SearchResult.Count];
}
return;
}
string text = searchText;
if (text.Length < 3)
return;
string[] split = text.Split(new char[] { ' ' }, System.StringSplitOptions.RemoveEmptyEntries);
if (split.Length == 0)
return;
for (int i = 0; i < split.Length; ++i)
{
split[i] = split[i].ToLower();
}
List<GHelpEntry> entries = GHelpDatabase.Instance.Entries;
for (int i = 0; i < entries.Count; ++i)
{
float count = 0;
GHelpEntry e = entries[i];
for (int j = 0; j < split.Length; ++j)
{
count += e.Question.ToLower().Contains(split[j]) ? 1 : 0;
count += e.Answer.ToLower().Contains(split[j]) ? 0.5f : 0;
}
SearchResult.Add(i);
HitCount.Add(count);
}
SearchResult.Sort((i0, i1) => -HitCount[i0].CompareTo(HitCount[i1]));
HitCount.Sort((i0, i1) => -i0.CompareTo(i1));
expandedFlags = new bool[SearchResult.Count];
}
private static void DrawSearchResult()
{
GUtilities.EnsureArrayLength<bool>(ref expandedFlags, SearchResult.Count);
scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
if (string.IsNullOrEmpty(searchText))
{
DrawSearchSuggestions();
}
else
{
EditorGUI.indentLevel += 1;
List<GHelpEntry> entries = GHelpDatabase.Instance.Entries;
int resultCount = searchText.Equals("?") ? SearchResult.Count : Mathf.Min(10, SearchResult.Count);
for (int i = 0; i < resultCount; ++i)
{
if (HitCount[i] == 0)
break;
int index = SearchResult[i];
GHelpEntry e = entries[index];
string label = string.Format("[{0}] {1}", e.Id.ToString("000"), e.Question);
expandedFlags[i] = EditorGUILayout.Foldout(expandedFlags[i], label);
if (expandedFlags[i])
{
EditorGUI.indentLevel += 1;
EditorGUILayout.LabelField(e.Answer, RichTextStyle);
if (e.Links.Count > 0)
{
EditorGUILayout.LabelField("Link" + (e.Links.Count >= 2 ? "s" : ""));
for (int j = 0; j < e.Links.Count; ++j)
{
if (LinkButton("- " + e.Links[j].DisplayText, e.Links[j].Link))
{
if (e.Links[j].Link.StartsWith("~"))
{
searchText = e.Links[j].Link.Substring(1);
EditorGUI.FocusTextInControl(null);
OnSearchTextChanged();
Event.current.Use();
return;
}
else
{
Application.OpenURL(e.Links[j].Link);
}
}
}
}
EditorGUI.indentLevel -= 1;
EditorGUILayout.Space();
}
}
EditorGUI.indentLevel -= 1;
}
EditorGUILayout.EndScrollView();
}
private static void DrawSearchSuggestions()
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Try the following: ", GUILayout.Width(100));
string suggestion = searchSuggestions[suggestionIndex];
Rect r0 = EditorGUILayout.GetControlRect(GUILayout.Height(EditorGUIUtility.singleLineHeight));
EditorGUIUtility.AddCursorRect(r0, MouseCursor.Link);
if (GUI.Button(r0, suggestion, LinkButtonStyle))
{
searchText = suggestion;
EditorGUI.FocusTextInControl(null);
OnSearchTextChanged();
}
GUILayout.FlexibleSpace();
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Can't find your answer? ", GUILayout.Width(137));
Rect r1 = EditorGUILayout.GetControlRect();
EditorGUIUtility.AddCursorRect(r1, MouseCursor.Link);
if (GUI.Button(r1, "Ask me directly", LinkButtonStyle))
{
GEditorCommon.OpenEmailEditor(
"customer@pinwheel.studio",
"[POLARIS V2 - HELP] SHORT_QUESTION_HERE",
"YOUR_QUESTION_IN_DETAIL");
}
GUILayout.FlexibleSpace();
EditorGUILayout.EndHorizontal();
}
private static bool LinkButton(string label, string tooltip = "")
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.GetControlRect(GUILayout.Width(EditorGUI.indentLevel * GEditorCommon.indentSpace));
Rect r = EditorGUILayout.GetControlRect();
EditorGUIUtility.AddCursorRect(r, MouseCursor.Link);
bool clicked = GUI.Button(r, new GUIContent(label, tooltip), LinkButtonStyle);
EditorGUILayout.EndHorizontal();
return clicked;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 337d18f209556d045a07afadd2b899f0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: