#if UNITY_EDITOR using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEngine; /// /// LmHouses 十二栋:XPbr Prefab,按高度缩放到场景可用尺寸。原点已在底面,不做 +90X。 /// unity command run_script --file AgentScripts/SetupLmHouses.cs --entry SetupLmHouses.Run /// 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(); 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(basePath); var mixMap = AssetDatabase.LoadAssetAtPath(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(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(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.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()) { 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