Files

141 lines
5.1 KiB
C#

#if UNITY_EDITOR
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
/// <summary>
/// LmHouses 十二栋:XPbr Prefab,按高度缩放到场景可用尺寸。原点已在底面,不做 +90X。
/// unity command run_script --file AgentScripts/SetupLmHouses.cs --entry SetupLmHouses.Run
/// </summary>
public static class SetupLmHouses
{
const string Root = "Assets/Bundles/Scenes/Test/LmHouses";
const string XPbrShaderName = "Test/XPbr";
static readonly (string name, float height)[] Houses =
{
("cream_tile", 7.0f),
("cream_red", 7.2f),
("white_balcony", 7.0f),
("brown_wood", 6.8f),
("cream_porch", 7.2f),
("stone_balcony", 7.0f),
("thatched", 4.4f),
("white_blue", 7.0f),
("wood_fence", 6.6f),
("shop_awning", 7.0f),
("picket", 6.8f),
("gate", 7.0f),
};
public static string Run()
{
AssetDatabase.Refresh();
var reports = new List<string>();
foreach (var (name, height) in Houses)
reports.Add(EnsurePrefab(name, height));
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
return string.Join(" | ", reports);
}
static string EnsurePrefab(string name, float height)
{
var dir = $"{Root}/{name}";
var fbxPath = $"{dir}/{name}.fbx";
var basePath = $"{dir}/{name}_base.png";
var mixPath = $"{dir}/{name}_mix.png";
var matPath = $"{dir}/{name}.mat";
var prefabPath = $"{dir}/{name}.prefab";
if (!File.Exists(fbxPath))
return name + ":missing";
ConfigureTexture(basePath, srgb: true);
ConfigureTexture(mixPath, srgb: false);
var model = AssetImporter.GetAtPath(fbxPath) as ModelImporter;
if (model != null)
{
model.globalScale = 1f;
model.useFileScale = false;
model.bakeAxisConversion = true;
model.materialImportMode = File.Exists(matPath)
? ModelImporterMaterialImportMode.ImportViaMaterialDescription
: ModelImporterMaterialImportMode.None;
model.meshCompression = ModelImporterMeshCompression.Medium;
model.isReadable = false;
model.SaveAndReimport();
}
var baseMap = AssetDatabase.LoadAssetAtPath<Texture2D>(basePath);
var mixMap = AssetDatabase.LoadAssetAtPath<Texture2D>(mixPath);
var xpbr = Shader.Find(XPbrShaderName);
var urpLit = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard");
var useXpbr = xpbr != null && baseMap != null && mixMap != null;
var shader = useXpbr ? xpbr : urpLit;
var mat = AssetDatabase.LoadAssetAtPath<Material>(matPath);
if (mat == null)
{
mat = new Material(shader);
AssetDatabase.CreateAsset(mat, matPath);
}
else
{
mat.shader = shader;
}
if (useXpbr)
{
if (mat.HasProperty("_MainTex")) mat.SetTexture("_MainTex", baseMap);
if (mat.HasProperty("_MixTex")) mat.SetTexture("_MixTex", mixMap);
if (mat.HasProperty("_BaseColor")) mat.SetColor("_BaseColor", Color.white);
if (mat.HasProperty("_Metallic")) mat.SetFloat("_Metallic", 1f);
if (mat.HasProperty("_Roughness")) mat.SetFloat("_Roughness", 1f);
if (mat.HasProperty("_AO")) mat.SetFloat("_AO", 1f);
}
else if (baseMap != null && mat.HasProperty("_BaseMap"))
{
mat.SetTexture("_BaseMap", baseMap);
}
EditorUtility.SetDirty(mat);
var modelRoot = AssetDatabase.LoadAssetAtPath<GameObject>(fbxPath);
if (modelRoot == null)
return name + ":fbx-not-loaded";
var instance = (GameObject)PrefabUtility.InstantiatePrefab(modelRoot);
instance.name = name;
foreach (var renderer in instance.GetComponentsInChildren<Renderer>())
renderer.sharedMaterial = mat;
instance.transform.localPosition = Vector3.zero;
instance.transform.localRotation = Quaternion.identity;
instance.transform.localScale = Vector3.one;
var bounds = default(Bounds);
var has = false;
foreach (var renderer in instance.GetComponentsInChildren<Renderer>())
{
if (!has) { bounds = renderer.bounds; has = true; }
else bounds.Encapsulate(renderer.bounds);
}
if (has && bounds.size.y > 0.01f)
instance.transform.localScale = Vector3.one * (height / bounds.size.y);
PrefabUtility.SaveAsPrefabAsset(instance, prefabPath);
Object.DestroyImmediate(instance);
return name + "=" + height.ToString("0.0");
}
static void ConfigureTexture(string path, bool srgb)
{
if (!File.Exists(path)) return;
var importer = AssetImporter.GetAtPath(path) as TextureImporter;
if (importer == null) return;
importer.textureType = TextureImporterType.Default;
importer.sRGBTexture = srgb;
importer.mipmapEnabled = true;
importer.alphaIsTransparency = srgb;
importer.SaveAndReimport();
}
}
#endif