using System; using System.Collections; using System.Collections.Generic; using DG.Tweening; using Ichni.Editor; using Ichni.RhythmGame.Beatmap; using Ichni.RhythmGame.ThemeBundles.Basic.Beatmap; using Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse.Beatmap; using UnityEngine; using UnityEngine.InputSystem; namespace Ichni.RhythmGame.ThemeBundles.DepartureToMultiverse { public partial class DTMTrail : EnvironmentObject, IHaveTrail, IHaveInteraction { public GameObject headPoint, headCircle; public GameObject trailBody; public bool isHeadEnabled; public List renderers; public ParticleSystem headCircleParticle; public TrailRenderer trailRenderer { get; set; } public FlexibleFloat visibleTimeLength; public FlexibleBool enableTimes; public float enableProcessTime = 0.5f; public float headSize = 1f; public FlexibleFloat headRotateSpeed; public override bool haveEmission => true; public static DTMTrail GenerateElement(string elementName, Guid id, List tags, bool isFirstGenerated, string themeBundleName, string objectName, GameElement parentElement, bool isStatic, FlexibleFloat visibleTimeLength, FlexibleBool enableTimes, FlexibleFloat headRotateSpeed, float enableProcessTime, float headSize) { DTMTrail dtmTrail = EnvironmentObject.GenerateElement(elementName, id, tags, isFirstGenerated, themeBundleName, objectName, parentElement, isStatic).GetComponent(); dtmTrail.isHeadEnabled = false; dtmTrail.visibleTimeLength = visibleTimeLength; dtmTrail.enableTimes = enableTimes; dtmTrail.headRotateSpeed = headRotateSpeed; dtmTrail.enableProcessTime = enableProcessTime; dtmTrail.headSize = headSize; return dtmTrail; } public override void SetDefaultSubmodules() { base.SetDefaultSubmodules(); colorSubmodule.emissionEnabled = true; colorSubmodule.originalEmissionColor = Color.white; colorSubmodule.originalEmissionIntensity = 1; } public override void FirstSetUpObject(bool isFirstGenerated) { if (isFirstGenerated) { enableTimes = new FlexibleBool(); enableTimes.Add(new AnimatedBool(0f, false)); enableTimes.Add(new AnimatedBool(1f, true)); } SetUpTweeners(); trailRenderer = trailBody.GetComponent(); var rotationBySpeedModule = headCircleParticle.rotationBySpeed; rotationBySpeedModule.z = 0; headPoint.transform.localScale = Vector3.zero; headCircle.transform.localScale = Vector3.zero; renderers.ForEach(rend => rend.InitializeShader()); Refresh(); } public override void Refresh() { base.Refresh(); renderers.ForEach(rend => { if (colorSubmodule.emissionEnabled) { rend.material.EnableKeyword("_EMISSION_ON"); Debug.Log("Enable emission"); } else { rend.material.DisableKeyword("_EMISSION_ON"); } rend.material.EnableKeyword("_USEREDASALPHA_ON"); Debug.Log(rend.material.IsKeywordEnabled("_EMISSION_ON") + " " + rend.material.IsKeywordEnabled("_USEREDASALPHA_ON")); rend.material.SetColor("_BaseColor", colorSubmodule.currentBaseColor); rend.material.SetColor("_EmissionColor", colorSubmodule.GetCurrentEmissionColor()); }); } private void Update() { float songTime = EditorManager.instance.songInformation.songTime; enableTimes.UpdateFlexibleBool(songTime); if(enableTimes.value && !isHeadEnabled) { EnableHead(); isHeadEnabled = true; } else if(!enableTimes.value && isHeadEnabled) { DisableHead(); isHeadEnabled = false; } visibleTimeLength.UpdateFlexibleFloat(songTime); if (visibleTimeLength.animations.Count > 0) { Debug.Log(trailRenderer == null); trailRenderer.time = visibleTimeLength.value; } if (isHeadEnabled && headRotateSpeed.animations.Count > 0) { headRotateSpeed.UpdateFlexibleFloat(songTime); var rotationBySpeedModule = headCircleParticle.rotationBySpeed; rotationBySpeedModule.z = headRotateSpeed.value; } if (Keyboard.current.spaceKey.wasPressedThisFrame) { TriggerInteraction(); } } private void EnableHead() { enableHeadSequence.PlayForward(); } private void DisableHead() { enableHeadSequence.PlayBackwards(); } private Sequence enableHeadSequence; private Sequence disableHeadSequence; private Sequence headBounceSequence; public void SetUpTweeners() { enableHeadSequence?.Kill(true); disableHeadSequence?.Kill(true); headBounceSequence?.Kill(true); enableHeadSequence = DOTween.Sequence(); enableHeadSequence.Append(headPoint.transform.DOScale(headSize, enableProcessTime).SetEase(Ease.OutQuad)); enableHeadSequence.Join(headCircle.transform.DOScale(headSize, enableProcessTime).SetEase(Ease.OutQuad)); enableHeadSequence.SetAutoKill(false); disableHeadSequence = DOTween.Sequence(); disableHeadSequence.Append(headPoint.transform.DOScale(0, enableProcessTime).SetEase(Ease.OutQuad)); disableHeadSequence.Join(headCircle.transform.DOScale(0, enableProcessTime).SetEase(Ease.OutQuad)); disableHeadSequence.SetAutoKill(false); headBounceSequence = DOTween.Sequence(); headBounceSequence.Append(headPoint.transform.DOBlendableScaleBy(Vector3.one * 0.2f, 0.2f).SetEase(Ease.OutBack)); headBounceSequence.Join(headCircle.transform.DOBlendableScaleBy(Vector3.one * 0.2f, 0.2f).SetEase(Ease.OutBack)); headBounceSequence.Append(headPoint.transform.DOBlendableScaleBy(Vector3.one * -0.2f, 0.2f).SetEase(Ease.OutBack)); headBounceSequence.Join(headCircle.transform.DOBlendableScaleBy(Vector3.one * -0.2f, 0.2f).SetEase(Ease.OutBack)); headBounceSequence.SetAutoKill(false); } public void TriggerInteraction() { headBounceSequence.Restart(); } } public partial class DTMTrail { public override void SaveBM() { matchedBM = new DTMTrail_BM(elementName, elementGuid, tags, parentElement.matchedBM as GameElement_BM, themeBundleName, objectName, isStatic, visibleTimeLength, enableTimes, headRotateSpeed, enableProcessTime, headSize); } public override void SetUpInspector() { base.SetUpInspector(); IHaveInspection inspector = EditorManager.instance.uiManager.inspector; var container = inspector.GenerateContainer("DTMTrail"); var subcontainer = container.GenerateSubcontainer(3); var visibleTimeLengthButton = inspector.GenerateButton(this, subcontainer, "Visible Time Length", () => { var ew = inspector.GenerateCompositeParameterWindow( this, "Visible Time Length", nameof(visibleTimeLength)); ew.SetAsFlexibleFloat(); }); var enableTimeListButton = inspector.GenerateButton(this, subcontainer, "Enable Head Time List", () => { var ew = inspector.GenerateCompositeParameterWindow( this, "Enable Head Time List", nameof(enableTimes)); ew.SetAsFlexibleBool(); }); var headRotateSpeedButton = inspector.GenerateButton(this, subcontainer, "Head Rotate Speed", () => { var ew = inspector.GenerateCompositeParameterWindow( this, "Head Rotate Speed", nameof(headRotateSpeed)); ew.SetAsFlexibleFloat(); }); var enableProcessTimeInputField = inspector.GenerateInputField(this, subcontainer, "Enable Process Time", nameof(enableProcessTime)) .AddListenerFunction(SetUpTweeners); var headSizeInputField = inspector.GenerateInputField(this, subcontainer, "Head Size", nameof(headSize)) .AddListenerFunction(SetUpTweeners); } } namespace Beatmap { public partial class DTMTrail_BM : EnvironmentObject_BM { public FlexibleFloat_BM visibleTimeLength; public FlexibleBool_BM enableTimes; public float enableProcessTime = 0.5f; public float headSize = 1f; public FlexibleFloat_BM headRotateSpeed; public DTMTrail_BM() { } public DTMTrail_BM(string elementName, Guid elementGuid, List tags, GameElement_BM parentElement, string themeBundleName, string objectName, bool isStatic, FlexibleFloat visibleTimeLength, FlexibleBool enableTimes, FlexibleFloat headRotateSpeed, float enableProcessTime, float headSize): base(elementName, elementGuid, tags, parentElement, themeBundleName, objectName, isStatic) { this.visibleTimeLength = visibleTimeLength.ConvertToBM(); this.enableTimes = enableTimes.ConvertToBM(); this.headRotateSpeed = headRotateSpeed.ConvertToBM(); this.enableProcessTime = enableProcessTime; this.headSize = headSize; } public override void ExecuteBM() { matchedElement = DTMTrail.GenerateElement(elementName, elementGuid, tags, false, themeBundleName, objectName, GetElement(attachedElementGuid), isStatic, visibleTimeLength?.ConvertToGameType(), enableTimes.ConvertToGameType(), headRotateSpeed?.ConvertToGameType(), enableProcessTime, headSize); } public override GameElement DuplicateBM(GameElement parent) { return DTMTrail.GenerateElement(elementName, Guid.NewGuid(), tags, false, themeBundleName, objectName, parent, isStatic, visibleTimeLength?.ConvertToGameType(), enableTimes.ConvertToGameType(), headRotateSpeed?.ConvertToGameType(), enableProcessTime, headSize); } } } }