using System; using UnityEngine; using Ichni.Editor; using Ichni.RhythmGame; using Ichni.RhythmGame.Beatmap; using System.Collections.Generic; using Beatmap; namespace Ichni.RhythmGame { // 以EnvironmentObject为基底,支持伪阴影shader参数刷新 public class BasicEnvironmentObject : EnvironmentObject { [Header("Pseudo Shadow Settings")] public Renderer shadowRenderer; // 指向带有伪阴影shader的Renderer [Range(-1, 1)] public float shadowThreshold = 0.2f; [Range(0, 1)] public float shadowSmoothness = 0.5f; public bool useWorldLight = false; public Vector3 fakeLightDir = new Vector3(0.5f, 1, 0.5f); public override bool haveEmissionColor => true; public static BasicEnvironmentObject GenerateElement(string elementName, Guid id, List tags, bool isFirstGenerated, string themeBundleName, string objectName, GameElement parentElement, bool isStatic, float shadowThreshold, float shadowSmoothness, bool useWorldLight, Vector3 fakeLightDir) { BasicEnvironmentObject basicEnvObj = EnvironmentObject.GenerateElement(elementName, id, tags, isFirstGenerated, themeBundleName, objectName, parentElement, isStatic).GetComponent(); basicEnvObj.shadowThreshold = shadowThreshold; basicEnvObj.shadowSmoothness = shadowSmoothness; basicEnvObj.useWorldLight = useWorldLight; basicEnvObj.fakeLightDir = fakeLightDir; return basicEnvObj; } public override void Refresh() { base.Refresh(); if (shadowRenderer == null || shadowRenderer.material == null) return; var mat = shadowRenderer.material; mat.SetColor("_Color", colorSubmodule.currentBaseColor); mat.SetColor("_ShadowColor", colorSubmodule.currentEmissionColor); mat.SetFloat("_ShadowThreshold", shadowThreshold); mat.SetFloat("_ShadowSmoothness", shadowSmoothness); mat.SetVector("_FakeLightDir", new Vector4(fakeLightDir.x, fakeLightDir.y, fakeLightDir.z, 0)); mat.SetFloat("_UseWorldLight", useWorldLight ? 1 : 0); } // 可选:在属性变更时自动刷新 public override void SetUpInspector() { base.SetUpInspector(); IHaveInspection inspector = EditorManager.instance.uiManager.inspector; var container = inspector.GenerateContainer("Basic Environment Object"); var shadowSettings = container.GenerateSubcontainer(3); var i = inspector.GenerateInputField(this, shadowSettings, "Shadow Threshold (-1 to 1)", nameof(shadowThreshold)); var j = inspector.GenerateInputField(this, shadowSettings, "Shadow Smoothness (0 to 1)", nameof(shadowSmoothness)); var u = inspector.GenerateToggle(this, shadowSettings, "Use World Light", nameof(useWorldLight)); var shadowSettings2 = container.GenerateSubcontainer(1); var w = inspector.GenerateVector3InputField(this, shadowSettings2, "Fake Light Direction", nameof(fakeLightDir)); } public override void SaveBM() { base.SaveBM(); matchedBM = new BasicEnvironmentObject_BM(elementName, elementGuid, tags, parentElement.matchedBM as GameElement_BM, themeBundleName, objectName, isStatic, shadowThreshold, shadowSmoothness, useWorldLight, fakeLightDir); } } } namespace Beatmap { public class BasicEnvironmentObject_BM : EnvironmentObject_BM { public float shadowThreshold; public float shadowSmoothness; public bool useWorldLight; public Vector3 fakeLightDir; public BasicEnvironmentObject_BM() { } public BasicEnvironmentObject_BM(string elementName, Guid elementGuid, List tags, GameElement_BM parentElement, string themeBundleName, string objectName, bool isStatic, float shadowThreshold, float shadowSmoothness, bool useWorldLight, Vector3 fakeLightDir) : base(elementName, elementGuid, tags, parentElement, themeBundleName, objectName, isStatic) { this.shadowThreshold = shadowThreshold; this.shadowSmoothness = shadowSmoothness; this.useWorldLight = useWorldLight; this.fakeLightDir = fakeLightDir; } public override void ExecuteBM() { matchedElement = BasicEnvironmentObject.GenerateElement(elementName, elementGuid, tags, false, themeBundleName, objectName, GetElement(attachedElementGuid), isStatic, shadowThreshold, shadowSmoothness, useWorldLight, fakeLightDir); } public override GameElement DuplicateBM(GameElement parent) { return BasicEnvironmentObject.GenerateElement(elementName, Guid.NewGuid(), tags, false, themeBundleName, objectName, parent, isStatic, shadowThreshold, shadowSmoothness, useWorldLight, fakeLightDir); } } }