249 lines
13 KiB
C#
249 lines
13 KiB
C#
#if UNITY_EDITOR
|
|
using ShrinkApp.Editor;
|
|
using ShrinkContext.AppAdapter;
|
|
using UnityEditor;
|
|
using UnityEditor.SceneManagement;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace ShrinkApp.Starter.Basic.Editor
|
|
{
|
|
public static class ShrinkAppBasicStarterGenerator
|
|
{
|
|
private const string MenuPath = "ShrinkApp/Starter/生成 Basic Entry 场景";
|
|
private const string CompositionMenuPath = "ShrinkApp/Starter/创建默认 Cordis Composition";
|
|
private const string CompositionPath = "Assets/Resources/ShrinkAppComposition.asset";
|
|
|
|
[MenuItem(MenuPath)]
|
|
public static void Generate()
|
|
{
|
|
EnsureAssets();
|
|
BuildScene();
|
|
AssetDatabase.SaveAssets();
|
|
AssetDatabase.Refresh();
|
|
Debug.Log("[ShrinkApp.Starter.Basic] 已生成 Basic Entry 场景与配置。");
|
|
}
|
|
|
|
[MenuItem(CompositionMenuPath)]
|
|
public static void CreateDefaultCompositionAsset()
|
|
{
|
|
EnsureResourcesDirectory();
|
|
var existing = AssetDatabase.LoadAssetAtPath<ShrinkAppCompositionProfile>(CompositionPath);
|
|
if (existing != null)
|
|
{
|
|
Selection.activeObject = existing;
|
|
return;
|
|
}
|
|
|
|
// 修复脚本/asmdef 变更期间可能留下的无主 .asset,而不是在同一路径叠加创建。
|
|
if (!string.IsNullOrEmpty(AssetDatabase.AssetPathToGUID(CompositionPath)))
|
|
AssetDatabase.DeleteAsset(CompositionPath);
|
|
|
|
var composition = ScriptableObject.CreateInstance<ShrinkAppCompositionProfile>();
|
|
composition.SetDocument(ShrinkAppBasicContextComposition.CreateDefaultDocument());
|
|
AssetDatabase.CreateAsset(composition, CompositionPath);
|
|
AssetDatabase.SaveAssets();
|
|
AssetDatabase.Refresh();
|
|
Selection.activeObject = composition;
|
|
}
|
|
|
|
private static void EnsureAssets()
|
|
{
|
|
ShrinkAppEditorMenu.CreateSettingsAsset();
|
|
|
|
EnsureResourcesDirectory();
|
|
|
|
const string dataSaverSettingsPath = "Assets/Resources/ShrinkDataSaverSettings.asset";
|
|
if (AssetDatabase.LoadAssetAtPath<ScriptableObject>(dataSaverSettingsPath) == null)
|
|
{
|
|
var asset = ScriptableObject.CreateInstance("ShrinkDataSaverSettings");
|
|
if (asset == null)
|
|
throw new System.InvalidOperationException(
|
|
"Cannot create ShrinkDataSaverSettings. Ensure ShrinkDataSaver.Runtime is imported and compiled.");
|
|
|
|
AssetDatabase.CreateAsset(asset, dataSaverSettingsPath);
|
|
}
|
|
|
|
const string starterSettingsPath = "Assets/Resources/ShrinkAppBasicStarterSettings.asset";
|
|
if (AssetDatabase.LoadAssetAtPath<ShrinkAppBasicStarterSettings>(starterSettingsPath) == null)
|
|
{
|
|
var starterAsset = ScriptableObject.CreateInstance<ShrinkAppBasicStarterSettings>();
|
|
starterAsset.autoBindLoopbackTransport = true;
|
|
starterAsset.defaultCommandText = "starter status";
|
|
starterAsset.defaultLoopbackSessionId = 1;
|
|
starterAsset.logCommandOutputToConsole = true;
|
|
starterAsset.maxCommandOutputLines = 12;
|
|
AssetDatabase.CreateAsset(starterAsset, starterSettingsPath);
|
|
}
|
|
|
|
CreateDefaultCompositionAsset();
|
|
}
|
|
|
|
private static void EnsureResourcesDirectory()
|
|
{
|
|
const string resourcesDir = "Assets/Resources";
|
|
if (!AssetDatabase.IsValidFolder(resourcesDir))
|
|
AssetDatabase.CreateFolder("Assets", "Resources");
|
|
}
|
|
|
|
private static void BuildScene()
|
|
{
|
|
const string scenesDir = "Assets/Scenes";
|
|
if (!AssetDatabase.IsValidFolder(scenesDir))
|
|
AssetDatabase.CreateFolder("Assets", "Scenes");
|
|
|
|
var scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
|
|
|
|
new GameObject("Main Camera", typeof(Camera));
|
|
new GameObject("EventSystem", typeof(UnityEngine.EventSystems.EventSystem),
|
|
typeof(UnityEngine.EventSystems.StandaloneInputModule));
|
|
|
|
var canvasGo = new GameObject("Canvas", typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster));
|
|
var canvas = canvasGo.GetComponent<Canvas>();
|
|
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
|
|
var scaler = canvasGo.GetComponent<CanvasScaler>();
|
|
scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
|
|
scaler.referenceResolution = new Vector2(1920, 1080);
|
|
|
|
var panelGo = new GameObject("Panel", typeof(RectTransform), typeof(Image));
|
|
panelGo.transform.SetParent(canvasGo.transform, false);
|
|
var panelRect = panelGo.GetComponent<RectTransform>();
|
|
panelRect.sizeDelta = new Vector2(980f, 720f);
|
|
panelRect.anchoredPosition = Vector2.zero;
|
|
panelGo.GetComponent<Image>().color = new Color(0.12f, 0.15f, 0.2f, 0.92f);
|
|
|
|
var statusText = CreateText("StatusText", panelGo.transform, new Vector2(0f, 240f), new Vector2(840f, 120f),
|
|
"ShrinkApp Basic starter ready.");
|
|
statusText.alignment = TextAnchor.MiddleCenter;
|
|
var detailText = CreateText("DetailText", panelGo.transform, new Vector2(0f, 135f), new Vector2(840f, 140f),
|
|
"app=False, save=False, cmd=False, net=False");
|
|
detailText.alignment = TextAnchor.UpperLeft;
|
|
detailText.fontSize = 20;
|
|
var commandInputField = CreateInputField("CommandInput", panelGo.transform, new Vector2(0f, 20f),
|
|
new Vector2(520f, 54f), "starter status");
|
|
var outputText = CreateText("OutputText", panelGo.transform, new Vector2(0f, -250f), new Vector2(840f, 180f),
|
|
string.Empty);
|
|
outputText.alignment = TextAnchor.UpperLeft;
|
|
outputText.fontSize = 20;
|
|
outputText.horizontalOverflow = HorizontalWrapMode.Wrap;
|
|
outputText.verticalOverflow = VerticalWrapMode.Overflow;
|
|
var saveMetaText = CreateText("SaveMetaText", panelGo.transform, new Vector2(-280f, -430f), new Vector2(240f, 150f),
|
|
"No save slots found.");
|
|
saveMetaText.alignment = TextAnchor.UpperLeft;
|
|
saveMetaText.fontSize = 18;
|
|
var moduleText = CreateText("ModuleText", panelGo.transform, new Vector2(0f, -430f), new Vector2(240f, 150f),
|
|
"No started modules.");
|
|
moduleText.alignment = TextAnchor.UpperLeft;
|
|
moduleText.fontSize = 18;
|
|
var serviceText = CreateText("ServiceText", panelGo.transform, new Vector2(280f, -430f), new Vector2(240f, 150f),
|
|
"No registered services.");
|
|
serviceText.alignment = TextAnchor.UpperLeft;
|
|
serviceText.fontSize = 18;
|
|
var commandListText = CreateText("CommandListText", panelGo.transform, new Vector2(-280f, -600f), new Vector2(240f, 150f),
|
|
"Command service not ready.");
|
|
commandListText.alignment = TextAnchor.UpperLeft;
|
|
commandListText.fontSize = 18;
|
|
var networkText = CreateText("NetworkText", panelGo.transform, new Vector2(280f, -600f), new Vector2(240f, 150f),
|
|
"Network service not ready.");
|
|
networkText.alignment = TextAnchor.UpperLeft;
|
|
networkText.fontSize = 18;
|
|
|
|
var saveButton = CreateButton("SaveButton", panelGo.transform, new Vector2(-250f, -70f), "Save Slot 0");
|
|
var loadButton = CreateButton("LoadButton", panelGo.transform, new Vector2(0f, -70f), "Load Slot 0");
|
|
var commandButton = CreateButton("CommandButton", panelGo.transform, new Vector2(250f, -70f), "Run Command");
|
|
var loopbackButton = CreateButton("LoopbackButton", panelGo.transform, new Vector2(-250f, -165f), "Bind Loopback");
|
|
var disconnectButton = CreateButton("DisconnectLoopbackButton", panelGo.transform, new Vector2(0f, -165f), "Disconnect Loopback");
|
|
var refreshButton = CreateButton("RefreshButton", panelGo.transform, new Vector2(250f, -165f), "Refresh Status");
|
|
var clearOutputButton = CreateButton("ClearOutputButton", panelGo.transform, new Vector2(0f, -345f), "Clear Output");
|
|
|
|
var controller = panelGo.AddComponent<ShrinkAppBasicSampleController>();
|
|
var serializedObject = new SerializedObject(controller);
|
|
serializedObject.FindProperty("statusText").objectReferenceValue = statusText;
|
|
serializedObject.FindProperty("detailText").objectReferenceValue = detailText;
|
|
serializedObject.FindProperty("outputText").objectReferenceValue = outputText;
|
|
serializedObject.FindProperty("moduleText").objectReferenceValue = moduleText;
|
|
serializedObject.FindProperty("serviceText").objectReferenceValue = serviceText;
|
|
serializedObject.FindProperty("saveMetaText").objectReferenceValue = saveMetaText;
|
|
serializedObject.FindProperty("commandListText").objectReferenceValue = commandListText;
|
|
serializedObject.FindProperty("networkText").objectReferenceValue = networkText;
|
|
serializedObject.FindProperty("saveButton").objectReferenceValue = saveButton;
|
|
serializedObject.FindProperty("loadButton").objectReferenceValue = loadButton;
|
|
serializedObject.FindProperty("commandButton").objectReferenceValue = commandButton;
|
|
serializedObject.FindProperty("loopbackButton").objectReferenceValue = loopbackButton;
|
|
serializedObject.FindProperty("refreshButton").objectReferenceValue = refreshButton;
|
|
serializedObject.FindProperty("clearOutputButton").objectReferenceValue = clearOutputButton;
|
|
serializedObject.FindProperty("disconnectLoopbackButton").objectReferenceValue = disconnectButton;
|
|
serializedObject.FindProperty("commandInputField").objectReferenceValue = commandInputField;
|
|
serializedObject.ApplyModifiedPropertiesWithoutUndo();
|
|
|
|
EditorSceneManager.SaveScene(scene, "Assets/Scenes/ShrinkAppEntry.unity");
|
|
}
|
|
|
|
private static Text CreateText(string name, Transform parent, Vector2 anchoredPosition, Vector2 size, string text)
|
|
{
|
|
var go = new GameObject(name, typeof(RectTransform), typeof(Text));
|
|
go.transform.SetParent(parent, false);
|
|
var rect = go.GetComponent<RectTransform>();
|
|
rect.sizeDelta = size;
|
|
rect.anchoredPosition = anchoredPosition;
|
|
var label = go.GetComponent<Text>();
|
|
label.text = text;
|
|
label.font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
|
|
label.fontSize = 28;
|
|
label.color = Color.white;
|
|
return label;
|
|
}
|
|
|
|
private static Button CreateButton(string name, Transform parent, Vector2 anchoredPosition, string labelText)
|
|
{
|
|
var go = new GameObject(name, typeof(RectTransform), typeof(Image), typeof(Button));
|
|
go.transform.SetParent(parent, false);
|
|
var rect = go.GetComponent<RectTransform>();
|
|
rect.sizeDelta = new Vector2(220f, 72f);
|
|
rect.anchoredPosition = anchoredPosition;
|
|
go.GetComponent<Image>().color = new Color(0.24f, 0.45f, 0.75f, 1f);
|
|
|
|
var label = CreateText("Label", go.transform, Vector2.zero, new Vector2(220f, 72f), labelText);
|
|
label.alignment = TextAnchor.MiddleCenter;
|
|
label.resizeTextForBestFit = true;
|
|
label.resizeTextMinSize = 18;
|
|
label.resizeTextMaxSize = 28;
|
|
|
|
return go.GetComponent<Button>();
|
|
}
|
|
|
|
private static InputField CreateInputField(string name, Transform parent, Vector2 anchoredPosition, Vector2 size, string defaultText)
|
|
{
|
|
var go = new GameObject(name, typeof(RectTransform), typeof(Image), typeof(InputField));
|
|
go.transform.SetParent(parent, false);
|
|
var rect = go.GetComponent<RectTransform>();
|
|
rect.sizeDelta = size;
|
|
rect.anchoredPosition = anchoredPosition;
|
|
go.GetComponent<Image>().color = new Color(0.08f, 0.1f, 0.14f, 1f);
|
|
|
|
var text = CreateText("Text", go.transform, Vector2.zero, size, defaultText);
|
|
text.alignment = TextAnchor.MiddleLeft;
|
|
text.fontSize = 24;
|
|
text.color = Color.white;
|
|
var textRect = text.GetComponent<RectTransform>();
|
|
textRect.offsetMin = new Vector2(16f, 8f);
|
|
textRect.offsetMax = new Vector2(-16f, -8f);
|
|
|
|
var placeholder = CreateText("Placeholder", go.transform, Vector2.zero, size, "Enter command...");
|
|
placeholder.alignment = TextAnchor.MiddleLeft;
|
|
placeholder.fontSize = 24;
|
|
placeholder.color = new Color(1f, 1f, 1f, 0.35f);
|
|
var placeholderRect = placeholder.GetComponent<RectTransform>();
|
|
placeholderRect.offsetMin = new Vector2(16f, 8f);
|
|
placeholderRect.offsetMax = new Vector2(-16f, -8f);
|
|
|
|
var inputField = go.GetComponent<InputField>();
|
|
inputField.textComponent = text;
|
|
inputField.placeholder = placeholder;
|
|
inputField.text = defaultText;
|
|
return inputField;
|
|
}
|
|
}
|
|
}
|
|
#endif
|