using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Ichni.RhythmGame.Beatmap; using UniRx; using Unity.Mathematics; using UnityEngine; using UnityEngine.Events; namespace Ichni.RhythmGame { public class TransformSubmodule : SubmoduleBase { public Vector3 originalPosition; public Vector3 originalEulerAngles; public Vector3 originalScale; public List positionOffset; public List eulerAnglesOffset; public List scaleOffset; public Vector3 currentPosition; public Vector3 currentEulerAngles; public Vector3 currentScale; public bool positionDirtyMark; public bool eulerAnglesDirtyMark; public bool scaleDirtyMark; public bool eulerAnglesOffsetLock; public TransformSubmodule(GameElement attachedGameElement) : base(attachedGameElement) { this.originalPosition = Vector3.zero; this.originalEulerAngles = Vector3.zero; this.originalScale = Vector3.one; positionOffset = new List(); eulerAnglesOffset = new List(); scaleOffset = new List(); currentPosition = Vector3.zero; currentEulerAngles = Vector3.zero; currentScale = Vector3.one; positionDirtyMark = false; eulerAnglesDirtyMark = false; scaleDirtyMark = false; eulerAnglesOffsetLock = false; // (attachedGameElement as IHaveTransformSubmodule).SetTransformObserver(); } public TransformSubmodule(GameElement attachedGameElement, Vector3 originalPosition, Vector3 originalEulerAngles, Vector3 originalScale) : base(attachedGameElement) { this.originalPosition = originalPosition; this.originalEulerAngles = originalEulerAngles; this.originalScale = originalScale; positionOffset = new List(); eulerAnglesOffset = new List(); scaleOffset = new List(); currentPosition = originalPosition; currentEulerAngles = originalEulerAngles; currentScale = originalScale; positionDirtyMark = false; eulerAnglesDirtyMark = false; scaleDirtyMark = false; eulerAnglesOffsetLock = false; // (attachedGameElement as IHaveTransformSubmodule).SetTransformObserver(); } public override void SaveBM() { matchedBM = new TransformSubmodule_BM(attachedGameElement); } } public interface IHaveTransformSubmodule { TransformSubmodule transformSubmodule { get; set; } public void SetTransformObserver() { GameElement attachedGameElement = transformSubmodule.attachedGameElement; Observable.EveryUpdate().Subscribe(_ => { if (transformSubmodule == null) { return; } if (transformSubmodule.scaleDirtyMark) { Vector3 offset = Vector3.zero; foreach (Vector3 scaleOffset in transformSubmodule.scaleOffset) { offset += scaleOffset; } transformSubmodule.currentScale = transformSubmodule.originalScale + offset; attachedGameElement.transform.localScale = transformSubmodule.currentScale; transformSubmodule.scaleDirtyMark = false; } if (transformSubmodule.eulerAnglesDirtyMark) { Vector3 offset = Vector3.zero; foreach (Vector3 eulerOffset in transformSubmodule.eulerAnglesOffset) { offset += eulerOffset; } transformSubmodule.currentEulerAngles = transformSubmodule.originalEulerAngles + offset; attachedGameElement.transform.localEulerAngles = transformSubmodule.currentEulerAngles; transformSubmodule.eulerAnglesDirtyMark = false; } if (transformSubmodule.positionDirtyMark) { Vector3 offset = Vector3.zero; foreach (Vector3 posOffset in transformSubmodule.positionOffset) { offset += posOffset; } transformSubmodule.currentPosition = transformSubmodule.originalPosition + offset; attachedGameElement.transform.localPosition = transformSubmodule.currentPosition; transformSubmodule.positionDirtyMark = false; } transformSubmodule.scaleOffset.Clear(); transformSubmodule.eulerAnglesOffset.Clear(); transformSubmodule.positionOffset.Clear(); }).AddTo(attachedGameElement); } } namespace Beatmap { public class TransformSubmodule_BM : Submodule_BM { public Vector3 originalPosition; public Vector3 originalEulerAngles; public Vector3 originalScale; public TransformSubmodule_BM() { } public TransformSubmodule_BM(GameElement attachedElement) : base(attachedElement) { TransformSubmodule transformSubmodule = (attachedElement as IHaveTransformSubmodule).transformSubmodule; this.originalPosition = transformSubmodule.originalPosition; this.originalEulerAngles = transformSubmodule.originalEulerAngles; this.originalScale = transformSubmodule.originalScale; } public override void ExecuteBM() { attachedElement = GameElement_BM.GetElement(attachedElementGuid); (attachedElement as IHaveTransformSubmodule).transformSubmodule = new TransformSubmodule(attachedElement, originalPosition, originalEulerAngles, originalScale); } public override void DuplicateBM(GameElement attached) { (attached as IHaveTransformSubmodule).transformSubmodule = new TransformSubmodule(attached, originalPosition, originalEulerAngles, originalScale); } } } }