champions-of-luneraria/Assets/Luneraria/View/LuneMaterialSet.cs
Martin Stickelbroeck 8a72cb165a U2B World Geometry
G1-Karte in Unity (Assets/Luneraria/Scenes/G1_Map.unity), reproduzierbar
gebaut aus dem Godot-Weltgenerator (gebacken), den FBX-Modellen aus U2A und der
Karte des C#-Kerns.

- tools/godot-golden/world_export.gd: backt Gelände (Raster, Farben, Lauf- und
  Standhöhen), Lanebeläge, Plattform, Brücke, Randsteine, Basen, Landmarken,
  Vegetation, Adern, Grottentreppen, Aufstellungsbereiche und Licht. Braucht
  einen echten Renderer (HEADLESS=0); prüft auf Headless-Einheitstransformationen.
- LuneWorldBuilder: Meshes (GUID-stabil), Szene, Licht, Himmel, Post-Processing,
  16 Türme, 2 Ancients und die Grotte aus LuneMap mit Teammaterialien.
- Materialsystem: Luneraria/Surface (Gelände, Kluft-Oberflächen, Fluss, Adern,
  Kristall, G2-Werte mit Teamvarianten und Vertex-AO) und Luneraria/Pad;
  LuneMaterialSet.Dress wie Godots dress.
- View-Assembly: LuneSpace (Unity = (-x, h, y)), LuneGround, LuneCameraMath,
  LuneBuildingView (Zustände intakt bis Ruine).
- Vergleichsbilder mit den Kameraeinstellungen der Godot-G2-Aufnahmen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 16:01:25 +02:00

71 lines
2.6 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
namespace Luneraria.View
{
/// <summary>
/// The shared material library (port of scripts/luneraria/view/lune_materials.gd). Models name
/// their surfaces (LN_*, ENV_*); Dress swaps them for one shared material per name and team,
/// so all buildings share a few materials (SRP batcher friendly). Team 0 Blau, 1 Rot, 2 neutral.
/// </summary>
public sealed class LuneMaterialSet : ScriptableObject
{
[Serializable]
public sealed class Entry
{
public string Key;
public Material Neutral;
public Material Blau;
public Material Rot;
}
public List<Entry> Entries = new List<Entry>();
Dictionary<string, Entry> _index;
public Material Get(string key, int team)
{
if (_index == null)
{
_index = new Dictionary<string, Entry>();
foreach (Entry entry in Entries)
_index[entry.Key] = entry;
}
if (!_index.TryGetValue(key, out Entry found))
return null;
Material team_material = team == 0 ? found.Blau : team == 1 ? found.Rot : null;
return team_material != null ? team_material : found.Neutral;
}
/// <summary>Material key of an imported slot material ("LN_Stone_Pale", "ENV_bark (Instance)" -> key).</summary>
public static string KeyOf(Material material)
{
if (material == null)
return "";
string name = material.name;
int cut = name.IndexOf(" (", StringComparison.Ordinal);
return cut < 0 ? name : name.Substring(0, cut);
}
/// <summary>Swaps every known surface below root for the shared material of the team.</summary>
public void Dress(GameObject root, int team)
{
foreach (Renderer renderer in root.GetComponentsInChildren<Renderer>(true))
{
Material[] materials = renderer.sharedMaterials;
bool changed = false;
for (int i = 0; i < materials.Length; i++)
{
Material shared = Get(KeyOf(materials[i]), team);
if (shared != null && shared != materials[i])
{
materials[i] = shared;
changed = true;
}
}
if (changed)
renderer.sharedMaterials = materials;
}
}
}
}