Files
2025-11-30 08:35:03 +02:00

231 lines
8.2 KiB
C#

using System;
using System.ComponentModel.Composition.Primitives;
using System.Linq;
using System.Threading.Tasks;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
using Object = UnityEngine.Object;
namespace Needle.Engine.Deployment
{
public class BuildWindowDeployOptions : INeedleBuildPlatformGUIProvider
{
private GUIStyle fixedMiniLabel;
public void OnBuildPlatformsGUI(NeedleEngineBuildOptions options)
{
if (fixedMiniLabel == null)
{
fixedMiniLabel = new GUIStyle(EditorStyles.wordWrappedMiniLabel);
fixedMiniLabel.padding.left = 0;
}
if (NeedleDebug.DeveloperMode)
{
EditorGUILayout.HelpBox("DEVELOPER MODE IS ENABLED", MessageType.Warning);
GUILayout.Space(5);
}
var hasLicense = LicenseCheck.HasCommercialLicense;
var hasValidLicense = LicenseCheck.LicenseIsActive;
var width = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth -= 30;
using (new EditorGUILayout.HorizontalScope())
{
var tooltip = NeedleEngineBuildOptions.DevelopmentBuild
? "Development build enabled - this means your project will produce bigger files because textures and meshes will not be compressed. Press this button to enable Production builds and compress your glTF files after building."
: "Production build enabled - when building your resulting glTF files will get compressed using toktx (this means mainly meshes and textures will get way smaller)";
NeedleEngineBuildOptions.DevelopmentBuild = EditorGUILayout.Toggle(new GUIContent("Development Build", tooltip), NeedleEngineBuildOptions.DevelopmentBuild);
if (NeedleEngineBuildOptions.DevelopmentBuild)
{
using(new EditorGUI.DisabledScope(true))
GUILayout.Label(new GUIContent("No mesh/texture compression", "For production we recommend to disable the development build option. Development builds produce uncompressed output resulting in larger assets, higher runtime memory requirements, and reduced performance."), EditorStyles.wordWrappedLabel);
}
}
using (new EditorGUILayout.HorizontalScope())
{
var tooltip = "When enabled, HTML, CSS and JS files will be gzip-compressed during the build process, reducing their size. This is recommended for production builds. Make sure your server is set up to serve gzipped files.";
using (new EditorGUI.DisabledScope(!hasValidLicense))
{
if (!hasValidLicense) NeedleEngineBuildOptions.UseGzipCompression = true;
NeedleEngineBuildOptions.UseGzipCompression = EditorGUILayout.Toggle(new GUIContent("Gzip Compression", tooltip), NeedleEngineBuildOptions.UseGzipCompression);
}
}
EditorGUILayout.Space(10);
using (new EditorGUILayout.VerticalScope())
{
// var main = EditorStyles.wordWrappedLabel;
// GUILayout.Label(
// new GUIContent("Deployment",
// "Click any of the buttons below to add the deployment component to your scene or (if it already exists) ping the object"),
// EditorStyles.boldLabel);
// GUILayout.Space(6);
// if (!Authentication.IsLoggedIn())
// {
// using (new EditorGUILayout.HorizontalScope())
// {
// EditorGUILayout.HelpBox("Get a Needle Engine license to deploy with ease to any platform", MessageType.Info);
// if (GUILayout.Button(new GUIContent("Login to Needle Cloud", "See the available commercial plans - deploy with ease with Needle Engine"), GUILayout.Width(150), GUILayout.Height(38)))
// {
// Authentication.Login();
// }
// }
// GUILayout.Space(5);
// }
EditorGUILayout.LabelField("Deploy to Needle Cloud", EditorStyles.boldLabel);
GUILayout.Space(-5);
EditorGUILayout.LabelField("Fast deployments, versioning, and collaboration.", fixedMiniLabel);
var exp = ExportInfo.Get();
if (exp)
{
NeedleCloudGUI.Instance.OnGUI();
}
GUILayout.Space(5);
GUILayout.FlexibleSpace();
EditorGUILayout.LabelField("Other Platforms", EditorStyles.boldLabel, GUILayout.MaxWidth(150), GUILayout.MaxHeight(10));
if (!hasLicense)
{
using(new EditorGUI.DisabledScope(true))
EditorGUILayout.LabelField("Deploy to Needle Cloud for free or get PRO to deploy anywhere: Fast deployment to other platforms", fixedMiniLabel);
}
else
{
EditorGUILayout.LabelField("Fast deployment to various hosting platforms.", fixedMiniLabel);
}
using (new EditorGUI.DisabledScope(!hasValidLicense || !hasLicense))
{
DrawDeployToOptionButtons();
}
// if (hasValidLicense)
// {
// GUILayout.Space(5);
// using (new EditorGUILayout.HorizontalScope())
// {
// EditorGUILayout.LabelField(
// new GUIContent(
// "Learn more about all our deployment options by visiting the Needle Engine documentation."),
// main);
// if (GUILayout.Button("Open Documentation ↗"))
// Help.BrowseURL(Constants.DocumentationUrlDeployment);
// }
// }
}
EditorGUIUtility.labelWidth = width;
}
private class DeploymentComponentEntry
{
public Type type;
public Texture2D icon;
public string label;
public string niceName;
public GUIContent content;
}
private static DeploymentComponentEntry[] deploymentComponents;
private static GUIStyle buttonLeftAligned;
private static void DrawDeployToOptionButtons()
{
deploymentComponents ??= TypeCache
.GetTypesWithAttribute<DeploymentComponentAttribute>()
.Where(t => typeof(MonoBehaviour).IsAssignableFrom(t))
.OrderBy(t => t.Name)
.Select(x =>
{
var labelText = ObjectNames.NicifyVariableName(x.Name);
if (labelText.StartsWith("Deploy To"))
labelText = labelText.Substring("Deploy To".Length);
var entry = new DeploymentComponentEntry
{
type = x,
niceName = labelText,
};
if (x
.GetCustomAttributes(typeof(CustomComponentHeaderLinkAttribute), true)
.FirstOrDefault() is CustomComponentHeaderLinkAttribute comp &&
!string.IsNullOrEmpty(comp.IconIconPathOrGuid))
{
entry.icon = AssetDatabase.LoadAssetAtPath<Texture2D>(
AssetDatabase.GUIDToAssetPath(comp.IconIconPathOrGuid));;
}
if (x
.GetCustomAttributes(typeof(AddComponentMenu), true)
.FirstOrDefault() is AddComponentMenu menu &&
!string.IsNullOrEmpty(menu.componentMenu))
{
entry.label = menu.componentMenu;
}
entry.content = new GUIContent(entry.niceName, entry.icon,"Click to add the '" + entry.label + "' component to your scene");
return entry;
})
.ToArray();
buttonLeftAligned ??= new GUIStyle(GUI.skin.button)
{
alignment = TextAnchor.MiddleLeft,
padding = new RectOffset(5,5,5,5),
};
EditorGUILayout.BeginHorizontal();
var i = 0;
const int leftColumnWidth = 295;
var maxWidthPerButton = (Screen.width / EditorGUIUtility.pixelsPerPoint - leftColumnWidth) / 2.0f;
maxWidthPerButton -= 7; // to avoid horizontal scrollbar IF we have a vertical scrollbar (seems to be windows only)
var width = GUILayout.Width(maxWidthPerButton);
var height = GUILayout.Height(24);
for (var index = 0; index < deploymentComponents.Length; index++)
{
var entry = deploymentComponents[index];
if (i++ >= 2)
{
i = 1;
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
}
if (GUILayout.Button(entry.content, buttonLeftAligned, width, height))
{
var existing = Object.FindAnyObjectByType(entry.type);
if (existing)
{
EditorGUIUtility.PingObject(existing);
Selection.activeObject = existing;
}
else
{
var exp = ExportInfo.Get();
if (exp)
{
var gameObject = exp.gameObject;
EditorGUIUtility.PingObject(exp);
Selection.activeObject = gameObject;
AddDelayed();
async void AddDelayed()
{
await Task.Delay(300);
Debug.Log("Added the \"" + entry.niceName + "\" component to " + gameObject, gameObject);
Undo.AddComponent(exp.gameObject, entry.type);
}
}
}
}
}
EditorGUILayout.EndHorizontal();
}
}
}