Substantial Object生成调整
可以正确的生成NoteVisual
This commit is contained in:
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Dreamteck.Splines;
|
||||
using Ichni.Editor;
|
||||
using Ichni.RhythmGame.Beatmap;
|
||||
using Lean.Pool;
|
||||
using Unity.VisualScripting;
|
||||
@@ -52,6 +53,18 @@ namespace Ichni.RhythmGame
|
||||
{
|
||||
matchedBM = new Tap_BM(elementName, elementGuid, tags, parentElement.matchedBM as GameElement_BM, exactJudgeTime);
|
||||
}
|
||||
|
||||
public override void SetUpInspector()
|
||||
{
|
||||
base.SetUpInspector();
|
||||
|
||||
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
|
||||
var container = inspector.GenerateContainer("Generate");
|
||||
var generateNoteVisualButton = inspector.GenerateButton(this, container, "Generate Note Visual", () =>
|
||||
{
|
||||
TemporaryObject.GenerateElement("New Note Visual", Guid.NewGuid(), new List<string>(), true, this);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
namespace Beatmap
|
||||
|
||||
@@ -21,10 +21,22 @@ namespace Ichni.RhythmGame
|
||||
GameObject themeBundleObject = ThemeBundleManager.instance.GetObject<GameObject>(themeBundleName, objectName);
|
||||
SubstantialObject substantialObject = Instantiate(themeBundleObject, parentElement.transform).GetComponent<SubstantialObject>();
|
||||
substantialObject.Initialize(elementName, id, tags, isFirstGenerated, parentElement);
|
||||
|
||||
substantialObject.themeBundleName = themeBundleName;
|
||||
substantialObject.objectName = objectName;
|
||||
substantialObject.FirstSetUpObject(isFirstGenerated);
|
||||
return substantialObject;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初次生成继承自SubstantialObject的对象时,生成方法必然使用SubstantialObject中的GenerateElement方法。
|
||||
/// 因此对于需要进行特殊处理的子类,需要重写FirstSetUpObject方法。
|
||||
/// 在读取Beatmap时,生成物体则使用子类本身的GenerateElement方法。
|
||||
/// </summary>
|
||||
public virtual void FirstSetUpObject(bool isFirstGenerated)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void SetDefaultSubmodules()
|
||||
{
|
||||
transformSubmodule = new TransformSubmodule(this);
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace Ichni.RhythmGame
|
||||
{
|
||||
Delete();
|
||||
inspectorMain.ClearInspector();
|
||||
SubstantialObject.GenerateElement(elementName, elementGuid, tags, false, themeBundleName, objectName, parentElement);
|
||||
SubstantialObject.GenerateElement(elementName, elementGuid, tags, true, themeBundleName, objectName, parentElement);
|
||||
});
|
||||
|
||||
if (themeBundleName == String.Empty || objectName == String.Empty)
|
||||
|
||||
@@ -14,18 +14,20 @@ namespace Ichni.RhythmGame
|
||||
public partial class PathNode : GameElement, IHaveTransformSubmodule, IHaveTimeDurationSubmodule, IHaveColorSubmodule
|
||||
{
|
||||
public Track track;
|
||||
|
||||
public int index => track.trackPathSubmodule.pathNodeList.IndexOf(this);
|
||||
|
||||
public SplinePoint node;
|
||||
|
||||
public int index => track.trackPathSubmodule.pathNodeList.IndexOf(this);
|
||||
public TransformSubmodule transformSubmodule { get; set; }
|
||||
public TimeDurationSubmodule timeDurationSubmodule { get; set; }
|
||||
public ColorSubmodule colorSubmodule { get; set; }
|
||||
public bool haveEmission => false;
|
||||
|
||||
[Title("Editor独有参数")]
|
||||
[SerializeField] [HideInPlayMode]
|
||||
private GameObject pathNodeSphere;
|
||||
public bool isShowingSphere;
|
||||
|
||||
public static PathNode GenerateElement(string elementName, Guid id, List<string> tags, bool isFirstGenerated,
|
||||
Track track)
|
||||
Track track, bool isShowingSphere)
|
||||
{
|
||||
PathNode pathNode = Instantiate(EditorManager.instance.basePrefabs.pathNode, track.transform)
|
||||
.GetComponent<PathNode>();
|
||||
@@ -33,6 +35,8 @@ namespace Ichni.RhythmGame
|
||||
pathNode.Initialize(elementName, id, tags, isFirstGenerated, track);
|
||||
|
||||
pathNode.track = track;
|
||||
pathNode.isShowingSphere = isShowingSphere;
|
||||
pathNode.SetPathNodeSphere(isShowingSphere);
|
||||
track.trackPathSubmodule.pathNodeList.Add(pathNode);
|
||||
|
||||
return pathNode;
|
||||
@@ -78,7 +82,13 @@ namespace Ichni.RhythmGame
|
||||
{
|
||||
public override void SaveBM()
|
||||
{
|
||||
matchedBM = new Beatmap.PathNode_BM(elementName, elementGuid, tags, parentElement.matchedBM as GameElement_BM);
|
||||
matchedBM = new Beatmap.PathNode_BM(elementName, elementGuid, tags, parentElement.matchedBM as GameElement_BM, isShowingSphere);
|
||||
}
|
||||
|
||||
public void SetPathNodeSphere(bool isShowing)
|
||||
{
|
||||
isShowingSphere = isShowing;
|
||||
pathNodeSphere.SetActive(isShowing);
|
||||
}
|
||||
|
||||
public override void SetUpInspector()
|
||||
@@ -89,6 +99,8 @@ namespace Ichni.RhythmGame
|
||||
|
||||
var container = inspector.GenerateContainer("Path Node");
|
||||
var indexText = inspector.GenerateHintText(this, container, "Index: " + index);
|
||||
var isShowingSphereToggle = inspector.GenerateToggle(this, container, "Is Showing Sphere", nameof(isShowingSphere));
|
||||
isShowingSphereToggle.AddListenerFunction(SetPathNodeSphere);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,26 +108,28 @@ namespace Ichni.RhythmGame
|
||||
{
|
||||
public class PathNode_BM : GameElement_BM
|
||||
{
|
||||
public bool isShowingSphere;
|
||||
public PathNode_BM()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public PathNode_BM(string elementName, Guid elementGuid, List<string> tags, GameElement_BM attachedElement)
|
||||
public PathNode_BM(string elementName, Guid elementGuid, List<string> tags, GameElement_BM attachedElement,
|
||||
bool isShowingSphere)
|
||||
: base(elementName, elementGuid, tags, attachedElement)
|
||||
{
|
||||
|
||||
this.isShowingSphere = isShowingSphere;
|
||||
}
|
||||
|
||||
public override void ExecuteBM()
|
||||
{
|
||||
matchedElement = PathNode.GenerateElement(elementName, elementGuid, tags, false,
|
||||
GetElement(attachedElementGuid) as Track);
|
||||
GetElement(attachedElementGuid) as Track, isShowingSphere);
|
||||
}
|
||||
|
||||
public override GameElement DuplicateBM(GameElement parent)
|
||||
{
|
||||
return PathNode.GenerateElement(elementName, elementGuid, tags, false, parent as Track);
|
||||
return PathNode.GenerateElement(elementName, elementGuid, tags, false, parent as Track, isShowingSphere);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,35 +75,35 @@ namespace Ichni.RhythmGame
|
||||
Inspector inspectorMain = EditorManager.instance.uiManager.inspector;
|
||||
base.SetUpInspector();
|
||||
|
||||
var container = inspector.GenerateContainer("Track");
|
||||
var trackPathButton = inspector.GenerateButton(this, container, "Track Path",
|
||||
var trackSubmodulesContainer = inspector.GenerateContainer("Track Submodules"); //次级模块
|
||||
var trackPathButton = inspector.GenerateButton(this, trackSubmodulesContainer, "Track Path",
|
||||
() =>
|
||||
{
|
||||
trackPathSubmodule = new TrackPathSubmodule(this, TrackSpaceType.CatmullRom,
|
||||
TrackSamplingType.TimeDistributed, false);
|
||||
inspectorMain.SetInspector(this);
|
||||
});
|
||||
var trackTimeMovableButton = inspector.GenerateButton(this, container, "Track Time Movable",
|
||||
var trackTimeMovableButton = inspector.GenerateButton(this, trackSubmodulesContainer, "Track Time Movable",
|
||||
() =>
|
||||
{
|
||||
trackTimeSubmodule = new TrackTimeSubmoduleMovable(this, 0, 1, 1, AnimationCurveType.Linear);
|
||||
inspectorMain.SetInspector(this);
|
||||
});
|
||||
var trackTimeStaticButton = inspector.GenerateButton(this, container, "Track Time Static",
|
||||
var trackTimeStaticButton = inspector.GenerateButton(this, trackSubmodulesContainer, "Track Time Static",
|
||||
() =>
|
||||
{
|
||||
trackTimeSubmodule = new TrackTimeSubmoduleStatic(this, 1, AnimationCurveType.Linear);
|
||||
inspectorMain.SetInspector(this);
|
||||
});
|
||||
|
||||
var trackRendererAutoOrientButton = inspector.GenerateButton(this, container, "Track Renderer Auto Orient",
|
||||
var trackRendererAutoOrientButton = inspector.GenerateButton(this, trackSubmodulesContainer, "Track Renderer Auto Orient",
|
||||
() =>
|
||||
{
|
||||
trackRendererSubmodule = new TrackRendererSubmoduleAutoOrient(this);
|
||||
inspectorMain.SetInspector(this);
|
||||
});
|
||||
|
||||
var trackRendererPathGeneratorButton = inspector.GenerateButton(this, container,
|
||||
var trackRendererPathGeneratorButton = inspector.GenerateButton(this, trackSubmodulesContainer,
|
||||
"Track Renderer Path Generator",
|
||||
() =>
|
||||
{
|
||||
@@ -131,21 +131,70 @@ namespace Ichni.RhythmGame
|
||||
trackRendererSubmodule.SetUpInspector();
|
||||
}
|
||||
|
||||
var displacementButton = inspector.GenerateButton(this, container, "Displacement",
|
||||
var generateContainer = inspector.GenerateContainer("Generate Elements"); //物体生成
|
||||
|
||||
var pathNodeButton = inspector.GenerateButton(this, generateContainer, "Path Node",
|
||||
() =>
|
||||
{
|
||||
PathNode.GenerateElement("New Path Node", Guid.NewGuid(), new List<string>(), true, this, true);
|
||||
}); //路径点
|
||||
|
||||
var trackPercentPointButton = inspector.GenerateButton(this, generateContainer, "Track Percent Point",
|
||||
() =>
|
||||
{
|
||||
TrackPercentPoint.GenerateElement("New Track Percent Point", Guid.NewGuid(), new List<string>(),
|
||||
true, this, new FlexibleFloat());
|
||||
}); //百分比点
|
||||
|
||||
var trackHeadPointButton = inspector.GenerateButton(this, generateContainer, "Track Head Point",
|
||||
() =>
|
||||
{
|
||||
TrackHeadPoint.GenerateElement("New Track Head Point", Guid.NewGuid(), new List<string>(),
|
||||
true, this);
|
||||
}); //头部点(必须先有TrackTimeSubmoduleMovable)
|
||||
if (trackTimeSubmodule is not TrackTimeSubmoduleMovable) trackHeadPointButton.button.interactable = false;
|
||||
|
||||
var tapButton = inspector.GenerateButton(this, generateContainer, "Tap",
|
||||
() =>
|
||||
{
|
||||
Tap.GenerateElement("New Tap", Guid.NewGuid(), new List<string>(), true, this, 0f);
|
||||
}); //Note Tap
|
||||
|
||||
var stayButton = inspector.GenerateButton(this, generateContainer, "Stay",
|
||||
() =>
|
||||
{
|
||||
Stay.GenerateElement("New Stay", Guid.NewGuid(), new List<string>(), true, this, 0f);
|
||||
}); //Note Stay
|
||||
|
||||
// var holdButton = inspector.GenerateButton(this, generateContainer, "Hold",
|
||||
// () =>
|
||||
// {
|
||||
// Hold.GenerateElement("New Hold", Guid.NewGuid(), new List<string>(), true, this, 0f);
|
||||
// }); //Note Hold
|
||||
|
||||
var flickButton = inspector.GenerateButton(this, generateContainer, "Flick",
|
||||
() =>
|
||||
{
|
||||
Flick.GenerateElement("New Flick", Guid.NewGuid(), new List<string>(), true, this, 0f,
|
||||
new List<Vector2>());
|
||||
}); //Note Flick
|
||||
|
||||
var displacementButton = inspector.GenerateButton(this, generateContainer, "Displacement",
|
||||
() =>
|
||||
{
|
||||
Displacement.GenerateElement("New Displacement", Guid.NewGuid(), new List<string>(), true, this,
|
||||
new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat());
|
||||
});
|
||||
}); //位移
|
||||
|
||||
var swirlButton = inspector.GenerateButton(this, container, "Swirl",
|
||||
var swirlButton = inspector.GenerateButton(this, generateContainer, "Swirl",
|
||||
() =>
|
||||
{
|
||||
Swirl.GenerateElement("New Swirl", Guid.NewGuid(), new List<string>(), true, this,
|
||||
new FlexibleFloat(), new FlexibleFloat(), new FlexibleFloat());
|
||||
});
|
||||
}); //旋转
|
||||
|
||||
var QuickCopyButton = inspector.GenerateButton(this, container, "QuickCopy", () =>
|
||||
var toolsContainerTrack = inspector.GenerateContainer("Track Tools"); //轨道(整体)快捷工具
|
||||
var quickCopyButton = inspector.GenerateButton(this, toolsContainerTrack, "QuickCopy", () =>
|
||||
{
|
||||
IHaveInspection qcWindow = inspectorMain.GenerateSecondaryWindow(this, elementName + "'s Quick Copy");
|
||||
var qcContainer = qcWindow.GenerateContainer();
|
||||
@@ -163,9 +212,72 @@ namespace Ichni.RhythmGame
|
||||
bool includeAnimation = includeAnimationToggle.toggle.isOn;
|
||||
QuickCopy(positionOffset, timeOffset, includeAnimation, iteration);
|
||||
});
|
||||
}); //快速复制
|
||||
|
||||
var wholeTrackMoveButton = inspector.GenerateButton(this, toolsContainerTrack, "Whole Track Move", () =>
|
||||
{
|
||||
IHaveInspection wholeMoveWindow = inspectorMain.GenerateSecondaryWindow(this, elementName + "'s Whole Track Move");
|
||||
var wmContainer = wholeMoveWindow.GenerateContainer();
|
||||
var xField = wholeMoveWindow.GenerateGetterInputField(wmContainer, "X offset", "0");
|
||||
var yField = wholeMoveWindow.GenerateGetterInputField(wmContainer, "Y offset", "0");
|
||||
var zField = wholeMoveWindow.GenerateGetterInputField(wmContainer, "Z offset", "0");
|
||||
wholeMoveWindow.GenerateButton(this, wmContainer, "Move", () =>
|
||||
{
|
||||
Vector3 positionOffset = new Vector3(xField.GetResult<float>(), yField.GetResult<float>(), zField.GetResult<float>());
|
||||
WholeTrackMove(positionOffset);
|
||||
});
|
||||
}); //整体移动
|
||||
|
||||
var wholeTrackSwirlButton = inspector.GenerateButton(this, toolsContainerTrack, "Whole Track Swirl", () =>
|
||||
{
|
||||
IHaveInspection wholeSwirlWindow = inspectorMain.GenerateSecondaryWindow(this, elementName + "'s Whole Track Swirl");
|
||||
var wsContainer = wholeSwirlWindow.GenerateContainer();
|
||||
var angleField = wholeSwirlWindow.GenerateGetterInputField(wsContainer, "Angle", "0");
|
||||
var centerXField = wholeSwirlWindow.GenerateGetterInputField(wsContainer, "Center X", "0");
|
||||
var centerYField = wholeSwirlWindow.GenerateGetterInputField(wsContainer, "Center Y", "0");
|
||||
var centerZField = wholeSwirlWindow.GenerateGetterInputField(wsContainer, "Center Z", "0");
|
||||
var axisDirXField = wholeSwirlWindow.GenerateGetterInputField(wsContainer, "Axis Direction X", "0");
|
||||
var axisDirYField = wholeSwirlWindow.GenerateGetterInputField(wsContainer, "Axis Direction Y", "0");
|
||||
var axisDirZField = wholeSwirlWindow.GenerateGetterInputField(wsContainer, "Axis Direction Z", "0");
|
||||
wholeSwirlWindow.GenerateButton(this, wsContainer, "Swirl", () =>
|
||||
{
|
||||
float angle = angleField.GetResult<float>();
|
||||
Vector3 center = new Vector3(centerXField.GetResult<float>(), centerYField.GetResult<float>(), centerZField.GetResult<float>());
|
||||
Vector3 axisDirection = new Vector3(axisDirXField.GetResult<float>(), axisDirYField.GetResult<float>(), axisDirZField.GetResult<float>());
|
||||
WholeTrackSwirl(angle, center, axisDirection);
|
||||
});
|
||||
}); //整体旋转
|
||||
|
||||
var wholeTrackFlipButton = inspector.GenerateButton(this, toolsContainerTrack, "Whole Track Flip", () =>
|
||||
{
|
||||
IHaveInspection wholeFlipWindow = inspectorMain.GenerateSecondaryWindow(this, elementName + "'s Whole Track Flip");
|
||||
var wfContainer = wholeFlipWindow.GenerateContainer();
|
||||
var axisStartXField = wholeFlipWindow.GenerateGetterInputField(wfContainer, "Axis Start X", "0");
|
||||
var axisStartYField = wholeFlipWindow.GenerateGetterInputField(wfContainer, "Axis Start Y", "0");
|
||||
var axisStartZField = wholeFlipWindow.GenerateGetterInputField(wfContainer, "Axis Start Z", "0");
|
||||
var axisEndXField = wholeFlipWindow.GenerateGetterInputField(wfContainer, "Axis End X", "0");
|
||||
var axisEndYField = wholeFlipWindow.GenerateGetterInputField(wfContainer, "Axis End Y", "0");
|
||||
var axisEndZField = wholeFlipWindow.GenerateGetterInputField(wfContainer, "Axis End Z", "0");
|
||||
wholeFlipWindow.GenerateButton(this, wfContainer, "Flip", () =>
|
||||
{
|
||||
Vector3 axisStart = new Vector3(axisStartXField.GetResult<float>(), axisStartYField.GetResult<float>(), axisStartZField.GetResult<float>());
|
||||
Vector3 axisEnd = new Vector3(axisEndXField.GetResult<float>(), axisEndYField.GetResult<float>(), axisEndZField.GetResult<float>());
|
||||
WholeTrackFlip(axisStart, axisEnd);
|
||||
});
|
||||
}); //整体翻转
|
||||
|
||||
var toolsContainerPathNode = inspector.GenerateContainer("Path Node Tools"); //路径点快捷工具
|
||||
var setAllPathNodeSphereButton = inspector.GenerateButton(this, toolsContainerPathNode,
|
||||
"Set All Path Node Sphere", () =>
|
||||
{
|
||||
bool firstPathNodeSphere = trackPathSubmodule.pathNodeList[0].isShowingSphere;
|
||||
SetAllPathNodeSphere(!firstPathNodeSphere);
|
||||
});
|
||||
|
||||
container.SetDeviver(1);
|
||||
var setOnlyStartEndPathNodeSphereEnabledButton = inspector.GenerateButton(this, toolsContainerPathNode,
|
||||
"Only Start & End Path Node's sphere enabled", SetOnlyStartEndPathNodeSphereEnabled);
|
||||
|
||||
trackSubmodulesContainer.SetDeviver(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace Ichni.RhythmGame
|
||||
isClosedToggle.AddListenerFunction(_ => ClosePath());
|
||||
var generatePathNodeButton = inspector.GenerateButton(this, container, "Generate Path Node", () =>
|
||||
{
|
||||
PathNode.GenerateElement("New Path Node", Guid.NewGuid(), new List<string>(), true, track);
|
||||
PathNode.GenerateElement("New Path Node", Guid.NewGuid(), new List<string>(), true, track, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ using Dreamteck.Splines;
|
||||
using Ichni.Editor;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
using Inspector = Unity.VisualScripting.Inspector;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
|
||||
@@ -16,8 +16,8 @@ namespace Ichni.RhythmGame
|
||||
/// <param name="iteration">迭代次数,即产生几个粘贴的Track</param>
|
||||
private void QuickCopy(Vector3 unitPositionOffset, float unitTimeOffset, bool includeAnimations = true, int iteration = 1)
|
||||
{
|
||||
if(iteration <= 0) return;
|
||||
|
||||
if (iteration <= 0) return;
|
||||
|
||||
CopyPasteDeleteModule cpd = EditorManager.instance.operationManager.CopyPasteDeleteModule;
|
||||
cpd.CopyElement(this);
|
||||
for (int i = 1; i <= iteration; i++)
|
||||
@@ -26,31 +26,34 @@ namespace Ichni.RhythmGame
|
||||
Track newTrack = cpd.pastedElementList[0] as Track;
|
||||
Vector3 positionOffset = unitPositionOffset * i;
|
||||
float timeOffset = unitTimeOffset * i;
|
||||
|
||||
//对Track的所有有效的Submodule和子GameElement进行偏移
|
||||
if (newTrack.trackTimeSubmodule is TrackTimeSubmoduleMovable movable)
|
||||
{
|
||||
movable.trackStartTime += timeOffset;
|
||||
movable.trackEndTime += timeOffset;
|
||||
}
|
||||
|
||||
|
||||
//以下:对Track的所有有效的Submodule和子GameElement进行偏移 TODO: 需要思考是否有统一时间偏移的方法?
|
||||
|
||||
//PathNode,位置偏移
|
||||
newTrack.trackPathSubmodule.pathNodeList.ForEach(pn =>
|
||||
{
|
||||
pn.transformSubmodule.originalPosition += positionOffset;
|
||||
pn.transformSubmodule.Refresh();
|
||||
});
|
||||
|
||||
|
||||
|
||||
//TrackTimeSubmoduleMovable,时间偏移
|
||||
if (newTrack.trackTimeSubmodule is TrackTimeSubmoduleMovable movable)
|
||||
{
|
||||
movable.trackStartTime += timeOffset;
|
||||
movable.trackEndTime += timeOffset;
|
||||
}
|
||||
|
||||
//获取所有newTrack及之下(所有layer)的GameElement
|
||||
List<GameElement> allNewGameElements = newTrack.GetAllGameElementsFromThis();
|
||||
|
||||
List<TrackPercentPoint> percentPoints = allNewGameElements
|
||||
.FindAll(x => x is TrackPercentPoint).Cast<TrackPercentPoint>().ToList();
|
||||
//TrackPercentPoint,时间偏移
|
||||
List<TrackPercentPoint> percentPoints = allNewGameElements.FindAll(x => x is TrackPercentPoint).Cast<TrackPercentPoint>().ToList();
|
||||
percentPoints.ForEach(pp =>
|
||||
{
|
||||
pp.trackPercent.animations.ForEach(anim => anim.ApplyTimeOffset(timeOffset));
|
||||
});
|
||||
|
||||
|
||||
//Note,时间偏移
|
||||
List<NoteBase> notes = allNewGameElements.FindAll(x => x is NoteBase).Cast<NoteBase>().ToList();
|
||||
notes.ForEach(note =>
|
||||
{
|
||||
@@ -58,19 +61,97 @@ namespace Ichni.RhythmGame
|
||||
note.Refresh();
|
||||
});
|
||||
|
||||
//Animation,时间偏移(可以根据需要选择是否偏移)
|
||||
if (includeAnimations)
|
||||
{
|
||||
List<AnimationBase> animations = allNewGameElements
|
||||
.FindAll(x => x.GetType().IsSubclassOf(typeof(AnimationBase))).Cast<AnimationBase>().ToList();
|
||||
|
||||
animations.ForEach(anim =>
|
||||
{
|
||||
anim.ApplyTimeOffset(timeOffset);
|
||||
});
|
||||
.FindAll(x => x is AnimationBase).Cast<AnimationBase>().ToList();
|
||||
|
||||
animations.ForEach(anim => { anim.ApplyTimeOffset(timeOffset); });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cpd.pastedElementList.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Track整体移动
|
||||
/// </summary>
|
||||
/// <param name="positionOffset">坐标偏移量</param>
|
||||
private void WholeTrackMove(Vector3 positionOffset)
|
||||
{
|
||||
trackPathSubmodule.pathNodeList.ForEach(pn =>
|
||||
{
|
||||
pn.transformSubmodule.originalPosition += positionOffset;
|
||||
pn.transformSubmodule.Refresh();
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Track整体旋转
|
||||
/// </summary>
|
||||
/// <param name="angle">旋转角度,单位:度,方向:顺时针</param>
|
||||
/// <param name="center">旋转中心</param>
|
||||
/// <param name="axisDirection">旋转轴方向</param>
|
||||
private void WholeTrackSwirl(float angle, Vector3 center, Vector3 axisDirection)
|
||||
{
|
||||
if (axisDirection == Vector3.zero)
|
||||
{
|
||||
LogWindow.Log("Axis direction cannot be zero!", Color.red);
|
||||
return;
|
||||
}
|
||||
|
||||
trackPathSubmodule.pathNodeList.ForEach(pn =>
|
||||
{
|
||||
Vector3 originalPosition = pn.transformSubmodule.originalPosition;
|
||||
Vector3 rotatedPosition = Quaternion.AngleAxis(angle, axisDirection) * (originalPosition - center) + center;
|
||||
pn.transformSubmodule.originalPosition = rotatedPosition;
|
||||
pn.transformSubmodule.Refresh();
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Track整体翻转
|
||||
/// </summary>
|
||||
/// <param name="axisStart">翻转轴起点</param>
|
||||
/// <param name="axisEnd">翻转轴终点</param>
|
||||
private void WholeTrackFlip(Vector3 axisStart, Vector3 axisEnd)
|
||||
{
|
||||
trackPathSubmodule.pathNodeList.ForEach(pn =>
|
||||
{
|
||||
Vector3 originalPosition = pn.transformSubmodule.originalPosition;
|
||||
Vector3 flippedPosition = Vector3.Reflect(originalPosition - axisStart, axisEnd - axisStart) + axisStart;
|
||||
pn.transformSubmodule.originalPosition = flippedPosition;
|
||||
pn.transformSubmodule.Refresh();
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 仅开启起点和终点的PathNode的Sphere显示,中间的PathNode不显示
|
||||
/// </summary>
|
||||
private void SetOnlyStartEndPathNodeSphereEnabled()
|
||||
{
|
||||
if (trackPathSubmodule.pathNodeList.Count < 2)
|
||||
{
|
||||
LogWindow.Log("PathNode amount is less than 2!", Color.red);
|
||||
return;
|
||||
}
|
||||
|
||||
trackPathSubmodule.pathNodeList[0].SetPathNodeSphere(true);
|
||||
trackPathSubmodule.pathNodeList[^1].SetPathNodeSphere(true);
|
||||
for (int i = 1; i < trackPathSubmodule.pathNodeList.Count - 1; i++)
|
||||
{
|
||||
trackPathSubmodule.pathNodeList[i].SetPathNodeSphere(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量开启或关闭所有PathNode的Sphere显示
|
||||
/// </summary>
|
||||
/// <param name="isShowing"></param>
|
||||
private void SetAllPathNodeSphere(bool isShowing)
|
||||
{
|
||||
trackPathSubmodule.pathNodeList.ForEach(pn => pn.SetPathNodeSphere(isShowing));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user