using System; using System.Collections; using System.Collections.Generic; using Ichni.RhythmGame.Beatmap; using UnityEngine; namespace Ichni.RhythmGame { /// /// 将物体的z轴指向目标物体,注意,LookAt的启用期间,物体的旋转将被锁定 /// public partial class LookAt : AnimationBase { public GameElement targetGameElement; public TransformSubmodule targetTransformSubmodule; public GameElement lookAtObject; 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.lookAtObject = lookAtTarget; 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); } protected override void UpdateAnimation(float songTime) { enabling.UpdateFlexibleBool(songTime); if (enabling.value) { animationReturnType = FlexibleReturnType.MiddleExecuting; Vector3 lookingDirection = (lookAtObject.transform.position - animatedObject.transform.position).normalized; Vector3 eulerAnglesOffset = Quaternion.LookRotation(lookingDirection).eulerAngles; targetTransformSubmodule.eulerAnglesOffsetLock = true; targetTransformSubmodule.currentEulerAngles = eulerAnglesOffset; } else { animationReturnType = FlexibleReturnType.MiddleInterval; targetTransformSubmodule.eulerAnglesOffsetLock = false; } } public override void SaveBM() { matchedBM = new LookAt_BM(elementName, elementGuid, tags, parentElement.matchedBM as GameElement_BM, enabling.ConvertToBM(), lookAtObject.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()); } public override GameElement DuplicateBM(GameElement parent) { return LookAt.GenerateElement(elementName, Guid.NewGuid(), tags, false, parent, GetElement(lookAtObjectGuid), enabling.ConvertToGameType()); } } } }