|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
using UnityEditor;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using System.Runtime.Serialization.Formatters.Binary;
|
|
|
|
|
|
using UnityEditor.SceneManagement;
|
|
|
|
|
|
using MapOfProfile = System.Collections.Generic.Dictionary<string, Shipper.Profile>;
|
|
|
|
|
|
|
|
|
|
|
|
public class BackgroundColorScope : GUI.Scope
|
|
|
|
|
|
{
|
|
|
|
|
|
private readonly Color color;
|
|
|
|
|
|
public BackgroundColorScope(Color color)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.color = GUI.backgroundColor;
|
|
|
|
|
|
GUI.backgroundColor = color;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected override void CloseScope()
|
|
|
|
|
|
{
|
|
|
|
|
|
GUI.backgroundColor = color;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class InputDialog : EditorWindow
|
|
|
|
|
|
{
|
|
|
|
|
|
class Info
|
|
|
|
|
|
{
|
|
|
|
|
|
public RangeAttribute range;
|
|
|
|
|
|
public FieldInfo field;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
List<Info> m_lst_field = new List<Info>();
|
|
|
|
|
|
public delegate void OnButton(object sender, bool isOK);
|
|
|
|
|
|
public event OnButton EventButton;
|
|
|
|
|
|
|
|
|
|
|
|
public static InputDialog Create< T >(string title = null) where T : InputDialog
|
|
|
|
|
|
{
|
|
|
|
|
|
T obj = CreateInstance< T >();
|
|
|
|
|
|
obj.mf_Init(obj.GetType());
|
|
|
|
|
|
if (title != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
obj.titleContent = new GUIContent(title);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void ShowDialog()
|
|
|
|
|
|
{
|
|
|
|
|
|
ShowUtility();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void OnGUI()
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorGUILayout.Separator();
|
|
|
|
|
|
|
|
|
|
|
|
foreach (Info info in m_lst_field)
|
|
|
|
|
|
{
|
|
|
|
|
|
FieldInfo field = info.field;
|
|
|
|
|
|
|
|
|
|
|
|
if (field.FieldType == typeof(float))
|
|
|
|
|
|
{
|
|
|
|
|
|
float val;
|
|
|
|
|
|
if (info.range != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
val = EditorGUILayout.Slider(field.Name, (float)field.GetValue(this), info.range.min, info.range.max);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
val = EditorGUILayout.FloatField(field.Name, (float)field.GetValue(this));
|
|
|
|
|
|
}
|
|
|
|
|
|
field.SetValue(this, val);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (field.FieldType == typeof(int))
|
|
|
|
|
|
{
|
|
|
|
|
|
int val;
|
|
|
|
|
|
if (info.range != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
val = EditorGUILayout.IntSlider(field.Name, (int)field.GetValue(this), (int)info.range.min, (int)info.range.max);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
val = EditorGUILayout.IntField(field.Name, (int)field.GetValue(this));
|
|
|
|
|
|
}
|
|
|
|
|
|
field.SetValue(this, val);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (field.FieldType == typeof(string))
|
|
|
|
|
|
{
|
|
|
|
|
|
string text = EditorGUILayout.TextField(field.Name, (string)field.GetValue(this));
|
|
|
|
|
|
field.SetValue(this, text);
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (field.FieldType.BaseType == typeof(Enum))
|
|
|
|
|
|
{
|
|
|
|
|
|
Enum e = EditorGUILayout.EnumPopup(field.Name, (Enum)field.GetValue(this));
|
|
|
|
|
|
field.SetValue(this, e);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.Separator();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.Space();
|
|
|
|
|
|
|
|
|
|
|
|
using (new EditorGUILayout.HorizontalScope())
|
|
|
|
|
|
{
|
|
|
|
|
|
GUILayout.FlexibleSpace();
|
|
|
|
|
|
|
|
|
|
|
|
if (GUILayout.Button("Confirm", GUILayout.Width(64)))
|
|
|
|
|
|
{
|
|
|
|
|
|
EventButton(this, true);
|
|
|
|
|
|
Close();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (GUILayout.Button("Cancel", GUILayout.Width(64)))
|
|
|
|
|
|
{
|
|
|
|
|
|
EventButton(this, false);
|
|
|
|
|
|
Close();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void mf_Init(Type real_type)
|
|
|
|
|
|
{
|
|
|
|
|
|
BindingFlags bindingFlag = BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly;
|
|
|
|
|
|
foreach (FieldInfo field in real_type.GetFields(bindingFlag))
|
|
|
|
|
|
{
|
|
|
|
|
|
RangeAttribute[] attr = field.GetCustomAttributes(typeof(RangeAttribute), true) as RangeAttribute[];
|
|
|
|
|
|
|
|
|
|
|
|
Info info = new Info();
|
|
|
|
|
|
info.field = field;
|
|
|
|
|
|
info.range = attr.Length > 0 ? attr[0] : null;
|
|
|
|
|
|
m_lst_field.Add(info);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class CreateDialog : InputDialog
|
|
|
|
|
|
{
|
|
|
|
|
|
public string ProfileName = "Profile";
|
|
|
|
|
|
public BuildTarget Platfrom = BuildTarget.StandaloneWindows;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class DuplicateDialog : InputDialog
|
|
|
|
|
|
{
|
|
|
|
|
|
public string ProfileName = "Profile";
|
|
|
|
|
|
|
|
|
|
|
|
public Shipper.Profile DuplicatedProfile
|
|
|
|
|
|
{
|
|
|
|
|
|
set { m_duplicated_profile = value; }
|
|
|
|
|
|
get { return m_duplicated_profile; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private Shipper.Profile m_duplicated_profile;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class RenameDialog: InputDialog
|
|
|
|
|
|
{
|
|
|
|
|
|
public string RenameTo = "";
|
|
|
|
|
|
|
|
|
|
|
|
public Shipper.Profile RenameProfile
|
|
|
|
|
|
{
|
|
|
|
|
|
set { m_rename_profile = value; }
|
|
|
|
|
|
get { return m_rename_profile; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private Shipper.Profile m_rename_profile;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class Shipper : EditorWindow
|
|
|
|
|
|
{
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
|
public class SaveData
|
|
|
|
|
|
{
|
|
|
|
|
|
public string[] pronames;
|
|
|
|
|
|
public Profile[] profiles;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
|
public class Profile
|
|
|
|
|
|
{
|
|
|
|
|
|
[Serializable]
|
|
|
|
|
|
public class SceneInfo
|
|
|
|
|
|
{
|
|
|
|
|
|
public string path = "";
|
|
|
|
|
|
public bool is_enable = false;
|
|
|
|
|
|
|
|
|
|
|
|
public SceneInfo Clone()
|
|
|
|
|
|
{
|
|
|
|
|
|
SceneInfo cloned_obj = new SceneInfo();
|
|
|
|
|
|
cloned_obj.path = path;
|
|
|
|
|
|
cloned_obj.is_enable = is_enable;
|
|
|
|
|
|
return cloned_obj;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public string name;
|
|
|
|
|
|
public BuildTarget platform;
|
|
|
|
|
|
public string build_path = "";
|
|
|
|
|
|
public string filename = "";
|
|
|
|
|
|
public List<SceneInfo> scenes = new List<SceneInfo>();
|
|
|
|
|
|
public bool need_silent_crashes = true;
|
|
|
|
|
|
public bool need_open_folder = true;
|
|
|
|
|
|
public string batch_path_relative = "/";
|
|
|
|
|
|
public string batch_filename = "";
|
|
|
|
|
|
|
|
|
|
|
|
public Profile Clone()
|
|
|
|
|
|
{
|
|
|
|
|
|
Profile cloned_obj = new Profile();
|
|
|
|
|
|
cloned_obj.name = name;
|
|
|
|
|
|
cloned_obj.platform = platform;
|
|
|
|
|
|
cloned_obj.build_path = build_path;
|
|
|
|
|
|
cloned_obj.filename = filename;
|
|
|
|
|
|
cloned_obj.need_silent_crashes = need_silent_crashes;
|
|
|
|
|
|
cloned_obj.need_open_folder = need_open_folder;
|
|
|
|
|
|
cloned_obj.batch_path_relative = batch_path_relative;
|
|
|
|
|
|
cloned_obj.batch_filename = batch_filename;
|
|
|
|
|
|
|
|
|
|
|
|
foreach (SceneInfo info in scenes)
|
|
|
|
|
|
{
|
|
|
|
|
|
cloned_obj.scenes.Add(info.Clone());
|
|
|
|
|
|
}
|
|
|
|
|
|
return cloned_obj;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public string batch_path_abs
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return UltraCombos.Utils.GetProjectPath() + batch_path_relative;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
|
|
|
|
|
batch_path_relative = "/" + UltraCombos.Utils.MakeRelativePath(UltraCombos.Utils.GetProjectPath(), value);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public BuildBatchInfo CreateBuildBatchInfo()
|
|
|
|
|
|
{
|
|
|
|
|
|
BuildBatchInfo info = new BuildBatchInfo();
|
|
|
|
|
|
info.platform = platform.ToString();
|
|
|
|
|
|
info.build_path = build_path;
|
|
|
|
|
|
info.filename = filename;
|
|
|
|
|
|
info.scenes = ToScenePathArray(true);
|
|
|
|
|
|
info.neeed_open_the_folder_when_sccuess = need_open_folder;
|
|
|
|
|
|
info.need_silent_crashes = need_silent_crashes;
|
|
|
|
|
|
return info;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public string ToFullBuildPath()
|
|
|
|
|
|
{
|
|
|
|
|
|
return build_path + filename;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public string ToFullBatchPath()
|
|
|
|
|
|
{
|
|
|
|
|
|
return batch_path_abs + batch_filename;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool IsAnyEnabledSceneExist()
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (SceneInfo scene in scenes)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!scene.is_enable)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public string[] ToScenePathArray(bool check_enable = true)
|
|
|
|
|
|
{
|
|
|
|
|
|
List<string> path = new List<string>();
|
|
|
|
|
|
foreach (SceneInfo scene in scenes)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (check_enable && !scene.is_enable)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
path.Add(scene.path);
|
|
|
|
|
|
}
|
|
|
|
|
|
return path.ToArray();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private bool m_is_init = false;
|
|
|
|
|
|
private bool m_is_dirty = false;
|
|
|
|
|
|
private bool m_need_reload = false;
|
|
|
|
|
|
private bool m_is_playing = false;
|
|
|
|
|
|
private bool m_need_run = false;
|
|
|
|
|
|
private Profile m_deploy_profile = null;
|
|
|
|
|
|
|
|
|
|
|
|
private Texture m_tex_icon_folder = null;
|
|
|
|
|
|
|
|
|
|
|
|
private MapOfProfile m_map_profile = new MapOfProfile();
|
|
|
|
|
|
private List<string> m_lst_proname = new List<string>();
|
|
|
|
|
|
private string[] m_keys;
|
|
|
|
|
|
|
|
|
|
|
|
private CreateDialog m_dialog_for_creating;
|
|
|
|
|
|
private DuplicateDialog m_dialog_for_duplicating;
|
|
|
|
|
|
private RenameDialog m_dialog_for_renaming;
|
|
|
|
|
|
|
|
|
|
|
|
private Vector2 m_pos_scroll_view_for_item;
|
|
|
|
|
|
private Vector2 m_pos_scroll_view_for_info;
|
|
|
|
|
|
private Vector2 m_pos_scroll_view_for_scene;
|
|
|
|
|
|
|
|
|
|
|
|
private GUIStyle m_style_profile_name;
|
|
|
|
|
|
|
|
|
|
|
|
private int m_selected = -1;
|
|
|
|
|
|
private int m_index_default = -1;
|
|
|
|
|
|
private static Shipper s_shipper = null;
|
|
|
|
|
|
private static bool s_can_depoly_default = true;
|
|
|
|
|
|
|
|
|
|
|
|
public static bool CanDeployDefault()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (s_shipper != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return s_shipper.mf_CanDeployDefault(); ;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (s_index_default < 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return s_can_depoly_default;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static void DeployDefault()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (s_shipper != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
s_shipper.mf_DeployDefault();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
s_can_depoly_default = false;
|
|
|
|
|
|
Profile profile = Shipper.sf_LoadDefaultProfile();
|
|
|
|
|
|
if (profile != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
sf_DeployProfile(profile);
|
|
|
|
|
|
}
|
|
|
|
|
|
s_can_depoly_default = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[MenuItem("Window/UC/Shipper _F10")]
|
|
|
|
|
|
public static Shipper GetShipper()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Get existing open window or if none, make a new one:
|
|
|
|
|
|
Shipper shipper = EditorWindow.GetWindow<Shipper>();
|
|
|
|
|
|
return shipper;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void mf_Setup()
|
|
|
|
|
|
{
|
|
|
|
|
|
s_shipper = this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private bool mf_CheckProfileName(string name)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (name == null || name.Length == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogWarning("ProfileName is empty.");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (m_map_profile.ContainsKey(name))
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogWarning("Profile: " + name + " is exist.");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private bool mf_CanDeployDefault()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (m_deploy_profile != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (m_index_default < 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (m_index_default >= m_lst_proname.Count)
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Profile profile;
|
|
|
|
|
|
if (!m_map_profile.TryGetValue(m_lst_proname[m_selected], out profile))
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return mf_CanDeploy(profile);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void mf_DeployDefault()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (m_index_default < 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (m_index_default >= m_lst_proname.Count)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Profile profile;
|
|
|
|
|
|
if (!m_map_profile.TryGetValue(m_lst_proname[m_index_default], out profile))
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (m_deploy_profile != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_deploy_profile = profile;
|
|
|
|
|
|
sf_DeployProfile(m_deploy_profile);
|
|
|
|
|
|
m_deploy_profile = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void OnButton_InputDialog(object sender, bool is_ok)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (m_dialog_for_creating != null && m_dialog_for_creating == sender as CreateDialog)
|
|
|
|
|
|
{
|
|
|
|
|
|
do
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!is_ok)
|
|
|
|
|
|
{
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!mf_CheckProfileName(m_dialog_for_creating.ProfileName))
|
|
|
|
|
|
{
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!ucDeployTool.IsSupportPlatform(m_dialog_for_creating.Platfrom))
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogWarning("Profile: " + m_dialog_for_creating.Platfrom + " is not support.");
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Profile profile = new Profile();
|
|
|
|
|
|
profile.name = m_dialog_for_creating.ProfileName;
|
|
|
|
|
|
profile.platform = m_dialog_for_creating.Platfrom;
|
|
|
|
|
|
profile.batch_filename = profile.name + ".bat";
|
|
|
|
|
|
|
|
|
|
|
|
m_map_profile.Add(profile.name, profile);
|
|
|
|
|
|
m_lst_proname.Add(profile.name);
|
|
|
|
|
|
m_keys = m_lst_proname.ToArray();
|
|
|
|
|
|
|
|
|
|
|
|
if (m_selected < 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_selected = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_is_dirty = true;
|
|
|
|
|
|
|
|
|
|
|
|
} while (false);
|
|
|
|
|
|
|
|
|
|
|
|
m_dialog_for_creating = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (m_dialog_for_duplicating != null && m_dialog_for_duplicating == sender as DuplicateDialog)
|
|
|
|
|
|
{
|
|
|
|
|
|
do
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!is_ok)
|
|
|
|
|
|
{
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!mf_CheckProfileName(m_dialog_for_duplicating.ProfileName))
|
|
|
|
|
|
{
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Profile profile = m_dialog_for_duplicating.DuplicatedProfile.Clone();
|
|
|
|
|
|
profile.name = m_dialog_for_duplicating.ProfileName;
|
|
|
|
|
|
|
|
|
|
|
|
m_map_profile.Add(profile.name, profile);
|
|
|
|
|
|
m_lst_proname.Add(profile.name);
|
|
|
|
|
|
m_keys = m_lst_proname.ToArray();
|
|
|
|
|
|
|
|
|
|
|
|
m_is_dirty = true;
|
|
|
|
|
|
|
|
|
|
|
|
} while (false);
|
|
|
|
|
|
|
|
|
|
|
|
m_dialog_for_duplicating = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (m_dialog_for_renaming != null && m_dialog_for_renaming == sender as RenameDialog)
|
|
|
|
|
|
{
|
|
|
|
|
|
do
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!is_ok)
|
|
|
|
|
|
{
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!mf_CheckProfileName(m_dialog_for_renaming.RenameTo))
|
|
|
|
|
|
{
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Profile profile = m_dialog_for_renaming.RenameProfile;
|
|
|
|
|
|
|
|
|
|
|
|
if (m_dialog_for_renaming.RenameTo.Equals(profile.name))
|
|
|
|
|
|
{
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (m_map_profile.ContainsKey(m_dialog_for_renaming.RenameTo))
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogWarning("Failed to rename [" + profile.name + "] to [" + m_dialog_for_renaming.RenameTo + "].\n[" + m_dialog_for_renaming.RenameTo + "] is exist.");
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_map_profile.Remove(profile.name);
|
|
|
|
|
|
m_lst_proname[m_lst_proname.IndexOf(profile.name)] = m_dialog_for_renaming.RenameTo;
|
|
|
|
|
|
profile.name = m_dialog_for_renaming.RenameTo;
|
|
|
|
|
|
m_map_profile.Add(m_dialog_for_renaming.RenameTo, profile);
|
|
|
|
|
|
m_keys = m_lst_proname.ToArray();
|
|
|
|
|
|
m_is_dirty = true;
|
|
|
|
|
|
|
|
|
|
|
|
} while (false);
|
|
|
|
|
|
|
|
|
|
|
|
m_dialog_for_renaming = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void OnInspectorUpdate()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!m_is_init)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (m_deploy_profile != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool yes = sf_DeployProfile(m_deploy_profile);
|
|
|
|
|
|
if (yes && m_need_run)
|
|
|
|
|
|
{
|
|
|
|
|
|
string path = m_deploy_profile.ToFullBuildPath().Replace(".exe", ".bat");
|
|
|
|
|
|
ucDeployTool.Run(path);
|
|
|
|
|
|
m_need_run = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_deploy_profile = null;
|
|
|
|
|
|
m_need_reload = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (Application.isPlaying != m_is_playing)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_is_playing = Application.isPlaying;
|
|
|
|
|
|
m_need_reload = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (m_need_reload)
|
|
|
|
|
|
{
|
|
|
|
|
|
mf_Load();
|
|
|
|
|
|
m_need_reload = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void OnGUI()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!m_is_init)
|
|
|
|
|
|
{
|
|
|
|
|
|
mf_Init();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUI.BeginDisabledGroup(m_deploy_profile != null);
|
|
|
|
|
|
|
|
|
|
|
|
const int btn_rect_height = 26;
|
|
|
|
|
|
|
|
|
|
|
|
DragAndDrop.AcceptDrag();
|
|
|
|
|
|
|
|
|
|
|
|
if (Event.current.keyCode == KeyCode.Escape)
|
|
|
|
|
|
{
|
|
|
|
|
|
Close();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUI.BeginDisabledGroup(mf_IsDialogExist());
|
|
|
|
|
|
|
|
|
|
|
|
using (var main_scope = new EditorGUILayout.HorizontalScope())
|
|
|
|
|
|
{
|
|
|
|
|
|
using (var editor_scope = new EditorGUILayout.VerticalScope(GUILayout.Width(position.width / 3)))
|
|
|
|
|
|
{
|
|
|
|
|
|
using (var control_item_scope = new EditorGUILayout.HorizontalScope())
|
|
|
|
|
|
{
|
|
|
|
|
|
if (GUILayout.Button("Create", GUILayout.MaxWidth(64)))
|
|
|
|
|
|
{
|
|
|
|
|
|
mf_CreateProfile();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GUILayout.FlexibleSpace();
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUI.BeginDisabledGroup(m_selected < 0);
|
|
|
|
|
|
|
|
|
|
|
|
if (GUILayout.Button("Delete", GUILayout.MaxWidth(64)))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (m_selected >= 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (mf_DeleteProfile(m_keys[m_selected]))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (m_lst_proname.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (m_selected > m_lst_proname.Count - 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_selected = m_lst_proname.Count - 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
m_selected = -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (GUILayout.Button("Duplicate", GUILayout.MaxWidth(64)))
|
|
|
|
|
|
{
|
|
|
|
|
|
Profile profile = mf_SelectedProfile();
|
|
|
|
|
|
if (profile != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
mf_DuplicateProfile(profile);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUI.EndDisabledGroup();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.Separator();
|
|
|
|
|
|
//EditorGUI.indentLevel += 2;
|
|
|
|
|
|
using (var item_scope = new EditorGUILayout.ScrollViewScope(m_pos_scroll_view_for_item, GUILayout.MaxWidth(position.width / 3), GUILayout.MaxHeight(position.height - btn_rect_height * 2)))
|
|
|
|
|
|
{
|
|
|
|
|
|
m_pos_scroll_view_for_item = item_scope.scrollPosition;
|
|
|
|
|
|
|
|
|
|
|
|
if (m_lst_proname.Count > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_selected = GUILayout.SelectionGrid(m_selected, m_keys, 1, "PreferencesKeysElement");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
//EditorGUI.indentLevel -= 2;
|
|
|
|
|
|
//EditorGUILayout.Space();
|
|
|
|
|
|
using (var control_item_scope = new EditorGUILayout.HorizontalScope())
|
|
|
|
|
|
{
|
|
|
|
|
|
using (new BackgroundColorScope(m_is_dirty ? new Color(1.0f, 0.5f, 0.5f) : GUI.backgroundColor))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (GUILayout.Button(m_is_dirty ? "Save *" : "Save", GUILayout.MaxWidth(64)))
|
|
|
|
|
|
{
|
|
|
|
|
|
mf_Save();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GUILayout.FlexibleSpace();
|
|
|
|
|
|
|
|
|
|
|
|
if (GUILayout.Button("Load", GUILayout.MaxWidth(64)))
|
|
|
|
|
|
{
|
|
|
|
|
|
mf_Load();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
float max_info_width = position.width * 2 / 3;
|
|
|
|
|
|
|
|
|
|
|
|
using (var info_view_scope = new EditorGUILayout.ScrollViewScope(m_pos_scroll_view_for_info, "Box", GUILayout.MaxWidth(max_info_width), GUILayout.MaxHeight(position.height)))
|
|
|
|
|
|
{
|
|
|
|
|
|
m_pos_scroll_view_for_info = info_view_scope.scrollPosition;
|
|
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
|
{
|
|
|
|
|
|
if (m_map_profile.Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Profile profile = mf_SelectedProfile();
|
|
|
|
|
|
if (profile == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool is_deploy_ok = true;
|
|
|
|
|
|
|
|
|
|
|
|
using (var info_scope = new EditorGUILayout.VerticalScope(GUILayout.MaxHeight(position.height - btn_rect_height)))
|
|
|
|
|
|
{
|
|
|
|
|
|
using (new EditorGUILayout.HorizontalScope())
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorGUILayout.LabelField(profile.name, m_style_profile_name, GUILayout.MaxHeight(m_style_profile_name.fontSize * 1.2f));
|
|
|
|
|
|
GUILayout.FlexibleSpace();
|
|
|
|
|
|
if (GUILayout.Button("Rename", GUILayout.MaxWidth(64)))
|
|
|
|
|
|
{
|
|
|
|
|
|
mf_RenameProfile(profile);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool is_deploy_quickely = m_index_default == m_selected;
|
|
|
|
|
|
bool yes = GUILayout.Toggle(is_deploy_quickely, "Default", "Button", GUILayout.MaxWidth(64));
|
|
|
|
|
|
if (yes != is_deploy_quickely)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (yes)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_index_default = m_selected;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
m_index_default = -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_is_dirty = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.Separator();
|
|
|
|
|
|
|
|
|
|
|
|
BuildTarget selected_target = (BuildTarget)EditorGUILayout.EnumPopup("Platform", profile.platform);
|
|
|
|
|
|
if (!ucDeployTool.IsSupportPlatform(selected_target))
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogWarning("Profile: " + selected_target + " is not support.");
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (selected_target != profile.platform)
|
|
|
|
|
|
{
|
|
|
|
|
|
profile.platform = selected_target;
|
|
|
|
|
|
m_is_dirty = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
using (new EditorGUILayout.HorizontalScope(GUI.skin.box))
|
|
|
|
|
|
{
|
|
|
|
|
|
string build_path = "";
|
|
|
|
|
|
string filename = "";
|
|
|
|
|
|
|
|
|
|
|
|
using (new EditorGUILayout.VerticalScope())
|
|
|
|
|
|
{
|
|
|
|
|
|
build_path = EditorGUILayout.TextField("BuildPath", profile.build_path);
|
|
|
|
|
|
filename = EditorGUILayout.TextField("Filename", profile.filename);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (GUILayout.Button(new GUIContent(m_tex_icon_folder), GUILayout.Width(32), GUILayout.Height(32)))
|
|
|
|
|
|
{
|
|
|
|
|
|
string path = ucDeployTool.SelectBuildPath(profile.platform, profile.build_path);
|
|
|
|
|
|
if (path.Length > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
UltraCombos.Utils.SplitPath(path, out build_path, out filename);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!build_path.Equals(profile.build_path) || !filename.Equals(profile.filename))
|
|
|
|
|
|
{
|
|
|
|
|
|
profile.build_path = build_path;
|
|
|
|
|
|
profile.filename = filename;
|
|
|
|
|
|
m_is_dirty = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.Separator();
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.LabelField("Scene In Build");
|
|
|
|
|
|
|
|
|
|
|
|
using (var scene_scope = new EditorGUILayout.ScrollViewScope(m_pos_scroll_view_for_scene, GUILayout.MinHeight(60), GUILayout.MaxHeight(120)))
|
|
|
|
|
|
{
|
|
|
|
|
|
m_pos_scroll_view_for_scene = scene_scope.scrollPosition;
|
|
|
|
|
|
|
|
|
|
|
|
using (var scene_scope2 = new EditorGUILayout.VerticalScope(GUI.skin.textField, GUILayout.MinHeight(60), GUILayout.MaxHeight(120)))
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
if (profile.scenes.Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorGUILayout.LabelField("Empty");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const float max_width = 16;
|
|
|
|
|
|
const float max_height = 16;
|
|
|
|
|
|
const float btn_width = 18;
|
|
|
|
|
|
const float btn_height = 18;
|
|
|
|
|
|
|
|
|
|
|
|
Profile.SceneInfo removed_scene_info = null;
|
|
|
|
|
|
|
|
|
|
|
|
foreach (Profile.SceneInfo info in profile.scenes)
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorGUILayout.BeginHorizontal(GUILayout.MaxHeight(max_height));
|
|
|
|
|
|
using (var scene_item_scope = new EditorGUILayout.HorizontalScope(GUILayout.MaxHeight(max_height)))
|
|
|
|
|
|
{
|
|
|
|
|
|
bool yes = EditorGUILayout.Toggle(info.is_enable, GUILayout.MaxWidth(max_width), GUILayout.MaxHeight(max_height));
|
|
|
|
|
|
if (yes != info.is_enable)
|
|
|
|
|
|
{
|
|
|
|
|
|
info.is_enable = yes;
|
|
|
|
|
|
m_is_dirty = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.LabelField(info.path, GUILayout.MaxHeight(max_height), GUILayout.MaxWidth(max_info_width));
|
|
|
|
|
|
|
|
|
|
|
|
GUILayout.FlexibleSpace();
|
|
|
|
|
|
|
|
|
|
|
|
if (GUILayout.Button("X", GUILayout.Width(btn_width), GUILayout.Height(btn_height)))
|
|
|
|
|
|
{
|
|
|
|
|
|
removed_scene_info = info;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (removed_scene_info != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
profile.scenes.Remove(removed_scene_info);
|
|
|
|
|
|
|
|
|
|
|
|
m_is_dirty = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string path = mf_CheckDragAndDropPath(Event.current, scene_scope2.rect, ".unity");
|
|
|
|
|
|
if (path != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!sf_IsScenePathExist(profile, path))
|
|
|
|
|
|
{
|
|
|
|
|
|
Profile.SceneInfo info = new Profile.SceneInfo();
|
|
|
|
|
|
info.path = path;
|
|
|
|
|
|
info.is_enable = false;
|
|
|
|
|
|
profile.scenes.Add(info);
|
|
|
|
|
|
|
|
|
|
|
|
m_is_dirty = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
using (new EditorGUILayout.HorizontalScope())
|
|
|
|
|
|
{
|
|
|
|
|
|
GUILayout.FlexibleSpace();
|
|
|
|
|
|
|
|
|
|
|
|
if (GUILayout.Button("Add Open Scenes", GUILayout.MaxWidth(128)))
|
|
|
|
|
|
{
|
|
|
|
|
|
SceneSetup[] opened_scenes = EditorSceneManager.GetSceneManagerSetup();
|
|
|
|
|
|
|
|
|
|
|
|
foreach (SceneSetup opened_scene in opened_scenes)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool is_found = false;
|
|
|
|
|
|
|
|
|
|
|
|
foreach (Profile.SceneInfo info in profile.scenes)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (info.path.Equals(opened_scene.path))
|
|
|
|
|
|
{
|
|
|
|
|
|
is_found = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (is_found)
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Profile.SceneInfo info_new = new Profile.SceneInfo();
|
|
|
|
|
|
info_new.path = opened_scene.path;
|
|
|
|
|
|
info_new.is_enable = false;
|
|
|
|
|
|
profile.scenes.Add(info_new);
|
|
|
|
|
|
|
|
|
|
|
|
m_is_dirty = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.Separator();
|
|
|
|
|
|
|
|
|
|
|
|
bool need_silent_crashes = EditorGUILayout.Toggle("Silent Crashes", profile.need_silent_crashes);
|
|
|
|
|
|
if (need_silent_crashes != profile.need_silent_crashes)
|
|
|
|
|
|
{
|
|
|
|
|
|
profile.need_silent_crashes = need_silent_crashes;
|
|
|
|
|
|
m_is_dirty = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool need_open_folder = EditorGUILayout.Toggle("Auto Open Build Folder", profile.need_open_folder);
|
|
|
|
|
|
if (need_open_folder != profile.need_open_folder)
|
|
|
|
|
|
{
|
|
|
|
|
|
profile.need_open_folder = need_open_folder;
|
|
|
|
|
|
m_is_dirty = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (profile.build_path == null || profile.build_path.Length == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorGUILayout.HelpBox("[BuildPath] is invalid.", MessageType.Error, true);
|
|
|
|
|
|
is_deploy_ok = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (profile.filename == null || profile.filename.Length == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorGUILayout.HelpBox("[Filename] is invalid.", MessageType.Error);
|
|
|
|
|
|
is_deploy_ok = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (profile.scenes.Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorGUILayout.HelpBox("Please add at least one scene to [Scene In Build].", MessageType.Error);
|
|
|
|
|
|
is_deploy_ok = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (!profile.IsAnyEnabledSceneExist())
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorGUILayout.HelpBox("Please enable at least one scene in [Scene In Build].", MessageType.Error);
|
|
|
|
|
|
is_deploy_ok = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}//info_scope
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUI.BeginDisabledGroup(!is_deploy_ok);
|
|
|
|
|
|
|
|
|
|
|
|
using (new EditorGUILayout.VerticalScope("Box"))
|
|
|
|
|
|
{
|
|
|
|
|
|
using (new EditorGUILayout.HorizontalScope())
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorGUILayout.LabelField("★ Quick One Click Deploy Batch ★");
|
|
|
|
|
|
|
|
|
|
|
|
GUILayout.FlexibleSpace();
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUI.BeginDisabledGroup(!(profile.batch_filename.Length > 0 && profile.batch_path_relative.Length > 0));
|
|
|
|
|
|
|
|
|
|
|
|
if (GUILayout.Button("Create", GUILayout.MaxWidth(64)))
|
|
|
|
|
|
{
|
|
|
|
|
|
BuildBatchInfo info = profile.CreateBuildBatchInfo();
|
|
|
|
|
|
ucDeployTool.CreateOneClickBuildBatch(profile.ToFullBatchPath(), info);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUI.EndDisabledGroup();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.Separator();
|
|
|
|
|
|
|
|
|
|
|
|
using (new EditorGUILayout.HorizontalScope())
|
|
|
|
|
|
{
|
|
|
|
|
|
string batch_path = "";
|
|
|
|
|
|
string batch_filename = "";
|
|
|
|
|
|
|
|
|
|
|
|
using (new EditorGUILayout.VerticalScope())
|
|
|
|
|
|
{
|
|
|
|
|
|
batch_path = EditorGUILayout.TextField("[Batch] Path", profile.batch_path_abs);
|
|
|
|
|
|
batch_filename = EditorGUILayout.TextField("[Batch] Filename", profile.batch_filename);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (GUILayout.Button(new GUIContent(m_tex_icon_folder), GUILayout.Width(32), GUILayout.Height(32)))
|
|
|
|
|
|
{
|
|
|
|
|
|
string path = EditorUtility.SaveFilePanel("Select Batch Path", profile.batch_path_abs, profile.batch_filename, "bat");
|
|
|
|
|
|
if (path.Length > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
UltraCombos.Utils.SplitPath(path, out batch_path, out batch_filename);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!batch_path.Equals(profile.batch_path_abs) || !batch_filename.Equals(profile.batch_filename))
|
|
|
|
|
|
{
|
|
|
|
|
|
profile.batch_path_abs = batch_path;
|
|
|
|
|
|
profile.batch_filename = batch_filename;
|
|
|
|
|
|
m_is_dirty = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.Separator();
|
|
|
|
|
|
|
|
|
|
|
|
using (new EditorGUILayout.HorizontalScope())
|
|
|
|
|
|
{
|
|
|
|
|
|
GUILayout.FlexibleSpace();
|
|
|
|
|
|
|
|
|
|
|
|
//[Bug] Can not call BuildPipeline.BuildPlayer in beginHorizontal or vertical
|
|
|
|
|
|
//https://forum.unity3d.com/threads/i-have-error-if-i-use-a-custom-editorwindow-and-pipeline-buildplayer.371431/
|
|
|
|
|
|
if (GUILayout.Button("Deploy", GUILayout.MaxWidth(64)))
|
|
|
|
|
|
{
|
|
|
|
|
|
m_deploy_profile = profile;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (GUILayout.Button("Deploy And Run", GUILayout.MaxWidth(128)))
|
|
|
|
|
|
{
|
|
|
|
|
|
m_deploy_profile = profile;
|
|
|
|
|
|
m_need_run = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUI.EndDisabledGroup();
|
|
|
|
|
|
|
|
|
|
|
|
} while (false);
|
|
|
|
|
|
|
|
|
|
|
|
}//info_view_scope
|
|
|
|
|
|
|
|
|
|
|
|
}//main_scope
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUI.EndDisabledGroup(); //Dialog ing;
|
|
|
|
|
|
|
|
|
|
|
|
EditorGUI.EndDisabledGroup(); //Deploying;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool mf_CanDeploy(Profile profile)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!ucDeployTool.IsSupportPlatform(profile.platform))
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (profile.build_path == null || profile.build_path.Length == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (profile.filename == null || profile.filename.Length == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (profile.scenes.Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (!profile.IsAnyEnabledSceneExist())
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void OnDestroy()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (m_is_dirty)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool yes = EditorUtility.DisplayDialog("[WARNING] Value Dirty", "The shipper will be closed, \nbut some values are modified.\nDo you want to save those changed?", "Save", "Give up");
|
|
|
|
|
|
if (yes)
|
|
|
|
|
|
{
|
|
|
|
|
|
mf_Save();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
s_shipper = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static bool sf_IsScenePathExist(Profile profile, string path)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach(Profile.SceneInfo info in profile.scenes)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (info.path == path)
|
|
|
|
|
|
{
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static bool sf_DeployProfile(Profile profile)
|
|
|
|
|
|
{
|
|
|
|
|
|
string path = profile.ToFullBuildPath();
|
|
|
|
|
|
string[] scenes = profile.ToScenePathArray();
|
|
|
|
|
|
|
|
|
|
|
|
if (scenes.Length == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool yes = ucDeployTool.Deploy(path, profile.platform, scenes);
|
|
|
|
|
|
if (!yes)
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (ucDeployTool.NeedBatch(profile.platform))
|
|
|
|
|
|
{
|
|
|
|
|
|
ucDeployTool.CreateBatchFileAndHideTheExe(path, profile.need_silent_crashes);
|
|
|
|
|
|
|
|
|
|
|
|
if (profile.need_open_folder)
|
|
|
|
|
|
{
|
|
|
|
|
|
ucDeployTool.OpenTheFolder(path);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static string sf_GetSavedataPath()
|
|
|
|
|
|
{
|
|
|
|
|
|
return UltraCombos.Utils.GetProjectPath() + "/ShipperProfiles.json";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static string s_str_hash_code
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return Animator.StringToHash(Application.dataPath).ToString();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static int s_index_default
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return EditorPrefs.GetInt("Shipper_IndexDefault_" + s_str_hash_code) - 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
|
|
|
|
|
EditorPrefs.SetInt("Shipper_IndexDefault_" + s_str_hash_code, value + 1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void mf_Save()
|
|
|
|
|
|
{
|
|
|
|
|
|
Profile[] profiles = m_map_profile.Values.ToArray();
|
|
|
|
|
|
string data = "";
|
|
|
|
|
|
if (profiles.Length != 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
SaveData savedata = new SaveData();
|
|
|
|
|
|
savedata.profiles = profiles;
|
|
|
|
|
|
savedata.pronames = m_keys;
|
|
|
|
|
|
data = JsonUtility.ToJson(savedata, true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
System.IO.File.WriteAllText(sf_GetSavedataPath(), data);
|
|
|
|
|
|
s_index_default = m_index_default;
|
|
|
|
|
|
|
|
|
|
|
|
m_is_dirty = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static Profile sf_LoadDefaultProfile()
|
|
|
|
|
|
{
|
|
|
|
|
|
int index_default = s_index_default;
|
|
|
|
|
|
if (index_default < 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string data = System.IO.File.ReadAllText(sf_GetSavedataPath());
|
|
|
|
|
|
if (data.Length <= 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SaveData savedata = null;
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
savedata = JsonUtility.FromJson<SaveData>(data);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (System.Exception exception)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogWarning(exception.Message);
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (index_default >= savedata.profiles.Length)
|
|
|
|
|
|
{
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return savedata.profiles[index_default];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool mf_Load()
|
|
|
|
|
|
{
|
|
|
|
|
|
string data = System.IO.File.ReadAllText(sf_GetSavedataPath());
|
|
|
|
|
|
if (data.Length > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
SaveData savedata = null;
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
savedata = JsonUtility.FromJson<SaveData>(data);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (System.Exception exception)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogWarning(exception.Message);
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (savedata == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_map_profile.Clear();
|
|
|
|
|
|
m_lst_proname.Clear();
|
|
|
|
|
|
|
|
|
|
|
|
foreach (Profile profile in savedata.profiles)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_map_profile.Add(profile.name, profile);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_lst_proname.AddRange(savedata.pronames);
|
|
|
|
|
|
m_keys = savedata.pronames;
|
|
|
|
|
|
m_index_default = s_index_default;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
m_map_profile.Clear();
|
|
|
|
|
|
m_lst_proname.Clear();
|
|
|
|
|
|
m_keys = new string[] {};
|
|
|
|
|
|
m_index_default = -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (m_keys.Length > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (m_selected < 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_selected = m_index_default < 0? 0: m_index_default;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (m_selected >= m_keys.Length)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_selected = m_keys.Length - 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
m_is_dirty = false;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool mf_IsDialogExist()
|
|
|
|
|
|
{
|
|
|
|
|
|
return (m_dialog_for_creating != null || m_dialog_for_duplicating != null || m_dialog_for_renaming != null);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void mf_SetupDialogPos(InputDialog dialog)
|
|
|
|
|
|
{
|
|
|
|
|
|
Rect p = dialog.position;
|
|
|
|
|
|
p.x = position.x + (position.width - p.width) * 0.5f;
|
|
|
|
|
|
p.y = position.y + (position.height - p.height) * 0.5f;
|
|
|
|
|
|
dialog.position = p;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void mf_CreateProfile()
|
|
|
|
|
|
{
|
|
|
|
|
|
m_dialog_for_creating = InputDialog.Create<CreateDialog>("Create The Profile") as CreateDialog;
|
|
|
|
|
|
m_dialog_for_creating.minSize = new Vector2(360, 95);
|
|
|
|
|
|
m_dialog_for_creating.maxSize = m_dialog_for_creating.minSize;
|
|
|
|
|
|
m_dialog_for_creating.EventButton += OnButton_InputDialog;
|
|
|
|
|
|
m_dialog_for_creating.ShowDialog();
|
|
|
|
|
|
|
|
|
|
|
|
mf_SetupDialogPos(m_dialog_for_creating);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void mf_DuplicateProfile(Profile profile)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_dialog_for_duplicating = InputDialog.Create<DuplicateDialog>("Duplicate The Profile") as DuplicateDialog;
|
|
|
|
|
|
m_dialog_for_duplicating.ProfileName = profile.name + "_Duplicate";
|
|
|
|
|
|
m_dialog_for_duplicating.DuplicatedProfile = profile;
|
|
|
|
|
|
m_dialog_for_duplicating.minSize = new Vector2(360, 75);
|
|
|
|
|
|
m_dialog_for_duplicating.maxSize = m_dialog_for_duplicating.minSize;
|
|
|
|
|
|
m_dialog_for_duplicating.EventButton += OnButton_InputDialog;
|
|
|
|
|
|
m_dialog_for_duplicating.ShowDialog();
|
|
|
|
|
|
|
|
|
|
|
|
mf_SetupDialogPos(m_dialog_for_duplicating);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void mf_RenameProfile(Profile profile)
|
|
|
|
|
|
{
|
|
|
|
|
|
m_dialog_for_renaming = InputDialog.Create<RenameDialog>("Rename The Profile") as RenameDialog;
|
|
|
|
|
|
m_dialog_for_renaming.RenameTo = profile.name;
|
|
|
|
|
|
m_dialog_for_renaming.RenameProfile = profile;
|
|
|
|
|
|
m_dialog_for_renaming.minSize = new Vector2(360, 75);
|
|
|
|
|
|
m_dialog_for_renaming.maxSize = m_dialog_for_renaming.minSize;
|
|
|
|
|
|
m_dialog_for_renaming.EventButton += OnButton_InputDialog;
|
|
|
|
|
|
m_dialog_for_renaming.ShowDialog();
|
|
|
|
|
|
|
|
|
|
|
|
mf_SetupDialogPos(m_dialog_for_renaming);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool mf_DeleteProfile(string key)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool yes = EditorUtility.DisplayDialog("[WARNING] Delete Profile: " + key , "Are you sure you want to delete this profile [" + key +"] ?", "Confirm", "Cancel");
|
|
|
|
|
|
if (yes)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (m_map_profile.ContainsKey(key))
|
|
|
|
|
|
{
|
|
|
|
|
|
m_map_profile.Remove(key);
|
|
|
|
|
|
m_lst_proname.Remove(key);
|
|
|
|
|
|
m_keys = m_lst_proname.ToArray();
|
|
|
|
|
|
m_is_dirty = true;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Profile mf_SelectedProfile()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (m_selected < 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string key = m_keys[m_selected];
|
|
|
|
|
|
Profile profile;
|
|
|
|
|
|
if (!m_map_profile.TryGetValue(key, out profile))
|
|
|
|
|
|
{
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return profile;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
UnityEngine.Object mf_CheckDragAndDrop< T >(Event e, Rect rect)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (e.type)
|
|
|
|
|
|
{
|
|
|
|
|
|
case EventType.DragUpdated:
|
|
|
|
|
|
case EventType.DragPerform:
|
|
|
|
|
|
if (rect.Contains(e.mousePosition))
|
|
|
|
|
|
{
|
|
|
|
|
|
UnityEngine.Object obj = null;
|
|
|
|
|
|
foreach (UnityEngine.Object dragged_object in DragAndDrop.objectReferences)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (dragged_object is T)
|
|
|
|
|
|
{
|
|
|
|
|
|
obj = dragged_object;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (obj == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
|
|
|
|
|
|
if (e.type == EventType.DragPerform)
|
|
|
|
|
|
{
|
|
|
|
|
|
return obj;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string mf_CheckDragAndDropPath(Event e, Rect rect, string substirng = null)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (e.type)
|
|
|
|
|
|
{
|
|
|
|
|
|
case EventType.DragUpdated:
|
|
|
|
|
|
case EventType.DragPerform:
|
|
|
|
|
|
if (rect.Contains(e.mousePosition))
|
|
|
|
|
|
{
|
|
|
|
|
|
string path = null;
|
|
|
|
|
|
foreach (string dragged_path in DragAndDrop.paths)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (substirng == null || dragged_path.Contains(substirng))
|
|
|
|
|
|
{
|
|
|
|
|
|
path = dragged_path;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (path == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
|
|
|
|
|
|
if (e.type == EventType.DragPerform)
|
|
|
|
|
|
{
|
|
|
|
|
|
return path;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void mf_Init()
|
|
|
|
|
|
{
|
|
|
|
|
|
s_shipper = this;
|
|
|
|
|
|
m_tex_icon_folder = AssetDatabase.LoadAssetAtPath<Texture>("Assets/UC/Deployment/Editor/Resource/icon_folder.png");
|
|
|
|
|
|
m_style_profile_name = new GUIStyle(GUI.skin.label);
|
|
|
|
|
|
m_style_profile_name.fontSize = 16;
|
|
|
|
|
|
m_style_profile_name.fontStyle = FontStyle.Bold;
|
|
|
|
|
|
m_is_init = true;
|
|
|
|
|
|
|
|
|
|
|
|
mf_Load();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//public void Print()
|
|
|
|
|
|
//{
|
|
|
|
|
|
// foreach(string s in m_map_profile.Keys)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// Debug.Log(s);
|
|
|
|
|
|
// }
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
}
|