This commit is contained in:
CortexCore
2023-10-20 19:31:12 +08:00
parent 5cd094ed9a
commit a160813262
1878 changed files with 630581 additions and 4485 deletions

View File

@@ -0,0 +1,91 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace MeshCombineStudio
{
[CustomEditor(typeof(CombinedLODManager))]
public class CombinedLODManagerEditor : Editor
{
SerializedProperty drawGizmos, distances, lodMode, lodDistanceMode, showLod, lodCulled, lodCullDistance;
SerializedProperty[] distanceElements;
float editorSkinMulti;
private void OnEnable()
{
editorSkinMulti = EditorGUIUtility.isProSkin ? 1 : 0.35f;
drawGizmos = serializedObject.FindProperty("drawGizmos");
lodMode = serializedObject.FindProperty("lodMode");
lodDistanceMode = serializedObject.FindProperty("lodDistanceMode");
showLod = serializedObject.FindProperty("showLod");
distances = serializedObject.FindProperty("distances");
lodCulled = serializedObject.FindProperty("lodCulled");
lodCullDistance = serializedObject.FindProperty("lodCullDistance");
}
public override void OnInspectorGUI()
{
// DrawDefaultInspector();
CombinedLODManager combinedLODManager = (CombinedLODManager)target;
serializedObject.Update();
GUI.color = Color.yellow * editorSkinMulti;
EditorGUILayout.BeginVertical("Box");
GUI.color = Color.white;
GUIDraw.LabelWidthUnderline(new GUIContent("LOD Settings", ""), 14);
EditorGUILayout.PropertyField(drawGizmos);
EditorGUILayout.PropertyField(lodMode);
GUI.changed = false;
EditorGUILayout.PropertyField(lodDistanceMode);
if (GUI.changed)
{
MeshCombiner meshCombiner = combinedLODManager.GetComponent<MeshCombiner>();
if (meshCombiner != null)
{
serializedObject.ApplyModifiedProperties();
combinedLODManager.UpdateDistances(meshCombiner);
return;
}
}
EditorGUILayout.PropertyField(lodCulled);
if (lodCulled.boolValue)
{
EditorGUILayout.PropertyField(lodCullDistance);
if (lodCullDistance.floatValue < 0) lodCullDistance.floatValue = 0;
}
if (lodMode.enumValueIndex == 1)
{
EditorGUILayout.PropertyField(showLod);
if (showLod.intValue < 0) showLod.intValue = 0;
if (showLod.intValue >= distances.arraySize) showLod.intValue = distances.arraySize - 1;
}
else
{
GUI.changed = false;
GUIDraw.PropertyArray(distances, new GUIContent(""), new GUIContent(""), false, false);
if (GUI.changed) lodDistanceMode.enumValueIndex = 1;
if (distanceElements == null || distanceElements.Length != distances.arraySize) distanceElements = new SerializedProperty[distances.arraySize];
for (int i = 0; i < distances.arraySize; i++)
{
distanceElements[i] = distances.GetArrayElementAtIndex(i);
if (i == 0) distanceElements[i].floatValue = 0;
else if (distanceElements[i].floatValue < distanceElements[i - 1].floatValue) distanceElements[i].floatValue = distanceElements[i - 1].floatValue + 0.1f;
}
}
EditorGUILayout.EndVertical();
serializedObject.ApplyModifiedProperties();
}
}
}

View File

@@ -0,0 +1,24 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace MeshCombineStudio
{
#if MCS2_DETECT_MESH_IMPORT_SETTINGS_CHANGE
public class DetectMeshImportSettingsChange : AssetPostprocessor
{
void OnPreprocessModel()
{
// ModelImporter importer = (ModelImporter)assetImporter;
// List<MeshCombiner> instances = MeshCombiner.instances;
// Debug.Log("MeshCombiner instances " + instances.Count);
MeshCombineJobManager.ResetMeshCache();
}
}
#endif
}

View File

