2025-06-03 02:42:28 -04:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections;
|
|
|
|
|
|
using System.Collections.Generic;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
using System.Linq;
|
2025-06-03 02:42:28 -04:00
|
|
|
|
using Ichni.RhythmGame.Beatmap;
|
|
|
|
|
|
using UniRx;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
using UniRx.Triggers;
|
|
|
|
|
|
using Unity.VisualScripting;
|
2025-06-03 02:42:28 -04:00
|
|
|
|
using UnityEngine;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
using Object = UnityEngine.Object;
|
2025-06-03 02:42:28 -04:00
|
|
|
|
|
|
|
|
|
|
namespace Ichni.RhythmGame
|
|
|
|
|
|
{
|
|
|
|
|
|
public class TransformSubmodule : SubmoduleBase
|
|
|
|
|
|
{
|
|
|
|
|
|
public Vector3 originalPosition;
|
|
|
|
|
|
public Vector3 originalEulerAngles;
|
|
|
|
|
|
public Vector3 originalScale;
|
|
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
public Vector3 positionOffset;
|
|
|
|
|
|
public Vector3 eulerAnglesOffset;
|
|
|
|
|
|
public Vector3 scaleOffset;
|
2025-06-03 02:42:28 -04:00
|
|
|
|
|
|
|
|
|
|
public Vector3 currentPosition;
|
|
|
|
|
|
public Vector3 currentEulerAngles;
|
|
|
|
|
|
public Vector3 currentScale;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
|
2025-06-03 02:42:28 -04:00
|
|
|
|
public bool positionDirtyMark;
|
|
|
|
|
|
public bool eulerAnglesDirtyMark;
|
|
|
|
|
|
public bool scaleDirtyMark;
|
|
|
|
|
|
|
|
|
|
|
|
public bool eulerAnglesOffsetLock;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
|
|
|
|
|
|
public IDisposable observer;
|
2025-06-03 02:42:28 -04:00
|
|
|
|
|
|
|
|
|
|
public TransformSubmodule(GameElement attachedGameElement) : base(attachedGameElement)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.originalPosition = Vector3.zero;
|
|
|
|
|
|
this.originalEulerAngles = Vector3.zero;
|
|
|
|
|
|
this.originalScale = Vector3.one;
|
|
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
positionOffset = Vector3.zero;
|
|
|
|
|
|
eulerAnglesOffset = Vector3.zero;
|
|
|
|
|
|
scaleOffset = Vector3.zero;
|
2025-06-03 02:42:28 -04:00
|
|
|
|
|
|
|
|
|
|
currentPosition = Vector3.zero;
|
|
|
|
|
|
currentEulerAngles = Vector3.zero;
|
|
|
|
|
|
currentScale = Vector3.one;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
|
2025-06-03 02:42:28 -04:00
|
|
|
|
positionDirtyMark = true;
|
|
|
|
|
|
eulerAnglesDirtyMark = true;
|
|
|
|
|
|
scaleDirtyMark = true;
|
|
|
|
|
|
|
|
|
|
|
|
eulerAnglesOffsetLock = false;
|
|
|
|
|
|
|
|
|
|
|
|
if (!HaveSameSubmodule)
|
|
|
|
|
|
{
|
|
|
|
|
|
(attachedGameElement as IHaveTransformSubmodule).transformSubmodule = this;
|
|
|
|
|
|
(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;
|
|
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
positionOffset = Vector3.zero;
|
|
|
|
|
|
eulerAnglesOffset = Vector3.zero;
|
|
|
|
|
|
scaleOffset = Vector3.zero;
|
2025-06-03 02:42:28 -04:00
|
|
|
|
|
|
|
|
|
|
currentPosition = originalPosition;
|
|
|
|
|
|
currentEulerAngles = originalEulerAngles;
|
|
|
|
|
|
currentScale = originalScale;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
|
2025-06-03 02:42:28 -04:00
|
|
|
|
positionDirtyMark = true;
|
|
|
|
|
|
eulerAnglesDirtyMark = true;
|
|
|
|
|
|
scaleDirtyMark = true;
|
|
|
|
|
|
|
|
|
|
|
|
eulerAnglesOffsetLock = false;
|
|
|
|
|
|
|
|
|
|
|
|
attachedGameElement.transform.localScale = currentScale;
|
|
|
|
|
|
attachedGameElement.transform.localEulerAngles = currentEulerAngles;
|
|
|
|
|
|
attachedGameElement.transform.localPosition = currentPosition;
|
|
|
|
|
|
|
|
|
|
|
|
if (!HaveSameSubmodule)
|
|
|
|
|
|
{
|
|
|
|
|
|
(attachedGameElement as IHaveTransformSubmodule).transformSubmodule = this;
|
|
|
|
|
|
(attachedGameElement as IHaveTransformSubmodule).SetTransformObserver();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void SaveBM()
|
|
|
|
|
|
{
|
|
|
|
|
|
matchedBM = new TransformSubmodule_BM(attachedGameElement);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void Refresh()
|
|
|
|
|
|
{
|
|
|
|
|
|
positionDirtyMark = true;
|
|
|
|
|
|
eulerAnglesDirtyMark = true;
|
|
|
|
|
|
scaleDirtyMark = true;
|
|
|
|
|
|
}
|
2025-07-21 05:42:20 -04:00
|
|
|
|
|
|
|
|
|
|
private bool HaveAnimation() => attachedGameElement.childElementList
|
|
|
|
|
|
.Any(element => element is Displacement or Swirl or Scale or LookAt);
|
|
|
|
|
|
|
|
|
|
|
|
public override void CheckAndRemoveObservers()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!HaveAnimation())
|
|
|
|
|
|
{
|
|
|
|
|
|
observer?.Dispose();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-06-03 02:42:28 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public interface IHaveTransformSubmodule
|
|
|
|
|
|
{
|
|
|
|
|
|
TransformSubmodule transformSubmodule { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 设置物体Transform的监听,顺序为Scale -> EulerAngles -> Position
|
|
|
|
|
|
/// 如果有一些特殊的物体(例如Camera,ElementFolder),需要自定义监听,可以重写这个方法
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public void SetTransformObserver()
|
|
|
|
|
|
{
|
2025-07-21 05:42:20 -04:00
|
|
|
|
transformSubmodule.observer = Observable.EveryUpdate()
|
|
|
|
|
|
.Subscribe(_ => UpdateTransform())
|
|
|
|
|
|
.AddTo(transformSubmodule.attachedGameElement);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void UpdateTransform()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!GameManager.instance.audioManager.isUpdating)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-03 02:42:28 -04:00
|
|
|
|
GameElement attachedGameElement = transformSubmodule.attachedGameElement;
|
2025-07-21 05:42:20 -04:00
|
|
|
|
bool willRefresh = false;
|
2025-06-03 02:42:28 -04:00
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
if (transformSubmodule.scaleDirtyMark)
|
2025-06-03 02:42:28 -04:00
|
|
|
|
{
|
2025-07-21 05:42:20 -04:00
|
|
|
|
transformSubmodule.currentScale = transformSubmodule.originalScale + transformSubmodule.scaleOffset;
|
|
|
|
|
|
attachedGameElement.transform.localScale = transformSubmodule.currentScale;
|
|
|
|
|
|
transformSubmodule.scaleDirtyMark = false;
|
|
|
|
|
|
willRefresh = true;
|
|
|
|
|
|
transformSubmodule.scaleOffset = Vector3.zero;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!transformSubmodule.eulerAnglesOffsetLock && transformSubmodule.eulerAnglesDirtyMark)
|
|
|
|
|
|
{
|
|
|
|
|
|
transformSubmodule.currentEulerAngles = transformSubmodule.originalEulerAngles + transformSubmodule.eulerAnglesOffset;
|
|
|
|
|
|
attachedGameElement.transform.localEulerAngles = transformSubmodule.currentEulerAngles;
|
|
|
|
|
|
transformSubmodule.eulerAnglesDirtyMark = false;
|
|
|
|
|
|
willRefresh = true;
|
|
|
|
|
|
transformSubmodule.eulerAnglesOffset = Vector3.zero;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (transformSubmodule.positionDirtyMark)
|
|
|
|
|
|
{
|
|
|
|
|
|
transformSubmodule.currentPosition = transformSubmodule.originalPosition + transformSubmodule.positionOffset;
|
|
|
|
|
|
attachedGameElement.transform.localPosition = transformSubmodule.currentPosition;
|
|
|
|
|
|
transformSubmodule.positionDirtyMark = false;
|
|
|
|
|
|
willRefresh = true;
|
|
|
|
|
|
transformSubmodule.positionOffset = Vector3.zero;
|
|
|
|
|
|
}
|
2025-06-03 02:42:28 -04:00
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
if(willRefresh)
|
|
|
|
|
|
{
|
|
|
|
|
|
attachedGameElement.Refresh();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void UpdateLookAt(LookAt lookAt) // 处理LookAt
|
|
|
|
|
|
{
|
|
|
|
|
|
Transform target = lookAt.lookAtObject.transform;
|
|
|
|
|
|
Transform self = transformSubmodule.attachedGameElement.transform;
|
|
|
|
|
|
|
|
|
|
|
|
if (transformSubmodule.eulerAnglesOffsetLock && transformSubmodule.eulerAnglesDirtyMark)
|
|
|
|
|
|
{
|
|
|
|
|
|
Vector3 lookingDirection = (target.position - self.position).normalized;
|
2025-06-03 02:42:28 -04:00
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
Vector3 eulerAnglesOffset = Quaternion.LookRotation(lookingDirection).eulerAngles;
|
2025-06-03 02:42:28 -04:00
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
transformSubmodule.eulerAnglesOffset += eulerAnglesOffset;
|
|
|
|
|
|
transformSubmodule.currentEulerAngles = transformSubmodule.originalEulerAngles + transformSubmodule.eulerAnglesOffset;
|
|
|
|
|
|
|
|
|
|
|
|
self.localEulerAngles = transformSubmodule.currentEulerAngles;
|
|
|
|
|
|
|
|
|
|
|
|
transformSubmodule.eulerAnglesDirtyMark = false;
|
|
|
|
|
|
transformSubmodule.eulerAnglesOffsetLock = false;
|
|
|
|
|
|
transformSubmodule.eulerAnglesOffset = Vector3.zero;
|
|
|
|
|
|
}
|
2025-06-03 02:42:28 -04:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
2025-07-21 05:42:20 -04:00
|
|
|
|
//if(attachedElement == null)Debug.Log(attachedElementGuid);
|
2025-06-03 02:42:28 -04:00
|
|
|
|
|
|
|
|
|
|
(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);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|