Compare commits
4 Commits
master
...
leveldesig
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3583fc0d97 | ||
![]() |
c4068122ce | ||
![]() |
7ee781a0e6 | ||
![]() |
89d90bb274 |
@ -25,7 +25,6 @@ Material:
|
||||
m_Parent: {fileID: 0}
|
||||
m_ModifiedSerializedProperties: 0
|
||||
m_ValidKeywords:
|
||||
- _METALLICSPECGLOSSMAP
|
||||
- _NORMALMAP
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 4
|
||||
@ -68,7 +67,7 @@ Material:
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 2800000, guid: cfbfeafcbb7c2db488438b88670b6be9, type: 3}
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
@ -120,7 +119,7 @@ Material:
|
||||
- _Parallax: 0.02
|
||||
- _QueueOffset: 0
|
||||
- _ReceiveShadows: 1
|
||||
- _Smoothness: 0.486
|
||||
- _Smoothness: 0.255
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
|
@ -37,8 +37,8 @@ Material:
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: -2}
|
||||
m_Offset: {x: 0, y: 1.06}
|
||||
m_Scale: {x: 1, y: -1}
|
||||
m_Offset: {x: 0, y: 1}
|
||||
- _MainTex_R:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
|
Before Width: | Height: | Size: 347 KiB After Width: | Height: | Size: 160 KiB |
@ -69,7 +69,7 @@ TextureImporter:
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 1024
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
|
@ -69,7 +69,7 @@ TextureImporter:
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 1024
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
|
@ -69,7 +69,7 @@ TextureImporter:
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 1024
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
|
@ -69,7 +69,7 @@ TextureImporter:
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 1024
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
|
@ -69,7 +69,7 @@ TextureImporter:
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 1024
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
|
@ -69,7 +69,7 @@ TextureImporter:
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 1024
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
|
@ -69,7 +69,7 @@ TextureImporter:
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 1024
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
|
@ -69,7 +69,7 @@ TextureImporter:
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 1024
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
|
@ -69,7 +69,7 @@ TextureImporter:
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 1024
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
|
@ -69,7 +69,7 @@ TextureImporter:
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 1024
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 1.6 MiB |
@ -45,7 +45,7 @@ TextureImporter:
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
spriteMeshType: 0
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 90 KiB |
@ -45,7 +45,7 @@ TextureImporter:
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
spriteMeshType: 0
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
|
8
Viagg-io/Assets/Plugins/MT Assets.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b8b440160a98d1f489a9cc9d8aee405c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b2e7fc1fa2e07934e81429c1e0e78b4e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 025b94e332aaa3f439e82fc54a16dc42
|
||||
timeCreated: 1575203498
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fdf2798169aa8b849b8945135b07c507
|
||||
timeCreated: 1575203542
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2d42cc6f949491249a7b0cab7d8b97f7
|
||||
folderAsset: yes
|
||||
timeCreated: 1548710849
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e3c7d63750a70841b786c043ffce964
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,87 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor.Build;
|
||||
|
||||
public class EasyMeshCombinerCompressedTextures : AssetPostprocessor, IActiveBuildTargetChanged
|
||||
{
|
||||
//This class manages the Compressed Textures generated by merge done in the Editor, creating
|
||||
//Compressed Textures for the merges, according to the Platform currently active in the Editor.
|
||||
//This code is executed automatically by the editor whenever an asset is imported.
|
||||
|
||||
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths, bool didDomainReload)
|
||||
{
|
||||
//Prepare the list of imported assets of compressed textures
|
||||
List<string> compressedTextureImportedAssets = new List<string>();
|
||||
|
||||
//Check all new imported assets...
|
||||
foreach (string assetPath in importedAssets)
|
||||
if (assetPath.ToLower().Contains("/mt assets/_assetsdata/atlases") == true)
|
||||
compressedTextureImportedAssets.Add(assetPath);
|
||||
|
||||
//Process each compressed texture generated by EMC merge done in Editor
|
||||
foreach (string assetPath in compressedTextureImportedAssets)
|
||||
if (assetPath.Contains("EMC-NMin") == true || assetPath.Contains("EMC-HMin") == true)
|
||||
{
|
||||
//Skip this asset if is a RAW texture, uncompressed
|
||||
if (assetPath.Contains("RAW.asset") == true)
|
||||
continue;
|
||||
|
||||
//Create a copy of this texture, but in raw state, if not have
|
||||
if (File.Exists(("Assets/Plugins/MT Assets/_AssetsData/Atlases/" + Path.GetFileNameWithoutExtension(assetPath) + " RAW.asset")) == false)
|
||||
AssetDatabase.CopyAsset(assetPath, ("Assets/Plugins/MT Assets/_AssetsData/Atlases/" + Path.GetFileNameWithoutExtension(assetPath) + " RAW.asset"));
|
||||
|
||||
//Load the raw version of this texture
|
||||
Texture2D rawTexture = (Texture2D)AssetDatabase.LoadAssetAtPath(assetPath.Replace(".asset", " RAW.asset"), typeof(Texture2D));
|
||||
|
||||
//Load the pixels of raw texture
|
||||
Color[] rawTexturePixels = rawTexture.GetPixels();
|
||||
//Check if the raw texture have alpha
|
||||
bool rawTextureHaveAlpha = false;
|
||||
foreach (Color pixel in rawTexturePixels)
|
||||
if (pixel.a < 1.0f)
|
||||
{
|
||||
rawTextureHaveAlpha = true;
|
||||
break;
|
||||
}
|
||||
//If is a Normal Map raw texture, inform that have a alpha, to ensure best quality on normal map
|
||||
if (rawTexture.isDataSRGB == false) //<- Normal Maps use Linear instead of sRGB
|
||||
rawTextureHaveAlpha = true;
|
||||
//Detect the color format to use for the copy compressed texture
|
||||
TextureFormat targetFormat = TextureFormat.Alpha8;
|
||||
if (rawTextureHaveAlpha == true)
|
||||
targetFormat = TextureFormat.RGBA32;
|
||||
if (rawTextureHaveAlpha == false)
|
||||
targetFormat = TextureFormat.RGB24;
|
||||
|
||||
//Copy the raw version of this texture and compress it to desired compression level (RGBA32 to DXT5/ETC2 and RGB24 to DXT1/ETC1)
|
||||
Texture2D tempTexture = new Texture2D(rawTexture.width, rawTexture.height, targetFormat, rawTexture.mipmapCount, (!rawTexture.isDataSRGB));
|
||||
tempTexture.SetPixels(0, 0, rawTexture.width, rawTexture.height, rawTexturePixels, 0);
|
||||
tempTexture.Apply();
|
||||
if (assetPath.Contains("EMC-NMin") == true)
|
||||
tempTexture.Compress(false);
|
||||
if (assetPath.Contains("EMC-HMin") == true)
|
||||
tempTexture.Compress(true);
|
||||
|
||||
//Overwrite the texture used by merge, to be the new compressed texture
|
||||
if (!AssetDatabase.IsValidFolder("Assets/Plugins/MT Assets/_AssetsData/Atlases/Temp"))
|
||||
AssetDatabase.CreateFolder("Assets/Plugins/MT Assets/_AssetsData/Atlases", "Temp");
|
||||
AssetDatabase.CreateAsset(tempTexture, ("Assets/Plugins/MT Assets/_AssetsData/Atlases/Temp/" + Path.GetFileNameWithoutExtension(assetPath) + ".asset"));
|
||||
File.Delete(assetPath);
|
||||
File.Move(("Assets/Plugins/MT Assets/_AssetsData/Atlases/Temp/" + Path.GetFileNameWithoutExtension(assetPath) + ".asset"), assetPath);
|
||||
File.Delete(("Assets/Plugins/MT Assets/_AssetsData/Atlases/Temp/" + Path.GetFileNameWithoutExtension(assetPath) + ".asset.meta"));
|
||||
}
|
||||
|
||||
//Update the asset database
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
public void OnActiveBuildTargetChanged(BuildTarget previousTarget, BuildTarget newTarget)
|
||||
{
|
||||
//Force reimport the Atlases folder of MT Assets
|
||||
AssetDatabase.ImportAsset("Assets/Plugins/MT Assets/_AssetsData/Atlases", ImportAssetOptions.ImportRecursive | ImportAssetOptions.DontDownloadFromCacheServer);
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
public int callbackOrder { get { return 0; } }
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f5e69d6a5f3b0a04ea22ae7b3887f0f8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c620b7e1afbd8a942a487e6bacd8404b
|
||||
folderAsset: yes
|
||||
timeCreated: 1571441202
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,166 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MTAssets.EasyMeshCombiner.Editor
|
||||
{
|
||||
/*
|
||||
* This script is the Dataset of the scriptable object "Preferences". This script saves Easy Mesh Combiner preferences.
|
||||
*/
|
||||
|
||||
public class MeshCombinerPreferences : ScriptableObject
|
||||
{
|
||||
public enum AfterMerge
|
||||
{
|
||||
DisableOriginalMeshes,
|
||||
DeactiveOriginalGameObjects,
|
||||
DoNothing
|
||||
}
|
||||
public enum MergeMethod
|
||||
{
|
||||
OneMeshPerMaterial,
|
||||
AllInOne,
|
||||
JustMaterialColors
|
||||
}
|
||||
public enum AtlasSize
|
||||
{
|
||||
Pixels32x32,
|
||||
Pixels64x64,
|
||||
Pixels128x128,
|
||||
Pixels256x256,
|
||||
Pixels512x512,
|
||||
Pixels1024x1024,
|
||||
Pixels2048x2048,
|
||||
Pixels4096x4096,
|
||||
Pixels8192x8192
|
||||
}
|
||||
public enum MipMapEdgesSize
|
||||
{
|
||||
Pixels0x0,
|
||||
Pixels16x16,
|
||||
Pixels32x32,
|
||||
Pixels64x64,
|
||||
Pixels128x128,
|
||||
Pixels256x256,
|
||||
Pixels512x512,
|
||||
Pixels1024x1024,
|
||||
}
|
||||
public enum AtlasPadding
|
||||
{
|
||||
Pixels0x0,
|
||||
Pixels2x2,
|
||||
Pixels4x4,
|
||||
Pixels8x8,
|
||||
Pixels16x16,
|
||||
}
|
||||
public enum MergeTiledTextures
|
||||
{
|
||||
SkipAll,
|
||||
LegacyMode
|
||||
}
|
||||
public enum TextureCompression
|
||||
{
|
||||
Disabled,
|
||||
NormalQuality,
|
||||
HighQuality
|
||||
}
|
||||
public enum LightmapMode
|
||||
{
|
||||
RecycleData,
|
||||
GenerateData
|
||||
}
|
||||
public enum MaterialGlobalIllumination
|
||||
{
|
||||
None,
|
||||
Realtime,
|
||||
Baked
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class OneMeshPerMaterialParams
|
||||
{
|
||||
public bool addMeshCollider = false;
|
||||
}
|
||||
[System.Serializable]
|
||||
public class AllInOneParams
|
||||
{
|
||||
public Material materialToUse;
|
||||
public int maxTexturesPerAtlas = 12;
|
||||
public AtlasSize atlasResolution = AtlasSize.Pixels1024x1024;
|
||||
public MipMapEdgesSize mipMapEdgesSize = MipMapEdgesSize.Pixels64x64;
|
||||
public AtlasPadding atlasPadding = AtlasPadding.Pixels0x0;
|
||||
public MergeTiledTextures mergeTiledTextures = MergeTiledTextures.LegacyMode;
|
||||
public bool useDefaultMainTextureProperty = true;
|
||||
public string mainTexturePropertyToFind = "_MainTex";
|
||||
public string mainTexturePropertyToInsert = "_MainTex";
|
||||
public bool materialColorSupport = false;
|
||||
public string materialColorPropertyToFind = "_Color";
|
||||
public bool metallicMapSupport = false;
|
||||
public string metallicMapPropertyToFind = "_MetallicGlossMap";
|
||||
public string metallicMapPropertyToInsert = "_MetallicGlossMap";
|
||||
public bool specularMapSupport = false;
|
||||
public string specularMapPropertyToFind = "_SpecGlossMap";
|
||||
public string specularMapPropertyToInsert = "_SpecGlossMap";
|
||||
public bool normalMapSupport = false;
|
||||
public string normalMapPropertyToFind = "_BumpMap";
|
||||
public string normalMapPropertyToInsert = "_BumpMap";
|
||||
public bool normalMap2Support = false;
|
||||
public string normalMap2PropertyFind = "_DetailNormalMap";
|
||||
public string normalMap2PropertyToInsert = "_DetailNormalMap";
|
||||
public bool heightMapSupport = false;
|
||||
public string heightMapPropertyToFind = "_ParallaxMap";
|
||||
public string heightMapPropertyToInsert = "_ParallaxMap";
|
||||
public bool occlusionMapSupport = false;
|
||||
public string occlusionMapPropertyToFind = "_OcclusionMap";
|
||||
public string occlusionMapPropertyToInsert = "_OcclusionMap";
|
||||
public bool detailAlbedoMapSupport = false;
|
||||
public string detailMapPropertyToFind = "_DetailAlbedoMap";
|
||||
public string detailMapPropertyToInsert = "_DetailAlbedoMap";
|
||||
public bool detailMaskSupport = false;
|
||||
public string detailMaskPropertyToFind = "_DetailMask";
|
||||
public string detailMaskPropertyToInsert = "_DetailMask";
|
||||
public bool emissionMapSupport = false;
|
||||
public string emissionMapPropertyToFind = "_EmissionMap";
|
||||
public string emissionMapPropertyToInsert = "_EmissionMap";
|
||||
public string emissionColorPropertyToFind = "_EmissionColor";
|
||||
public MaterialGlobalIllumination emissionLightType = MaterialGlobalIllumination.None;
|
||||
public bool pinkNormalMapsFix = true;
|
||||
public TextureCompression textureCompression = TextureCompression.Disabled;
|
||||
public bool addMeshCollider = false;
|
||||
public bool highlightUvVertices = false;
|
||||
}
|
||||
[System.Serializable]
|
||||
public class JustMaterialColorsParams
|
||||
{
|
||||
public Material materialToUse;
|
||||
public bool useDefaultColorProperty = true;
|
||||
public string colorPropertyToFind = "_Color";
|
||||
public string mainTexturePropertyToInsert = "_MainTex";
|
||||
public TextureCompression textureCompression = TextureCompression.Disabled;
|
||||
public bool addMeshCollider = false;
|
||||
}
|
||||
|
||||
public string projectName;
|
||||
public Rect windowPosition;
|
||||
public bool representLogsInScene = true;
|
||||
|
||||
public AfterMerge afterMerge = AfterMerge.DisableOriginalMeshes;
|
||||
public MergeMethod mergeMethod = MergeMethod.OneMeshPerMaterial;
|
||||
public OneMeshPerMaterialParams oneMeshPerMaterialParams = new OneMeshPerMaterialParams();
|
||||
public AllInOneParams allInOneParams = new AllInOneParams();
|
||||
public JustMaterialColorsParams justMaterialColorsParams = new JustMaterialColorsParams();
|
||||
public bool combineChildrens = true;
|
||||
public bool combineInactives = false;
|
||||
public bool lightmapSupport = false;
|
||||
public LightmapMode lightmapMode = LightmapMode.GenerateData;
|
||||
public bool lightmapUseDefaultGenerationParams = true;
|
||||
public float lightmapParamAngleError = 0.08f; //default: 0.08
|
||||
public float lightmapParamAreaError = 0.15f; //default: 0.15
|
||||
public float lightmapParamHardAngle = 88.0f; //default: 88.0
|
||||
public float lightmapParamPackMargin = 0.04f; //default: 0.04
|
||||
public bool saveMeshInAssets = true;
|
||||
public bool savePrefabOfThis = false;
|
||||
public string prefabName = "prefab";
|
||||
public string nameOfThisMerge = "Combined Meshes";
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9168bd0e7d7ff4e409b67e0c31e28ca7
|
||||
timeCreated: 1571441231
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,105 @@
|
||||
using UnityEditor;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace MTAssets.EasyMeshCombiner.Editor
|
||||
{
|
||||
/*
|
||||
* This class is responsible for displaying the welcome message when installing this asset.
|
||||
*/
|
||||
|
||||
[InitializeOnLoad]
|
||||
class Greetings
|
||||
{
|
||||
//This asset parameters
|
||||
|
||||
public static string assetName = "Easy Mesh Combiner";
|
||||
public static string pathForThisAsset = "Assets/Plugins/MT Assets/Easy Mesh Combiner";
|
||||
public static string pathForThisAssetDocumentation = "/_Documentation/Documentation (Open With Browser).html";
|
||||
public static string optionalObservation = "";
|
||||
public static string pathToGreetingsFile = "Assets/Plugins/MT Assets/_AssetsData/Greetings/GreetingsData.Emc.ini";
|
||||
public static string linkForAssetStorePage = "https://assetstore.unity.com/publishers/40306";
|
||||
public static string linkForDiscordCommunity = "https://discord.gg/44aGAt4Sv4";
|
||||
|
||||
//Greetings script methods
|
||||
|
||||
static Greetings()
|
||||
{
|
||||
//Run the script after Unity compiles
|
||||
EditorApplication.delayCall += Run;
|
||||
}
|
||||
|
||||
static void Run()
|
||||
{
|
||||
//Create base directory "_AssetsData" and "Greetings" if not exists yet
|
||||
CreateBaseDirectoriesIfNotExists();
|
||||
|
||||
//Verify if the greetings message already showed, if not yet, show the message
|
||||
VerifyAndShowAssetGreentingsMessageIfNeverShowedYet();
|
||||
}
|
||||
|
||||
public static void CreateBaseDirectoriesIfNotExists()
|
||||
{
|
||||
//Create the directory to feedbacks folder, of this asset
|
||||
if (!AssetDatabase.IsValidFolder("Assets/Plugins/MT Assets"))
|
||||
AssetDatabase.CreateFolder("Assets/Plugins", "MT Assets");
|
||||
if (!AssetDatabase.IsValidFolder("Assets/Plugins/MT Assets/_AssetsData"))
|
||||
AssetDatabase.CreateFolder("Assets/Plugins/MT Assets", "_AssetsData");
|
||||
if (!AssetDatabase.IsValidFolder("Assets/Plugins/MT Assets/_AssetsData/Greetings"))
|
||||
AssetDatabase.CreateFolder("Assets/Plugins/MT Assets/_AssetsData", "Greetings");
|
||||
}
|
||||
|
||||
public static void VerifyAndShowAssetGreentingsMessageIfNeverShowedYet()
|
||||
{
|
||||
//If the greetings file not exists
|
||||
if (AssetDatabase.LoadAssetAtPath(pathToGreetingsFile, typeof(object)) == null)
|
||||
{
|
||||
//Create a new greetings file
|
||||
File.WriteAllText(pathToGreetingsFile, "Done");
|
||||
|
||||
//Show greetings and save
|
||||
Regex regexFilter = new Regex("Assets/");
|
||||
bool optionClicked = EditorUtility.DisplayDialog(assetName + " was imported!",
|
||||
"The " + assetName + " was imported for your project. Please do not change the directory of the files for this asset. You should be able to locate it in the folder \"" + regexFilter.Replace(pathForThisAsset, "", 1) + "\"" +
|
||||
"\n\n" +
|
||||
((string.IsNullOrEmpty(optionalObservation) == false) ? optionalObservation + "\n\n" : "") +
|
||||
"Remember to read the documentation to understand how to use this asset and get the most out of it!" +
|
||||
"\n\n" +
|
||||
"You can get support at email (mtassets@windsoft.xyz)" +
|
||||
"\n\n" +
|
||||
"- Thank you for purchasing the asset! :)",
|
||||
"Ok, Cool!", "Open Documentation");
|
||||
|
||||
//If clicked on "Ok, Cool!"
|
||||
if (optionClicked == true)
|
||||
{
|
||||
//Select the folder of project
|
||||
UnityEngine.Object assetFolder = (UnityEngine.Object)AssetDatabase.LoadAssetAtPath(pathForThisAsset, typeof(UnityEngine.Object));
|
||||
Selection.activeObject = assetFolder;
|
||||
EditorGUIUtility.PingObject(assetFolder);
|
||||
}
|
||||
//If clicked on "Open Documentation"
|
||||
if (optionClicked == false)
|
||||
{
|
||||
//Select the folder of project
|
||||
UnityEngine.Object docItem = (UnityEngine.Object)AssetDatabase.LoadAssetAtPath(pathForThisAsset + pathForThisAssetDocumentation, typeof(UnityEngine.Object));
|
||||
Selection.activeObject = docItem;
|
||||
EditorGUIUtility.PingObject(docItem);
|
||||
AssetDatabase.OpenAsset(docItem);
|
||||
}
|
||||
|
||||
//Show discord MT Assets Community invite
|
||||
bool joinOptionClicked = EditorUtility.DisplayDialog("MT Assets Community on Discord",
|
||||
"The MT Assets Community on Discord is a place where you can get support for the MT Assets tools, you will also be able to send suggestions, ask questions, find out about news in advance and " +
|
||||
"interact with the community of devs and customers who also use MT Assets tools. It is worth checking!\n\nWould you like to join the MT Assets Community on Discord?",
|
||||
"Join MT Assets Community on Discord!", "No, thank you");
|
||||
//If clicked on Join the Community
|
||||
if (joinOptionClicked == true)
|
||||
Help.BrowseURL(Greetings.linkForDiscordCommunity);
|
||||
|
||||
//Update files
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2039de207d96fa1418fca3e37e0bb85c
|
||||
timeCreated: 1544918828
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d2d03a6fac17c044a82a57721605f21
|
||||
folderAsset: yes
|
||||
timeCreated: 1571665254
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 6.5 KiB |
@ -0,0 +1,108 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 06319526e165e4c4b9d1e530e0f1110e
|
||||
timeCreated: 1571778662
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 18 KiB |
@ -0,0 +1,108 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3cc9f4f19194bb14eb0be711ed2210b1
|
||||
timeCreated: 1572052278
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 94 KiB |
@ -0,0 +1,108 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d4b9f5cbc67a57c48a0fc92b9b22ac5f
|
||||
timeCreated: 1571665267
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 22 KiB |
@ -0,0 +1,108 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8bce6b5d631d70c48807b8ac203c5392
|
||||
timeCreated: 1572052559
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 2.0 KiB |
@ -0,0 +1,103 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e91200c7f48a7ca4ea58d3d21eeac124
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 10
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,86 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.IO;
|
||||
|
||||
namespace MTAssets.EasyMeshCombiner.Editor
|
||||
{
|
||||
|
||||
/*
|
||||
* This class is responsible for creating the menu for this asset.
|
||||
*/
|
||||
|
||||
public class Menu : MonoBehaviour
|
||||
{
|
||||
//Right click menu items
|
||||
|
||||
[MenuItem("GameObject/Combine Meshes", false, 30)]
|
||||
static void OpenMeshCombinerToolWithHierarchy()
|
||||
{
|
||||
MeshCombinerTool.OpenWindow();
|
||||
}
|
||||
|
||||
//Menu items
|
||||
|
||||
[MenuItem("Tools/MT Assets/Easy Mesh Combiner/Mesh Combiner Tool", false, 10)]
|
||||
static void OpenMeshCombinerTool()
|
||||
{
|
||||
MeshCombinerTool.OpenWindow();
|
||||
}
|
||||
|
||||
[MenuItem("Tools/MT Assets/Easy Mesh Combiner/View Changelog", false, 10)]
|
||||
static void OpenChangeLog()
|
||||
{
|
||||
string filePath = Greetings.pathForThisAsset + "/List Of Changes.txt";
|
||||
|
||||
if (File.Exists(filePath) == true)
|
||||
AssetDatabase.OpenAsset(AssetDatabase.LoadAssetAtPath(filePath, typeof(TextAsset)));
|
||||
|
||||
if (File.Exists(filePath) == false)
|
||||
EditorUtility.DisplayDialog(
|
||||
"Error",
|
||||
"Unable to open file. The file has been deleted, or moved. Please, to correct this problem and avoid future problems with this tool, remove the directory from this asset and install it again.",
|
||||
"Ok");
|
||||
}
|
||||
|
||||
[MenuItem("Tools/MT Assets/Easy Mesh Combiner/Read Documentation", false, 30)]
|
||||
static void ReadDocumentation()
|
||||
{
|
||||
EditorUtility.DisplayDialog(
|
||||
"Read Documentation",
|
||||
"The Documentation HTML file will open in your default application.",
|
||||
"Cool!");
|
||||
|
||||
string filePath = Greetings.pathForThisAsset + Greetings.pathForThisAssetDocumentation;
|
||||
|
||||
if (File.Exists(filePath) == true)
|
||||
AssetDatabase.OpenAsset(AssetDatabase.LoadAssetAtPath(filePath, typeof(TextAsset)));
|
||||
|
||||
if (File.Exists(filePath) == false)
|
||||
EditorUtility.DisplayDialog(
|
||||
"Error",
|
||||
"Unable to open file. The file has been deleted, or moved. Please, to correct this problem and avoid future problems with this tool, remove the directory from this asset and install it again.",
|
||||
"Ok");
|
||||
}
|
||||
|
||||
[MenuItem("Tools/MT Assets/Easy Mesh Combiner/More Assets", false, 30)]
|
||||
static void MoreAssets()
|
||||
{
|
||||
Help.BrowseURL(Greetings.linkForAssetStorePage);
|
||||
}
|
||||
|
||||
[MenuItem("Tools/MT Assets/Easy Mesh Combiner/Get Support", false, 30)]
|
||||
static void GetSupport()
|
||||
{
|
||||
EditorUtility.DisplayDialog(
|
||||
"Support",
|
||||
"If you have any questions, problems or want to contact me, just contact me by email (mtassets@windsoft.xyz).",
|
||||
"Got it!");
|
||||
}
|
||||
|
||||
[MenuItem("Tools/MT Assets/Easy Mesh Combiner/Discord Community", false, 30)]
|
||||
static void JoinTheCommunity()
|
||||
{
|
||||
Help.BrowseURL(Greetings.linkForDiscordCommunity);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b407ff593966f6e4397dd7a063a34846
|
||||
timeCreated: 1544916341
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d4806b6822fe964fb927325da05511c
|
||||
timeCreated: 1548711569
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cb17cc495afdfac40a1054a82a4ce260
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2062e948587d34a49b904451e71686f2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,99 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
|
||||
namespace MTAssets.EasyMeshCombiner
|
||||
{
|
||||
/*
|
||||
* This is a script that is part of the essential library for "MT Assets" assets.
|
||||
*/
|
||||
|
||||
[AddComponentMenu("")] //Hide this script in component menu.
|
||||
public class MTAssetsEditorUi : MonoBehaviour
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
|
||||
//Public methods
|
||||
|
||||
//This method disable gizmo of a script that have a icon
|
||||
public static bool DisableGizmosInSceneView(string scriptClassNameToDisable, bool isGizmosDisabled)
|
||||
{
|
||||
/*
|
||||
* This method disables Gizmos in scene view, for this component
|
||||
*/
|
||||
|
||||
if (isGizmosDisabled == true)
|
||||
return true;
|
||||
|
||||
//Try to disable
|
||||
try
|
||||
{
|
||||
//Get all data of Unity Gizmos manager window
|
||||
var Annotation = System.Type.GetType("UnityEditor.Annotation, UnityEditor");
|
||||
var ClassId = Annotation.GetField("classID");
|
||||
var ScriptClass = Annotation.GetField("scriptClass");
|
||||
var Flags = Annotation.GetField("flags");
|
||||
var IconEnabled = Annotation.GetField("iconEnabled");
|
||||
|
||||
System.Type AnnotationUtility = System.Type.GetType("UnityEditor.AnnotationUtility, UnityEditor");
|
||||
var GetAnnotations = AnnotationUtility.GetMethod("GetAnnotations", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
|
||||
var SetIconEnabled = AnnotationUtility.GetMethod("SetIconEnabled", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
|
||||
|
||||
//Scann all Gizmos of Unity, of this project
|
||||
System.Array annotations = (System.Array)GetAnnotations.Invoke(null, null);
|
||||
foreach (var a in annotations)
|
||||
{
|
||||
int classId = (int)ClassId.GetValue(a);
|
||||
string scriptClass = (string)ScriptClass.GetValue(a);
|
||||
int flags = (int)Flags.GetValue(a);
|
||||
int iconEnabled = (int)IconEnabled.GetValue(a);
|
||||
|
||||
// this is done to ignore any built in types
|
||||
if (string.IsNullOrEmpty(scriptClass))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const int HasIcon = 1;
|
||||
bool hasIconFlag = (flags & HasIcon) == HasIcon;
|
||||
|
||||
//If the current gizmo is of the class desired, disable the gizmo in scene
|
||||
if (scriptClass == scriptClassNameToDisable)
|
||||
{
|
||||
if (hasIconFlag && (iconEnabled != 0))
|
||||
{
|
||||
/*UnityEngine.Debug.LogWarning(string.Format("Script:'{0}' is not ment to show its icon in the scene view and will auto hide now. " +
|
||||
"Icon auto hide is checked on script recompile, if you'd like to change this please remove it from the config", scriptClass));*/
|
||||
SetIconEnabled.Invoke(null, new object[] { classId, scriptClass, 0 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//Catch any error
|
||||
catch (System.Exception exception)
|
||||
{
|
||||
string exceptionOcurred = "";
|
||||
exceptionOcurred = exception.Message;
|
||||
if (exceptionOcurred != null)
|
||||
exceptionOcurred = "";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//This method returns the current width of inspector window
|
||||
public static Rect GetInspectorWindowSize()
|
||||
{
|
||||
//Returns the current size of inspector window
|
||||
return EditorGUILayout.GetControlRect(true, 0f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b341aafd810fa5c4ca132d2c0e886ab2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 46fa253953ac8cc47a4d6699a4670b78
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,54 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
|
||||
namespace MTAssets.EasyMeshCombiner
|
||||
{
|
||||
/*
|
||||
* This is a script that is part of the essential library for "MT Assets" assets.
|
||||
*/
|
||||
|
||||
[AddComponentMenu("")] //Hide this script in component menu.
|
||||
public class MTAssetsMathematics : MonoBehaviour
|
||||
{
|
||||
//This method, randomize a specific list
|
||||
public static List<T> RandomizeThisList<T>(List<T> list)
|
||||
{
|
||||
int count = list.Count;
|
||||
int last = count - 1;
|
||||
for (int i = 0; i < last; ++i)
|
||||
{
|
||||
int r = UnityEngine.Random.Range(i, count);
|
||||
var tmp = list[i];
|
||||
list[i] = list[r];
|
||||
list[r] = tmp;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
//This method return a half position between two Vector 3
|
||||
public static Vector3 GetHalfPositionBetweenTwoPoints(Vector3 pointA, Vector3 pointB)
|
||||
{
|
||||
return Vector3.Lerp(pointA, pointB, 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
//Extensions classes
|
||||
public static class ListMethodsExtensions
|
||||
{
|
||||
//Return the count of elements in list
|
||||
public static void RemoveAllNullItems<T>(this List<T> list)
|
||||
{
|
||||
for (int i = list.Count - 1; i >= 0; i--)
|
||||
if (list[i] == null)
|
||||
list.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e7382ac35b2fcb4ca1cfa4e81cd9b33
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,327 @@
|
||||
|
||||
/////////////////////
|
||||
MT ASSETS
|
||||
CHANGELOG
|
||||
/////////////////////
|
||||
|
||||
v3.2.0
|
||||
- Added support for Emissive Maps and Emissive Map Colors. Support is in experimental status.
|
||||
- Demo scenes have been updated.
|
||||
- The documentation has been updated to reflect the new changes.
|
||||
|
||||
v3.1.0
|
||||
- The default format generated by EMC texture processing has been changed from ARGB32 to RGBA32.
|
||||
- Added options to copy the Primary UV of the merged mesh to other UV Channels in the Combined Mesh Manager.
|
||||
- In the "Material To Use" variables in the Editor, a "+" button has been added that allows you to quickly create a new
|
||||
Material, and save it locally in the project.
|
||||
- Fixed a bug that caused some merged models to appear darker, when they had Normal Maps.
|
||||
- Fixed a bug that very rarely caused merging to fail due to the 64k vertex limit error.
|
||||
- It is now possible to control the compression quality of textures generated by EMC, through the "Just Material Colors"
|
||||
and "All In One" merge methods. This control is done through the "Texture Compression" property.
|
||||
- Pink Normal Maps fix has been extended for better compatibility.
|
||||
- The Lightmaps Support framework has been revised, and more settings are available.
|
||||
- Now, the meshes resulting from merging done in the Editor have a Suffix, to make it easier to find them later.
|
||||
- Some new reliability mechanisms for Lightmap Support, have been added.
|
||||
- Support for Material Colors has been added. You can now enable Material Colors support in blends that use the "All
|
||||
In One" method. When activating this feature, the texture that will go to the Atlas will be colored with its
|
||||
respective Material color, in the same way that Shaders do.
|
||||
- Now, textures not found in their original materials before merging in "All In One", will no longer be highlighted
|
||||
in the Atlas as the Red color, but the White color so that they are still compatible with the Material Colors.
|
||||
- The EMC demo scenes have been updated to demonstrate new functionality and for greater clarity.
|
||||
- The documentation has been updated to address the new changes.
|
||||
|
||||
v3.0.7
|
||||
- ****
|
||||
WARNING:
|
||||
- In this version, the Easy Mesh Combiner path has been changed from "/Assets/MT Assets" to
|
||||
"/Assets/Plugins/MT Assets", for better organization of your project. Because of this, before installing this new
|
||||
version in your project, delete the "Easy Mesh Combiner" directory present inside your project
|
||||
in "/Assets/MT Assets".
|
||||
|
||||
The folder "/Assets/MT Assets/_AssetsData" must be kept if you intend to undo any merges already made at some
|
||||
point. But if you want to move this folder, undo all existing merges in your project, then delete this folder. After
|
||||
that, just redo the merges and then the files will be generated in the new default path automatically by the tool.
|
||||
|
||||
If you have any questions, feel free to contact support at "mtassets@windsoft.xyz"!
|
||||
****
|
||||
|
||||
- Some small adjustments have been made to the tool's UI to improve it.
|
||||
- The tool has been updated to fully support Unity 6+!
|
||||
- There is MUCH, MUCH more to come soon! :)
|
||||
|
||||
v3.0.6
|
||||
- In HDRP and URP the default selected properties names for main textures have been changed to match the new
|
||||
default names for Shader properties.
|
||||
|
||||
v3.0.5
|
||||
- In this small update, the tool has been updated to include links to the new MT Assets Community on Discord. You
|
||||
can join the community for support, ask your questions, submit suggestions, and interact with the dev
|
||||
community! Come be part of the community and make it even better!
|
||||
MT Assets Community on Discord: https://discord.gg/44aGAt4Sv4
|
||||
|
||||
v3.0.4
|
||||
- An attempt was made to fix a bug that messed up the position of the mesh resulting from the merge when merging
|
||||
meshes thar are in movement using the Runtime Mesh Combiner. There are new best practices and recommendations
|
||||
for you to combine meshes that are in movement during your game's runtime, please read the Documentation for
|
||||
more details!
|
||||
IMPORTANT: IF YOU ARE STILL HAVING AN ISSUE WITH THIS MOVING MESHES MERGE BUG DURING RUNTIME, PLEASE REPORT THE
|
||||
ISSUE TO SUPPORT VIA EMAIL "mtassets@windsoft.xyz", I WILL BE HAPPY TO HELP! :)
|
||||
- The Runtime Merge Demo scene has been updated to show merging effects in a static environment (meshes that are
|
||||
not moving) and in an environment with moving meshes (meshes that are moving across the scene).
|
||||
- Now the Runtime Mesh Combiner component will no longer merge meshes if you place it in a GameObject that already
|
||||
contains a Mesh Filter and Mesh Renderer component, as the Runtime Mesh Combiner needs a GameObject that does
|
||||
not contain these two components in order to merge without problems.
|
||||
- The documentation has been updated to contain new tips and more details on how the Runtime Mesh Combiner
|
||||
component works, especially regarding moving mesh merges during Runtime.
|
||||
|
||||
v3.0.3
|
||||
- Now the officially supported minimum version is Unity 2019.4 or higher. Support for this version of Unity or
|
||||
higher will make it possible to add different new features and improvements in the future. This change also aims
|
||||
to ensure that the tool can always have mature, stable and continuous update support!
|
||||
- Minor layout adjustments have been made to the Mesh Combiner Tool's UI to ensure greater perfection in the
|
||||
latest Unity versions.
|
||||
|
||||
v3.0.2
|
||||
- Added one more helpful hint to Easy Mesh Combiner documentation.
|
||||
|
||||
v3.0.1
|
||||
- ** WARNING: This is a major update for the Easy Mesh Combiner! Several improvements have been made and
|
||||
incredible new additions too! **
|
||||
-
|
||||
- The documentation has been completely redone and updated as well. Now the new documentation is more modern
|
||||
and more beautiful, it can be found in the folder "_Documentation/Documentation.html" and you can open it
|
||||
directly from within your Unity Editor. If your project still has the old "Documentation.zip" file, you can
|
||||
delete it without any problems.
|
||||
- Some fields that were used only for internal codes, but which were not used for external scripts, were hidden
|
||||
to avoid confusion.
|
||||
- Some minor changes, optimizations and improvements have been made to the Editor UI.
|
||||
- Some extra warnings have been added to make sure you stay on top of everything before merging!
|
||||
- Now, after the merge is finished, Easy Mesh Combiner will display the merge processing time.
|
||||
- The Combined Meshes Manager has been rewritten to adapt to the new functions of the Easy Mesh Combiner. He
|
||||
also underwent some minor optimization and UI changes.
|
||||
- The Combined Meshes Manager UI will now adapt according to the chosen blending method and other parameters.
|
||||
- Combined Meshes Manager now has a bulletin board to communicate with you if you encounter any problems with
|
||||
the merge.
|
||||
- It will now be possible to export the Atlas generated during the merge. Through the Combined Meshes Manager.
|
||||
- Easy Mesh Combiner now has a selection of "Combine Method". Through this selection, you can choose which
|
||||
Combine Method Easy Mesh Combiner will use to combine your meshes!
|
||||
(If you are a user of the Skinned Mesh Combiner MT tool, you already know how it works!)
|
||||
- New Combine Method added: One Mesh Per Material. This method of blending works identically to the way in which
|
||||
Easy Mesh Combiner has always worked! This is the standard Combine Method.
|
||||
- New Combine Method added: All In One. This method of merging supports and generates Atlas from the meshes that
|
||||
have been selected for merging. In this merge method the Easy Mesh Combiner will combine the meshes that
|
||||
have Tilings (in order to preserve the quality of these meshes as much as possible) and combine the meshes that
|
||||
do not have Tilings, all together, generating an Atlas with various textures. You can decide how many textures
|
||||
an Atlas can have, if you want to have a better control of the quality that each texture will have in the Atlas.
|
||||
After all, only the mesh resulting from the merge will remain.
|
||||
- New Combine Method added: Just Material Colors. This method of blending only works with meshes that use only
|
||||
colors in their materials, instead of textures. This blending method combines all meshes in just one mesh, then
|
||||
extracts the color from all materials and creates a single Atals texture that works as a color palette,
|
||||
containing all colors for all meshes combined. This will always optimize your meshes to generate only 1 Draw
|
||||
Call at all times, while still retaining their original colors of the materials.
|
||||
- Now, when activating "Lightmaps Support", you will see a button called "Deselect Excessive". By clicking on
|
||||
this button, Easy Mesh Combiner will deselect any excess GameObjects.
|
||||
- Fixed a bug that caused the vertex count to be increased after merge, in some rare cases.
|
||||
- Fixed a bug that caused the vertex count to be increased after merge, in some rare cases (For Runtime Mesh
|
||||
Combiner too).
|
||||
- New function added to be performed after performing a merge: Now, when completing a merge with Easy Mesh Combiner
|
||||
you can choose the option "Do Nothing" and so Easy Mesh Combiner will do absolutely nothing after performing
|
||||
your merge! (For Editor)
|
||||
- New function added to be performed after performing a merge: Now, when completing a merge with Easy Mesh Combiner
|
||||
you can choose the option "Do Nothing" and so Easy Mesh Combiner will do absolutely nothing after performing
|
||||
your merge! (For Runtime Mesh Combiner too)
|
||||
|
||||
v2.6.4
|
||||
- Fixed some minor bugs and minor code changes.
|
||||
- The option to Optimize the mesh resulting from the merge has been added to the combined mesh manager.
|
||||
- An option to optimize the mesh was added to the Runtime Mesh Combiner component.
|
||||
- Now the management buttons of the combined mesh through the Editor, send messages for each action performed.
|
||||
- A button for quickly adding the Mesh Collider component, has been added to the combined mesh manager.
|
||||
- The documentation has been updated to contain minor changes and additions made in this version.
|
||||
|
||||
v2.6.3
|
||||
- A bug has been fixed that caused the selection gizmos not to be hidden, after closing the merge window in
|
||||
the Editor, without combining any mesh.
|
||||
- The UI of the merge window in the Editor, has undergone some improvements.
|
||||
- The options for recalculating normals and tangens have been moved from the merge window to the management
|
||||
component of the combined mesh, which is on the mesh resulting from the merge.
|
||||
- Fixed a bug that caused disabled daughter meshes to still be combined, even if the "Combine Inactives"
|
||||
option was unchecked.
|
||||
- The "Combined Meshes Manager" component now has an option so that it is possible to export the mesh resulting
|
||||
from the merge, as OBJ, so the editing of this mesh in external modeling software is made easier.
|
||||
- Now the "Combine On Start" option of the "Runtime Mesh Combiner" has the options of "On Start" and "On Awake",
|
||||
for greater control of when the merging should occur.
|
||||
- Now the GameObject that contains the mesh resulting from the merge will always be placed very close to the
|
||||
first selected GameObject and in addition, it will also be the child of the first selected GameObject.
|
||||
- The component icons have been slightly updated.
|
||||
- Now the official version of the Easy Mesh Combiner, is 2019.3.x.
|
||||
- The documentation has been updated.
|
||||
|
||||
v2.5.2
|
||||
- Correction of small bugs.
|
||||
- There's more to come, soon!
|
||||
|
||||
v2.5.1
|
||||
- It is now possible to disable the calculation of normals and tangents of the meshes resulting from the merging.
|
||||
- Correction of small bugs.
|
||||
- Documentation updated.
|
||||
|
||||
v2.4.3
|
||||
- Correction of small bugs.
|
||||
|
||||
v2.4.2
|
||||
- A bug has been fixed that caused the automatic deactivation of some scripts' Gizmos to stop working.
|
||||
- Fixed a bug where changing Easy Mesh Combiner UI parameters did not work on some versions
|
||||
of Unity 2019.3.x.
|
||||
|
||||
v2.4.1
|
||||
- Combined Meshes Manager is now not displayed in the component list.
|
||||
- Now the Gizmos of the RuntimeMeshCombiner and other components are no longer displayed.
|
||||
- Now, by default, the option to launch debug logs on the console, is enabled so that in case of any
|
||||
runtime merging error, you know. You can always disable it if you prefer!
|
||||
- The documentation has been updated to ensure greater clarity, volume of information, tips and minor corrections!
|
||||
- Fixed a bug in the creation of prefabs, which affected versions newer to Unity 2018.3.
|
||||
- Now the meshes that are disabled, will not be included in the run-time merges, even if they are in the list
|
||||
to merge.
|
||||
- Easy Mesh Combiner will no longer issue merge warnings about possible problems with Lightmaps, if you
|
||||
have not checked the support option for Lightmaps.
|
||||
|
||||
v2.4.0
|
||||
- Following the rhythm of Unity Engine versions and to guarantee the good permanent support of this asset,
|
||||
now the minimum recommended version is 2018.1, however, you can still use this asset in the 2017.4 LTS
|
||||
version if you prefer. This will allow this asset to always have the latest features and better and
|
||||
more effective support!
|
||||
- Fixed a bug that caused the merging of very large meshes to suffer from distortions in the 2018.1
|
||||
version of Unity.
|
||||
- Fixed a bug that caused GameObjects to be active, but with MeshFilters disabled, also be combined
|
||||
while selecting all meshes or a GameObject that contains all meshes in the scenario.
|
||||
- Easy Mesh Combiner is now able to give an automatic name to the prefab you want to save.
|
||||
- To avoid problems, Easy Mesh Combiner will now only display the combined mesh management buttons,
|
||||
in the original meshes and no longer in their respective prefabs.
|
||||
- The combined mesh manager interface has undergone some changes for clarity. Now the selection of
|
||||
meshes combined by materials has a scrollview to make things more organized.
|
||||
|
||||
v2.3.0
|
||||
- In this version, some unused files have been removed from the package. For example, the demo scene
|
||||
materials now use standard Unity shaders. Nothing that will affect the way the EMC works.
|
||||
- All resources, persistent asset data and other files are now saved in "MT Assets/_AssetsData".
|
||||
This makes it easy to manage all files generated by MT assets and if you need to remove any asset,
|
||||
just delete the asset folder. So, even if you want to remove some MT assets from your project, or
|
||||
update it, you will not lose any files or information that you would like to keep!
|
||||
|
||||
v2.2.1
|
||||
- Fixed a bug that caused the compilation or loading time of the scene execution to increase considerably
|
||||
in the editor.
|
||||
|
||||
v2.2.0
|
||||
- Now you no longer need to check the option of more than 64,000 vertices to combine giant meshes.
|
||||
Easy Mesh Combiner can automatically identify the size of the meshes and will select whether the
|
||||
resulting mesh will be 16 bits or 32 bits.
|
||||
|
||||
v2.1.1
|
||||
- Fixed a compatibility issue with Unity version 2018.1.
|
||||
|
||||
v2.1.0
|
||||
- This major update has brought several enhancements, feature additions, and enhancements to EMC's workflow!
|
||||
- This update may cause your combined mesh managers of version 1.7.1 or lower to stop working as they
|
||||
should. Back up your project to revert changes if you prefer. The new combined mesh manager is
|
||||
better and smarter, read on.
|
||||
- Minor additions to the asset menu.
|
||||
- Improvement of some asset codes.
|
||||
- Improvements to undo actions.
|
||||
- Updated UI! Easy Mesh Combiner is now more intuitive and optimized for use in the Editor!
|
||||
- Improvements in displaying merge statistics.
|
||||
- Added merge log. Through it, you can identify problems in meshes before you merge, and also get
|
||||
the root of what is causing the problem.
|
||||
- All EMC source code has been rewritten, optimized and revamped!
|
||||
- Easy Mesh Combiner will now keep your merge preferences even if you close the editor window.
|
||||
- Now the merge window continues to update even while it is not in focus. So you can select meshes
|
||||
while everything is updated automatically!
|
||||
- Now the Easy Mesh Combiner window will remember which position you left it when you closed it.
|
||||
- Valid GameObjects selected for merge will now be highlighted in blue. Invalid GameObjects will
|
||||
be highlighted in red in your scene. (Highlights only appear with the merge window open).
|
||||
- The option to add a comment to the GameObject resulting from the merge has been removed,
|
||||
however, you can now choose the name of this GameObject before merging.
|
||||
- Easy Mesh Combiner should now work smoothly on versions older than 2017.4, but mesh support
|
||||
with more than 65,000 vertices will not work on versions older than 2017.4.
|
||||
- Now, when you finish a merge, only 1 new GameObject will be generated that will contain a
|
||||
single mesh resulting from the merge!
|
||||
- The resulting GameObject merge will now be positioned as close as possible to the selected
|
||||
GameObjects to be merged into the hierarchy. The resulting GameObject from the merge will no
|
||||
longer appear at the end of your scene hierarchy.
|
||||
- Several improvements made to the combined mesh manager. You now have better mesh management after the merge.
|
||||
- Fixed a bug where previously disabled meshes are enabled when undoing a merge!
|
||||
- Fixed a bug when importing this asset for the first time, where a file error message was displayed.
|
||||
It was more common with Windows 10 users.
|
||||
- Several interface improvements.
|
||||
- Fixing a bug that caused Unity to crash (in some versions) upon completion of a merge.
|
||||
- Documentation updated.
|
||||
- Added a feature so you can merge and unmerge at runtime, so you can optimize your game even
|
||||
as it runs, quickly and optimally!
|
||||
- Added new sample scene to show merge at runtime.
|
||||
- You can have a complete debug of the merge process at run time.
|
||||
- Fixed a compatibility issue with prefab creation in the latest versions of Unity.
|
||||
- The management of combined mesh prefabs has also been improved.
|
||||
- Better organization of source code.
|
||||
- There was a slight change in the asset API. Now, to access the API methods of this
|
||||
asset, use "using MTAssets.EasyMeshCombiner".
|
||||
- Added function to select all original GameObjects containing X material in combined mesh
|
||||
manager (after merging using Editor).
|
||||
|
||||
v1.7.1
|
||||
- More interface improvements.
|
||||
- Small corrections.
|
||||
- Fix a bug with the welcome message.
|
||||
- Small housekeeping in scripts
|
||||
- Added an option to select all the original meshes of a merge.
|
||||
- You can now include a comment in the GameObject resulting from the merge.
|
||||
|
||||
v1.6.2
|
||||
- Workflow Improvement
|
||||
- Fixes and enhancements in the user interface
|
||||
- Improvements in integrated materials
|
||||
- The compatibility of the tool has been extended among more Unity versions!
|
||||
|
||||
v1.6.1
|
||||
- Small improvements in code.
|
||||
|
||||
v1.6
|
||||
- Improvements in tool interface.
|
||||
|
||||
v1.5
|
||||
- Your merge preferences will now persist even if the merge window is closed.
|
||||
- Fix of small bugs.
|
||||
- Small improvements in tool interface.
|
||||
- Now you can save prefabs from the merge, quickly, just by activating an option before the merge!
|
||||
|
||||
v1.4
|
||||
- The minimum support version is now Unity 2018.1.0f2. This change was made to ensure future improvements to the tool! Stay tuned!
|
||||
- The 65,000 vertices limit has been removed! Now you can combine your knits without worrying about this limitation!
|
||||
- Now the tool interface shows the information you are merging.
|
||||
|
||||
v1.3
|
||||
- Small improvements in documentation.
|
||||
- Improved support for lightmaps in merged meshes!
|
||||
- Addition of explanations on the merge of meshes and generation of lightmaps in the documentation.
|
||||
|
||||
v1.2
|
||||
- A lot of minor improvements.
|
||||
- Fix small bugs.
|
||||
|
||||
v1.1
|
||||
- Do not worry about duplicates when saving the meshes combined in your project file!
|
||||
- If you have saved the merge files in your project files, and you want to undo the merge,
|
||||
all unnecessary files are also deleted from your project. So you do not worry about memory problems!
|
||||
- The combined mesh manager now shows you a warning if it detects that one of the meshes combined
|
||||
does not have any important files.
|
||||
- The documentation has been contemplated with the new details!
|
||||
|
||||
v1.0
|
||||
- The Easy Mesh Combiner has just been released! I will always be working to support and add new features!
|
||||
Do you have any suggestions, Bug reports or any problems with using this asset? Contact by email!
|
||||
(mtassets@windsoft.xyz)
|
||||
|
||||
/////////////////////
|
||||
Email for support
|
||||
mtassets@windsoft.xyz
|
||||
/////////////////////
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 96d1a3e90cecf644da53be88a271d326
|
||||
timeCreated: 1545776247
|
||||
licenseType: Store
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,21 @@
|
||||
|
||||
/////////////////////
|
||||
MT ASSETS
|
||||
/////////////////////
|
||||
|
||||
In this tool, the files or folders listed below can be deleted from your project, without
|
||||
negatively affects the installation of this tool. You can delete them if you want to reduce disc use,
|
||||
if you prefer, and this action will not cause problems for the overall operation of the tool.
|
||||
|
||||
- "/_Documentation"
|
||||
- "/_ScenesDemo"
|
||||
- "DemoScene (Example Of Editor Merge).unity"
|
||||
- "DemoScene (Example Of Runtime Merge).unity"
|
||||
|
||||
Each of these files can be re-installed on your project by re-importing this tool. Feel free to contact
|
||||
MT Assets Support if you have any questions.
|
||||
|
||||
/////////////////////
|
||||
Email for support
|
||||
mtassets@windsoft.xyz
|
||||
/////////////////////
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8fb0949b21591a946af005527de78174
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a7754f83ec2ba914aa2b5cbc596f5fcc
|
||||
folderAsset: yes
|
||||
timeCreated: 1548972319
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,713 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEngine.SceneManagement;
|
||||
using System.IO;
|
||||
#endif
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace MTAssets.EasyMeshCombiner
|
||||
{
|
||||
/*
|
||||
This class is responsible for the functioning of the "Combined Meshes Manager" component, and all its functions.
|
||||
*/
|
||||
/*
|
||||
* The Easy Mesh Combiner was developed by Marcos Tomaz in 2019.
|
||||
* Need help? Contact me (mtassets@windsoft.xyz)
|
||||
*/
|
||||
|
||||
[AddComponentMenu("")] //Hide this script in component menu.
|
||||
public class CombinedMeshesManager : MonoBehaviour
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
//------------------------------------------- START OF PARAMETERS OF INFORMATION OF MERGE -----------------------------------------
|
||||
//Enums of script
|
||||
public enum MergeMethod
|
||||
{
|
||||
OneMeshPerMaterial,
|
||||
AllInOne,
|
||||
JustMaterialColors
|
||||
}
|
||||
public enum UndoMethod
|
||||
{
|
||||
EnableOriginalMeshes,
|
||||
ReactiveOriginalGameObjects,
|
||||
DoNothing
|
||||
}
|
||||
public enum AssetType
|
||||
{
|
||||
Unknown,
|
||||
Mesh,
|
||||
Texture,
|
||||
Material
|
||||
}
|
||||
|
||||
//Classes of script
|
||||
[System.Serializable]
|
||||
public class OriginalGameObjectWithMesh
|
||||
{
|
||||
//Class that stores a original GameObject With Mesh data, to restore on undo merge.
|
||||
|
||||
public GameObject gameObject;
|
||||
public bool originalGoState;
|
||||
public MeshRenderer meshRenderer;
|
||||
public bool originalMrState;
|
||||
|
||||
public OriginalGameObjectWithMesh(GameObject gameObject, bool originalGoState, MeshRenderer meshRenderer, bool originalMrState)
|
||||
{
|
||||
this.gameObject = gameObject;
|
||||
this.originalGoState = originalGoState;
|
||||
this.meshRenderer = meshRenderer;
|
||||
this.originalMrState = originalMrState;
|
||||
}
|
||||
}
|
||||
[System.Serializable]
|
||||
public class PathAndTypeOfAAsset
|
||||
{
|
||||
//Class that stores path and type of a asset
|
||||
|
||||
public AssetType type = AssetType.Unknown;
|
||||
public string path;
|
||||
|
||||
public PathAndTypeOfAAsset(AssetType type, string path)
|
||||
{
|
||||
this.type = type;
|
||||
this.path = path;
|
||||
}
|
||||
}
|
||||
|
||||
//Variables of script, informations about this merge
|
||||
///<summary>[WARNING] This variable is only available in the Editor and will not be included in the compilation of your project, in the final Build.</summary>
|
||||
[HideInInspector]
|
||||
public MergeMethod mergeMethodUsed;
|
||||
///<summary>[WARNING] This variable is only available in the Editor and will not be included in the compilation of your project, in the final Build.</summary>
|
||||
[HideInInspector]
|
||||
public UndoMethod undoMethod;
|
||||
///<summary>[WARNING] This variable is only available in the Editor and will not be included in the compilation of your project, in the final Build.</summary>
|
||||
[HideInInspector]
|
||||
public List<OriginalGameObjectWithMesh> originalsGameObjectsWithMesh = new List<OriginalGameObjectWithMesh>();
|
||||
///<summary>[WARNING] This variable is only available in the Editor and will not be included in the compilation of your project, in the final Build.</summary>
|
||||
[HideInInspector]
|
||||
public List<PathAndTypeOfAAsset> pathsAndTypesOfAssetsOfThisMerge = new List<PathAndTypeOfAAsset>();
|
||||
///<summary>[WARNING] This variable is only available in the Editor and will not be included in the compilation of your project, in the final Build.</summary>
|
||||
[HideInInspector]
|
||||
public bool thisIsPrefab = false;
|
||||
//------------------------------------------ END OF PARAMETERS OF INFORMATION OF MERGE ------------------------------------------
|
||||
|
||||
//Private variables of Editor Methods
|
||||
[HideInInspector]
|
||||
[SerializeField]
|
||||
private int exportToObjStartIndexOffSet = 0;
|
||||
[HideInInspector]
|
||||
[SerializeField]
|
||||
private bool hideWarningsForThisMerge = false;
|
||||
//Private variables of Editor Interface
|
||||
private bool gizmosOfThisComponentIsDisabled = false;
|
||||
|
||||
//The UI of this component
|
||||
#region INTERFACE_CODE
|
||||
[UnityEditor.CustomEditor(typeof(CombinedMeshesManager))]
|
||||
public class CustomInspector : UnityEditor.Editor
|
||||
{
|
||||
//Private temp variables
|
||||
Vector2 scrollviewMaterials = Vector2.zero;
|
||||
List<string> warningsOfChecks = new List<string>();
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
//Start the undo event support, draw default inspector and monitor of changes
|
||||
CombinedMeshesManager script = (CombinedMeshesManager)target;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
Undo.RecordObject(target, "Undo Event");
|
||||
script.gizmosOfThisComponentIsDisabled = MTAssetsEditorUi.DisableGizmosInSceneView("CombinedMeshesManager", script.gizmosOfThisComponentIsDisabled);
|
||||
|
||||
//Start of UI
|
||||
EditorGUILayout.HelpBox("This GameObject contains the meshes you previously combined. Through this component you can manage the mesh resulting from the merge.", MessageType.Info);
|
||||
GUILayout.Space(10);
|
||||
|
||||
//Show the merge method used in this merge
|
||||
GUIStyle titulo = new GUIStyle();
|
||||
titulo.fontSize = 16;
|
||||
titulo.normal.textColor = new Color(0, 79.0f / 250.0f, 3.0f / 250.0f);
|
||||
titulo.alignment = TextAnchor.MiddleCenter;
|
||||
if (script.mergeMethodUsed == MergeMethod.OneMeshPerMaterial)
|
||||
EditorGUILayout.LabelField("Merged Using One Mesh Per Material", titulo);
|
||||
if (script.mergeMethodUsed == MergeMethod.AllInOne)
|
||||
EditorGUILayout.LabelField("Merged Using All In One", titulo);
|
||||
if (script.mergeMethodUsed == MergeMethod.JustMaterialColors)
|
||||
EditorGUILayout.LabelField("Merged Using Just Material Colors", titulo);
|
||||
//Show warning box, if necessary
|
||||
RunFilesAndCheckersAndGenerateWarningBoxIfNecessary(script);
|
||||
GUILayout.Space(10);
|
||||
//Render the box of materials and assets
|
||||
RenderTheBoxOfMaterialsAndAssetsManagement(script);
|
||||
//Select all original gameObjects
|
||||
if (GUILayout.Button("Select All Original GameObjects", GUILayout.Height(30)))
|
||||
{
|
||||
List<GameObject> gameObjects = new List<GameObject>();
|
||||
foreach (OriginalGameObjectWithMesh ogo in script.originalsGameObjectsWithMesh)
|
||||
gameObjects.Add(ogo.gameObject);
|
||||
Selection.objects = gameObjects.ToArray();
|
||||
}
|
||||
GUILayout.Space(10);
|
||||
//Render the management buttons of this mesh
|
||||
RenderTheMainManagementButtonsForThisMesh(script);
|
||||
GUILayout.Space(10);
|
||||
EditorGUILayout.LabelField("More Informations About", EditorStyles.boldLabel);
|
||||
GUILayout.Space(10);
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
StringBuilder informationsBuild = new StringBuilder();
|
||||
informationsBuild.Append("What will be done after undoing the merge\n");
|
||||
if (script.undoMethod == UndoMethod.EnableOriginalMeshes)
|
||||
informationsBuild.Append("The original Mesh Renderers will return to their original state.");
|
||||
if (script.undoMethod == UndoMethod.ReactiveOriginalGameObjects)
|
||||
informationsBuild.Append("The original GameObjects will return to their original state.");
|
||||
if (script.undoMethod == UndoMethod.DoNothing)
|
||||
informationsBuild.Append("Nothing will be done.");
|
||||
informationsBuild.Append("\n\nAbout this GameObject\n");
|
||||
if (script.thisIsPrefab == true)
|
||||
informationsBuild.Append("This merged GameObject is or was originally generated as a Prefab. If you decide to undo the merging, the generated files will not be deleted, in order to avoid breaking the copy of this prefab in other scenes.");
|
||||
if (script.thisIsPrefab == false)
|
||||
informationsBuild.Append("This merged GameObject is not and was not originally generated as a Prefab. If you decide to undo the merge, the generated files will be deleted automatically, too.");
|
||||
EditorGUILayout.HelpBox(informationsBuild.ToString(), MessageType.Info);
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
//Final space
|
||||
GUILayout.Space(10);
|
||||
//Stop paint of GUI, if this gameobject no more exists
|
||||
if (script == null)
|
||||
return;
|
||||
|
||||
//Apply changes on script, case is not playing in editor
|
||||
if (GUI.changed == true && Application.isPlaying == false)
|
||||
{
|
||||
EditorUtility.SetDirty(script);
|
||||
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(script.gameObject.scene);
|
||||
}
|
||||
if (EditorGUI.EndChangeCheck() == true)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void RunFilesAndCheckersAndGenerateWarningBoxIfNecessary(CombinedMeshesManager script)
|
||||
{
|
||||
//This method will run some checkers and verifications and, if needed will show a box with warnings about merge
|
||||
warningsOfChecks.Clear();
|
||||
|
||||
//Verify if has missing files of merge, if data save in assets option is enabled
|
||||
bool haveFilesMissing = false;
|
||||
foreach (PathAndTypeOfAAsset item in script.pathsAndTypesOfAssetsOfThisMerge)
|
||||
if (File.Exists(item.path) == false)
|
||||
haveFilesMissing = true;
|
||||
if (haveFilesMissing == true)
|
||||
warningsOfChecks.Add("It appears that one or more files that were generated for this merge, are missing or have been moved from their original locations. If your merge is not as expected, try to redo it.");
|
||||
|
||||
//Verify it the mesh of mesh filter is missing
|
||||
MeshFilter mergedMesh = script.GetComponent<MeshFilter>();
|
||||
if (mergedMesh.sharedMesh == null)
|
||||
warningsOfChecks.Add("It looks like there are missing mesh file in this merge. To solve this problem, you can undo this merge and re-do it again!");
|
||||
|
||||
//Verify if some original GameObject is not present more
|
||||
bool haveOriginalGameObjectsMissing = false;
|
||||
foreach (OriginalGameObjectWithMesh obj in script.originalsGameObjectsWithMesh)
|
||||
if (obj.gameObject == null || obj.meshRenderer == null)
|
||||
haveOriginalGameObjectsMissing = true;
|
||||
if (haveOriginalGameObjectsMissing == true)
|
||||
warningsOfChecks.Add("It seems that some of the original GameObjects or MeshRenderers that make up this merge are no longer present in this scene, or have been deleted. The original GameObjects that are not found cannot be restored to their original state if you decide to undo this merge.");
|
||||
|
||||
//Show the warnings
|
||||
if (warningsOfChecks.Count > 0)
|
||||
{
|
||||
GUILayout.Space(10);
|
||||
EditorGUILayout.BeginHorizontal("box");
|
||||
GUIStyle tituloBox = new GUIStyle();
|
||||
tituloBox.fontStyle = FontStyle.Bold;
|
||||
tituloBox.alignment = TextAnchor.MiddleLeft;
|
||||
EditorGUILayout.LabelField("Warnings For This Merge (" + warningsOfChecks.Count + ")", tituloBox);
|
||||
if (script.hideWarningsForThisMerge == true)
|
||||
if (GUILayout.Button("Show", GUILayout.Height(18), GUILayout.Width(50)))
|
||||
script.hideWarningsForThisMerge = false;
|
||||
if (script.hideWarningsForThisMerge == false)
|
||||
if (GUILayout.Button("Hide", GUILayout.Height(18), GUILayout.Width(50)))
|
||||
script.hideWarningsForThisMerge = true;
|
||||
EditorGUILayout.EndHorizontal();
|
||||
if (script.hideWarningsForThisMerge == false)
|
||||
{
|
||||
EditorGUILayout.BeginVertical("box");
|
||||
foreach (string str in warningsOfChecks)
|
||||
EditorGUILayout.HelpBox(str, MessageType.Warning);
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RenderTheBoxOfMaterialsAndAssetsManagement(CombinedMeshesManager script)
|
||||
{
|
||||
//If this is this mesh was generated by One Mesh Per Material
|
||||
if (script.mergeMethodUsed == MergeMethod.OneMeshPerMaterial)
|
||||
{
|
||||
//Create a scroll view to select all gameobjects where material is equal to...
|
||||
EditorGUILayout.LabelField("Selection By Materials", EditorStyles.boldLabel);
|
||||
GUILayout.Space(10);
|
||||
//Select all original gameObjects with X material
|
||||
Dictionary<Material, List<GameObject>> objects = new Dictionary<Material, List<GameObject>>();
|
||||
foreach (OriginalGameObjectWithMesh oGo in script.originalsGameObjectsWithMesh)
|
||||
{
|
||||
if (oGo == null || oGo.meshRenderer == null)
|
||||
continue;
|
||||
for (int i = 0; i < oGo.meshRenderer.sharedMaterials.Length; i++)
|
||||
{
|
||||
Material mat = oGo.meshRenderer.sharedMaterials[i];
|
||||
if (mat == null)
|
||||
continue;
|
||||
if (objects.ContainsKey(mat) == false)
|
||||
objects.Add(mat, new List<GameObject>() { oGo.gameObject });
|
||||
if (objects.ContainsKey(mat) == true)
|
||||
objects[mat].Add(oGo.gameObject);
|
||||
}
|
||||
}
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Select All Original Meshes That Uses...", GUILayout.Width(320));
|
||||
GUILayout.Space(MTAssetsEditorUi.GetInspectorWindowSize().x - 320);
|
||||
EditorGUILayout.LabelField("Size", GUILayout.Width(30));
|
||||
EditorGUILayout.IntField(objects.Keys.Count, GUILayout.Width(50));
|
||||
EditorGUILayout.EndHorizontal();
|
||||
GUILayout.BeginVertical("box");
|
||||
scrollviewMaterials = EditorGUILayout.BeginScrollView(scrollviewMaterials, GUIStyle.none, GUI.skin.verticalScrollbar, GUILayout.Width(MTAssetsEditorUi.GetInspectorWindowSize().x), GUILayout.Height(150));
|
||||
if (objects.Keys.Count == 0)
|
||||
EditorGUILayout.HelpBox("Oops! The original materials of this merge were not found!", MessageType.Info);
|
||||
if (objects.Keys.Count > 0)
|
||||
foreach (var key in objects.Keys)
|
||||
if (GUILayout.Button("\"" + key.name + "\" Material", GUILayout.Height(24)))
|
||||
Selection.objects = objects[key].ToArray();
|
||||
EditorGUILayout.EndScrollView();
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
//If this is this mesh was generated by other merge method
|
||||
if (script.mergeMethodUsed != MergeMethod.OneMeshPerMaterial)
|
||||
{
|
||||
//Create a scroll view to view all generated files...
|
||||
EditorGUILayout.LabelField("All Generated Assets", EditorStyles.boldLabel);
|
||||
GUILayout.Space(10);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("All Generated Assets In This Merge...", GUILayout.Width(320));
|
||||
GUILayout.Space(MTAssetsEditorUi.GetInspectorWindowSize().x - 320);
|
||||
EditorGUILayout.LabelField("Size", GUILayout.Width(30));
|
||||
EditorGUILayout.IntField(script.pathsAndTypesOfAssetsOfThisMerge.Count, GUILayout.Width(50));
|
||||
EditorGUILayout.EndHorizontal();
|
||||
GUILayout.BeginVertical("box");
|
||||
scrollviewMaterials = EditorGUILayout.BeginScrollView(scrollviewMaterials, GUIStyle.none, GUI.skin.verticalScrollbar, GUILayout.Width(MTAssetsEditorUi.GetInspectorWindowSize().x), GUILayout.Height(118));
|
||||
foreach (PathAndTypeOfAAsset item in script.pathsAndTypesOfAssetsOfThisMerge)
|
||||
DrawItemOfListOfResourcesInStats(item.path);
|
||||
EditorGUILayout.EndScrollView();
|
||||
GUILayout.EndVertical();
|
||||
//Draw export options
|
||||
DrawExportAllAtlasOrMaterialsOption(script);
|
||||
}
|
||||
}
|
||||
|
||||
private void RenderTheMainManagementButtonsForThisMesh(CombinedMeshesManager script)
|
||||
{
|
||||
//This method will render the buttons to manage this merge
|
||||
EditorGUILayout.LabelField("Management Of This Merge", EditorStyles.boldLabel);
|
||||
GUILayout.Space(10);
|
||||
|
||||
if (script.GetComponent<MeshCollider>() == null)
|
||||
if (GUILayout.Button("Add Mesh Collider To This Mesh", GUILayout.Height(30)))
|
||||
{
|
||||
script.gameObject.AddComponent<MeshCollider>();
|
||||
Debug.Log("A Mesh Collider was added to this mesh!.");
|
||||
}
|
||||
if (GUILayout.Button("Recalculate Normals Of This Mesh", GUILayout.Height(30)))
|
||||
{
|
||||
script.GetComponent<MeshFilter>().sharedMesh.RecalculateNormals();
|
||||
Debug.Log("The normals of this mesh resulting from the merging were recalculated.");
|
||||
}
|
||||
if (GUILayout.Button("Recalculate Tangents Of This Mesh", GUILayout.Height(30)))
|
||||
{
|
||||
script.GetComponent<MeshFilter>().sharedMesh.RecalculateTangents();
|
||||
Debug.Log("The tangents of this mesh resulting from the merging were recalculated.");
|
||||
}
|
||||
if (GUILayout.Button("Copy Primary UV to UV2", GUILayout.Height(25)))
|
||||
{
|
||||
script.GetComponent<MeshFilter>().sharedMesh.uv2 = script.GetComponent<MeshFilter>().sharedMesh.uv;
|
||||
#if UNITY_EDITOR
|
||||
EditorUtility.SetDirty(script.GetComponent<MeshFilter>().sharedMesh);
|
||||
#endif
|
||||
Debug.Log("The Primary UV of mesh \"" + script.GetComponent<MeshFilter>().sharedMesh.name + "\" was copied to UV2 successfully!");
|
||||
}
|
||||
if (GUILayout.Button("Copy Primary UV to UV3", GUILayout.Height(25)))
|
||||
{
|
||||
script.GetComponent<MeshFilter>().sharedMesh.uv3 = script.GetComponent<MeshFilter>().sharedMesh.uv;
|
||||
#if UNITY_EDITOR
|
||||
EditorUtility.SetDirty(script.GetComponent<MeshFilter>().sharedMesh);
|
||||
#endif
|
||||
Debug.Log("The Primary UV of mesh \"" + script.GetComponent<MeshFilter>().sharedMesh.name + "\" was copied to UV3 successfully!");
|
||||
}
|
||||
if (GUILayout.Button("Copy Primary UV to UV4", GUILayout.Height(25)))
|
||||
{
|
||||
script.GetComponent<MeshFilter>().sharedMesh.uv4 = script.GetComponent<MeshFilter>().sharedMesh.uv;
|
||||
#if UNITY_EDITOR
|
||||
EditorUtility.SetDirty(script.GetComponent<MeshFilter>().sharedMesh);
|
||||
#endif
|
||||
Debug.Log("The Primary UV of mesh \"" + script.GetComponent<MeshFilter>().sharedMesh.name + "\" was copied to UV4 successfully!");
|
||||
}
|
||||
if (GUILayout.Button("Copy Primary UV to UV5", GUILayout.Height(25)))
|
||||
{
|
||||
script.GetComponent<MeshFilter>().sharedMesh.uv5 = script.GetComponent<MeshFilter>().sharedMesh.uv;
|
||||
#if UNITY_EDITOR
|
||||
EditorUtility.SetDirty(script.GetComponent<MeshFilter>().sharedMesh);
|
||||
#endif
|
||||
Debug.Log("The Primary UV of mesh \"" + script.GetComponent<MeshFilter>().sharedMesh.name + "\" was copied to UV5 successfully!");
|
||||
}
|
||||
if (GUILayout.Button("Copy Primary UV to UV6", GUILayout.Height(25)))
|
||||
{
|
||||
script.GetComponent<MeshFilter>().sharedMesh.uv6 = script.GetComponent<MeshFilter>().sharedMesh.uv;
|
||||
#if UNITY_EDITOR
|
||||
EditorUtility.SetDirty(script.GetComponent<MeshFilter>().sharedMesh);
|
||||
#endif
|
||||
Debug.Log("The Primary UV of mesh \"" + script.GetComponent<MeshFilter>().sharedMesh.name + "\" was copied to UV6 successfully!");
|
||||
}
|
||||
if (GUILayout.Button("Copy Primary UV to UV7", GUILayout.Height(25)))
|
||||
{
|
||||
script.GetComponent<MeshFilter>().sharedMesh.uv7 = script.GetComponent<MeshFilter>().sharedMesh.uv;
|
||||
#if UNITY_EDITOR
|
||||
EditorUtility.SetDirty(script.GetComponent<MeshFilter>().sharedMesh);
|
||||
#endif
|
||||
Debug.Log("The Primary UV of mesh \"" + script.GetComponent<MeshFilter>().sharedMesh.name + "\" was copied to UV7 successfully!");
|
||||
}
|
||||
if (GUILayout.Button("Export This Mesh As OBJ", GUILayout.Height(30)))
|
||||
script.ExportMeshAsObj(script);
|
||||
if (GUILayout.Button("Optimize This Mesh", GUILayout.Height(30)))
|
||||
{
|
||||
script.GetComponent<MeshFilter>().sharedMesh.Optimize();
|
||||
Debug.Log("The mesh resulting from the merge has been optimized!");
|
||||
}
|
||||
if (GUILayout.Button("Undo And Delete This Merge", GUILayout.Height(30)))
|
||||
{
|
||||
bool confirmation = EditorUtility.DisplayDialog("Undo",
|
||||
"This combined mesh and your GameObject will be deleted and removed from your scene. The original GameObjects/Meshes will be restored to their original state before the merge.\n\nAre you sure you want to undo this merge?",
|
||||
"Yes",
|
||||
"No");
|
||||
if (confirmation == true)
|
||||
script.UndoAndDeleteThisMerge();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawItemOfListOfResourcesInStats(string filePath)
|
||||
{
|
||||
//Get the type of asset
|
||||
Type assetType = AssetDatabase.GetMainAssetTypeAtPath(filePath);
|
||||
|
||||
//Load the asset
|
||||
var asset = AssetDatabase.LoadAssetAtPath(filePath, assetType);
|
||||
|
||||
//Draw the item and represent the desired file
|
||||
GUILayout.Space(2);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (assetType == null)
|
||||
{
|
||||
assetType = typeof(object);
|
||||
}
|
||||
if (assetType != null)
|
||||
{
|
||||
if (assetType != typeof(Texture) && assetType != typeof(Texture2D))
|
||||
{
|
||||
GUILayout.Box("R", GUILayout.Width(28), GUILayout.Height(28));
|
||||
}
|
||||
if (assetType == typeof(Texture) || assetType == typeof(Texture2D))
|
||||
{
|
||||
GUIStyle estiloIcone = new GUIStyle();
|
||||
estiloIcone.border = new RectOffset(0, 0, 0, 0);
|
||||
estiloIcone.margin = new RectOffset(4, 0, 4, 0);
|
||||
GUILayout.Box((Texture)asset, estiloIcone, GUILayout.Width(28), GUILayout.Height(28));
|
||||
}
|
||||
}
|
||||
EditorGUILayout.BeginVertical();
|
||||
if (asset == null)
|
||||
EditorGUILayout.LabelField("Resource Not Found", EditorStyles.boldLabel);
|
||||
if (asset != null)
|
||||
EditorGUILayout.LabelField(asset.name, EditorStyles.boldLabel);
|
||||
GUILayout.Space(-3);
|
||||
if (assetType == typeof(Mesh))
|
||||
EditorGUILayout.LabelField("Mesh/" + Path.GetExtension(filePath));
|
||||
if (assetType == typeof(Texture) || assetType == typeof(Texture2D))
|
||||
EditorGUILayout.LabelField("Texture/" + Path.GetExtension(filePath));
|
||||
if (assetType == typeof(Material))
|
||||
EditorGUILayout.LabelField("Material/" + Path.GetExtension(filePath));
|
||||
if (assetType == typeof(object))
|
||||
EditorGUILayout.LabelField("Unknow/???");
|
||||
EditorGUILayout.EndVertical();
|
||||
GUILayout.Space(20);
|
||||
EditorGUILayout.BeginVertical();
|
||||
GUILayout.Space(8);
|
||||
if (GUILayout.Button("Resource", GUILayout.Height(20)))
|
||||
{
|
||||
EditorGUIUtility.PingObject(asset);
|
||||
}
|
||||
EditorGUILayout.EndVertical();
|
||||
EditorGUILayout.EndHorizontal();
|
||||
GUILayout.Space(2);
|
||||
}
|
||||
|
||||
private void DrawExportAllAtlasOrMaterialsOption(CombinedMeshesManager script)
|
||||
{
|
||||
//Draw buttons to export resources
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
//Create button to export all textures
|
||||
if (GUILayout.Button("Export All Atlas", GUILayout.Height(30)))
|
||||
{
|
||||
//Open selection of folder
|
||||
string folder = EditorUtility.OpenFolderPanel("Select Folder To Save", "", "");
|
||||
if (String.IsNullOrEmpty(folder) == true)
|
||||
return;
|
||||
|
||||
//Show progress bar
|
||||
EditorUtility.DisplayProgressBar("A moment", "Exporting Atlas as PNG", 1.0f);
|
||||
|
||||
//For file of list of assets saved
|
||||
foreach (PathAndTypeOfAAsset item in script.pathsAndTypesOfAssetsOfThisMerge)
|
||||
{
|
||||
//Load type of asset and the asset
|
||||
var asset = AssetDatabase.LoadAssetAtPath(item.path, typeof(object));
|
||||
var type = typeof(object);
|
||||
if (asset != null)
|
||||
type = asset.GetType();
|
||||
|
||||
if (asset == null)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Atlas Not Found", "It was not possible to export the texture, as it was not found in the directory below\n\n" + item.path, "Continue");
|
||||
continue;
|
||||
}
|
||||
if (asset != null && type != typeof(Texture2D))
|
||||
continue;
|
||||
if (asset != null && type == typeof(Texture2D))
|
||||
{
|
||||
Texture2D texture = asset as Texture2D;
|
||||
byte[] mainTextureBytes = texture.EncodeToPNG();
|
||||
File.WriteAllBytes(folder + "/" + asset.name + ".png", mainTextureBytes);
|
||||
}
|
||||
}
|
||||
|
||||
//Clear progress bar
|
||||
EditorUtility.ClearProgressBar();
|
||||
|
||||
//Show warning
|
||||
EditorUtility.DisplayDialog("Done", "Exporting process is finished. All atlas generated by this merge, was exported to path below\n\n" + folder, "Ok");
|
||||
}
|
||||
//Create button to export all materials
|
||||
if (GUILayout.Button("Export Material", GUILayout.Height(30)))
|
||||
{
|
||||
//Open selection of folder
|
||||
string folder = EditorUtility.OpenFolderPanel("Select Folder To Save", "", "");
|
||||
if (String.IsNullOrEmpty(folder) == true)
|
||||
return;
|
||||
|
||||
//Show progress bar
|
||||
EditorUtility.DisplayProgressBar("A moment", "Exporting Materials", 1.0f);
|
||||
|
||||
//For file of list of assets saved
|
||||
foreach (PathAndTypeOfAAsset item in script.pathsAndTypesOfAssetsOfThisMerge)
|
||||
{
|
||||
//Load type of asset and the asset
|
||||
var asset = AssetDatabase.LoadAssetAtPath(item.path, typeof(object));
|
||||
var type = typeof(object);
|
||||
if (asset != null)
|
||||
type = asset.GetType();
|
||||
|
||||
if (asset == null)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Materials Not Found", "It was not possible to export the material, as it was not found in the directory below\n\n" + item.path, "Continue");
|
||||
continue;
|
||||
}
|
||||
if (asset != null && type != typeof(Material))
|
||||
continue;
|
||||
if (asset != null && type == typeof(Material))
|
||||
{
|
||||
File.Copy(item.path, folder + "/" + asset.name + ".mat");
|
||||
}
|
||||
}
|
||||
|
||||
//Clear progress bar
|
||||
EditorUtility.ClearProgressBar();
|
||||
|
||||
//Show warning
|
||||
EditorUtility.DisplayDialog("Done", "Exporting process is finished. All materials generated by this merge, was exported to path below\n\n" + folder, "Ok");
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
//Core Methods
|
||||
|
||||
private void UndoAndDeleteThisMerge()
|
||||
{
|
||||
//Show progress bar
|
||||
EditorUtility.DisplayProgressBar("A moment", "Undoing...", 1.0f);
|
||||
|
||||
//Undo the merge according the type of merge
|
||||
if (undoMethod == UndoMethod.EnableOriginalMeshes)
|
||||
foreach (OriginalGameObjectWithMesh original in originalsGameObjectsWithMesh)
|
||||
{
|
||||
//Skip, if is null
|
||||
if (original.meshRenderer == null)
|
||||
continue;
|
||||
original.meshRenderer.enabled = original.originalMrState;
|
||||
}
|
||||
if (undoMethod == UndoMethod.ReactiveOriginalGameObjects)
|
||||
foreach (OriginalGameObjectWithMesh original in originalsGameObjectsWithMesh)
|
||||
{
|
||||
//Skip, if is null
|
||||
if (original.gameObject == null)
|
||||
continue;
|
||||
original.gameObject.SetActive(original.originalGoState);
|
||||
}
|
||||
|
||||
//Delete unused assets, if this is not a prefab
|
||||
if (thisIsPrefab == false)
|
||||
foreach (PathAndTypeOfAAsset item in pathsAndTypesOfAssetsOfThisMerge)
|
||||
{
|
||||
if (AssetDatabase.LoadAssetAtPath(item.path, typeof(object)) != null)
|
||||
AssetDatabase.DeleteAsset(item.path);
|
||||
|
||||
if (AssetDatabase.LoadAssetAtPath(item.path.Replace(".asset", " RAW.asset"), typeof(object)) != null)
|
||||
AssetDatabase.DeleteAsset(item.path.Replace(".asset", " RAW.asset"));
|
||||
}
|
||||
|
||||
//Set scene as dirty
|
||||
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene());
|
||||
|
||||
//Show dialog
|
||||
Debug.Log("The merge was successfully undone. All of the original GameObject/Meshes that this Manager could still access have been restored!\n\nIf you had chosen to save the merged meshes to your project files, all useless mesh files were deleted automatically!");
|
||||
|
||||
//Destroy this merge
|
||||
DestroyImmediate(this.gameObject, true);
|
||||
|
||||
//Clear progress bar
|
||||
EditorUtility.ClearProgressBar();
|
||||
}
|
||||
|
||||
private void ExportMeshAsObj(CombinedMeshesManager script)
|
||||
{
|
||||
//Open the export window
|
||||
string folder = EditorUtility.OpenFolderPanel("Select Folder To Export", "", "");
|
||||
if (String.IsNullOrEmpty(folder) == true)
|
||||
return;
|
||||
|
||||
//Show progress bar
|
||||
EditorUtility.DisplayProgressBar("A moment", "Exporting Mesh as OBJ", 1.0f);
|
||||
|
||||
//Get this mesh
|
||||
MeshRenderer meshRenderer = this.gameObject.GetComponent<MeshRenderer>();
|
||||
MeshFilter meshFilter = this.gameObject.GetComponent<MeshFilter>();
|
||||
|
||||
//Start export of mesh
|
||||
exportToObjStartIndexOffSet = 0;
|
||||
StringBuilder meshString = new StringBuilder();
|
||||
meshString.Append("#" + meshFilter.sharedMesh.name + ".obj"
|
||||
+ "\n#" + System.DateTime.Now.ToLongDateString()
|
||||
+ "\n#" + System.DateTime.Now.ToLongTimeString()
|
||||
+ "\n#-------"
|
||||
+ "\n\n");
|
||||
Transform transform = this.gameObject.transform;
|
||||
Vector3 originalPosition = transform.position;
|
||||
transform.position = Vector3.zero;
|
||||
meshString.Append(ExportToObjProcessTransform(transform, script));
|
||||
string meshStringResult = meshString.ToString();
|
||||
using (StreamWriter stringWriter = new StreamWriter(folder + "/" + meshFilter.sharedMesh.name + ".obj"))
|
||||
{
|
||||
stringWriter.Write(meshStringResult);
|
||||
}
|
||||
transform.position = originalPosition;
|
||||
exportToObjStartIndexOffSet = 0;
|
||||
|
||||
//Clear progress bar
|
||||
EditorUtility.ClearProgressBar();
|
||||
|
||||
//Show warning
|
||||
Debug.Log("The mesh was successfully exported to the directory \"" + folder + "\".");
|
||||
}
|
||||
|
||||
//Tools Methods For Core Methods
|
||||
|
||||
private static string ExportToObjProcessTransform(Transform transform, CombinedMeshesManager script)
|
||||
{
|
||||
StringBuilder meshString = new StringBuilder();
|
||||
meshString.Append("#" + transform.name
|
||||
+ "\n#-------"
|
||||
+ "\n");
|
||||
|
||||
meshString.Append("g ").Append(transform.name).Append("\n");
|
||||
|
||||
MeshFilter mf = transform.GetComponent<MeshFilter>();
|
||||
|
||||
if (mf)
|
||||
meshString.Append(ExportToObjMeshToString(mf, transform, script));
|
||||
|
||||
for (int i = 0; i < transform.childCount; i++)
|
||||
meshString.Append(ExportToObjProcessTransform(transform.GetChild(i), script));
|
||||
|
||||
return meshString.ToString();
|
||||
}
|
||||
|
||||
private static string ExportToObjMeshToString(MeshFilter mf, Transform t, CombinedMeshesManager script)
|
||||
{
|
||||
Vector3 s = t.localScale;
|
||||
Vector3 p = t.localPosition;
|
||||
Quaternion r = t.localRotation;
|
||||
int numVertices = 0;
|
||||
|
||||
Mesh m = mf.sharedMesh;
|
||||
if (!m)
|
||||
return "####Error####";
|
||||
|
||||
Material[] mats = mf.GetComponent<MeshRenderer>().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 + script.exportToObjStartIndexOffSet, triangles[i + 1] + 1 + script.exportToObjStartIndexOffSet, triangles[i + 2] + 1 + script.exportToObjStartIndexOffSet));
|
||||
}
|
||||
}
|
||||
|
||||
script.exportToObjStartIndexOffSet += numVertices;
|
||||
return sb.ToString();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 41659897ac0c84f49977383a29dd0100
|
||||
timeCreated: 1548972541
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: e5168e147f30ae54c9f1548c5e1c0492, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 48 KiB |
@ -0,0 +1,90 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5168e147f30ae54c9f1548c5e1c0492
|
||||
timeCreated: 1548972520
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,722 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
#endif
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace MTAssets.EasyMeshCombiner
|
||||
{
|
||||
/*
|
||||
This class is responsible for the functioning of the "Runtime Mesh Combiner" component, and all its functions.
|
||||
*/
|
||||
/*
|
||||
* The Easy Mesh Combiner was developed by Marcos Tomaz in 2019.
|
||||
* Need help? Contact me (mtassets@windsoft.xyz)
|
||||
*/
|
||||
|
||||
[AddComponentMenu("MT Assets/Easy Mesh Combiner/Runtime Mesh Combiner")] //Add this component in a category of addComponent menu
|
||||
public class RuntimeMeshCombiner : MonoBehaviour
|
||||
{
|
||||
//Private constants
|
||||
private int MAX_VERTICES_FOR_16BITS_MESH = 50000; //Not change this
|
||||
|
||||
//Classes of script
|
||||
private class GameObjectWithMesh
|
||||
{
|
||||
//Class that stores a valid gameobject that contains a mesh
|
||||
public GameObject gameObject;
|
||||
public MeshFilter meshFilter;
|
||||
public MeshRenderer meshRenderer;
|
||||
public GameObjectWithMesh(GameObject gameObject, MeshFilter meshFilter, MeshRenderer meshRenderer)
|
||||
{
|
||||
this.gameObject = gameObject;
|
||||
this.meshFilter = meshFilter;
|
||||
this.meshRenderer = meshRenderer;
|
||||
}
|
||||
}
|
||||
private class OriginalGameObjectWithMesh
|
||||
{
|
||||
//Class that stores a original GameObject With Mesh data, to restore on undo merge.
|
||||
|
||||
public GameObject gameObject;
|
||||
public bool originalGoState;
|
||||
public MeshRenderer meshRenderer;
|
||||
public bool originalMrState;
|
||||
|
||||
public OriginalGameObjectWithMesh(GameObject gameObject, bool originalGoState, MeshRenderer meshRenderer, bool originalMrState)
|
||||
{
|
||||
this.gameObject = gameObject;
|
||||
this.originalGoState = originalGoState;
|
||||
this.meshRenderer = meshRenderer;
|
||||
this.originalMrState = originalMrState;
|
||||
}
|
||||
}
|
||||
private class SubMeshToCombine
|
||||
{
|
||||
//Class that stores a mesh filter/renderer and respective submesh index, to combine
|
||||
public Transform transform;
|
||||
public MeshFilter meshFilter;
|
||||
public MeshRenderer meshRenderer;
|
||||
public int subMeshIndex;
|
||||
|
||||
public SubMeshToCombine(Transform transform, MeshFilter meshFilter, MeshRenderer meshRenderer, int subMeshIndex)
|
||||
{
|
||||
this.transform = transform;
|
||||
this.meshFilter = meshFilter;
|
||||
this.meshRenderer = meshRenderer;
|
||||
this.subMeshIndex = subMeshIndex;
|
||||
}
|
||||
}
|
||||
|
||||
//Enums of script
|
||||
public enum CombineOnStart
|
||||
{
|
||||
Disabled,
|
||||
OnStart,
|
||||
OnAwake
|
||||
}
|
||||
public enum AfterMerge
|
||||
{
|
||||
DisableOriginalMeshes,
|
||||
DeactiveOriginalGameObjects,
|
||||
DoNothing
|
||||
}
|
||||
|
||||
//Variables of script
|
||||
private Vector3 originalPosition = Vector3.zero;
|
||||
private Vector3 originalEulerAngles = Vector3.zero;
|
||||
private Vector3 originalScale = Vector3.zero;
|
||||
private List<OriginalGameObjectWithMesh> originalGameObjectsWithMeshToRestore = new List<OriginalGameObjectWithMesh>();
|
||||
private bool targetMeshesMerged = false;
|
||||
|
||||
//Variables of merge
|
||||
[HideInInspector]
|
||||
public AfterMerge afterMerge;
|
||||
[HideInInspector]
|
||||
public bool addMeshColliderAfter = true;
|
||||
[HideInInspector]
|
||||
public CombineOnStart combineMeshesAtStartUp = CombineOnStart.Disabled;
|
||||
[HideInInspector]
|
||||
public bool combineInChildren = false;
|
||||
[HideInInspector]
|
||||
public bool combineInactives = false;
|
||||
[HideInInspector]
|
||||
public bool recalculateNormals = true;
|
||||
[HideInInspector]
|
||||
public bool recalculateTangents = true;
|
||||
[HideInInspector]
|
||||
public bool optimizeResultingMesh = false;
|
||||
[HideInInspector]
|
||||
public List<GameObject> targetMeshes = new List<GameObject>();
|
||||
[HideInInspector]
|
||||
public bool showDebugLogs = true;
|
||||
[HideInInspector]
|
||||
public bool garbageCollectorAfterUndo = true;
|
||||
public UnityEvent onDoneMerge;
|
||||
public UnityEvent onDoneUnmerge;
|
||||
|
||||
//The UI of this component
|
||||
#if UNITY_EDITOR
|
||||
//Private variables of Interface
|
||||
private bool gizmosOfThisComponentIsDisabled = false;
|
||||
|
||||
#region INTERFACE_CODE
|
||||
[UnityEditor.CustomEditor(typeof(RuntimeMeshCombiner))]
|
||||
public class CustomInspector : UnityEditor.Editor
|
||||
{
|
||||
//Private temp variables
|
||||
public Vector2 targetMeshes_ScrollPos;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
//Start the undo event support, draw default inspector and monitor of changes
|
||||
RuntimeMeshCombiner script = (RuntimeMeshCombiner)target;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
Undo.RecordObject(target, "Undo Event");
|
||||
script.gizmosOfThisComponentIsDisabled = MTAssetsEditorUi.DisableGizmosInSceneView("RuntimeMeshCombiner", script.gizmosOfThisComponentIsDisabled);
|
||||
|
||||
//Support reminder
|
||||
GUILayout.Space(10);
|
||||
EditorGUILayout.HelpBox("Remember to read the Easy Mesh Combiner documentation to understand how to use it.\nGet support at: mtassets@windsoft.xyz", MessageType.None);
|
||||
|
||||
//Check if the component already have a Mesh Renderer and Mesh Filter components, if already have, show a warning
|
||||
MeshFilter meshFilter = script.GetComponent<MeshFilter>();
|
||||
MeshRenderer meshRenderer = script.GetComponent<MeshRenderer>();
|
||||
if (script.isTargetMeshesMerged() == false)
|
||||
if (meshFilter != null || meshRenderer != null)
|
||||
{
|
||||
GUILayout.Space(10);
|
||||
EditorGUILayout.HelpBox("It looks like this component already contains a Mesh Filter and/or Mesh Renderer component. The Runtime Mesh Combiner will save the mesh resulting from the merge in this GameObject and therefore it needs a GameObject that does not contain either of these two components. Please remove the Mesh Filter and Mesh Renderer from this GameObject or place the Runtime Mesh Combiner in a new empty GameObject, otherwise the API will not allow merges to be done.", MessageType.Error);
|
||||
}
|
||||
|
||||
//Start of preferences
|
||||
GUILayout.Space(10);
|
||||
EditorGUILayout.LabelField("Preferences", EditorStyles.boldLabel);
|
||||
GUILayout.Space(10);
|
||||
|
||||
script.afterMerge = (AfterMerge)EditorGUILayout.EnumPopup(new GUIContent("After Combine",
|
||||
"What do you do after you complete the merge?\n\nDisable Original Meshes - The original meshes will be deactivated, so all the colliders and other components of the scenario will be kept intact, but the meshes will still be combined!\n\nDeactive Original GameObjects - All original GameObjects will be disabled. When you do not need to keep colliders and other active components in the scene, this is a good option!\n\nRelax, however, it is possible to undo the merge later and re-activate everything again!"),
|
||||
script.afterMerge);
|
||||
if (script.afterMerge == AfterMerge.DeactiveOriginalGameObjects)
|
||||
{
|
||||
EditorGUI.indentLevel += 1;
|
||||
script.addMeshColliderAfter = (bool)EditorGUILayout.Toggle(new GUIContent("Add Mesh Collider After",
|
||||
"Add Mesh Collider to the merge mesh after combining?"),
|
||||
script.addMeshColliderAfter);
|
||||
EditorGUI.indentLevel -= 1;
|
||||
}
|
||||
|
||||
script.combineMeshesAtStartUp = (CombineOnStart)EditorGUILayout.EnumPopup(new GUIContent("Combine On Start",
|
||||
"Here you can enable or disable automatic meshing of meshes, right at the beginning of the execution of this scene in your game." +
|
||||
"\n\nDisabled - Auto merge will not be performed." +
|
||||
"\n\nOnAwake - Merging will take place in your game's Awake. Awake is executed before all the Start methods in your scene." +
|
||||
"\n\nOnStart - The merging will be done at the Start of your game."),
|
||||
script.combineMeshesAtStartUp);
|
||||
|
||||
script.combineInChildren = EditorGUILayout.Toggle(new GUIContent("Combine Childrens Too",
|
||||
"If this option is enabled, the EMC will combine the GameObjects children of the registered GameObjects for merging, too!"),
|
||||
script.combineInChildren);
|
||||
|
||||
script.combineInactives = EditorGUILayout.Toggle(new GUIContent("Combine Inactives Too",
|
||||
"If this option is active, the EMC will combine inactive GameObjects as well, even if they are registered in the list of meshes to be merged."),
|
||||
script.combineInactives);
|
||||
|
||||
script.recalculateNormals = EditorGUILayout.Toggle(new GUIContent("Recalculate Normals",
|
||||
"Enable this and the EMC will recalculate the normals of the mesh resulting from the merge. The EMC will preserve the normal data for the original fabrics if this is disabled."),
|
||||
script.recalculateNormals);
|
||||
|
||||
script.recalculateTangents = EditorGUILayout.Toggle(new GUIContent("Recalculate Tangents",
|
||||
"Enable this and the EMC will recalculate the tangents of the mesh resulting from the merge. The EMC will preserve the tangent data for the original meshes if this is disabled."),
|
||||
script.recalculateTangents);
|
||||
|
||||
script.optimizeResultingMesh = EditorGUILayout.Toggle(new GUIContent("Optimize Resulting Mesh",
|
||||
"If this option is enabled, the Runtime Mesh Combiner will optimize the mesh resulting from the merge. This may lead to performance gains in rendering the mesh resulting from the merging, through the mechanism of Unity.\n\nThis can slightly increase the mesh processing time."),
|
||||
script.optimizeResultingMesh);
|
||||
|
||||
script.garbageCollectorAfterUndo = EditorGUILayout.Toggle(new GUIContent("Run GC After Undo",
|
||||
"Garbage Collector will free up memory that was used by unnecessary assets after undoing a merge, but this can negatively impact your game performance, depending on the complexity of the mesh combined. Run garbage collector after undoing a merge?"),
|
||||
script.garbageCollectorAfterUndo);
|
||||
|
||||
//Start of target meshes
|
||||
GUILayout.Space(10);
|
||||
EditorGUILayout.LabelField("Target Meshes", EditorStyles.boldLabel);
|
||||
GUILayout.Space(10);
|
||||
|
||||
Texture2D removeItemIcon = (Texture2D)AssetDatabase.LoadAssetAtPath("Assets/Plugins/MT Assets/Easy Mesh Combiner/Editor/Images/Remove.png", typeof(Texture2D));
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Target Meshes To Merge", GUILayout.Width(145));
|
||||
GUILayout.Space(MTAssetsEditorUi.GetInspectorWindowSize().x - 145);
|
||||
EditorGUILayout.LabelField("Size", GUILayout.Width(30));
|
||||
EditorGUILayout.IntField(script.targetMeshes.Count, GUILayout.Width(50));
|
||||
EditorGUILayout.EndHorizontal();
|
||||
GUILayout.BeginVertical("box");
|
||||
targetMeshes_ScrollPos = EditorGUILayout.BeginScrollView(targetMeshes_ScrollPos, GUIStyle.none, GUI.skin.verticalScrollbar, GUILayout.Width(MTAssetsEditorUi.GetInspectorWindowSize().x), GUILayout.Height(100));
|
||||
if (script.targetMeshes.Count == 0)
|
||||
EditorGUILayout.HelpBox("Oops! No GameObjects with meshes was registered to be combined! If you want to subscribe any, click the button below!", MessageType.Info);
|
||||
if (script.targetMeshes.Count > 0)
|
||||
for (int i = 0; i < script.targetMeshes.Count; i++)
|
||||
{
|
||||
GUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button(removeItemIcon, GUILayout.Width(25), GUILayout.Height(16)))
|
||||
script.targetMeshes.RemoveAt(i);
|
||||
script.targetMeshes[i] = (GameObject)EditorGUILayout.ObjectField(new GUIContent("GameObject " + i.ToString(), "The mesh found in this GameObject will be combined. Click the button to the left if you want to remove this GameObject from the list."), script.targetMeshes[i], typeof(GameObject), true, GUILayout.Height(16));
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
EditorGUILayout.EndScrollView();
|
||||
GUILayout.EndVertical();
|
||||
GUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Add New Slot"))
|
||||
{
|
||||
script.targetMeshes.Add(null);
|
||||
targetMeshes_ScrollPos.y += 999999;
|
||||
}
|
||||
if (script.targetMeshes.Count > 0)
|
||||
if (GUILayout.Button("Remove Empty Slots", GUILayout.Width(Screen.width * 0.48f)))
|
||||
for (int i = script.targetMeshes.Count - 1; i >= 0; i--)
|
||||
if (script.targetMeshes[i] == null)
|
||||
script.targetMeshes.RemoveAt(i);
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
//Merge Events
|
||||
GUILayout.Space(10);
|
||||
EditorGUILayout.LabelField("Merge Events", EditorStyles.boldLabel);
|
||||
GUILayout.Space(10);
|
||||
DrawDefaultInspector();
|
||||
|
||||
//Start of debug
|
||||
GUILayout.Space(10);
|
||||
EditorGUILayout.LabelField("Debug", EditorStyles.boldLabel);
|
||||
GUILayout.Space(10);
|
||||
|
||||
EditorGUILayout.Toggle(new GUIContent("Target Meshes Merged",
|
||||
"Are the target meshes currently combined?"),
|
||||
script.isTargetMeshesMerged());
|
||||
|
||||
if (script.showDebugLogs == true)
|
||||
EditorGUILayout.HelpBox("Excessive debug logs can cause performance fluctuations in your game. Just enable this function while debugging your merge and game.", MessageType.Warning);
|
||||
script.showDebugLogs = EditorGUILayout.Toggle(new GUIContent("Show Debug Logs",
|
||||
"Debug logs notify you if the combiner encounters any invalid or similar mesh, but excessive debug logs can cause performance fluctuations in your game. View logs for debugging?"),
|
||||
script.showDebugLogs);
|
||||
|
||||
//Final space
|
||||
GUILayout.Space(10);
|
||||
|
||||
//Stop paint of GUI, if this gameobject no more exists
|
||||
if (script == null)
|
||||
return;
|
||||
|
||||
//Apply changes on script, case is not playing in editor
|
||||
if (GUI.changed == true && Application.isPlaying == false)
|
||||
{
|
||||
EditorUtility.SetDirty(script);
|
||||
UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(script.gameObject.scene);
|
||||
}
|
||||
if (EditorGUI.EndChangeCheck() == true)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#endif
|
||||
|
||||
//Component code
|
||||
|
||||
void Awake()
|
||||
{
|
||||
//Combine meshes on start
|
||||
if (combineMeshesAtStartUp == CombineOnStart.OnAwake)
|
||||
{
|
||||
if (showDebugLogs == true)
|
||||
Debug.Log("The merge started in Runtime Combiner \"" + this.gameObject.name + "\".");
|
||||
CombineMeshes();
|
||||
}
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
//Combine meshes on start
|
||||
if (combineMeshesAtStartUp == CombineOnStart.OnStart)
|
||||
{
|
||||
if (showDebugLogs == true)
|
||||
Debug.Log("The merge started in Runtime Combiner \"" + this.gameObject.name + "\".");
|
||||
CombineMeshes();
|
||||
}
|
||||
}
|
||||
|
||||
GameObjectWithMesh[] GetValidatedTargetGameObjects()
|
||||
{
|
||||
//Validate the target gameobjects and return a list of valids GameObjects with mesh
|
||||
|
||||
//Get all found gameobjects in targets gameobjects
|
||||
List<Transform> foundGameObjects = new List<Transform>();
|
||||
for (int i = 0; i < targetMeshes.Count; i++)
|
||||
{
|
||||
//Skips if this target mesh is null
|
||||
if (targetMeshes[i] == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (combineInChildren == true)
|
||||
{
|
||||
Transform[] childrenGameObjectsInThis = targetMeshes[i].GetComponentsInChildren<Transform>(true);
|
||||
foreach (Transform trs in childrenGameObjectsInThis)
|
||||
if (foundGameObjects.Contains(trs) == false) //<-- Check if this GameObject has already been added to the list before adding it, to avoid duplicates
|
||||
foundGameObjects.Add(trs);
|
||||
}
|
||||
if (combineInChildren == false)
|
||||
{
|
||||
Transform thisGameObjectTrs = targetMeshes[i].GetComponent<Transform>();
|
||||
if (foundGameObjects.Contains(thisGameObjectTrs) == false) //<-- Check if this GameObject has already been added to the list before adding it, to avoid duplicates
|
||||
foundGameObjects.Add(thisGameObjectTrs);
|
||||
}
|
||||
}
|
||||
|
||||
//Validate each found gameobject and split gameobjects that contains mesh filter or/and mesh renderer, and add to list of valid gameObjects
|
||||
List<GameObjectWithMesh> gameObjectsWithMesh = new List<GameObjectWithMesh>();
|
||||
for (int i = 0; i < foundGameObjects.Count; i++)
|
||||
{
|
||||
MeshFilter mf = foundGameObjects[i].GetComponent<MeshFilter>();
|
||||
MeshRenderer mr = foundGameObjects[i].GetComponent<MeshRenderer>();
|
||||
if (mf != null || mr != null)
|
||||
{
|
||||
//If combine inactives is disabled, and mesh filter component is disabled in this object, skips this
|
||||
if (combineInactives == false && mr.enabled == false)
|
||||
continue;
|
||||
if (combineInactives == false && foundGameObjects[i].gameObject.activeSelf == false)
|
||||
continue;
|
||||
if (combineInactives == false && foundGameObjects[i].gameObject.activeInHierarchy == false)
|
||||
continue;
|
||||
|
||||
gameObjectsWithMesh.Add(new GameObjectWithMesh(foundGameObjects[i].gameObject, mf, mr));
|
||||
}
|
||||
}
|
||||
|
||||
//Verify if each gameObject with mesh, is valid and have correct components settings
|
||||
List<GameObjectWithMesh> validsGameObjectsWithMesh = new List<GameObjectWithMesh>();
|
||||
for (int i = 0; i < gameObjectsWithMesh.Count; i++)
|
||||
{
|
||||
bool canAddToValidGameObjects = true;
|
||||
|
||||
//Verify if MeshFilter is null
|
||||
if (gameObjectsWithMesh[i].meshFilter == null)
|
||||
{
|
||||
if (showDebugLogs == true)
|
||||
{
|
||||
Debug.LogError("GameObject \"" + gameObjectsWithMesh[i].gameObject.name + "\" does not have the Mesh Filter component, so it is not a valid mesh and will be ignored in the merge process.");
|
||||
}
|
||||
canAddToValidGameObjects = false;
|
||||
}
|
||||
//Verify if MeshRenderer is null
|
||||
if (gameObjectsWithMesh[i].meshRenderer == null)
|
||||
{
|
||||
if (showDebugLogs == true)
|
||||
{
|
||||
Debug.LogError("GameObject \"" + gameObjectsWithMesh[i].gameObject.name + "\" does not have the Mesh Renderer component, so it is not a valid mesh and will be ignored in the merge process.");
|
||||
}
|
||||
canAddToValidGameObjects = false;
|
||||
}
|
||||
//Verify if SharedMesh is null
|
||||
if (gameObjectsWithMesh[i].meshFilter != null && gameObjectsWithMesh[i].meshFilter.sharedMesh == null)
|
||||
{
|
||||
if (showDebugLogs == true)
|
||||
{
|
||||
Debug.LogError("GameObject \"" + gameObjectsWithMesh[i].gameObject.name + "\" does not have a Mesh in Mesh Filter component, so it is not a valid mesh and will be ignored in the merge process.");
|
||||
}
|
||||
canAddToValidGameObjects = false;
|
||||
}
|
||||
//Verify if count of materials is different of count of submeshes
|
||||
if (gameObjectsWithMesh[i].meshFilter != null && gameObjectsWithMesh[i].meshRenderer != null && gameObjectsWithMesh[i].meshFilter.sharedMesh != null)
|
||||
{
|
||||
if (gameObjectsWithMesh[i].meshFilter.sharedMesh.subMeshCount != gameObjectsWithMesh[i].meshRenderer.sharedMaterials.Length)
|
||||
{
|
||||
if (showDebugLogs == true)
|
||||
{
|
||||
Debug.LogError("The Mesh Renderer component found in GameObject \"" + gameObjectsWithMesh[i].gameObject.name + "\" has more or less material needed. The mesh that is in this GameObject has " + gameObjectsWithMesh[i].meshFilter.sharedMesh.subMeshCount.ToString() + " submeshes, but has a number of " + gameObjectsWithMesh[i].meshRenderer.sharedMaterials.Length.ToString() + " materials. This mesh will be ignored during the merge process.");
|
||||
}
|
||||
canAddToValidGameObjects = false;
|
||||
}
|
||||
}
|
||||
//Verify if has null materials in MeshRenderer
|
||||
if (gameObjectsWithMesh[i].meshRenderer != null)
|
||||
{
|
||||
for (int x = 0; x < gameObjectsWithMesh[i].meshRenderer.sharedMaterials.Length; x++)
|
||||
{
|
||||
if (gameObjectsWithMesh[i].meshRenderer.sharedMaterials[x] == null)
|
||||
{
|
||||
if (showDebugLogs == true)
|
||||
{
|
||||
Debug.LogError("Material " + x.ToString() + " in Mesh Renderer present in component \"" + gameObjectsWithMesh[i].gameObject.name + "\" is null. For the merge process to work well, all materials must be completed. This GameObject will be ignored in the merge process.");
|
||||
}
|
||||
canAddToValidGameObjects = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
//Verify if this gameobject is already merged
|
||||
if (gameObjectsWithMesh[i].gameObject.GetComponent<CombinedMeshesManager>() != null)
|
||||
{
|
||||
if (showDebugLogs == true)
|
||||
{
|
||||
Debug.LogError("GameObject \"" + gameObjectsWithMesh[i].gameObject.name + "\" is the result of a previous merge, so it will be ignored by this merge.");
|
||||
}
|
||||
canAddToValidGameObjects = false;
|
||||
}
|
||||
|
||||
//If can add to valid GameObjects, add this gameobject
|
||||
if (canAddToValidGameObjects == true)
|
||||
{
|
||||
validsGameObjectsWithMesh.Add(gameObjectsWithMesh[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return validsGameObjectsWithMesh.ToArray();
|
||||
}
|
||||
|
||||
//API Methods
|
||||
|
||||
public bool CombineMeshes()
|
||||
{
|
||||
//If meshes already are merged
|
||||
if (isTargetMeshesMerged() == true)
|
||||
{
|
||||
if (showDebugLogs == true)
|
||||
Debug.Log("The Runtime Combiner \"" + this.gameObject.name + "\" meshes are already combined!");
|
||||
return true;
|
||||
}
|
||||
//If meshes is not merged
|
||||
if (isTargetMeshesMerged() == false)
|
||||
{
|
||||
//If this component already have a Mesh Filter and/or Mesh Renderer, cancel the merge
|
||||
if (this.gameObject.GetComponent<MeshFilter>() != null || this.gameObject.GetComponent<MeshRenderer>() != null)
|
||||
{
|
||||
if (showDebugLogs == true)
|
||||
Debug.LogError("Unable to merge. Apparently the GameObject \"" + this.gameObject.name + "\" already contains the Mesh Filter and/or Mesh Renderer component. The Runtime Mesh Combiner needs a GameObject that does not contain these two components. Please remove them or place the Runtime Mesh Combiner in a new GameObject and try again.");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Get the original position, rotation and scale of this GameObject and reset
|
||||
originalPosition = this.gameObject.transform.position;
|
||||
originalEulerAngles = this.gameObject.transform.eulerAngles;
|
||||
originalScale = this.gameObject.transform.lossyScale;
|
||||
this.gameObject.transform.position = Vector3.zero;
|
||||
this.gameObject.transform.eulerAngles = Vector3.zero;
|
||||
this.gameObject.transform.localScale = Vector3.one;
|
||||
|
||||
//Get the GameObjectsWithMesh validated
|
||||
GameObjectWithMesh[] validsGameObjectsWithMesh = GetValidatedTargetGameObjects();
|
||||
|
||||
//Verify if has valid gameObjects
|
||||
if (validsGameObjectsWithMesh.Length == 0)
|
||||
{
|
||||
if (showDebugLogs == true)
|
||||
Debug.LogError("No valid, meshed GameObjects were found in the target GameObjects list. Therefore the merge was interrupted.");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Separate each submesh according to your material
|
||||
Dictionary<Material, List<SubMeshToCombine>> subMeshesPerMaterial = new Dictionary<Material, List<SubMeshToCombine>>();
|
||||
for (int i = 0; i < validsGameObjectsWithMesh.Length; i++)
|
||||
{
|
||||
GameObjectWithMesh thisGoWithMesh = validsGameObjectsWithMesh[i];
|
||||
|
||||
for (int x = 0; x < thisGoWithMesh.meshFilter.sharedMesh.subMeshCount; x++)
|
||||
{
|
||||
Material currentMaterial = thisGoWithMesh.meshRenderer.sharedMaterials[x];
|
||||
if (subMeshesPerMaterial.ContainsKey(currentMaterial) == true)
|
||||
{
|
||||
subMeshesPerMaterial[currentMaterial].Add(new SubMeshToCombine(thisGoWithMesh.gameObject.transform, thisGoWithMesh.meshFilter, thisGoWithMesh.meshRenderer, x));
|
||||
}
|
||||
if (subMeshesPerMaterial.ContainsKey(currentMaterial) == false)
|
||||
{
|
||||
subMeshesPerMaterial.Add(currentMaterial, new List<SubMeshToCombine>() { new SubMeshToCombine(thisGoWithMesh.gameObject.transform, thisGoWithMesh.meshFilter, thisGoWithMesh.meshRenderer, x) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Configure this GameObject
|
||||
MeshFilter holderMeshFilter = this.gameObject.AddComponent<MeshFilter>();
|
||||
MeshRenderer holderMeshRenderer = this.gameObject.AddComponent<MeshRenderer>();
|
||||
|
||||
//Count the vertex in valids gameobjects
|
||||
int vertexCountInValidsGameObjects = 0;
|
||||
foreach (GameObjectWithMesh obj in validsGameObjectsWithMesh)
|
||||
{
|
||||
vertexCountInValidsGameObjects += obj.meshFilter.sharedMesh.vertexCount;
|
||||
}
|
||||
|
||||
//Combine the submeshes into one submesh according the material
|
||||
List<Mesh> combinedSubmehesPerMaterial = new List<Mesh>();
|
||||
foreach (var key in subMeshesPerMaterial)
|
||||
{
|
||||
//Get the submeshes to merge, of current material
|
||||
List<SubMeshToCombine> subMeshesOfCurrentMaterial = key.Value;
|
||||
|
||||
//Combine instances of submeshes from this material
|
||||
List<CombineInstance> combineInstancesOfCurrentMaterial = new List<CombineInstance>();
|
||||
|
||||
//Process each submesh
|
||||
for (int i = 0; i < subMeshesOfCurrentMaterial.Count; i++)
|
||||
{
|
||||
CombineInstance combineInstance = new CombineInstance();
|
||||
combineInstance.mesh = subMeshesOfCurrentMaterial[i].meshFilter.sharedMesh;
|
||||
combineInstance.subMeshIndex = subMeshesOfCurrentMaterial[i].subMeshIndex;
|
||||
combineInstance.transform = subMeshesOfCurrentMaterial[i].transform.localToWorldMatrix;
|
||||
combineInstancesOfCurrentMaterial.Add(combineInstance);
|
||||
}
|
||||
|
||||
//Create the submesh with all submeshes with current material, and set limitation of vertices
|
||||
Mesh mesh = new Mesh();
|
||||
#if UNITY_2017_4 || UNITY_2018_1_OR_NEWER
|
||||
if (vertexCountInValidsGameObjects <= MAX_VERTICES_FOR_16BITS_MESH)
|
||||
mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt16;
|
||||
if (vertexCountInValidsGameObjects > MAX_VERTICES_FOR_16BITS_MESH)
|
||||
mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
|
||||
#endif
|
||||
mesh.CombineMeshes(combineInstancesOfCurrentMaterial.ToArray(), true, true);
|
||||
|
||||
//Add to list of combined submeshes per material
|
||||
combinedSubmehesPerMaterial.Add(mesh);
|
||||
}
|
||||
|
||||
//Process each submeshes per material, creating final combine instances
|
||||
List<CombineInstance> finalCombineInstances = new List<CombineInstance>();
|
||||
foreach (Mesh mesh in combinedSubmehesPerMaterial)
|
||||
{
|
||||
CombineInstance combineInstanceOfThisSubMesh = new CombineInstance();
|
||||
combineInstanceOfThisSubMesh.mesh = mesh;
|
||||
combineInstanceOfThisSubMesh.subMeshIndex = 0;
|
||||
combineInstanceOfThisSubMesh.transform = Matrix4x4.identity;
|
||||
finalCombineInstances.Add(combineInstanceOfThisSubMesh);
|
||||
}
|
||||
|
||||
//Create the final mesh that contains all submeshes divided per material
|
||||
Mesh finalMesh = new Mesh();
|
||||
#if UNITY_2017_4 || UNITY_2018_1_OR_NEWER
|
||||
if (vertexCountInValidsGameObjects <= MAX_VERTICES_FOR_16BITS_MESH)
|
||||
finalMesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt16;
|
||||
if (vertexCountInValidsGameObjects > MAX_VERTICES_FOR_16BITS_MESH)
|
||||
finalMesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
|
||||
#endif
|
||||
#if !UNITY_2017_4 && !UNITY_2018_1_OR_NEWER
|
||||
if (vertexCountInValidsGameObjects > MAX_VERTICES_FOR_16BITS_MESH)
|
||||
Debug.Log("The sum of vertices in the target GameObjects is greater than 65k. The resulting mesh may contain artifacts or be deformed. You can work around this issue only if your version of Unity is 2017.4 or higher.");
|
||||
#endif
|
||||
finalMesh.name = this.gameObject.name + " (Temp Merge)";
|
||||
finalMesh.CombineMeshes(finalCombineInstances.ToArray(), false);
|
||||
finalMesh.RecalculateBounds();
|
||||
if (recalculateNormals == true)
|
||||
finalMesh.RecalculateNormals();
|
||||
if (recalculateTangents == true)
|
||||
finalMesh.RecalculateTangents();
|
||||
if (optimizeResultingMesh == true)
|
||||
finalMesh.Optimize();
|
||||
|
||||
//Polulate this GameObject with the data of combined mesh
|
||||
holderMeshFilter.sharedMesh = finalMesh;
|
||||
List<Material> materialsForSubMeshes = new List<Material>();
|
||||
foreach (var key in subMeshesPerMaterial)
|
||||
{
|
||||
materialsForSubMeshes.Add(key.Key);
|
||||
}
|
||||
holderMeshRenderer.sharedMaterials = materialsForSubMeshes.ToArray();
|
||||
|
||||
//Deactive original GameObjects if is desired
|
||||
if (afterMerge == AfterMerge.DeactiveOriginalGameObjects)
|
||||
{
|
||||
foreach (GameObjectWithMesh obj in validsGameObjectsWithMesh)
|
||||
{
|
||||
originalGameObjectsWithMeshToRestore.Add(new OriginalGameObjectWithMesh(obj.gameObject, obj.gameObject.activeSelf, obj.meshRenderer, obj.meshRenderer.enabled));
|
||||
obj.gameObject.SetActive(false);
|
||||
}
|
||||
//Add mesh collider, after merge, if disable gameobjects originals
|
||||
if (addMeshColliderAfter == true)
|
||||
{
|
||||
this.gameObject.AddComponent<MeshCollider>();
|
||||
}
|
||||
}
|
||||
//Disable original mesh filters and renderers if is desired
|
||||
if (afterMerge == AfterMerge.DisableOriginalMeshes)
|
||||
{
|
||||
foreach (GameObjectWithMesh obj in validsGameObjectsWithMesh)
|
||||
{
|
||||
originalGameObjectsWithMeshToRestore.Add(new OriginalGameObjectWithMesh(obj.gameObject, obj.gameObject.activeSelf, obj.meshRenderer, obj.meshRenderer.enabled));
|
||||
obj.meshRenderer.enabled = false;
|
||||
}
|
||||
}
|
||||
//Do nothing if is desired
|
||||
if (afterMerge == AfterMerge.DoNothing)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//Apply the original position, rotation and scale of this GameObject again
|
||||
this.gameObject.transform.position = originalPosition;
|
||||
this.gameObject.transform.eulerAngles = originalEulerAngles;
|
||||
this.gameObject.transform.localScale = originalScale;
|
||||
|
||||
//Show stats
|
||||
if (showDebugLogs == true)
|
||||
Debug.Log("The merge has been successfully completed in Runtime Combiner \"" + this.gameObject.name + "\"!");
|
||||
|
||||
//Run events
|
||||
if (onDoneMerge != null)
|
||||
{
|
||||
onDoneMerge.Invoke();
|
||||
}
|
||||
|
||||
targetMeshesMerged = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool UndoMerge()
|
||||
{
|
||||
//If meshes already uncombined
|
||||
if (isTargetMeshesMerged() == false)
|
||||
{
|
||||
if (showDebugLogs == true)
|
||||
Debug.Log("The Runtime Combiner \"" + this.gameObject.name + "\" meshes are already uncombined!");
|
||||
return true;
|
||||
}
|
||||
//If meshes are merged
|
||||
if (isTargetMeshesMerged() == true)
|
||||
{
|
||||
//Undo the merge according the type of merge
|
||||
if (afterMerge == AfterMerge.DisableOriginalMeshes)
|
||||
{
|
||||
foreach (OriginalGameObjectWithMesh original in originalGameObjectsWithMeshToRestore)
|
||||
{
|
||||
//Skip, if is null
|
||||
if (original.meshRenderer == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
original.meshRenderer.enabled = original.originalMrState;
|
||||
}
|
||||
}
|
||||
if (afterMerge == AfterMerge.DeactiveOriginalGameObjects)
|
||||
{
|
||||
foreach (OriginalGameObjectWithMesh original in originalGameObjectsWithMeshToRestore)
|
||||
{
|
||||
//Skip, if is null
|
||||
if (original.gameObject == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
original.gameObject.SetActive(original.originalGoState);
|
||||
}
|
||||
if (addMeshColliderAfter == true)
|
||||
{
|
||||
MeshCollider meshCollider = this.GetComponent<MeshCollider>();
|
||||
|
||||
//Remove the mesh collider
|
||||
if (meshCollider != null)
|
||||
{
|
||||
Destroy(meshCollider);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (afterMerge == AfterMerge.DoNothing)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//Reset variables
|
||||
originalGameObjectsWithMeshToRestore.Clear();
|
||||
|
||||
//Remove unecessary components
|
||||
Destroy(this.GetComponent<MeshRenderer>());
|
||||
Destroy(this.GetComponent<MeshFilter>());
|
||||
if (garbageCollectorAfterUndo == true)
|
||||
{
|
||||
Resources.UnloadUnusedAssets();
|
||||
System.GC.Collect();
|
||||
}
|
||||
|
||||
//Show stats
|
||||
if (showDebugLogs == true)
|
||||
Debug.Log("The Runtime Combiner \"" + this.gameObject.name + "\" merge was successfully undone!");
|
||||
|
||||
//Run events
|
||||
if (onDoneUnmerge != null)
|
||||
{
|
||||
onDoneUnmerge.Invoke();
|
||||
}
|
||||
|
||||
targetMeshesMerged = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool isTargetMeshesMerged()
|
||||
{
|
||||
//Return if the meshes are merged
|
||||
return targetMeshesMerged;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8556e5c749b98bd4fbf643d3644be6cf
|
||||
timeCreated: 1572089712
|
||||
licenseType: Store
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: 976b8d340887eba489742b4c188773f5, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
After Width: | Height: | Size: 49 KiB |
@ -0,0 +1,108 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 976b8d340887eba489742b4c188773f5
|
||||
timeCreated: 1572134897
|
||||
licenseType: Store
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
externalObjects: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapU: -1
|
||||
wrapV: -1
|
||||
wrapW: -1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: Android
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
- buildTarget: WebGL
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,87 @@
|
||||
|
||||
/////////////////////
|
||||
MT ASSETS
|
||||
Credits
|
||||
/////////////////////
|
||||
|
||||
- Fence Model
|
||||
created by George Piskas
|
||||
used through TurboSquid's "Royalty Free License", just as a demonstration model of the operation of this asset.
|
||||
available in
|
||||
https://www.turbosquid.com/FullPreview/Index.cfm/ID/600091 (Free)
|
||||
|
||||
- Grass Model
|
||||
created by Dultcraft Shop
|
||||
used through TurboSquid's "Royalty Free License", just as a demonstration model of the operation of this asset.
|
||||
available in
|
||||
https://www.turbosquid.com/FullPreview/Index.cfm/ID/703699 (Free)
|
||||
|
||||
- Low Poly Tree
|
||||
created by PaulsenDesign
|
||||
used through TurboSquid's "Royalty Free License", just as a demonstration model of the operation of this asset.
|
||||
available in
|
||||
https://www.turbosquid.com/FullPreview/Index.cfm/ID/961487 (Free)
|
||||
|
||||
- Barrel
|
||||
created by GetDeadEntertainment
|
||||
used through TurboSquid's "Royalty Free License", just as a demonstration model of the operation of this asset.
|
||||
available in
|
||||
https://www.turbosquid.com/3d-models/3d-barrels-industrial-container-1685817 (Free)
|
||||
|
||||
- Container
|
||||
created by Sezar1
|
||||
used through TurboSquid's "Royalty Free License", just as a demonstration model of the operation of this asset.
|
||||
available in
|
||||
https://www.turbosquid.com/3d-models/free-obj-mode-shipping-container/1051656 (Free)
|
||||
|
||||
- Big Bin
|
||||
created by SPACESCAN
|
||||
used through TurboSquid's "Royalty Free License", just as a demonstration model of the operation of this asset.
|
||||
available in
|
||||
https://www.turbosquid.com/3d-models/skip-bin-3d-model-1569563 (Free)
|
||||
|
||||
- Wooden Box
|
||||
created by RensiCG
|
||||
used through TurboSquid's "Royalty Free License", just as a demonstration model of the operation of this asset.
|
||||
available in
|
||||
https://www.turbosquid.com/3d-models/wooden-box-3d-model-1617331 (Free)
|
||||
|
||||
- Bucket
|
||||
created by Medbrat23
|
||||
used through TurboSquid's "Royalty Free License", just as a demonstration model of the operation of this asset.
|
||||
available in
|
||||
https://www.turbosquid.com/3d-models/3d-bucket-1714572 (Free)
|
||||
|
||||
- Trash Container
|
||||
created by zavorad
|
||||
used through TurboSquid's "Royalty Free License", just as a demonstration model of the operation of this asset.
|
||||
available in
|
||||
https://www.turbosquid.com/3d-models/trash-container-3d-model-1652950 (Free)
|
||||
|
||||
- Explosive Barrel
|
||||
created by HuNtEr_3DdD
|
||||
used through TurboSquid's "Royalty Free License", just as a demonstration model of the operation of this asset.
|
||||
available in
|
||||
https://www.turbosquid.com/3d-models/explosive-barrel-low-poly-3d-model-1590597 (Free)
|
||||
|
||||
- Traffic Light
|
||||
created by dimonewave
|
||||
used through SketchFab "CC Attribution", just as a demonstration model of the operation of this asset.
|
||||
available in
|
||||
https://sketchfab.com/3d-models/traffic-light-rust-0f326e6c609546bb9d32381529445550 (Free)
|
||||
|
||||
|
||||
Please note that: All third party assets (that were not created by MT Assets) included here, are used based on
|
||||
the license of the original authors contained in each asset link. You cannot use the third party assets included
|
||||
in this package, if you want to use them in your creation, purchase them from each link (informed above) and
|
||||
make sure you have permission from the author or carefully read the license that is in each link.
|
||||
|
||||
However, any asset in this package, which is not listed here, was created by MT Assets, and since you have purchased
|
||||
this package, you can use them in accordance with the license contained on this package's page on the Asset Store.
|
||||
If you have any questions about licensing or permission to use assets, do not hesitate to contact us through
|
||||
mtassets@windsoft.xyz
|
||||
|
||||
/////////////////////
|
||||
Email for support
|
||||
mtassets@windsoft.xyz
|
||||
/////////////////////
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4d4c7616c9fa8a247a4cab5a862eadc9
|
||||
timeCreated: 1545776247
|
||||
licenseType: Store
|
||||
TextScriptImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69ed9448dd5a473468e8f91b47652e33
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ab66425ecfaf2747a0d21bf59d1a40e
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1df97316e649d2b48b6bf83016f152d2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 820bd2285408fe947893c2f0049e8892
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,31 @@
|
||||
/* Default Paee CSS */
|
||||
|
||||
@import url(default-style/a.css);
|
||||
@import url(default-style/body.css);
|
||||
@import url(default-style/footer.css);
|
||||
@import url(default-style/fullscreenCodeViewer.css);
|
||||
@import url(default-style/fullscreenImageViewer.css);
|
||||
@import url(default-style/fullScreenLoading.css);
|
||||
@import url(default-style/goToTopButton.css);
|
||||
@import url(default-style/hr.css);
|
||||
@import url(default-style/processingTime.css);
|
||||
@import url(default-style/readProgress.css);
|
||||
@import url(default-style/scrollbar.css);
|
||||
@import url(default-style/subbody.css);
|
||||
@import url(default-style/topbar.css);
|
||||
|
||||
/* Tool Tags CSS */
|
||||
|
||||
@import url(tool-tags-style/achiev.css);
|
||||
@import url(tool-tags-style/code.css);
|
||||
@import url(tool-tags-style/detach.css);
|
||||
@import url(tool-tags-style/icon.css);
|
||||
@import url(tool-tags-style/frame.css);
|
||||
@import url(tool-tags-style/image.css);
|
||||
@import url(tool-tags-style/info.css);
|
||||
@import url(tool-tags-style/list.css);
|
||||
@import url(tool-tags-style/table.css);
|
||||
@import url(tool-tags-style/topicSubtitle.css);
|
||||
@import url(tool-tags-style/topicTitle.css);
|
||||
@import url(tool-tags-style/video.css);
|
||||
@import url(tool-tags-style/warn.css);
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e7955044de381744aa4d11fcdd795804
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7927399c489e1054690cdcca7227d386
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,17 @@
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #0046c0;
|
||||
cursor: pointer;
|
||||
}
|
||||
a:link {
|
||||
text-decoration: none;
|
||||
color: #0046c0;
|
||||
}
|
||||
a:hover {
|
||||
color: #0046c0;
|
||||
text-decoration: underline dotted #3a505b;
|
||||
}
|
||||
a:visited {
|
||||
color: #0046c0;
|
||||
text-decoration: none;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a7f9e1447f9141f4a8e636a8499f754e
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,16 @@
|
||||
html, body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
body {
|
||||
background-color: #686868;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% 100%;
|
||||
font-family: Helvetica, sans-seri;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
font-size: 14px;
|
||||
color: #303030;
|
||||
padding: 0;
|
||||
margin: 0 auto !important;
|
||||
overflow-y: scroll;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26d5b791592301545843097002b43a1a
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,16 @@
|
||||
.footer{
|
||||
margin-top: 16px;
|
||||
padding-top: 8px;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
padding-bottom: 8px;
|
||||
width: 95%;
|
||||
max-width: 1280px;
|
||||
background-color: #ffffff;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.footerSpacement{
|
||||
height: 16px;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b0ce2303115c8943803439b9fa0ab82
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,45 @@
|
||||
.fullscreenLoadingContent{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
pointer-events: all;
|
||||
opacity: 1.0;
|
||||
z-index: 100;
|
||||
transition: 200ms;
|
||||
}
|
||||
.fullscreenLoadingBg{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
width: 95%;
|
||||
max-width: 1280px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
background-color: #ffffff;
|
||||
line-height: 24px;
|
||||
font-weight: bolder;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
.fullscreenLoading{
|
||||
display: grid;
|
||||
grid-template-columns: 24px 8px auto;
|
||||
background-color: #ffffff;
|
||||
border-radius: 4px;
|
||||
padding: 8px;
|
||||
box-shadow: 0px 2px 16px -2px rgba(0, 0, 0, 0.165);
|
||||
user-select: none;
|
||||
}
|
||||
.fullscreenLoading img{
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
animation-name: fullscreenLoading;
|
||||
animation-duration: 800ms;
|
||||
animation-iteration-count: infinite;
|
||||
animation-timing-function: linear;
|
||||
pointer-events: none;
|
||||
}
|
||||
@keyframes fullscreenLoading {
|
||||
100% { transform: rotateZ(360deg); }
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 80ac3a601a3bec54aa7a7b1d2c8c8ac3
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,72 @@
|
||||
.fullscreenCodeBackground{
|
||||
z-index: 800;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #000000;
|
||||
transition: all 250ms;
|
||||
opacity: 0.0;
|
||||
pointer-events: none;
|
||||
cursor: zoom-out;
|
||||
}
|
||||
.fullscreenCodePopupContent{
|
||||
z-index: 1000;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transition: all 250ms;
|
||||
opacity: 0.0;
|
||||
pointer-events: none;
|
||||
}
|
||||
.fullscreenCodePopup{
|
||||
background-color: #ffffff;
|
||||
border-radius: 4px;
|
||||
padding: 8px;
|
||||
max-width: 95%;
|
||||
max-height: 95%;
|
||||
}
|
||||
.fullscreenCodeSandboxViewer{
|
||||
margin-top: 8px;
|
||||
max-width: 100%;
|
||||
max-height: 90%;
|
||||
overflow: auto;
|
||||
}
|
||||
.fullscreenCodeSandboxViewer::-webkit-scrollbar {
|
||||
height: 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.fullscreenCodeSandboxViewer::-webkit-scrollbar-track {
|
||||
background-color: #00000000;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.fullscreenCodeSandboxViewer::-webkit-scrollbar-thumb {
|
||||
background: #00000061;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.fullscreenCodeSandboxViewer::-webkit-scrollbar-thumb:hover {
|
||||
background: #00000061;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.fullscreenCodePopupClose{
|
||||
display: grid;
|
||||
grid-template-columns: auto 30px;
|
||||
}
|
||||
.fullscreenCodePopupClose div:nth-child(1){
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
font-weight: bold;
|
||||
font-size: 18;
|
||||
}
|
||||
.fullscreenCodePopupClose img{
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 4px;
|
||||
pointer-events: none;
|
||||
margin-left: 1px;
|
||||
cursor: pointer;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b25e538a36a9c649bf91b9282c8decb
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,53 @@
|
||||
.fullscreenImageBackground{
|
||||
z-index: 800;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #000000;
|
||||
transition: all 250ms;
|
||||
opacity: 0.0;
|
||||
pointer-events: none;
|
||||
cursor: zoom-out;
|
||||
}
|
||||
.fullscreenImagePopupContent{
|
||||
z-index: 1000;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transition: all 250ms;
|
||||
opacity: 0.0;
|
||||
pointer-events: none;
|
||||
}
|
||||
.fullscreenImagePopup{
|
||||
background-color: #ffffff;
|
||||
border-radius: 4px;
|
||||
padding: 8px;
|
||||
}
|
||||
.fullscreenImagePopup img{
|
||||
height: 92%;
|
||||
max-width: auto;
|
||||
border-radius: 4px;
|
||||
pointer-events: none;
|
||||
}
|
||||
@media screen and (max-width: 720px){
|
||||
/* IF IS MOBILE */
|
||||
.fullscreenImagePopup img{
|
||||
height: auto;
|
||||
width: 100%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.fullscreenImagePopup{
|
||||
max-width: 95%;
|
||||
}
|
||||
}
|
||||
.fullscreenImagePopupClose{
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
cursor: pointer;
|
||||
pointer-events: none;
|
||||
margin-left: calc(100% - 30px);
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e44c5c44e32c58849bf815db36e3c93f
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,22 @@
|
||||
.gotoTopButton{
|
||||
position: fixed;
|
||||
right: 16px;
|
||||
bottom: 16px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background-color: #ffffff;
|
||||
border-radius: 32px;
|
||||
cursor: pointer;
|
||||
transition: all 250ms;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
opacity: 0;
|
||||
box-shadow: 0px 2px 16px -2px rgba(0, 0, 0, 0.56);
|
||||
}
|
||||
.gotoTopButton img{
|
||||
margin-top: 1px;
|
||||
margin-right: 1px;
|
||||
width: 80%;
|
||||
height: 80%;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 30d1569099da0d34ea413280d96fa81e
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,5 @@
|
||||
hr {
|
||||
border: 0;
|
||||
height: 1px;
|
||||
background-image: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(206, 206, 206, 0.75), rgba(0, 0, 0, 0));
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc1cad9dc0872c84890656ba5877759e
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,6 @@
|
||||
.processingTimeResult{
|
||||
opacity: 0.5;
|
||||
}
|
||||
.processingTimeResult #processingTime{
|
||||
display: inline;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3db358c00058c6144b025cd962d8a5c3
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,14 @@
|
||||
.readProgressContainer {
|
||||
z-index: 400;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
background: #d6d6d6;
|
||||
top: 45;
|
||||
left: 0;
|
||||
}
|
||||
.readProgressBar {
|
||||
height: 3px;
|
||||
background: linear-gradient(141deg, #b72c2c 0%, #9f1717 51%, #780c0c 75%);
|
||||
width: 0%;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fb1444b6f546e7f469b03df4f8414556
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,12 @@
|
||||
::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: #d6d6d6;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #292929;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #292929;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8cd72e66a70234342bf96057405bd2e7
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,224 @@
|
||||
.subBody{
|
||||
padding-top: 54px;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
padding-bottom: 8px;
|
||||
width: 95%;
|
||||
max-width: 1280px;
|
||||
background-color: #ffffff;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
display: grid;
|
||||
grid-template-columns: 23% 1px auto;
|
||||
}
|
||||
@media screen and (max-width: 720px){
|
||||
/* IF IS MOBILE */
|
||||
.subBody {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.subBodySummary{
|
||||
height: 100px;
|
||||
overflow-y: hidden;
|
||||
overflow-x: hidden;
|
||||
transition: all 0ms;
|
||||
padding-right: 4px;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
@media screen and (max-width: 720px){
|
||||
/* IF IS MOBILE */
|
||||
.subBodySummary {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.subBodySummary:hover{
|
||||
overflow-y: scroll;
|
||||
overflow-x: auto;
|
||||
padding-right: 0px;
|
||||
}
|
||||
@-moz-document url-prefix() {
|
||||
.subBodySummary{
|
||||
padding-right: 17px;
|
||||
}
|
||||
.subBodySummary:hover{
|
||||
padding-right: 0px;
|
||||
}
|
||||
}
|
||||
.subBodySummary:nth-child(2){
|
||||
margin-bottom: 100px;
|
||||
}
|
||||
.subBodySummary::-webkit-scrollbar {
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.subBodySummary::-webkit-scrollbar-track {
|
||||
background-color: rgba(0, 0, 0, 0.048);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.subBodySummary::-webkit-scrollbar-thumb {
|
||||
background: #0000002f;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.subBodySummary::-webkit-scrollbar-thumb:hover {
|
||||
background: #0000002f;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.subBodySummary a{
|
||||
text-decoration: none;
|
||||
color: #374f77;
|
||||
cursor: pointer;
|
||||
}
|
||||
.subBodySummary a:hover{
|
||||
text-decoration: underline dotted #3a505b;
|
||||
}
|
||||
.subBodySummaryTitleAndSearch{
|
||||
display: grid;
|
||||
grid-template-columns: auto 48px;
|
||||
}
|
||||
.subBodySummaryTitle{
|
||||
display: block;
|
||||
font-weight: bolder;
|
||||
font-size: 16px;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
height: 36px;
|
||||
margin-top: 12px;
|
||||
margin-bottom: -4px;
|
||||
margin-left: 18px;
|
||||
overflow: hidden;
|
||||
transition: all 250ms;
|
||||
width: 224px;
|
||||
}
|
||||
.subBodySummarySearchBar{
|
||||
display: none;
|
||||
height: 36px;
|
||||
margin-top: 12px;
|
||||
margin-bottom: -4px;
|
||||
margin-left: 18px;
|
||||
overflow: hidden;
|
||||
transition: all 250ms;
|
||||
width: 224px;
|
||||
}
|
||||
.subBodySummarySearchBar input[type=text]{
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
outline: none;
|
||||
border-color: black;
|
||||
border-radius: 4px;
|
||||
border-width: 1px;
|
||||
box-sizing: border-box;
|
||||
padding-left: 8px;
|
||||
padding-right: 28px;
|
||||
}
|
||||
.subBodySummarySearchResults{
|
||||
height: 2px;
|
||||
text-align: center;
|
||||
font-size: 10px;
|
||||
transition: all 250ms;
|
||||
margin-top: -6px;
|
||||
margin-bottom: 18px;
|
||||
opacity: 0;
|
||||
}
|
||||
.subBodySummarySearchStart{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: -2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.subBodySummarySearchStart img{
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
.subBodySummarySearchEnd{
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 18px;
|
||||
left: 4px;
|
||||
}
|
||||
.subBodySummarySearchEnd img{
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
.subBodySummary ul{
|
||||
padding-left: 18px;
|
||||
list-style-type: disc;
|
||||
}
|
||||
.subBodySummary li{
|
||||
font-size: 12px;
|
||||
margin-right: 14px;
|
||||
transition: all 150ms;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.summaryItem{
|
||||
transition: all 150ms;
|
||||
}
|
||||
.summaryItemHighlighted{
|
||||
background-color: rgba(0, 96, 138, 0.15);
|
||||
padding-left: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
border-top-left-radius: 8px;
|
||||
}
|
||||
.summaryItemNotConnected{
|
||||
background-color: rgba(255, 0, 0, 0.15);
|
||||
padding-left: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
border-top-left-radius: 8px;
|
||||
}
|
||||
.summaryScrollDownIndicator{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #ececec;
|
||||
border-radius: 24px;
|
||||
transition: opacity 250ms;
|
||||
pointer-events: none;
|
||||
animation-name: summaryScrollAnimation;
|
||||
animation-duration: 1000ms;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
.summaryScrollDownIndicator img{
|
||||
height: 60%;
|
||||
transition: all 0ms;
|
||||
opacity: 0.0;
|
||||
margin-top: 2px;
|
||||
}
|
||||
@keyframes summaryScrollAnimation {
|
||||
0% { transform: translateY(0px); }
|
||||
50% { transform: translateY(-4px); }
|
||||
100% { transform: translateY(0px); }
|
||||
}
|
||||
.subBodyDivider{
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
background: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(206, 206, 206, 0.75), rgba(0, 0, 0, 0));
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
@media screen and (max-width: 720px){
|
||||
/* IF IS MOBILE */
|
||||
.subBodyDivider {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.subBodyContent{
|
||||
margin-left: 16px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
.endOfBodyContentPoint{
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
margin-top: -1px;
|
||||
position: relative;
|
||||
bottom: 20px;
|
||||
}
|