@@ -0,0 +1,214 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
namespace MeshCombineStudio
{
static public class GUIDraw
{
public static float indentSpace = 12;
public static void DrawHeader(SerializedProperty foldout, GUIContent guiContent, Color color)
{
GUI.color = color;
EditorGUILayout.BeginVertical("Box");
GUI.color = Color.white;
EditorGUILayout.BeginHorizontal();
GUILayout.Space(15);
LabelWidthUnderline(guiContent, 14, true, foldout.boolValue);
Rect rect = GUILayoutUtility.GetLastRect();
rect.x = 20;
rect.y += 3;
rect.width = 20;
rect.height = 20;
foldout.boolValue = EditorGUI.Foldout(rect, foldout.boolValue, GUIContent.none);
EditorGUILayout.EndHorizontal();
if (foldout.boolValue) GUILayout.Space(4);
}
static public void DrawSpacer(float spaceBegin = 5, float height = 5, float spaceEnd = 5)
{
GUILayout.Space(spaceBegin - 1);
EditorGUILayout.BeginHorizontal();
GUI.color = new Color(0.5f, 0.5f, 0.5f, 1);
GUILayout.Button(string.Empty, GUILayout.Height(height));
EditorGUILayout.EndHorizontal();
GUILayout.Space(spaceEnd - 1);
GUI.color = Color.white;
}
public static void PrefixAndLabel(GUIContent prefix, GUIContent label)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel(prefix);
EditorGUILayout.LabelField(label);
EditorGUILayout.EndHorizontal();
}
public static void PrefixAnd2Labels(string prefix, string label, float labelWidth, string label2)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel(prefix);
EditorGUILayout.LabelField(label, GUILayout.Width(labelWidth));
EditorGUILayout.LabelField(label2, GUILayout.Width(labelWidth));
EditorGUILayout.EndHorizontal();
}
public static void PrefixAnd2Labels(GUIContent prefix, GUIContent label, float labelWidth, GUIContent label2)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel(prefix);
EditorGUILayout.LabelField(label, GUILayout.Width(labelWidth));
EditorGUILayout.LabelField(label2, GUILayout.Width(labelWidth));
EditorGUILayout.EndHorizontal();
}
static public void Label(string label, int fontSize)
{
int fontSizeOld = EditorStyles.label.fontSize;
EditorStyles.boldLabel.fontSize = fontSize;
EditorGUILayout.LabelField(label, EditorStyles.boldLabel, GUILayout.Height(fontSize + 6));
EditorStyles.boldLabel.fontSize = fontSizeOld;
}
static public void LabelWidthUnderline(GUIContent guiContent, int fontSize, bool boldLabel = true, bool drawUnderline = true)
{
int fontSizeOld = EditorStyles.label.fontSize;
EditorStyles.boldLabel.fontSize = fontSize;
EditorGUILayout.LabelField(guiContent, boldLabel ? EditorStyles.boldLabel : EditorStyles.label, GUILayout.Height(fontSize + 6));
EditorStyles.boldLabel.fontSize = fontSizeOld;
if (drawUnderline) DrawUnderLine();
GUILayout.Space(5);
}
static public void PrefixAndLabelWidthUnderline(GUIContent prefix, GUIContent label, int fontSize, bool drawUnderline = true)
{
int fontSizeOld = EditorStyles.label.fontSize;
EditorStyles.boldLabel.fontSize = fontSize;
EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel(" ", EditorStyles.label, EditorStyles.boldLabel);
Rect rect = GUILayoutUtility.GetLastRect();
rect.height = fontSize + 6;
EditorGUI.LabelField(rect, prefix, EditorStyles.boldLabel);
GUILayout.Space(-2);
EditorGUILayout.LabelField(label, EditorStyles.boldLabel, GUILayout.Height(fontSize + 6));
EditorGUILayout.EndHorizontal();
EditorStyles.boldLabel.fontSize = fontSizeOld;
if (drawUnderline) DrawUnderLine();
GUILayout.Space(5);
}
static public void DrawUnderLine(float offsetY = 0)
{
Rect rect = GUILayoutUtility.GetLastRect();
if (EditorGUIUtility.isProSkin) GUI.color = Color.grey; else GUI.color = Color.black;
GUI.DrawTexture(new Rect(rect.x, rect.yMax + offsetY, rect.width, 1), Texture2D.whiteTexture);
GUI.color = Color.white;
}
static public void PropertyField(SerializedProperty property, GUIContent guiContent, bool indent = false, int indentMinus = 1)
{
EditorGUILayout.BeginHorizontal();
if (indent) EditorGUI.indentLevel++;
EditorGUILayout.PrefixLabel(guiContent);
if (indent) EditorGUI.indentLevel -= indentMinus;
EditorGUILayout.PropertyField(property, GUIContent.none);
EditorGUILayout.EndHorizontal();
}
static public void MaskField(SerializedProperty property, string[] masks, GUIContent guiContent, bool indent = false, int indentMinus = 1)
{
EditorGUILayout.BeginHorizontal();
if (indent) EditorGUI.indentLevel++;
EditorGUILayout.PrefixLabel(guiContent);
if (indent) EditorGUI.indentLevel -= indentMinus;
property.intValue = EditorGUILayout.MaskField(property.intValue, masks);
EditorGUILayout.EndHorizontal();
}
static public bool Toggle(bool toggle, GUIContent guiContent, bool indent = false)
{
EditorGUILayout.BeginHorizontal();
if (indent) EditorGUI.indentLevel++;
EditorGUILayout.PrefixLabel(guiContent);
if (indent) EditorGUI.indentLevel--;
toggle = EditorGUILayout.Toggle(GUIContent.none, toggle);
EditorGUILayout.EndHorizontal();
return toggle;
}
static public Enum EnumPopup(Enum enumValue, GUIContent guiContent, bool indent = false)
{
EditorGUILayout.BeginHorizontal();
if (indent) EditorGUI.indentLevel++;
EditorGUILayout.PrefixLabel(guiContent);
if (indent) EditorGUI.indentLevel--;
enumValue = EditorGUILayout.EnumPopup(enumValue);
EditorGUILayout.EndHorizontal();
return enumValue;
}
static public void LayerField(SerializedProperty property, GUIContent guiContent, bool indent = false)
{
EditorGUILayout.BeginHorizontal();
if (indent) EditorGUI.indentLevel++;
EditorGUILayout.PrefixLabel(guiContent);
if (indent) EditorGUI.indentLevel--;
property.intValue = EditorGUILayout.LayerField(GUIContent.none, property.intValue);
EditorGUILayout.EndHorizontal();
}
static public bool PropertyArray(SerializedProperty property, GUIContent arrayName, GUIContent elementName, bool drawUnderLine = true, bool editArrayLength = true, bool indent = false, bool newElementNull = false)
{
EditorGUILayout.BeginHorizontal();
// EditorGUI.indentLevel++;
// property.isExpanded = EditorGUILayout.Toggle(property.isExpanded, GUILayout.Width(15));
EditorGUILayout.PrefixLabel(new GUIContent(arrayName.text + " Size", arrayName.tooltip));
GUI.changed = false;
if (editArrayLength)
{
if (!indent) EditorGUI.indentLevel--;
int oldSize = property.arraySize;
property.arraySize = EditorGUILayout.IntField("", property.arraySize);
if (GUI.changed && newElementNull && property.arraySize > oldSize)
{
SerializedProperty prop = property.GetArrayElementAtIndex(property.arraySize - 1);
if (prop != null) prop.objectReferenceValue = null;
}
if (!indent) EditorGUI.indentLevel++;
}
// if (property.isExpanded)
{
EditorGUILayout.EndHorizontal();
// if (indent) EditorGUI.indentLevel++;
GUIContent elementNameCopy = new GUIContent(elementName);
for (int i = 0; i < property.arraySize; i++)
{
SerializedProperty elementProperty = property.GetArrayElementAtIndex(i);
elementNameCopy.text = elementName.text + " " + i;
PropertyField(elementProperty, elementNameCopy, true, indent ? 1 : 2);
if (!indent) EditorGUI.indentLevel++;
}
// if (indent) EditorGUI.indentLevel--;
}
return GUI.changed;
// else EditorGUILayout.EndHorizontal();
// EditorGUI.indentLevel--;
}
}
}

