141 lines
5.1 KiB
C#
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
|