211 lines
8.2 KiB
C#
211 lines
8.2 KiB
C#
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<Vector3> positionOffset;
|
||
public List<Vector3> eulerAnglesOffset;
|
||
public List<Vector3> 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<Vector3>();
|
||
eulerAnglesOffset = new List<Vector3>();
|
||
scaleOffset = new List<Vector3>();
|
||
|
||
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<Vector3>();
|
||
eulerAnglesOffset = new List<Vector3>();
|
||
scaleOffset = new List<Vector3>();
|
||
|
||
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 override void SetUpInspector()
|
||
{
|
||
var container = inspector.GenerateContainer("Transform");
|
||
var originalPosInputField =
|
||
inspector.GenerateVec3InputField(this, container, "Start Position", nameof(originalPosition));
|
||
var originalRotInputField =
|
||
inspector.GenerateVec3InputField(this, container, "Start Rotation", nameof(originalEulerAngles));
|
||
var originalScaleInputField =
|
||
inspector.GenerateVec3InputField(this, container, "Start Scale", nameof(originalScale));
|
||
var currentPosText =
|
||
inspector.GenerateText(this, container, "Current Position", nameof(currentPosition), true);
|
||
var currentRotText =
|
||
inspector.GenerateText(this, container, "Current Rotation", nameof(currentEulerAngles), true);
|
||
var currentScaleText =
|
||
inspector.GenerateText(this, container, "Current Scale", nameof(currentScale), true);
|
||
}
|
||
|
||
public override void Refresh()
|
||
{
|
||
positionDirtyMark = true;
|
||
eulerAnglesDirtyMark = true;
|
||
scaleDirtyMark = true;
|
||
}
|
||
}
|
||
|
||
public interface IHaveTransformSubmodule
|
||
{
|
||
TransformSubmodule transformSubmodule { get; set; }
|
||
|
||
/// <summary>
|
||
/// 设置物体Transform的监听,顺序为Scale -> EulerAngles -> Position
|
||
/// 如果有一些特殊的物体(例如Camera,ElementFolder),需要自定义监听,可以重写这个方法
|
||
/// </summary>
|
||
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);
|
||
attachedElement.submoduleList.Add((attachedElement as IHaveTransformSubmodule).transformSubmodule);
|
||
}
|
||
|
||
public override void DuplicateBM(GameElement attached)
|
||
{
|
||
(attached as IHaveTransformSubmodule).transformSubmodule = new TransformSubmodule(attached, originalPosition, originalEulerAngles, originalScale);
|
||
attached.submoduleList.Add((attached as IHaveTransformSubmodule).transformSubmodule);
|
||
}
|
||
}
|
||
}
|
||
} |