View File

@@ -0,0 +1,87 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace MeshCombineStudio
{
[CustomEditor(typeof(LODGroupSetup))]
public class LODGroupSetupEditor : Editor
{
LODGroupSetup lodGroupSetup;
LOD[] oldLods;
bool animateCrossFadingOld;
LODFadeMode fadeModeOld;
void OnEnable()
{
lodGroupSetup = (LODGroupSetup)target;
LODGroup lodGroup = lodGroupSetup.lodGroup;
oldLods = lodGroup.GetLODs();
animateCrossFadingOld = lodGroup.animateCrossFading;
fadeModeOld = lodGroup.fadeMode;
UnityEditor.EditorApplication.update += MyUpdate;
}
void OnDisable()
{
UnityEditor.EditorApplication.update -= MyUpdate;
}
void MyUpdate()
{
LODGroup lodGroup = lodGroupSetup.lodGroup;
lodGroup.size = lodGroupSetup.meshCombiner.cellSize;
LOD[] lods = lodGroup.GetLODs();
if (lods.Length != oldLods.Length)
{
Debug.LogError("Mesh Combine Studio -> Please don't change the amount of LODs, this is just a dummy LOD Group to apply settings to the LOD Groups in all children.");
lodGroup.SetLODs(oldLods);
return;
}
bool hasChanged = false;
if (lodGroup.animateCrossFading != animateCrossFadingOld || lodGroup.fadeMode != fadeModeOld)
{
hasChanged = true;
}
else
{
for (int i = 0; i < lods.Length; i++)
{
if (lods[i].renderers.Length != 0)
{
Debug.LogError("Mesh Combine Studio -> Please don't add any renderes, this is just a dummy LOD Group to apply settings to the LOD Groups in all children.");
lods[i].renderers = null;
lodGroup.SetLODs(lods);
return;
}
if (lods[i].screenRelativeTransitionHeight != oldLods[i].screenRelativeTransitionHeight) { hasChanged = true; break; }
if (lods[i].fadeTransitionWidth != oldLods[i].fadeTransitionWidth) { hasChanged = true; break; }
}
}
if (hasChanged)
{
lodGroupSetup.ApplySetup();
oldLods = lods;
}
}
public override void OnInspectorGUI()
{
GUIDraw.DrawSpacer();
GUI.color = Color.red;
EditorGUILayout.BeginVertical("Box");
GUI.color = Color.white;
GUIDraw.Label("Modifications to this LOD Group will apply to all children", 12);
EditorGUILayout.EndVertical();
GUIDraw.DrawSpacer();
}
}
}

