feat: improve map lighting and expand the playable training range

Add real-time lighting and shadows, training courses and targets, and animated salvage crates. Include bilingual assets and curated verification results.
This commit is contained in:
2026-11-12 18:03:04 +08:00
parent 0857e291d5
commit eb819c6688
75 changed files with 16903 additions and 121 deletions
+32 -6
View File
@@ -1,24 +1,27 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
namespace Ironspore
{
public static class WorldFactory
{
static readonly Dictionary<string, Material> materials = new Dictionary<string, Material>();
public static Material Material(Color color, bool glow = false)
public enum Surface { Painted, Concrete, BareMetal }
public static Material Material(Color color, bool glow = false, Surface surface = Surface.Painted)
{
string key = ColorUtility.ToHtmlStringRGB(color) + (glow ? "g" : "");
string key = ColorUtility.ToHtmlStringRGB(color) + (glow ? "g" : "") + (int)surface;
if (materials.TryGetValue(key, out var cached) && cached)
return cached;
var mat = new Material(Shader.Find("Standard"));
mat.color = color;
mat.SetFloat("_Metallic", .3f);
mat.SetFloat("_Glossiness", .35f);
mat.SetFloat("_Metallic", surface == Surface.BareMetal ? .78f : surface == Surface.Concrete ? 0 : .04f);
mat.SetFloat("_Glossiness", surface == Surface.Concrete ? .15f : surface == Surface.BareMetal ? .48f : .32f);
mat.enableInstancing = true;
if (glow)
{
mat.EnableKeyword("_EMISSION");
mat.SetColor("_EmissionColor", color * 1.8f);
mat.SetColor("_EmissionColor", color * 1.25f);
}
materials[key] = mat;
return mat;
@@ -38,7 +41,13 @@ namespace Ironspore
obj.transform.SetParent(parent);
obj.transform.position = position;
obj.transform.localScale = scale;
obj.GetComponent<Renderer>().sharedMaterial = Material(color, glow);
var renderer = obj.GetComponent<Renderer>();
var surface = name == "Ground" || name == "AccessRamp" ? Surface.Concrete : name == "ContainerRib" || name == "CanopyRail" ? Surface.BareMetal : Surface.Painted;
renderer.sharedMaterial = Material(color, glow, surface);
bool detail = name == "FloorSeam" || name == "AmberStripe" || name == "CrateLatch" || name == "RelayScreen" || name == "LandingLight" || name == "CanopyIndicator" || name.EndsWith("WorkFixture");
renderer.shadowCastingMode = detail || name == "EnemyBolt" ? ShadowCastingMode.Off : ShadowCastingMode.On;
renderer.receiveShadows = !glow;
if (name == "EnemyBolt") obj.layer = 10;
if (!collision)
Object.Destroy(obj.GetComponent<Collider>());
return obj;
@@ -59,6 +68,12 @@ namespace Ironspore
dashboard.transform.localPosition = new Vector3(0, -.42f, .75f);
foreach (var child in root.GetComponentsInChildren<Transform>())
child.gameObject.layer = 8;
foreach (var renderer in root.GetComponentsInChildren<Renderer>())
{
renderer.shadowCastingMode = ShadowCastingMode.Off;
renderer.lightProbeUsage = LightProbeUsage.Off;
renderer.reflectionProbeUsage = ReflectionProbeUsage.Off;
}
root.SetActive(false);
return root;
}
@@ -67,11 +82,17 @@ namespace Ironspore
var obj = new GameObject("Sign");
obj.transform.SetParent(parent);
obj.transform.position = position;
obj.layer = 11;
var label = obj.AddComponent<TextMesh>();
label.fontSize = 40;
label.characterSize = .09f;
label.anchor = TextAnchor.MiddleCenter;
label.color = color;
var renderer = obj.GetComponent<Renderer>();
renderer.shadowCastingMode = ShadowCastingMode.Off;
renderer.receiveShadows = false;
renderer.lightProbeUsage = LightProbeUsage.Off;
renderer.reflectionProbeUsage = ReflectionProbeUsage.Off;
obj.AddComponent<LocalizedWorldLabel>().Initialize(key);
obj.AddComponent<FaceCamera>();
}
@@ -79,6 +100,11 @@ namespace Ironspore
{
var obj = new GameObject("ShotTrace");
var line = obj.AddComponent<LineRenderer>();
obj.layer = 11;
line.shadowCastingMode = ShadowCastingMode.Off;
line.receiveShadows = false;
line.lightProbeUsage = LightProbeUsage.Off;
line.reflectionProbeUsage = ReflectionProbeUsage.Off;
line.positionCount = 2;
line.SetPosition(0, from);
line.SetPosition(1, to);