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:
@@ -4,6 +4,8 @@ namespace Ironspore
|
||||
{
|
||||
public sealed class EnemyUnit : MonoBehaviour
|
||||
{
|
||||
// DynamicProps keeps its original physical obstruction semantics after render-layer separation.
|
||||
const int WorldObstructionMask = (1 << 0) | (1 << 10);
|
||||
GameSession game;
|
||||
float health, cooldown, age;
|
||||
int type;
|
||||
@@ -41,7 +43,7 @@ namespace Ironspore
|
||||
if (type != 1 && distance > 10)
|
||||
{
|
||||
Vector3 step = flat.normalized * Time.deltaTime * (type == 3 ? 1.4f : type == 0 ? 2.5f : 1.2f);
|
||||
if (!Physics.Raycast(transform.position + Vector3.up, step.normalized, 1.1f, 1, QueryTriggerInteraction.Ignore))
|
||||
if (!Physics.Raycast(transform.position + Vector3.up, step.normalized, 1.1f, WorldObstructionMask, QueryTriggerInteraction.Ignore))
|
||||
transform.position += step;
|
||||
}
|
||||
if (type == 0)
|
||||
@@ -54,7 +56,7 @@ namespace Ironspore
|
||||
if (cooldown <= 0 && distance < 42)
|
||||
{
|
||||
Vector3 origin = transform.position + Vector3.up * (type == 3 ? 3.5f : 2);
|
||||
if (!Physics.Linecast(origin, target, 1, QueryTriggerInteraction.Ignore))
|
||||
if (!Physics.Linecast(origin, target, WorldObstructionMask, QueryTriggerInteraction.Ignore))
|
||||
{
|
||||
var bolt = WorldFactory.Primitive(PrimitiveType.Sphere, "EnemyBolt", origin, Vector3.one * .3f, new Color(1, .35f, .08f), null, false, true);
|
||||
bolt.AddComponent<EnemyBolt>().Initialize((target - origin).normalized, type == 3 ? 23 : 12);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user