using System; using System.Collections; using System.Collections.Generic; using Ichni.RhythmGame.Beatmap; using UniRx; using UnityEngine; namespace Ichni.RhythmGame { /// /// 将物体的z轴指向目标物体,注意,LookAt的启用期间,物体的旋转将被锁定 /// public partial class LookAt : AnimationBase { public GameElement targetGameElement; public TransformSubmodule targetTransformSubmodule; public FlexibleBool enabling; public static LookAt GenerateElement(string elementName, Guid id, List tags, bool isFirstGenerated, GameElement animatedObject, GameElement lookAtTarget, FlexibleBool enabling) { LookAt look = Instantiate(GameManager.instance.basePrefabs.emptyObject).AddComponent(); look.Initialize(elementName, id, tags, isFirstGenerated, animatedObject); look.animatedObject = animatedObject; look.enabling = enabling; look.animationReturnType = FlexibleReturnType.Before; look.targetGameElement = lookAtTarget; look.targetTransformSubmodule = (animatedObject as IHaveTransformSubmodule).transformSubmodule; //look.timeDurationSubmodule.SetDuration(-999f, 999f); //TODO: 换为(-delay, songLength) return look; } public override void SetDefaultSubmodules() { timeDurationSubmodule = new TimeDurationSubmodule(this); } void LateUpdate() { if (enabling.value) { (animatedObject as IHaveTransformSubmodule)?.UpdateLookAt(this); } } protected override void UpdateAnimation(float songTime) { if (targetGameElement is null) return; enabling.UpdateFlexibleBool(songTime); if (!targetTransformSubmodule.eulerAnglesOffsetLock || enabling.value) { targetTransformSubmodule.eulerAnglesOffsetLock = enabling.value; } if (enabling.value) { animationReturnType = FlexibleReturnType.MiddleExecuting; targetTransformSubmodule.eulerAnglesDirtyMark = true; } else if (animationReturnType != FlexibleReturnType.MiddleInterval) { animationReturnType = FlexibleReturnType.MiddleInterval; targetTransformSubmodule.eulerAnglesDirtyMark = true; } } public override void SaveBM() { matchedBM = new LookAt_BM(elementName, elementGuid, tags, parentElement.matchedBM as GameElement_BM, enabling.ConvertToBM(), targetGameElement.elementGuid); } public override void ApplyTimeOffset(float offset) { base.ApplyTimeOffset(offset); enabling.animations.ForEach(anim => anim.ApplyTimeOffset(offset)); } } namespace Beatmap { public class LookAt_BM : GameElement_BM { public FlexibleBool_BM enabling; public Guid lookAtObjectGuid; public LookAt_BM() { } public LookAt_BM(string elementName, Guid elementGuid, List tags, GameElement_BM attachedElement, FlexibleBool_BM enabling, Guid lookAtObjectGuid) : base(elementName, elementGuid, tags, attachedElement) { this.enabling = enabling; this.lookAtObjectGuid = lookAtObjectGuid; } public override void ExecuteBM() { matchedElement = LookAt.GenerateElement(elementName, elementGuid, tags, false, GetElement(attachedElementGuid), GetElement(lookAtObjectGuid), enabling.ConvertToGameType()); matchedElement.matchedBM = this; } public override void AfterExecute() { (matchedElement as LookAt).targetGameElement = GetElement(lookAtObjectGuid); } } } }