View File

@@ -0,0 +1,14 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace MeshCombineStudio
{
[CustomEditor(typeof(MeshCombineJobManager))]
public class MeshCombineJobManagerEditor : Editor
{
}
}

View File

@@ -0,0 +1,16 @@
{
"name": "MeshCombineStudio.Editor",
"references": [
"MeshCombineStudio.Runtime"
],
"optionalUnityReferences": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": []
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,167 @@
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.IO;
using System.Text;
namespace MeshCombineStudio
{
public class ObjExporterScript
{
private static int StartIndex = 0;
public static void Start()
{
StartIndex = 0;
}
public static void End()
{
StartIndex = 0;
}
public static string MeshToString(MeshRenderer mr, MeshFilter mf, Transform t)
{
// Vector3 s = t.localScale;
// Vector3 p = t.localPosition;
Quaternion r = t.localRotation;
int numVertices = 0;
Mesh m = mf.sharedMesh;
if (m == null) return "####Error####";
Material[] mats = mr.sharedMaterials;
StringBuilder sb = new StringBuilder();
foreach (Vector3 vv in m.vertices)
{
Vector3 v = t.TransformPoint(vv);
numVertices++;
sb.Append(string.Format("v {0} {1} {2}\n", v.x, v.y, -v.z));
}
sb.Append("\n");
foreach (Vector3 nn in m.normals)
{
Vector3 v = r * nn;
sb.Append(string.Format("vn {0} {1} {2}\n", -v.x, -v.y, v.z));
}
sb.Append("\n");
foreach (Vector3 v in m.uv)
{
sb.Append(string.Format("vt {0} {1}\n", v.x, v.y));
}
for (int material = 0; material < m.subMeshCount; material++)
{
sb.Append("\n");
sb.Append("usemtl ").Append(mats[material].name).Append("\n");
sb.Append("usemap ").Append(mats[material].name).Append("\n");
int[] triangles = m.GetTriangles(material);
for (int i = 0; i < triangles.Length; i += 3)
{
sb.Append(string.Format("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}\n",
triangles[i] + 1 + StartIndex, triangles[i + 1] + 1 + StartIndex, triangles[i + 2] + 1 + StartIndex));
}
}
StartIndex += numVertices;
return sb.ToString();
}
}
public class ObjExporter : ScriptableObject
{
[MenuItem("GameObject/Export/Wavefront OBJ")]
static void DoExportWSubmeshes()
{
DoExport(true);
}
[MenuItem("GameObject/Export/Wavefront OBJ (No Submeshes)")]
static void DoExportWOSubmeshes()
{
DoExport(false);
}
static void DoExport(bool makeSubmeshes)
{
if (Selection.gameObjects.Length == 0)
{
Debug.Log("Didn't Export Any Meshes; Nothing was selected!");
return;
}
string meshName = Selection.gameObjects[0].name;
string fileName = EditorUtility.SaveFilePanel("Export .obj file", "", meshName, "obj");
ObjExporterScript.Start();
StringBuilder meshString = new StringBuilder();
meshString.Append("#" + meshName + ".obj"
+ "\n#" + System.DateTime.Now.ToLongDateString()
+ "\n#" + System.DateTime.Now.ToLongTimeString()
+ "\n#-------"
+ "\n\n");
Transform t = Selection.gameObjects[0].transform;
Vector3 originalPosition = t.position;
t.position = Vector3.zero;
if (!makeSubmeshes)
{
meshString.Append("g ").Append(t.name).Append("\n");
}
meshString.Append(processTransform(t, makeSubmeshes));
WriteToFile(meshString.ToString(), fileName);
t.position = originalPosition;
ObjExporterScript.End();
Debug.Log("Exported Mesh: " + fileName);
}
static string processTransform(Transform t, bool makeSubmeshes)
{
StringBuilder meshString = new StringBuilder();
meshString.Append("#" + t.name
+ "\n#-------"
+ "\n");
if (makeSubmeshes)
{
meshString.Append("g ").Append(t.name).Append("\n");
}
MeshFilter mf = t.GetComponent<MeshFilter>();
if (mf)
{
MeshRenderer mr = t.GetComponent<MeshRenderer>();
if (mr != null)
{
meshString.Append(ObjExporterScript.MeshToString(mr, mf, t));
}
}
for (int i = 0; i < t.childCount; i++)
{
meshString.Append(processTransform(t.GetChild(i), makeSubmeshes));
}
return meshString.ToString();
}
static void WriteToFile(string s, string filename)
{
using (StreamWriter sw = new StreamWriter(filename))
{
sw.Write(s);
}
}
}
}

View File

@@ -0,0 +1,351 @@
using UnityEngine;
using UnityEditor;
using System;
using System.Collections;
using UnityEngine.Networking;
namespace MeshCombineStudio
{
public class MCSProducts
{
public Texture asIconSale, asIcon;
public Texture mcsIcon;
public Texture mcsCavesIcon;
public Texture deIcon;
public Texture tcIcon;
public Texture wcIcon;
public Texture saleIcon;
public bool mcsInProject, mcsCavesInProject, deInProject, tcInProject, wcInProject;
public bool showAs, hasSale, mcsSale, mcsCavesSale, deSale, tcSale, wcSale;
public string saleText, mcsSaleText, mcsCavesSaleText, deSaleText, tcSaleText, wcSaleText;
public string asUrl;
public int waitSecondsForRecheck;
float scrollBarX;
UnityWebRequest www;
public MCSProducts()
{
mcsInProject = (GetType("MeshCombineStudio.MeshCombiner") != null);
mcsCavesInProject = (GetType("MeshCombineStudio.RemoveOverlappingTris") != null);
deInProject = (GetType("DebuggingEssentials.RuntimeInspector") != null);
tcInProject = (GetType("TerrainComposer2.TC_Generate") != null);
wcInProject = (GetType("WorldComposer.terrain_area_class") != null);
}
public static Type GetType(string typeName)
{
Type type = Type.GetType(typeName + ", Assembly-CSharp");
if (type != null) return type;
type = Type.GetType(typeName + ", Assembly-CSharp-firstpass");
return type;
}
void UpdateSale()
{
if (www == null)
{
EditorApplication.update -= UpdateSale;
SetPlayerPrefs();
return;
}
if (!www.isDone) return;
EditorApplication.update -= UpdateSale;
#if UNITY_2020_2_OR_NEWER
if (www.result == UnityWebRequest.Result.ConnectionError ||
www.result == UnityWebRequest.Result.ProtocolError ||
www.result == UnityWebRequest.Result.DataProcessingError)
{
//Debug.Log(www.error);
SetPlayerPrefs();
return;
}
#else
if (www.isNetworkError || www.isHttpError)
{
//Debug.Log(www.error);
SetPlayerPrefs();
return;
}
#endif
string text = www.downloadHandler.text;
string[] lines = text.Split('\n');
// line 0 => seconds wait
// line 1 => "No Sale" or `Sale Name`
// line 2 => "AS__" or "AS_X" + AS URL
int.TryParse(lines[0], out waitSecondsForRecheck);
if (waitSecondsForRecheck < 10) waitSecondsForRecheck = 10;
showAs = lines[2].Contains("AS__");
if (showAs) asUrl = lines[2].Substring(5);
if (lines[1].Contains("No Sale"))
{
saleText = string.Empty;
SetPlayerPrefs();
return;
}
hasSale = true;
saleText = lines[1];
deSale = lines[3].Contains("DE_1");
mcsSale = lines[4].Contains("MCS_1");
mcsCavesSale = lines[5].Contains("MCSCaves_1");
wcSale = lines[6].Contains("WC_1");
tcSale = lines[7].Contains("TC_1");
if (deSale) deSaleText = "50% Discount on Unity's " + saleText + " NOW!\n" + lines[3].Replace("DE_1 ", "") + "\n\n";
if (mcsSale) mcsSaleText = "50% Discount on Unity's " + saleText + " NOW!\n" + lines[4].Replace("MCS_1 ", "") + "\n\n";
if (mcsCavesSale) mcsCavesSaleText = "50% Discount on Unity's " + saleText + " NOW!\n" + lines[5].Replace("MCSCaves_1 ", "") + "\n\n";
if (wcSale) wcSaleText = "50% Discount on Unity's " + saleText + " NOW!\n" + lines[6].Replace("WC_1 ", "") + "\n\n";
if (tcSale) tcSaleText = "50% Discount on Unity's " + saleText + " NOW!\n" + lines[7].Replace("TC_1 ", "") + "\n\n";
// Debug.Log(saleText + "de " + deSale + " mcs " + mcsSale + " mcsCaves " + mcsCavesSale + " wc " + wcSale + " tc " + tcSale);
//for (int i = 0; i < lines.Length; i++)
//{
// Debug.Log(lines[i]);
//}
SetPlayerPrefs();
UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
}
void SetPlayerPrefs()
{
PlayerPrefs.SetInt("PON_waitSecondsForRecheck", waitSecondsForRecheck);
PlayerPrefs.SetString("PON_sale", saleText);
PlayerPrefs.SetString("PON_deSale", deSaleText);
PlayerPrefs.SetString("PON_mcsSale", mcsSaleText);
PlayerPrefs.SetString("PON_mcsCavesSale", mcsCavesSaleText);
PlayerPrefs.SetString("PON_tcSale", tcSaleText);
PlayerPrefs.SetString("PON_wcSale", wcSaleText);
PlayerPrefs.SetString("PON_asUrl", asUrl);
}
void GetPlayerPrefs()
{
saleText = PlayerPrefs.GetString("PON_sale"); hasSale = (saleText != string.Empty);
deSaleText = PlayerPrefs.GetString("PON_deSale"); deSale = (deSaleText != string.Empty);
mcsSaleText = PlayerPrefs.GetString("PON_mcsSale"); mcsSale = (mcsSaleText != string.Empty);
mcsCavesSaleText = PlayerPrefs.GetString("PON_mcsCavesSale"); mcsCavesSale = (mcsCavesSaleText != string.Empty);
tcSaleText = PlayerPrefs.GetString("PON_tcSale"); tcSale = (tcSaleText != string.Empty);
wcSaleText = PlayerPrefs.GetString("PON_wcSale"); wcSale = (wcSaleText != string.Empty);
asUrl = PlayerPrefs.GetString("PON_asUrl"); showAs = (asUrl != string.Empty);
}
void GetSale()
{
bool checkForSales = true;
#if UNITY_2022_1_OR_NEWER
// TODO: Unity 2022.1 throws InvalidOperationException: Insecure connection not allowed because URL for checking sales is http
// need to update sale URL to https
checkForSales = false;
#endif
if (!checkForSales)
{
www = null;
return;
}
DateTime lastDate;
string lastDateText = PlayerPrefs.GetString("PON_LastSaleCheck");
DateTime dateTime = DateTime.Now;
if (lastDateText == string.Empty) lastDate = DateTime.Now;
else
{
DateTime.TryParse(lastDateText, out lastDate);
TimeSpan timeSpan = dateTime - lastDate;
// Debug.Log(timeSpan.TotalSeconds);
waitSecondsForRecheck = PlayerPrefs.GetInt("PON_waitSecondsForRecheck");
if (timeSpan.TotalSeconds < waitSecondsForRecheck)
{
GetPlayerPrefs();
return;
}
}
PlayerPrefs.SetString("PON_LastSaleCheck", dateTime.ToString("", System.Globalization.CultureInfo.InvariantCulture));
// Debug.Log("Get Sale");
hasSale = false;
www = UnityWebRequest.Get("http://www.terraincomposer.com/sales.html");
try
{
#if UNITY_2017_1
www.Send();
#else
www.SendWebRequest();
#endif
EditorApplication.update -= UpdateSale;
EditorApplication.update += UpdateSale;
}
catch
{
// Unity 2022.1 beta is throwing InvalidOperationException: Insecure connection not allowed
// Ignore the exception
// TODO: need to update sale URL to https
www = null;
}
}
string GetSaleText()
{
return "50% Discount on Unity's " + saleText + " NOW!";
}
public void Draw(MonoBehaviour monoBehaviour)
{
if (mcsCavesIcon == null || deIcon == null)
{
GetSale();
string path = AssetDatabase.GetAssetPath(MonoScript.FromMonoBehaviour(monoBehaviour)).Replace("Scripts/Mesh/MeshCombiner.cs", "Products/");
// string path = AssetDatabase.GetAssetPath(MonoScript.FromMonoBehaviour(monoBehaviour)).Replace("WindowManager/WindowManager.cs", "Products/");
// string path = AssetDatabase.GetAssetPath(MonoScript.FromMonoBehaviour(monoBehaviour)).Replace("Scripts/Terrain/TC_TerrainArea.cs", "Products/");
asIcon = AssetDatabase.LoadAssetAtPath(path + "asIcon.png", typeof(Texture)) as Texture;
asIconSale = AssetDatabase.LoadAssetAtPath(path + "asIconSale.png", typeof(Texture)) as Texture;
mcsIcon = AssetDatabase.LoadAssetAtPath(path + "MCSIcon.jpg", typeof(Texture)) as Texture;
mcsCavesIcon = AssetDatabase.LoadAssetAtPath(path + "MCSCavesIcon.jpg", typeof(Texture)) as Texture;
deIcon = AssetDatabase.LoadAssetAtPath(path + "deIcon.jpg", typeof(Texture)) as Texture;
tcIcon = AssetDatabase.LoadAssetAtPath(path + "tcIcon.jpg", typeof(Texture)) as Texture;
wcIcon = AssetDatabase.LoadAssetAtPath(path + "wcIcon.jpg", typeof(Texture)) as Texture;
saleIcon = AssetDatabase.LoadAssetAtPath(path + "saleIcon.png", typeof(Texture)) as Texture;
}
Rect rect1 = GUILayoutUtility.GetLastRect();
Rect rect = new Rect(rect1.x, rect1.y, 104, 104);
rect.x += 4;
rect.y += 2;
rect.x -= scrollBarX;
float width = rect.width + 4;
// Debug.Log(Screen.width + " " + (width * 4));
float alpha = 0.45f;
float active = 6.65f;
if (showAs)
{
if (GUI.Button(rect, new GUIContent(string.Empty, (hasSale ? asIconSale : asIcon), (hasSale ? ("Unity is running the " + saleText + "!\n\n") : "") + "Click to go to the 'Asset Store'.")))
{
Application.OpenURL(asUrl);
}
rect.x += width;
}
else active--;
if (!mcsInProject) DrawMCS(ref rect, width, alpha);
if (!mcsCavesInProject) DrawMCSCaves(ref rect, width, alpha);
if (!deInProject) DrawDE(ref rect, width, alpha);
if (!tcInProject) DrawTC(ref rect, width, alpha);
if (!wcInProject) DrawWC(ref rect, width, alpha);
if (mcsInProject) DrawMCS(ref rect, width, alpha);
if (mcsCavesInProject) DrawMCSCaves(ref rect, width, alpha);
if (deInProject) DrawDE(ref rect, width, alpha);
if (tcInProject) DrawTC(ref rect, width, alpha);
if (wcInProject) DrawWC(ref rect, width, alpha);
float size = (rect.width * active) - Screen.width;
GUILayout.Space(rect.width + 4);
if (size > 0)
{
scrollBarX = GUILayout.HorizontalScrollbar(scrollBarX, 25, 0, size);
}
DrawSpacer(0, 5, 0);
}
void DrawMCS(ref Rect rect, float width, float alpha)
{
if (mcsInProject) GUI.color = new Color(1, 1, 1, alpha);
if (GUI.Button(rect, new GUIContent(string.Empty, mcsIcon, mcsSaleText + "Click to go to 'Mesh Combine Studio 2'.\n\nMesh Combine Studio is an automatic grid cell based mesh combiner which can dramatically improve the performance of your game. MCS can give up to 20x better performance compared to Unitys static batching, while giving a more smooth and stable FPS.\n\nWe use MCS grid cell based combining in our game DRONE for the modular building in our arena editor and pre - made arenas, without MCS our game wouldn't run.\n\nInstead of manually combining meshes, which is very tedious, MCS will do this automatically for you sorted in grid cells, and the performance improvements it gives cannot be achieved with manual combining. Just simply drag and drop a MCS prefab in your Scene and tweak the many available conditions to your specific needs and you are ready to go.")))
{
Application.OpenURL("https://assetstore.unity.com/packages/tools/modeling/mesh-combine-studio-2-101956?aid=1011le9dK&pubref=uMCS");
}
if (mcsSale)
{
GUI.DrawTexture(new Rect(rect.x + 10, rect.y + 20, rect.width - 20, (rect.width - 20) * 0.37068f), saleIcon);
}
rect.x += width;
}
void DrawMCSCaves(ref Rect rect, float width, float alpha)
{
if (mcsCavesInProject) GUI.color = new Color(1, 1, 1, alpha); else GUI.color = Color.white;
if (GUI.Button(rect, new GUIContent(string.Empty, mcsCavesIcon, mcsCavesSaleText + "Click to go to 'MCS Caves & Overhangs' Extension.\n\nThis 'Mesh Combine Studio 2' extension gives the best performance possible by using the easiest way to get amazing looking Caves and Overhangs on any terrain solution.\n\nYou can use any Rock Asset pack from the Unity Asset Store and stack them together to create caves and overhangs, and this extension will combine all rocks and remove all inside polygons that are never visible. Resulting in a ~60-80% polygon removal + combining which gives unbeatable performance and lightmap texture reduction.\n\nOur arenas in DRONE are optimized with this MCS extension. It can also be used on any other kind of closed meshes like a level consisting out of snapped cubes.")))
{
Application.OpenURL("https://assetstore.unity.com/packages/tools/terrain/mcs-caves-overhangs-144413?aid=1011le9dK&pubref=uMCSCaves");
}
if (mcsCavesSale)
{
GUI.DrawTexture(new Rect(rect.x + 10, rect.y + 20, rect.width - 20, (rect.width - 20) * 0.37068f), saleIcon);
}
rect.x += width;
}
void DrawDE(ref Rect rect, float width, float alpha)
{
if (deInProject) GUI.color = new Color(1, 1, 1, alpha); else GUI.color = Color.white;
if (GUI.Button(rect, new GUIContent(string.Empty, deIcon, deSaleText + "Click to go to 'Debugging Essentials'.\n\nDebugging Essentials contains 5 crucial tools which will save you tons of time needed for coding while avoiding debugging headaches, making developing a lot more enjoyable!\n\n* Runtime Hierarchy.\n* Runtime Deep Inspector.\n* Runtime Camera Navigation.\n* Runtime Console.\n* HTML Debug Logs.")))
{
Application.OpenURL("https://assetstore.unity.com/packages/tools/utilities/debugging-essentials-170773?aid=1011le9dK&pubref=uDE");
}
if (deSale)
{
GUI.DrawTexture(new Rect(rect.x + 15, rect.y + 8, rect.width - 30, (rect.width - 30) * 0.37068f), saleIcon);
}
rect.x += width;
}
void DrawTC(ref Rect rect, float width, float alpha)
{
if (tcInProject) GUI.color = new Color(1, 1, 1, alpha); else GUI.color = Color.white;
if (GUI.Button(rect, new GUIContent(string.Empty, tcIcon, tcSaleText + "Click to go to 'Terrain Composer 2'.\n\nTerrainComposer2 is a powerful node based multi-terrain tile generator. TC2 makes use of the latest GPU technology to give you instant real-time results, which makes creating terrains faster and more easy than ever before.\n\nTC2 its folder like layer system and workflow is similar to that of Photoshop, which makes it possible to have full control and make quick changes any time during the workflow.")))
{
Application.OpenURL("https://assetstore.unity.com/packages/tools/terrain/terrain-composer-2-65563?aid=1011le9dK&pubref=uTC");
}
if (tcSale)
{
GUI.DrawTexture(new Rect(rect.x + 10, rect.y + 8, rect.width - 20, (rect.width - 20) * 0.37068f), saleIcon);
}
rect.x += width;
}
void DrawWC(ref Rect rect, float width, float alpha)
{
if (wcInProject) GUI.color = new Color(1, 1, 1, alpha); else GUI.color = Color.white;
if (GUI.Button(rect, new GUIContent(string.Empty, wcIcon, wcSaleText + "Click to go to 'World Composer'.\n\nWorldComposer is a tool to extract heightmap data and satellite images from the real world. It uses Bing maps, like in the new Microsoft Flight Simulator 2020.\n\nWorldComposer can create terrains by itself, but the exported heightmaps(e.g. as stamps) and satellite images can also be used in other terrain tools like TerrainComposer 2, Gaia, WorldMachine, MapMapic, WorldCreator, etc.")))
{
Application.OpenURL("https://assetstore.unity.com/packages/tools/terrain/world-composer-13238?aid=1011le9dK&pubref=uWC");
}
if (wcSale)
{
GUI.DrawTexture(new Rect(rect.x + 10, rect.y + 8, rect.width - 20, (rect.width - 20) * 0.37068f), saleIcon);
}
rect.x += width;
GUI.color = Color.white;
}
static public void DrawSpacer(float spaceBegin = 5, float height = 5, float spaceEnd = 5)
{
GUILayout.Space(spaceBegin - 1);
EditorGUILayout.BeginHorizontal();
GUI.color = new Color(0.5f, 0.5f, 0.5f, 1);
GUILayout.Button(string.Empty, GUILayout.Height(height));
EditorGUILayout.EndHorizontal();
GUILayout.Space(spaceEnd - 1);
GUI.color = Color.white;
}
}
}

View File

@@ -0,0 +1,40 @@
using UnityEngine;
using UnityEditor;
using System.Collections;
namespace MeshCombineStudio
{
[CustomEditor (typeof(ReadMe))]
public class ReadMeEditor : Editor
{
public override void OnInspectorGUI()
{
ReadMe r = (ReadMe)target;
Event eventCurrent = Event.current;
GUI.changed = false;
if (eventCurrent.control && eventCurrent.shift && eventCurrent.keyCode == KeyCode.E && eventCurrent.type == EventType.KeyDown)
{
r.buttonEdit = !r.buttonEdit;
GUI.changed = true;
}
GUILayout.Space(5);
if (r.buttonEdit)
{
EditorGUILayout.LabelField("EDIT MODE");
r.readme = EditorGUILayout.TextArea(r.readme);
}
else
{
EditorGUILayout.TextArea(r.readme);
}
if (GUI.changed) EditorUtility.SetDirty(target);
}
}
}