Second commit
This commit is contained in:
commit
36840f3ad4
999 files changed
+61364
No files matched your search
@@ -0,0 +1,62 @@
|
||||
//
|
||||
// This file is part of the Tremble package by Tiny Goose.
|
||||
// Copyright (c) 2024-2026 TinyGoose Ltd., All Rights Reserved.
|
||||
//
|
||||
|
||||
namespace TinyGoose.Tremble.Editor
|
||||
{
|
||||
[ManualPage("Entities/Brush Entities")]
|
||||
public class BrushEntitiesPage : ManualPageBase
|
||||
{
|
||||
protected override void OnGUI()
|
||||
{
|
||||
Text(
|
||||
"Brush Entities are brushes (models/shapes) in the map, which you want to apply a",
|
||||
"MonoBehaviour script to. For example, a moving platform whose shape you design in",
|
||||
"your TrenchBroom. Or, a trigger box which kills players on entry (see below).");
|
||||
|
||||
Image("T_Manual_BrushEntity");
|
||||
|
||||
Text("The following properties are available:");
|
||||
|
||||
PropertyDescription("name",
|
||||
"The name of the entity in TrenchBroom.",
|
||||
"If omitted, we convert your MonoBehaviour name according to your Naming Convention in settings."
|
||||
);
|
||||
|
||||
PropertyDescription("category",
|
||||
"The menu category to show the entity under, for example 'solid'.",
|
||||
$"If omitted, we use the default prefix, '{FgdConsts.BRUSH_PREFIX}'."
|
||||
);
|
||||
|
||||
PropertyDescription("type",
|
||||
"Which brush type to use, which defines how the brush appears and how its collision",
|
||||
"functions."
|
||||
);
|
||||
|
||||
Foldout("Available Brush Types", () =>
|
||||
{
|
||||
PropertyDescription("Solid",
|
||||
"A Solid brush with a texture.",
|
||||
"Example: a moving platform.");
|
||||
PropertyDescription("Liquid",
|
||||
"A brush with a texture, but with a trigger collision instead of a solid one.",
|
||||
"Example: a volume of water/lava, which damages players when entering.");
|
||||
PropertyDescription("Trigger",
|
||||
"A completely invisible brush which has a trigger collision.",
|
||||
"Example: a volume which triggers an event when players walk into the area.");
|
||||
PropertyDescription("Invisible",
|
||||
"A completely invisible brush which has solid collision.",
|
||||
"Example: an invisible wall to stop players going out of bounds.");
|
||||
});
|
||||
|
||||
H1("Brush Entity Wizard");
|
||||
Text(
|
||||
"Tremble can guide you through creating the correct attribute code for your entity,",
|
||||
"to help you get up and running quickly."
|
||||
);
|
||||
|
||||
ActionBar_SingleAction("Build Brush Entity", () => GoToPage(typeof(BrushBuilderPage)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 468269cf35e449789a6062b8bcf8066f
|
||||
timeCreated: 1723201757
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 277805
|
||||
packageName: Tremble - Map Importer
|
||||
packageVersion: 1.11.1
|
||||
assetPath: Assets/Tremble/Editor/Manual/Pages/Entities/BrushEntitiesPage.cs
|
||||
uploadId: 939664
|
||||
@@ -0,0 +1,94 @@
|
||||
//
|
||||
// This file is part of the Tremble package by Tiny Goose.
|
||||
// Copyright (c) 2024-2026 TinyGoose Ltd., All Rights Reserved.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.Eventing.Reader;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TinyGoose.Tremble.Editor
|
||||
{
|
||||
public abstract class BuilderPageBase<TDataClass> : ManualPageBase
|
||||
where TDataClass : ScriptableObject
|
||||
{
|
||||
private TDataClass m_Sample;
|
||||
private SerializedObject m_SampleSO;
|
||||
private TrembleSyncSettings m_SyncSettings;
|
||||
|
||||
protected virtual bool HasInitialQuestions { get; } = false;
|
||||
|
||||
private bool m_DoneInitialQuestions = false;
|
||||
|
||||
protected TDataClass Sample => m_Sample;
|
||||
protected SerializedObject SampleSO => m_SampleSO;
|
||||
protected TrembleSyncSettings SyncSettings => m_SyncSettings;
|
||||
|
||||
protected override void OnInit()
|
||||
{
|
||||
m_Sample = ScriptableObject.CreateInstance<TDataClass>();
|
||||
m_SampleSO = new(m_Sample);
|
||||
|
||||
m_SyncSettings = TrembleSyncSettings.Get();
|
||||
}
|
||||
|
||||
protected sealed override void OnGUI()
|
||||
{
|
||||
if (HasInitialQuestions && !m_DoneInitialQuestions)
|
||||
{
|
||||
OnInitialQuestionsGUI();
|
||||
return;
|
||||
}
|
||||
|
||||
OnPrePropertiesGUI();
|
||||
m_SampleSO.Update();
|
||||
{
|
||||
OnPropertiesGUI();
|
||||
}
|
||||
m_SampleSO.ApplyModifiedPropertiesWithoutUndo();
|
||||
OnPostPropertiesGUI();
|
||||
}
|
||||
|
||||
protected virtual void OnInitialQuestionsGUI() { }
|
||||
protected virtual void OnPrePropertiesGUI() { }
|
||||
protected virtual void OnPropertiesGUI() { }
|
||||
protected virtual void OnPostPropertiesGUI() { }
|
||||
|
||||
protected void MarkInitialQuestionsDone() => m_DoneInitialQuestions = true;
|
||||
|
||||
protected bool RenderProperty(string propName, string title, string description, Type objectReferenceType = null, Action extraContent = null)
|
||||
{
|
||||
SerializedProperty prop = m_SampleSO.FindProperty(propName);
|
||||
uint hash = prop.GetHashOfContent();
|
||||
|
||||
GUILayout.BeginVertical(EditorStyles.helpBox);
|
||||
{
|
||||
if (prop.propertyType == SerializedPropertyType.ObjectReference)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
{
|
||||
EditorGUILayout.PrefixLabel(new GUIContent(title));
|
||||
prop.objectReferenceValue = EditorGUILayout.ObjectField(prop.objectReferenceValue, objectReferenceType ?? typeof(GameObject), allowSceneObjects: false);
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
|
||||
m_SampleSO.ApplyModifiedProperties();
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.PropertyField(prop, new GUIContent(title));
|
||||
}
|
||||
|
||||
GUILayout.Label(description, ManualStyles.Styles.Text);
|
||||
|
||||
extraContent?.Invoke();
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
|
||||
GUILayout.Space(5f);
|
||||
|
||||
return hash != prop.GetHashOfContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 41ce3b3d48ed40cbbf56dd2e637d5e9e
|
||||
timeCreated: 1723225850
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 277805
|
||||
packageName: Tremble - Map Importer
|
||||
packageVersion: 1.11.1
|
||||
assetPath: Assets/Tremble/Editor/Manual/Pages/Entities/BuilderPageBase.cs
|
||||
uploadId: 939664
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f14b29b54b344b7b0aa40f206a78b41
|
||||
timeCreated: 1723226299
|
||||
@@ -0,0 +1,158 @@
|
||||
//
|
||||
// This file is part of the Tremble package by Tiny Goose.
|
||||
// Copyright (c) 2024-2026 TinyGoose Ltd., All Rights Reserved.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TinyGoose.Tremble.Editor
|
||||
{
|
||||
[ManualPage("Entities/Brush Entity Builder", showInTree: false)]
|
||||
public class BrushBuilderPage : BuilderPageBase<BrushBuilderPage.SampleData>
|
||||
{
|
||||
public class SampleData : ScriptableObject
|
||||
{
|
||||
[SerializeField] internal string m_UnityName = "MyCoolBrush";
|
||||
[SerializeField] internal string m_MapName = "";
|
||||
[SerializeField] internal string m_Category = "";
|
||||
[SerializeField] internal BrushType m_Type = BrushType.Solid;
|
||||
}
|
||||
|
||||
protected override void OnPropertiesGUI()
|
||||
{
|
||||
RenderProperty(nameof(SampleData.m_UnityName),
|
||||
title: "MonoBehaviour Name",
|
||||
description: "The name of the main MonoBehaviour script for your brush entity.");
|
||||
|
||||
RenderProperty(nameof(SampleData.m_MapName),
|
||||
title: "TrenchBroom name",
|
||||
description: "(optional) The entity name to use in TrenchBroom. Leave this blank to use the default.");
|
||||
|
||||
RenderProperty(nameof(SampleData.m_Category),
|
||||
title: "Category Name",
|
||||
description: "(optional) The category/group name to use in TrenchBroom. Leave this blank to use the default.");
|
||||
|
||||
RenderProperty(nameof(SampleData.m_Type),
|
||||
title: "Brush Type",
|
||||
description: "The brush type to use. Defaults to 'Solid'.",
|
||||
extraContent: () =>
|
||||
{
|
||||
Foldout("Available Brush Types", () =>
|
||||
{
|
||||
PropertyDescription("Solid",
|
||||
"A Solid brush with a texture.",
|
||||
"Example: a moving platform.");
|
||||
PropertyDescription("Liquid",
|
||||
"A brush with a texture, but with a trigger collision instead of a solid one.",
|
||||
"Example: a volume of water/lava, which damages players when entering.");
|
||||
PropertyDescription("Trigger",
|
||||
"A completely invisible brush which has a trigger collision.",
|
||||
"Example: a volume which triggers an event when players walk into the area.");
|
||||
PropertyDescription("Invisible",
|
||||
"A completely invisible brush which has solid collision.",
|
||||
"Example: an invisible wall to stop players going out of bounds.");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
protected override void OnPostPropertiesGUI()
|
||||
{
|
||||
List<string> attributeParts = new(16);
|
||||
|
||||
if (!Sample.m_MapName.IsNullOrEmpty())
|
||||
{
|
||||
attributeParts.Add($"\"{Sample.m_MapName}\"");
|
||||
}
|
||||
|
||||
if (!Sample.m_Category.IsNullOrEmpty())
|
||||
{
|
||||
attributeParts.Add($"category: \"{Sample.m_Category}\"");
|
||||
}
|
||||
|
||||
if (Sample.m_Type != BrushType.Solid)
|
||||
{
|
||||
attributeParts.Add($"type: {nameof(BrushType)}.{Sample.m_Type}");
|
||||
}
|
||||
|
||||
string attrName = FormatAttributeName(typeof(BrushEntityAttribute));
|
||||
string attributeLine = attributeParts.Count == 0
|
||||
? $"[{attrName}]"
|
||||
: $"[{attrName}({String.Join(", ", attributeParts)})]";
|
||||
|
||||
string unityName = Sample.m_UnityName.IsNullOrEmpty()
|
||||
? "<error>"
|
||||
: Sample.m_UnityName;
|
||||
|
||||
string catName = Sample.m_Category.IsNullOrEmpty() ? FgdConsts.BRUSH_PREFIX : Sample.m_Category;
|
||||
string entName = Sample.m_MapName.IsNullOrEmpty() ? Sample.m_UnityName.ToNamingConvention(SyncSettings.TypeNamingConvention) : Sample.m_MapName;
|
||||
|
||||
HorizontalLine();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
{
|
||||
GUILayout.BeginVertical();
|
||||
{
|
||||
H3("Create New Entity");
|
||||
|
||||
string code =
|
||||
"// Generated by Tremble v1.7.0\n" +
|
||||
$"// Brush entity '{catName}_{entName}'\n" +
|
||||
"\n" +
|
||||
"using UnityEngine;\n" +
|
||||
$"using {nameof(TinyGoose)}.{nameof(Tremble)};\n" +
|
||||
"\n" +
|
||||
attributeLine + "\n" +
|
||||
$"public class {unityName} : MonoBehaviour\n" +
|
||||
"{\n" +
|
||||
" // Your cool class here ;)\n" +
|
||||
"}";
|
||||
|
||||
CodeWithHeaderNoCopy($"Full source for {unityName}.cs", code);
|
||||
|
||||
ActionBar_SingleAction("Save to new MonoBehaviour class", () =>
|
||||
{
|
||||
string assetsFolder = Path.Combine(Directory.GetCurrentDirectory(), "Assets");
|
||||
|
||||
string filename = EditorUtility.SaveFilePanel($"Choose where to save {unityName}", assetsFolder, $"{unityName}.cs", "cs");
|
||||
if (!filename.IsNullOrEmpty())
|
||||
{
|
||||
File.WriteAllText(filename, code);
|
||||
EditorCompileUtil.CompileThen(typeof(BrushBuilderPage), nameof(OnPostCompile));
|
||||
}
|
||||
});
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
|
||||
GUILayout.Label("-or-", EditorStyles.centeredGreyMiniLabel, GUILayout.ExpandHeight(true));
|
||||
|
||||
GUILayout.BeginVertical();
|
||||
{
|
||||
H3("Add to existing MonoBehaviour");
|
||||
CodeWithHeaderNoCopy("Attribute line only (for existing MonoBehaviour)", attributeLine);
|
||||
ActionBar_SingleAction("Copy to clipboard", () => EditorGUIUtility.systemCopyBuffer = attributeLine);
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
private static void OnPostCompile()
|
||||
{
|
||||
string message = TrenchBroomUtil.IsTrenchBroomRunning
|
||||
? "Be sure to press F6 in TrenchBroom to reload entity definitions, so that your new entity appears!"
|
||||
: "All done!";
|
||||
EditorUtility.DisplayDialog("MonoBehaviour created!", message, "Great!");
|
||||
|
||||
ManualWindow mw = EditorWindow.GetWindow<ManualWindow>();
|
||||
if (mw)
|
||||
{
|
||||
mw.GoToPage(typeof(BrushEntitiesPage));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a19bc95fc7d74231b15345de8d617a86
|
||||
timeCreated: 1723368005
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 277805
|
||||
packageName: Tremble - Map Importer
|
||||
packageVersion: 1.11.1
|
||||
assetPath: Assets/Tremble/Editor/Manual/Pages/Entities/Builders/BrushBuilderPage.cs
|
||||
uploadId: 939664
|
||||
@@ -0,0 +1,163 @@
|
||||
//
|
||||
// This file is part of the Tremble package by Tiny Goose.
|
||||
// Copyright (c) 2024-2026 TinyGoose Ltd., All Rights Reserved.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TinyGoose.Tremble.Editor
|
||||
{
|
||||
[ManualPage("Entities/Point Entity Builder", showInTree: false)]
|
||||
public class PointBuilderPage : BuilderPageBase<PointBuilderPage.SampleData>
|
||||
{
|
||||
public class SampleData : ScriptableObject
|
||||
{
|
||||
[SerializeField] internal string m_UnityName = "MyCoolPoint";
|
||||
[SerializeField] internal string m_MapName = "";
|
||||
[SerializeField] internal string m_Category = "";
|
||||
[SerializeField] internal Color m_Colour = Color.white;
|
||||
[SerializeField] internal float m_Size = 0.25f;
|
||||
[SerializeField] internal Texture2D m_Sprite;
|
||||
}
|
||||
|
||||
protected override void OnPropertiesGUI()
|
||||
{
|
||||
RenderProperty(nameof(SampleData.m_UnityName),
|
||||
title: "MonoBehaviour Name",
|
||||
description: "The name of the main MonoBehaviour script of your point entity.");
|
||||
|
||||
RenderProperty(nameof(SampleData.m_MapName),
|
||||
title: "TrenchBroom name",
|
||||
description: "(optional) The entity name to use in TrenchBroom. Leave this blank to use the default.");
|
||||
|
||||
RenderProperty(nameof(SampleData.m_Category),
|
||||
title: "Category Name",
|
||||
description: "(optional) The category/group name to use in TrenchBroom. Leave this blank to use the default.");
|
||||
|
||||
RenderProperty(nameof(SampleData.m_Colour),
|
||||
title: "Preview Colour",
|
||||
description: "The colour of preview cube to represent this Point entity in TrenchBroom.");
|
||||
|
||||
RenderProperty(nameof(SampleData.m_Size),
|
||||
title: "Preview Size",
|
||||
description: "The size of preview cube to represent this Point entity in TrenchBroom.");
|
||||
|
||||
RenderProperty(nameof(SampleData.m_Sprite),
|
||||
title: "Preview Sprite",
|
||||
description: "(optional) A sprite to use to represent this Point entity in TrenchBroom.",
|
||||
objectReferenceType: typeof(Texture2D));
|
||||
}
|
||||
|
||||
protected override void OnPostPropertiesGUI()
|
||||
{
|
||||
List<string> attributeParts = new(16);
|
||||
|
||||
if (!Sample.m_MapName.IsNullOrEmpty())
|
||||
{
|
||||
attributeParts.Add($"\"{Sample.m_MapName}\"");
|
||||
}
|
||||
|
||||
if (!Sample.m_Category.IsNullOrEmpty())
|
||||
{
|
||||
attributeParts.Add($"category: \"{Sample.m_Category}\"");
|
||||
}
|
||||
|
||||
if (Sample.m_Sprite)
|
||||
{
|
||||
attributeParts.Add($"sprite: \"{Sample.m_Sprite.name}\"");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Sample.m_Colour != Color.white)
|
||||
{
|
||||
attributeParts.Add($"colour: \"{Sample.m_Colour.ToStringInvariant()}\"");
|
||||
}
|
||||
|
||||
if (Sample.m_Size != 0.25f)
|
||||
{
|
||||
attributeParts.Add($"size: {Sample.m_Size}");
|
||||
}
|
||||
}
|
||||
|
||||
string attrName = FormatAttributeName(typeof(PointEntityAttribute));
|
||||
|
||||
string attributeLine = attributeParts.Count == 0
|
||||
? $"[{attrName}]"
|
||||
: $"[{attrName}({String.Join(", ", attributeParts)})]";
|
||||
|
||||
string unityName = Sample.m_UnityName.IsNullOrEmpty()
|
||||
? "<error>"
|
||||
: Sample.m_UnityName;
|
||||
|
||||
string catName = Sample.m_Category.IsNullOrEmpty() ? FgdConsts.POINT_PREFIX : Sample.m_Category;
|
||||
string entName = Sample.m_MapName.IsNullOrEmpty() ? Sample.m_UnityName.ToNamingConvention(SyncSettings.TypeNamingConvention) : Sample.m_MapName;
|
||||
HorizontalLine();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
{
|
||||
GUILayout.BeginVertical();
|
||||
{
|
||||
H3("Create New Entity");
|
||||
|
||||
string code =
|
||||
"// Generated by Tremble v1.7.0\n" +
|
||||
$"// Point entity '{catName}_{entName}'\n" +
|
||||
"\n" +
|
||||
"using UnityEngine;\n" +
|
||||
$"using {nameof(TinyGoose)}.{nameof(Tremble)};\n" +
|
||||
"\n" +
|
||||
attributeLine + "\n" +
|
||||
$"public class {unityName} : MonoBehaviour\n" +
|
||||
"{\n" +
|
||||
" // Your cool class here ;)\n" +
|
||||
"}";
|
||||
|
||||
CodeWithHeaderNoCopy($"Full source for {unityName}.cs", code);
|
||||
|
||||
ActionBar_SingleAction("Save to new MonoBehaviour class", () =>
|
||||
{
|
||||
string assetsFolder = Path.Combine(Directory.GetCurrentDirectory(), "Assets");
|
||||
|
||||
string filename = EditorUtility.SaveFilePanel($"Choose where to save {unityName}", assetsFolder, $"{unityName}.cs", "cs");
|
||||
if (!filename.IsNullOrEmpty())
|
||||
{
|
||||
File.WriteAllText(filename, code);
|
||||
EditorCompileUtil.CompileThen(typeof(PointBuilderPage), nameof(OnPostCompile));
|
||||
}
|
||||
});
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
|
||||
GUILayout.Label("-or-", EditorStyles.centeredGreyMiniLabel, GUILayout.ExpandHeight(true));
|
||||
|
||||
GUILayout.BeginVertical();
|
||||
{
|
||||
H3("Add to existing MonoBehaviour");
|
||||
CodeWithHeaderNoCopy("Attribute line only (for existing MonoBehaviour)", attributeLine);
|
||||
ActionBar_SingleAction("Copy to clipboard", () => EditorGUIUtility.systemCopyBuffer = attributeLine);
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
private static void OnPostCompile()
|
||||
{
|
||||
string message = TrenchBroomUtil.IsTrenchBroomRunning
|
||||
? "Be sure to press F6 in TrenchBroom to reload entity definitions, so that your new entity appears!"
|
||||
: "All done!";
|
||||
EditorUtility.DisplayDialog("MonoBehaviour created!", message, "Great!");
|
||||
|
||||
ManualWindow mw = EditorWindow.GetWindow<ManualWindow>();
|
||||
if (mw)
|
||||
{
|
||||
mw.GoToPage(typeof(PointEntitiesPage));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d7c600b3e6a34d8a86cdaab529cef411
|
||||
timeCreated: 1723368625
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 277805
|
||||
packageName: Tremble - Map Importer
|
||||
packageVersion: 1.11.1
|
||||
assetPath: Assets/Tremble/Editor/Manual/Pages/Entities/Builders/PointBuilderPage.cs
|
||||
uploadId: 939664
|
||||
@@ -0,0 +1,592 @@
|
||||
//
|
||||
// This file is part of the Tremble package by Tiny Goose.
|
||||
// Copyright (c) 2024-2026 TinyGoose Ltd., All Rights Reserved.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace TinyGoose.Tremble.Editor
|
||||
{
|
||||
[ManualPage("Entities/Prefab Entity Builder", showInTree: false)]
|
||||
public class PrefabBuilderPage : BuilderPageBase<PrefabBuilderPage.SampleData>
|
||||
{
|
||||
private static readonly Dictionary<Type, string> s_ScriptFileLookup = new();
|
||||
|
||||
protected override bool HasInitialQuestions => true;
|
||||
|
||||
private bool m_MonoBehaviourListDirty = false;
|
||||
private readonly List<Type> m_CandidateTypes = new();
|
||||
|
||||
private readonly TrembleFieldConverterCollection m_FieldConverterCollection = new();
|
||||
|
||||
private Type m_UnityScriptType;
|
||||
private string m_NewUnityScriptName;
|
||||
private Action m_ResolutionAction;
|
||||
|
||||
private bool m_IsOnlyAddingSpawnablePrefab = false;
|
||||
|
||||
private bool m_IsAlreadyTrembleSpawnable = false;
|
||||
private bool m_IsAlreadyPrefabEntity = false;
|
||||
private bool m_IsMap = false;
|
||||
|
||||
private bool IsNewScript => !m_NewUnityScriptName.IsNullOrEmpty();
|
||||
private string ScriptName => m_UnityScriptType?.Name ?? m_NewUnityScriptName;
|
||||
|
||||
public class SampleData : ScriptableObject
|
||||
{
|
||||
[SerializeField] internal GameObject m_BasePrefab;
|
||||
[SerializeField] internal bool m_WantsData;
|
||||
|
||||
[SerializeField] internal string m_Category = "";
|
||||
[SerializeField] internal GameObject[] m_ExcludedPrefabs = Array.Empty<GameObject>();
|
||||
[SerializeField] internal GameObject[] m_IncludedPrefabs = Array.Empty<GameObject>();
|
||||
[SerializeField] internal bool m_OnlyVariants = false;
|
||||
}
|
||||
|
||||
protected override void OnInitialQuestionsGUI()
|
||||
{
|
||||
Text("Please select a prefab that you want to use in Tremble!");
|
||||
|
||||
m_MonoBehaviourListDirty = RenderProperty(nameof(SampleData.m_BasePrefab),
|
||||
title: "Target Prefab",
|
||||
description: "The prefab to use");
|
||||
|
||||
RenderProperty(nameof(SampleData.m_WantsData),
|
||||
title: "I want to add data",
|
||||
description: "Whether to allow setting fields on the prefab from TrenchBroom. e.g. "+
|
||||
"variables such as Health, Colour, etc?");
|
||||
|
||||
if (Sample.m_BasePrefab)
|
||||
{
|
||||
if (m_MonoBehaviourListDirty)
|
||||
{
|
||||
Type[] monoBehaviours = Sample.m_BasePrefab
|
||||
.GetComponents<MonoBehaviour>()
|
||||
.Select(m => m.GetType())
|
||||
.ToArray();
|
||||
|
||||
m_CandidateTypes.Clear();
|
||||
m_CandidateTypes.AddRange(monoBehaviours
|
||||
.Where(t => t != typeof(TrembleSpawnablePrefab)));
|
||||
|
||||
m_IsAlreadyTrembleSpawnable = monoBehaviours.Contains(typeof(TrembleSpawnablePrefab));
|
||||
m_IsMap = monoBehaviours.Contains(typeof(MapDocument));
|
||||
m_IsAlreadyPrefabEntity = !m_IsAlreadyTrembleSpawnable && monoBehaviours.Any(t => t.HasCustomAttribute<PrefabEntityAttribute>());
|
||||
}
|
||||
|
||||
if (m_IsMap)
|
||||
{
|
||||
Text("Ha! No, that's a map prefab. We better not.");
|
||||
}
|
||||
else if (m_IsAlreadyPrefabEntity)
|
||||
{
|
||||
Text("Well, that's already spawnable in TrenchBroom. Try another prefab!");
|
||||
}
|
||||
else if (m_CandidateTypes.Count == 0)
|
||||
{
|
||||
if (m_IsAlreadyTrembleSpawnable)
|
||||
{
|
||||
Callout("Note, this prefab already has a TrembleSpawnablePrefab component",
|
||||
"allowing it to be spawned from TrenchBroom - but without field support.",
|
||||
"Converting this to a PrefabEntity will remove the TrembleSpawnablePrefab component!");
|
||||
}
|
||||
|
||||
if (m_IsAlreadyTrembleSpawnable)
|
||||
{
|
||||
if (Sample.m_WantsData)
|
||||
{
|
||||
Resolution("Create a new MonoBehaviour to use - this allows",
|
||||
"you to add fields which can be set in TrenchBroom",
|
||||
"- in order to be able to set data (i.e. Health, Type, etc).");
|
||||
ActionBar_SingleAction("Create New MonoBehaviour", () =>
|
||||
{
|
||||
m_NewUnityScriptName = GetScriptNameFromPrefab(Sample.m_BasePrefab);
|
||||
|
||||
if (Sample.m_BasePrefab.TryGetComponent(out TrembleSpawnablePrefab tsp))
|
||||
{
|
||||
Sample.m_Category = tsp.Category;
|
||||
Sample.m_OnlyVariants = tsp.OnlyVariants;
|
||||
}
|
||||
|
||||
SetResolution(Resolve_CreateNewClassAndAdd);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Text("Well, that's already spawnable in TrenchBroom. Tick the box above",
|
||||
"to add data using a [PrefabEntity].");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Sample.m_WantsData)
|
||||
{
|
||||
Resolution("Create a new MonoBehaviour to use - this allows",
|
||||
"you to add fields which can be set in TrenchBroom",
|
||||
"- in order to be able to set data (i.e. Health, Type, etc).");
|
||||
ActionBar_SingleAction("Create New MonoBehaviour", () =>
|
||||
{
|
||||
m_NewUnityScriptName = GetScriptNameFromPrefab(Sample.m_BasePrefab);
|
||||
|
||||
if (Sample.m_BasePrefab.TryGetComponent(out TrembleSpawnablePrefab tsp))
|
||||
{
|
||||
Sample.m_Category = tsp.Category;
|
||||
Sample.m_OnlyVariants = tsp.OnlyVariants;
|
||||
}
|
||||
|
||||
SetResolution(Resolve_CreateNewClassAndAdd);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Resolution("Add a 'TrembleSpawnablePrefab' component - this",
|
||||
"only allows you to spawn this prefab without being able to",
|
||||
"set any data on it.");
|
||||
|
||||
ActionBar_SingleAction("Add TrembleSpawnablePrefab component", () =>
|
||||
{
|
||||
m_IsOnlyAddingSpawnablePrefab = true;
|
||||
SetResolution(Resolve_AddTrembleSpawnablePrefab);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_IsAlreadyTrembleSpawnable)
|
||||
{
|
||||
// Already spawnable, but no candidates for [PrefabEntity] - make a new code class
|
||||
if (Sample.m_WantsData)
|
||||
{
|
||||
Resolution("Upgrade to a [PrefabEntity] - this allows",
|
||||
"you to add fields which can be set in TrenchBroom",
|
||||
"- in order to be able to set data (i.e. Health, Type, etc).");
|
||||
|
||||
foreach (Type type in m_CandidateTypes)
|
||||
{
|
||||
Bullet(type.Name);
|
||||
ActionBar_SingleAction($"Add [PrefabEntity] to {type.Name}", () =>
|
||||
{
|
||||
m_UnityScriptType = type;
|
||||
|
||||
if (Sample.m_BasePrefab.TryGetComponent(out TrembleSpawnablePrefab tsp))
|
||||
{
|
||||
Sample.m_Category = tsp.Category;
|
||||
Sample.m_OnlyVariants = tsp.OnlyVariants;
|
||||
}
|
||||
|
||||
SetResolution(Resolve_AddPrefabEntityAttribute);
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Text("This is already a TrembleSpawnablePrefab. Unless you want to add data,",
|
||||
"you don't need to do anything!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Sample.m_WantsData)
|
||||
{
|
||||
if (m_CandidateTypes.Count == 1)
|
||||
{
|
||||
Type type = m_CandidateTypes[0];
|
||||
|
||||
Resolution($"You can add a [PrefabEntity] attribute to {type.Name} on this",
|
||||
"prefab. This will enable setting the following fields:");
|
||||
|
||||
Indent(() =>
|
||||
{
|
||||
foreach (string fieldName in GetFieldNames(type))
|
||||
{
|
||||
Bullet(fieldName);
|
||||
}
|
||||
});
|
||||
|
||||
ActionBar_SingleAction($"Add [PrefabEntity]", () =>
|
||||
{
|
||||
m_UnityScriptType = type;
|
||||
SetResolution(Resolve_AddPrefabEntityAttribute);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Resolution("This prefab has MonoBehaviours which can be set to be a",
|
||||
"[PrefabEntity]. Select which one to add this attribute to.");
|
||||
|
||||
foreach (Type type in m_CandidateTypes)
|
||||
{
|
||||
string[] fieldNames = GetFieldNames(type);
|
||||
|
||||
string fields = (fieldNames is { Length: > 0 }) ? String.Join(", ", fieldNames) : "no fields";
|
||||
Bullet($"{type.Name} ({fields})");
|
||||
|
||||
ActionBar_SingleAction($"Add [PrefabEntity] to {type.Name}", () =>
|
||||
{
|
||||
m_UnityScriptType = type;
|
||||
SetResolution(Resolve_AddPrefabEntityAttribute);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Resolution("Simply add a TrembleSpawnablePrefab component to it, which will",
|
||||
"allow you to spawn the prefab in TrenchBroom, but not allow you to set any",
|
||||
"data on it.");
|
||||
ActionBar_SingleAction("Add TrembleSpawnablePrefab component", () =>
|
||||
{
|
||||
m_IsOnlyAddingSpawnablePrefab = true;
|
||||
SetResolution(Resolve_AddTrembleSpawnablePrefab);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string[] GetFieldNames(Type type)
|
||||
{
|
||||
List<Type> soTypes= new();
|
||||
FgdClass dummyClass = new(FgdClassType.Point, type.Name, type.Name);
|
||||
TrembleSync.AddExposedFieldsToEntity(type, dummyClass, m_FieldConverterCollection, soTypes);
|
||||
|
||||
// Gather spawnflags
|
||||
NamingConvention spawnFlagNaming = TrembleSyncSettings.Get().SpawnFlagNamingConvention;
|
||||
|
||||
IEnumerable<string> spawnFlagNames = dummyClass.AllSpawnFlags
|
||||
.Select(f =>
|
||||
{
|
||||
string name = f.FieldName.ToNamingConvention(spawnFlagNaming);
|
||||
if (spawnFlagNaming == NamingConvention.HumanFriendly)
|
||||
{
|
||||
name += "?";
|
||||
}
|
||||
|
||||
return $"{name} (Boolean)";
|
||||
});
|
||||
|
||||
return dummyClass.AllFields
|
||||
.Select(f => $"{f.FieldName} ({f.FriendlyTypeName})")
|
||||
.Concat(spawnFlagNames)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
protected override void OnPropertiesGUI()
|
||||
{
|
||||
H2("Optional Extras");
|
||||
|
||||
RenderProperty(nameof(SampleData.m_Category),
|
||||
title: "Category Name",
|
||||
description: "(optional) The category/group name to use in TrenchBroom. Leave this blank to use the default.");
|
||||
|
||||
Foldout("(optional) Include/Exclude specific Prefabs?", () =>
|
||||
{
|
||||
if (!m_IsOnlyAddingSpawnablePrefab)
|
||||
{
|
||||
Text("By default, any other prefabs containing your MonoBehaviour will be exported.");
|
||||
Text("Instead, you can choose to explicitly whitelist prefab(s) here.");
|
||||
Text("Or, you can choose to blacklist certain prefab(s) here.");
|
||||
|
||||
RenderProperty(nameof(SampleData.m_IncludedPrefabs),
|
||||
title: "Included Prefabs",
|
||||
description: $"A whitelist of the ONLY prefab(s) to include, even though others may include your {ScriptName} MonoBehaviour?");
|
||||
|
||||
RenderProperty(nameof(SampleData.m_ExcludedPrefabs),
|
||||
title: "Excluded Prefabs",
|
||||
description: $"A blacklist of any prefab(s) to ignore, even though they include your {ScriptName} MonoBehaviour?");
|
||||
}
|
||||
|
||||
RenderProperty(nameof(SampleData.m_OnlyVariants),
|
||||
title: "Only Prefab Variants?",
|
||||
description: "Whether to only export VARIANTS of the prefab(s) found?");
|
||||
});
|
||||
}
|
||||
|
||||
protected override void OnPostPropertiesGUI()
|
||||
{
|
||||
string catName = Sample.m_Category.IsNullOrEmpty() ? FgdConsts.PREFAB_PREFIX : Sample.m_Category;
|
||||
//string entName = Sample.m_UnityName.ToNamingConvention(SyncSettings.TypeNamingConvention);
|
||||
string fullEntName = $"{catName}_{Sample.m_BasePrefab.name}";
|
||||
|
||||
if (m_IsOnlyAddingSpawnablePrefab)
|
||||
{
|
||||
H2("Tremble Spawnable Prefab Details");
|
||||
PropertyDescription("Prefab Name", labelWidth: 250f, Sample.m_BasePrefab.name);
|
||||
PropertyDescription("Exported TrenchBroom Name", labelWidth: 250f, fullEntName);
|
||||
}
|
||||
else
|
||||
{
|
||||
H2("C# Code");
|
||||
Text($"This is the code that will be used for {Sample.m_BasePrefab.name} if you click Apply below. You don't need to copy",
|
||||
"it manually (unless you want to!)");
|
||||
CodeWithHeader($"C# Script: {ScriptName}.cs (for TrenchBroom Prefab entity '{fullEntName}')", GenerateFullCodeSnippet());
|
||||
}
|
||||
|
||||
Space();
|
||||
|
||||
GUI.color = Color.green;
|
||||
LargeButton("Apply & Finish!", Resolve);
|
||||
GUI.color = Color.white;
|
||||
}
|
||||
|
||||
private void Resolution(params string[] resolution)
|
||||
{
|
||||
HorizontalLine();
|
||||
|
||||
H1("Action to take");
|
||||
Text(resolution);
|
||||
}
|
||||
|
||||
private string GetAttributeLine()
|
||||
{
|
||||
List<string> attributeParts = new(16);
|
||||
|
||||
if (!Sample.m_Category.IsNullOrEmpty())
|
||||
{
|
||||
attributeParts.Add($"category: \"{Sample.m_Category}\"");
|
||||
}
|
||||
|
||||
if (TryFormatPrefabNames("excludePrefab", Sample.m_ExcludedPrefabs, out string excludePart))
|
||||
{
|
||||
attributeParts.Add(excludePart);
|
||||
}
|
||||
|
||||
if (TryFormatPrefabNames("includePrefab", Sample.m_IncludedPrefabs, out string includePart))
|
||||
{
|
||||
attributeParts.Add(includePart);
|
||||
}
|
||||
|
||||
if (Sample.m_OnlyVariants)
|
||||
{
|
||||
attributeParts.Add("onlyVariants: true");
|
||||
}
|
||||
|
||||
string attrName = FormatAttributeName(typeof(PrefabEntityAttribute));
|
||||
|
||||
return attributeParts.Count == 0
|
||||
? $"[{attrName}]"
|
||||
: $"[{attrName}({String.Join(", ", attributeParts)})]";
|
||||
}
|
||||
|
||||
private string GenerateFullCodeSnippet()
|
||||
{
|
||||
return
|
||||
"using UnityEngine;\n" +
|
||||
$"using {nameof(TinyGoose)}.{nameof(Tremble)};\n" +
|
||||
"\n" +
|
||||
GetAttributeLine() + "\n" +
|
||||
$"public class {ScriptName} : MonoBehaviour\n" +
|
||||
"{\n" +
|
||||
(IsNewScript ? $" // Your new {ScriptName} class contents ;)" : $" // (your existing {ScriptName} code)") + "\n" +
|
||||
"}";
|
||||
}
|
||||
|
||||
private bool TryFormatPrefabNames(string propertyName, GameObject[] prefabs, out string formatted)
|
||||
{
|
||||
GameObject[] filteredPrefabs = prefabs.Where(p => p).ToArray();
|
||||
|
||||
switch (filteredPrefabs.Length)
|
||||
{
|
||||
case 1:
|
||||
formatted = $"{propertyName}: \"{filteredPrefabs[0].name}\"";
|
||||
return true;
|
||||
case > 1:
|
||||
{
|
||||
string prefabList = String.Join("\", \"", filteredPrefabs.Select(p => p.name));
|
||||
formatted = $"{propertyName}s: \"{prefabList}\"";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
formatted = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
private void SetResolution(Action resolutionAction)
|
||||
{
|
||||
m_ResolutionAction = resolutionAction;
|
||||
MarkInitialQuestionsDone();
|
||||
}
|
||||
|
||||
private void Resolve()
|
||||
{
|
||||
m_ResolutionAction.Invoke();
|
||||
GoToPage(typeof(PrefabEntitiesPage));
|
||||
}
|
||||
|
||||
private void Resolve_AddTrembleSpawnablePrefab()
|
||||
{
|
||||
Sample.m_BasePrefab.AddComponent<TrembleSpawnablePrefab>().Modify(so =>
|
||||
{
|
||||
so.FindBackedProperty(nameof(TrembleSpawnablePrefab.OnlyVariants)).boolValue = Sample.m_OnlyVariants;
|
||||
so.FindBackedProperty(nameof(TrembleSpawnablePrefab.Category)).stringValue = Sample.m_Category;
|
||||
});
|
||||
|
||||
EditorUtility.SetDirty(Sample.m_BasePrefab);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
EditorApplication.delayCall += TrembleEditorAPI.SyncToTrenchBroom;
|
||||
|
||||
ShowCompleteDialog(
|
||||
title: "TrembleSpawnablePrefab component added!",
|
||||
message: $"{Sample.m_BasePrefab.name} now has a Tremble Spawnable Prefab component and should be available from TrenchBroom.");
|
||||
}
|
||||
|
||||
private void Resolve_CreateNewClassAndAdd()
|
||||
{
|
||||
// Write code and compile
|
||||
string assetsFolder = Path.Combine(Directory.GetCurrentDirectory(), "Assets");
|
||||
|
||||
string scriptFilePath = EditorUtility.SaveFilePanel($"Choose where to save {ScriptName}", assetsFolder, $"{ScriptName}.cs", "cs");
|
||||
if (scriptFilePath.IsNullOrEmpty())
|
||||
return;
|
||||
|
||||
File.WriteAllText(scriptFilePath, GenerateFullCodeSnippet());
|
||||
|
||||
EditorCompileUtil.CompileThen(typeof(PrefabBuilderPage), nameof(OnPostCompile_AddNewScript),
|
||||
ScriptName, AssetDatabase.GetAssetPath(Sample.m_BasePrefab));
|
||||
}
|
||||
|
||||
private void Resolve_AddPrefabEntityAttribute()
|
||||
{
|
||||
string scriptFileName = GetScriptFilename(m_UnityScriptType);
|
||||
if (scriptFileName.IsNullOrEmpty())
|
||||
{
|
||||
EditorUtility.DisplayDialog(
|
||||
title: "Uh-oh!",
|
||||
message: $"Tremble could not find the source file for {ScriptName}.",
|
||||
"Oh no!");
|
||||
return;
|
||||
}
|
||||
|
||||
bool prefabEntityWasAdded = false;
|
||||
bool usingWasAdded = false;
|
||||
|
||||
string[] lines = File.ReadAllLines(scriptFileName);
|
||||
List<string> outLines = new(lines.Length+2);
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (!usingWasAdded && !line.ContainsInvariant("using", caseSensitive: true))
|
||||
{
|
||||
outLines.Add("using TinyGoose.Tremble;");
|
||||
usingWasAdded = true;
|
||||
}
|
||||
|
||||
if (line.ContainsInvariant($"class {ScriptName}", caseSensitive: true))
|
||||
{
|
||||
prefabEntityWasAdded = true;
|
||||
outLines.Add($"\t{GetAttributeLine()}");
|
||||
}
|
||||
|
||||
outLines.Add(line);
|
||||
}
|
||||
|
||||
if (!prefabEntityWasAdded)
|
||||
{
|
||||
EditorUtility.DisplayDialog(
|
||||
title: "Uh-oh!",
|
||||
message: $"Tremble could not find the class {ScriptName} in the source file {Path.GetFileName(scriptFileName)}.",
|
||||
"Oh no!");
|
||||
return;
|
||||
}
|
||||
|
||||
File.WriteAllLines(scriptFileName, outLines);
|
||||
|
||||
EditorCompileUtil.CompileThen(typeof(PrefabBuilderPage), nameof(OnPostCompile_AddAttribute), ScriptName);
|
||||
}
|
||||
|
||||
private static string GetScriptNameFromPrefab(GameObject prefab)
|
||||
{
|
||||
string newName = prefab.name;
|
||||
if (newName.StartsWithInvariant("P_", caseSensitive: true))
|
||||
return newName.Substring(2);
|
||||
|
||||
StringBuilder finalName = new(newName.Length);
|
||||
foreach (char c in newName)
|
||||
{
|
||||
if (c is '-')
|
||||
{
|
||||
// Swap characters
|
||||
finalName.Append('_');
|
||||
}
|
||||
else if (c is ' ')
|
||||
{
|
||||
// Omit characters
|
||||
}
|
||||
else
|
||||
{
|
||||
// Allowed characters
|
||||
finalName.Append(c);
|
||||
}
|
||||
}
|
||||
|
||||
return finalName.ToString();
|
||||
}
|
||||
|
||||
private static string GetScriptFilename(Type monoBehaviourType)
|
||||
{
|
||||
if (s_ScriptFileLookup.TryGetValue(monoBehaviourType, out string existingPath))
|
||||
return existingPath;
|
||||
|
||||
foreach (string path in AssetDatabase.GetAllAssetPaths())
|
||||
{
|
||||
// Check if the file name matches exactly (without the full path)
|
||||
if (Path.GetFileNameWithoutExtension(path).EqualsInvariant(monoBehaviourType.Name))
|
||||
{
|
||||
s_ScriptFileLookup[monoBehaviourType] = path;
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void ShowCompleteDialog(string title, string message)
|
||||
{
|
||||
if (TrenchBroomUtil.IsTrenchBroomRunning)
|
||||
{
|
||||
message += "\n\n Note: Press F6 inside TrenchBroom to refresh Entity Definitions for it to appear!";
|
||||
}
|
||||
|
||||
EditorUtility.DisplayDialog(title, message, "Great!");
|
||||
}
|
||||
|
||||
private static void OnPostCompile_AddAttribute(string scriptName)
|
||||
{
|
||||
TrembleEditorAPI.SyncToTrenchBroom();
|
||||
|
||||
ShowCompleteDialog(
|
||||
title: "[PrefabEntity] attribute added!",
|
||||
message: $"{scriptName} now has a [PrefabEntity] attribute and should be available from TrenchBroom.");
|
||||
}
|
||||
|
||||
private static void OnPostCompile_AddNewScript(string scriptName, string prefabPath)
|
||||
{
|
||||
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
|
||||
|
||||
Type newComponentType = Unsupported.GetTypeFromFullName(scriptName);
|
||||
prefab.AddComponent(newComponentType);
|
||||
|
||||
foreach (TrembleSpawnablePrefab tsp in prefab.GetComponents<TrembleSpawnablePrefab>())
|
||||
{
|
||||
Component.DestroyImmediate(tsp, true);
|
||||
}
|
||||
|
||||
EditorUtility.SetDirty(prefab);
|
||||
AssetDatabase.SaveAssets();
|
||||
|
||||
// Now sync
|
||||
EditorApplication.delayCall += TrembleEditorAPI.SyncToTrenchBroom;
|
||||
|
||||
// And tell the user!
|
||||
ShowCompleteDialog(
|
||||
title: "New Prefab Entity Created!",
|
||||
message: $"{scriptName}.cs was created and attached to {prefab.name}, and should be available from TrenchBroom.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 76e837b79b44474bb99e6e62f09d2af6
|
||||
timeCreated: 1723206660
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 277805
|
||||
packageName: Tremble - Map Importer
|
||||
packageVersion: 1.11.1
|
||||
assetPath: Assets/Tremble/Editor/Manual/Pages/Entities/Builders/PrefabBuilderPage.cs
|
||||
uploadId: 939664
|
||||
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// This file is part of the Tremble package by Tiny Goose.
|
||||
// Copyright (c) 2024-2026 TinyGoose Ltd., All Rights Reserved.
|
||||
//
|
||||
|
||||
namespace TinyGoose.Tremble.Editor
|
||||
{
|
||||
[ManualPage("Entities/Overview")]
|
||||
public class EntitiesOverviewPage : ManualPageBase
|
||||
{
|
||||
protected override void OnGUI()
|
||||
{
|
||||
Text(
|
||||
"Entities are used to place objects (for example prefabs, trigger volumes, etc.)",
|
||||
"into your map to make them more interactive."
|
||||
);
|
||||
|
||||
Text("Tremble supports 3 kinds of Entities:");
|
||||
|
||||
Space();
|
||||
|
||||
PropertyDescription("Prefab Entities",
|
||||
"These are 1:1 representations of your Unity prefabs, which can be dropped into a map.",
|
||||
$"You can either use a '{nameof(TrembleSpawnablePrefab)}' component in your prefab to allow it to",
|
||||
"be simply spawned from your map, or you can mark your scripts up with",
|
||||
$"'[{FormatAttributeName(typeof(PrefabEntityAttribute))}]' to synchronise properties and more!");
|
||||
ActionBar(() =>
|
||||
{
|
||||
Action("More about Spawnable Prefabs", () => GoToPage(typeof(SpawnablePrefabEntitiesPage)));
|
||||
Action("More about Prefab Entities", () => GoToPage(typeof(PrefabEntitiesPage)));
|
||||
});
|
||||
|
||||
Space();
|
||||
|
||||
PropertyDescription("Brush Entities",
|
||||
"These are brushes (shapes/meshes) in the map, which you want to apply a MonoBehaviour script to.",
|
||||
"These can be Solids - for example, a moving platform whose shape you design in TrenchBroom,",
|
||||
"Triggers - for example an area which triggers an event, and more!");
|
||||
ActionBar_SingleAction("More about Brush Entities", () => GoToPage(typeof(BrushEntitiesPage)));
|
||||
|
||||
Space();
|
||||
|
||||
PropertyDescription("Point Entities",
|
||||
"These are points in space which contain data - for example a target location for spawning enemies,",
|
||||
"or a goal location for a player to go to.");
|
||||
ActionBar_SingleAction("More about Point Entities", () => GoToPage(typeof(PointEntitiesPage)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 62b4b35600af4819baf0389a9252be03
|
||||
timeCreated: 1723278285
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 277805
|
||||
packageName: Tremble - Map Importer
|
||||
packageVersion: 1.11.1
|
||||
assetPath: Assets/Tremble/Editor/Manual/Pages/Entities/EntitiesOverviewPage.cs
|
||||
uploadId: 939664
|
||||
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// This file is part of the Tremble package by Tiny Goose.
|
||||
// Copyright (c) 2024-2026 TinyGoose Ltd., All Rights Reserved.
|
||||
//
|
||||
|
||||
namespace TinyGoose.Tremble.Editor
|
||||
{
|
||||
[ManualPage("Entities/Point Entities")]
|
||||
public class PointEntitiesPage : ManualPageBase
|
||||
{
|
||||
protected override void OnGUI()
|
||||
{
|
||||
Text(
|
||||
"Point Entities are points/positions in space in the map, which you want to apply a",
|
||||
"MonoBehaviour script to. They do not have a visual representation (mesh).",
|
||||
"For example, a target position that an enemy should move to. Or, a position in space",
|
||||
"in which to spawn the player (see below).");
|
||||
|
||||
Image("T_Manual_PointEntity");
|
||||
|
||||
Text("The following properties are available:");
|
||||
|
||||
PropertyDescription("name",
|
||||
"The name of the entity in TrenchBroom.",
|
||||
"If omitted, we convert your MonoBehaviour name according to your Naming Convention in settings."
|
||||
);
|
||||
|
||||
PropertyDescription("category",
|
||||
"The menu category to show the entity under, for example 'solid'.",
|
||||
$"If omitted, we use the default prefix, '{FgdConsts.BRUSH_PREFIX}'."
|
||||
);
|
||||
|
||||
PropertyDescription("colour, size",
|
||||
"Colour and Size define how to display this Point entity's preview cube in TrenchBroom."
|
||||
);
|
||||
|
||||
PropertyDescription("sprite",
|
||||
"(optional) A sprite to show, instead of a coloured cube for this Point entity in TrenchBroom.",
|
||||
"This should be the name of a texture in your project, e.g. 'T_MyTexture'."
|
||||
);
|
||||
|
||||
H1("Point Entity Wizard");
|
||||
Text(
|
||||
"Tremble can guide you through creating the correct attribute code for your entity,",
|
||||
"to help you get up and running quickly."
|
||||
);
|
||||
|
||||
ActionBar_SingleAction("Build Point Entity", () => GoToPage(typeof(PointBuilderPage)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d1a1a3ae162244f1819732c6cb04f4a8
|
||||
timeCreated: 1723201769
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 277805
|
||||
packageName: Tremble - Map Importer
|
||||
packageVersion: 1.11.1
|
||||
assetPath: Assets/Tremble/Editor/Manual/Pages/Entities/PointEntitiesPage.cs
|
||||
uploadId: 939664
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5dbfda69803f4f39ac23255094985859
|
||||
timeCreated: 1723206454
|
||||
@@ -0,0 +1,54 @@
|
||||
//
|
||||
// This file is part of the Tremble package by Tiny Goose.
|
||||
// Copyright (c) 2024-2026 TinyGoose Ltd., All Rights Reserved.
|
||||
//
|
||||
|
||||
namespace TinyGoose.Tremble.Editor
|
||||
{
|
||||
[ManualPage("Entities/Prefabs/Prefab Entities")]
|
||||
public class PrefabEntitiesPage : ManualPageBase
|
||||
{
|
||||
protected override void OnGUI()
|
||||
{
|
||||
Text(
|
||||
"Prefab Entities are 1:1 representations of your Unity prefabs, which can be dropped into a map.",
|
||||
$"All you have to do is mark up your scripts with '[{FormatAttributeName(typeof(PrefabEntityAttribute))}]' to synchronise properties and more!");
|
||||
|
||||
Image("T_Manual_PrefabEntity");
|
||||
|
||||
Text("The following properties are available:");
|
||||
|
||||
PropertyDescription("category",
|
||||
"The menu category to show the entity under, for example 'player'.",
|
||||
$"If omitted, we use the default prefix, '{FgdConsts.PREFAB_PREFIX}'."
|
||||
);
|
||||
|
||||
PropertyDescription("excludePrefab(s)",
|
||||
"Exclude prefabs with the given name. For example, if your",
|
||||
"script appears on multiple prefabs 'P_Coin' and 'P_CoinSpecial', and you only",
|
||||
" want to show 'P_Coin' in TrenchBroom, you can pass 'P_CoinSpecial' in here."
|
||||
);
|
||||
|
||||
PropertyDescription("includePrefab(s)",
|
||||
"Only include prefabs with the given name. For example, if your",
|
||||
"script appears on multiple prefabs 'P_Coin' and 'P_CoinSpecial', and you only",
|
||||
" want to show 'P_Coin' in TrenchBroom, you can pass 'P_Coin' in here."
|
||||
);
|
||||
|
||||
PropertyDescription("onlyVariants",
|
||||
"Only include variants of this prefab, not the base prefab itself.",
|
||||
"For example, imagine your game has a 'P_Sign' prefab, which is an empty signpost,",
|
||||
"but also has Prefab Variants 'P_Sign_Info' and 'P_Sign_QuestionMark' - ticking",
|
||||
"this box will export those variants but not the base 'P_Sign'."
|
||||
);
|
||||
|
||||
H1("Prefab Entity Wizard");
|
||||
Text(
|
||||
"Tremble can guide you through creating the correct attribute code for your entity,",
|
||||
"to help you get up and running quickly."
|
||||
);
|
||||
|
||||
ActionBar_SingleAction("Build Prefab Entity", () => GoToPage(typeof(PrefabBuilderPage)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fdcea6d257154068a23f70d1bdb72b0a
|
||||
timeCreated: 1723201724
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 277805
|
||||
packageName: Tremble - Map Importer
|
||||
packageVersion: 1.11.1
|
||||
assetPath: Assets/Tremble/Editor/Manual/Pages/Entities/Prefabs/PrefabEntitiesPage.cs
|
||||
uploadId: 939664
|
||||
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// This file is part of the Tremble package by Tiny Goose.
|
||||
// Copyright (c) 2024-2026 TinyGoose Ltd., All Rights Reserved.
|
||||
//
|
||||
|
||||
namespace TinyGoose.Tremble.Editor
|
||||
{
|
||||
[ManualPage("Entities/Prefabs/Spawnable Prefabs")]
|
||||
public class SpawnablePrefabEntitiesPage : ManualPageBase
|
||||
{
|
||||
protected override void OnGUI()
|
||||
{
|
||||
Text(
|
||||
"Spawnable Prefabs are a quick way to add a single script to ANY prefab in editor, to",
|
||||
"allow your prefab to be instantiated from TrenchBroom without any code changes.",
|
||||
"Note that this method does not allow you to set variables on those prefabs!"
|
||||
);
|
||||
|
||||
Image("T_Manual_SpawnablePrefab");
|
||||
|
||||
Text(
|
||||
$"Add a '{nameof(TrembleSpawnablePrefab)}' component to your prefab. This gives you the following",
|
||||
"options:"
|
||||
);
|
||||
|
||||
PropertyDescription("Category",
|
||||
"You can supply the 'Category' of prefab here, too - the menu category to",
|
||||
"show the entity under, for example 'player'. If omitted, we use the prefix defined in",
|
||||
"the settings (default: 'p')"
|
||||
);
|
||||
|
||||
PropertyDescription("Only Variants",
|
||||
"Only Variants: Tremble will ignore the base prefab and only export Prefab Variants of",
|
||||
"the prefab. See the above explanation about 'onlyVariants' for more information."
|
||||
);
|
||||
|
||||
ActionBar_SingleAction("Build Prefab Entity", () => GoToPage(typeof(PrefabBuilderPage)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a0a012f06324a7e962feefd29e85628
|
||||
timeCreated: 1723206473
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 277805
|
||||
packageName: Tremble - Map Importer
|
||||
packageVersion: 1.11.1
|
||||
assetPath: Assets/Tremble/Editor/Manual/Pages/Entities/Prefabs/SpawnablePrefabsPage.cs
|
||||
uploadId: 939664
|
||||
Reference in new issue
Block a user