1.新增了SplineAnchor的旋转跟随2.修复了IInteraction交互物体的乱序错误

This commit is contained in:
2025-10-08 21:47:18 +08:00
parent 0c11c917c4
commit 943c86d5f5
55 changed files with 329 additions and 555 deletions

1
.gitignore vendored
View File

@@ -9,6 +9,7 @@
/[Bb]uild/
/[Bb]uilds/
/[Ll]ogs/
/[Aa]ssetBundle/
/[Uu]ser[Ss]ettings/
*.log

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: fe9ab46835e7de443be9cbb34ebb4b72
guid: 2027eceef64b9bf45b03a8e69e672d9d
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -19,46 +19,96 @@ namespace Demo.Game
item.SetupDuration(new(VisibleDuration.x, VisibleDuration.y), GetTimelineItemColor());
}
[Serializable]
public enum DurationStats
{
BeforeBegin = 0,
BeforeEnd,
After,
Judgement
}
public const float IdentifiableJudgementTerminal = 0.16f;
[Content, SerializeField, Header("Cache")]
public float MyCacheUpdateTick = 0;
[Header(nameof(VisibleDuration))]
[Content, SerializeField] private Vector2 VisibleDuration;
public static float DefaultVisibleLength = IdentifiableJudgementTerminal * 15;
[Content, SerializeField] public UnityEvent VisibleDurationBeforeEvent = new(),
VisibleDurationBeginEvent = new(), VisibleDurationEndEvent = new();
[Content, SerializeField] private DurationStats VisibleDurationStats = default;
[Header(nameof(InteractiveDuration))]
[Content, SerializeField] private Vector2 InteractiveDuration;
public static float DefaultInteractiveLength = IdentifiableJudgementTerminal * 9;
[Content, SerializeField] public UnityEvent InteractiveDurationBeforeEvent = new(),
InteractiveDurationBeginEvent = new(), InteractiveDurationEndEvent = new();
[Content, SerializeField] private DurationStats InteractiveDurationStats = default;
[Header(nameof(InteractableScoreInterval))]
[Content, SerializeField] private Vector2 InteractableScoreInterval;
public static float DefaultInteractableScoreIntervalLength = IdentifiableJudgementTerminal * 6;
[Content, SerializeField] public UnityEvent InteractableScoreIntervalBeforeEvent = new(),
InteractableScoreIntervalBeginEvent = new(), InteractableScoreIntervalEndEvent = new();
[Content, SerializeField] private DurationStats InteractableScoreIntervalStats = default;
[Header(nameof(InteractableIntervalThatCanScoreBest))]
[Content, SerializeField] private Vector2 InteractableIntervalThatCanScoreBest;
public static float DefaultInteractableIntervalLengthThatCanScoreBest = IdentifiableJudgementTerminal * 3;
[Content, SerializeField] public UnityEvent InteractableIntervalThatCanScoreBestBeforeEvent = new(),
InteractableIntervalThatCanScoreBestBeginEvent = new(), InteractableIntervalThatCanScoreBestEndEvent = new();
[Content, SerializeField] private DurationStats InteractableIntervalThatCanScoreBestStats = default;
[Flags,Serializable]
public enum UpdatePhaseComponent
{
OutsideVisibleDuration = 0b00000000,
//
InsideVisibleDuration = 0b00000001,
InsideInteractiveDuration = 0b00000010,
InsideInteractableScoreInterval = 0b00000100,
InsideInteractableIntervalThatCanScoreBest = 0b00001000,
//
EnterVisibleDuration = 0b00010000,
EnterInteractiveDuration = 0b00100000,
EnterInteractableScoreInterval = 0b01000000,
EnterInteractableIntervalThatCanScoreBest = 0b10000000,
}
[Flags, Serializable]
public enum UpdatePhase
{
// 进入可视区间之前
BeforeVisibleDuration
= UpdatePhaseComponent.OutsideVisibleDuration,
// 进入不可判定但可视的3级判定区间
EnterVisibleDuration
= UpdatePhaseComponent.InsideVisibleDuration | UpdatePhaseComponent.EnterVisibleDuration,
// 进入可判定为失误的2级判定区间
EnterInteractiveDuration
= UpdatePhaseComponent.InsideInteractiveDuration | UpdatePhaseComponent.EnterInteractiveDuration | UpdatePhase.EnterVisibleDuration,
// 进入可得分的1级判定区间
EnterInteractableScoreInterval
= UpdatePhaseComponent.InsideInteractableScoreInterval | UpdatePhaseComponent.EnterInteractableScoreInterval | UpdatePhase.EnterInteractiveDuration,
// 进入可得满分的0级判定区间
EnterInteractableIntervalThatCanScoreBest
= UpdatePhaseComponent.InsideInteractableIntervalThatCanScoreBest| UpdatePhaseComponent.EnterInteractableIntervalThatCanScoreBest
| UpdatePhase.EnterInteractableScoreInterval,
// 退出0级判定区间
AfterInteractableIntervalThatCanScoreBest
= UpdatePhase.EnterInteractableIntervalThatCanScoreBest&(~UpdatePhaseComponent.InsideInteractableIntervalThatCanScoreBest),
// 退出1级判定区间
AfterInteractableScoreInterval
= UpdatePhase.AfterInteractableIntervalThatCanScoreBest & (~UpdatePhaseComponent.InsideInteractableScoreInterval),
// 退出2级判断区间
AfterInteractiveDuration
= UpdatePhase.AfterInteractableScoreInterval & (~UpdatePhaseComponent.InsideInteractiveDuration),
// 退出3级判断区间, 已不可视
AfterVisibleDuration
= UpdatePhase.AfterInteractiveDuration & (~UpdatePhaseComponent.InsideVisibleDuration)
}
public enum JudgementLevel
{
None = -2,//No Judge
Default = -1,
BestLevel = 0,//Level0
ScoreLevel = 1,//Level1
Bad = 128,
}
[Header("Judgement")]
[Content, SerializeField] private JudgementLevel MyJudgementLevel = JudgementLevel.None;
[Content, SerializeField] private UpdatePhase MyUpdatePhase = default;
[Content, SerializeField] private float BestJudgementTimePoint = -1;
[Content, SerializeField] public UnityEvent<JudgementLevel> JudgementEvent = new();
@@ -67,14 +117,14 @@ namespace Demo.Game
return BestJudgementTimePoint;
}
public bool IsInInteractiveDuration()
{
return InteractiveDurationStats == DurationStats.BeforeEnd;
}
public bool IsInInteractiveDuration(float time)
{
return time > InteractiveDuration.x && time < InteractiveDuration.y;
}
public bool IsInInteractiveDuration()
{
return IsInInteractiveDuration(MyCacheUpdateTick);
}
public const int JudgementLevelCount = 3;
@@ -105,92 +155,126 @@ namespace Demo.Game
{
if (level == JudgementLevel.None)
return;
// 进入已判定状态
MyJudgementLevel = level;
JudgementEvent.Invoke(level);
VisibleDurationStats = DurationStats.Judgement;
VisibleDurationEndEvent.Invoke();
InteractiveDurationStats = DurationStats.Judgement;
InteractableScoreIntervalStats = DurationStats.Judgement;
InteractableIntervalThatCanScoreBestStats = DurationStats.Judgement;
InteractiveDurationEndEvent.Invoke();
InteractableScoreIntervalEndEvent.Invoke();
InteractableIntervalThatCanScoreBestEndEvent.Invoke();
}
private static DurationStats UpdateDurationStats(float begin, UnityEvent beforeEvent, UnityEvent beginEvent, float end, UnityEvent endEvent,
float current, DurationStats currentStats)
{
if (currentStats == DurationStats.After)
return DurationStats.After;
else if (current < begin)
// 触发还未触发的退出事件
{
if (currentStats != DurationStats.BeforeBegin)
beforeEvent.Invoke();
return DurationStats.BeforeBegin;
if (((int)MyUpdatePhase & (int)UpdatePhaseComponent.EnterInteractableIntervalThatCanScoreBest) != 0)
{
InteractableIntervalThatCanScoreBestEndEvent.Invoke();
}
if (((int)MyUpdatePhase & (int)UpdatePhaseComponent.EnterInteractableScoreInterval) != 0)
{
InteractableScoreIntervalEndEvent.Invoke();
}
if (((int)MyUpdatePhase & (int)UpdatePhaseComponent.EnterInteractiveDuration) != 0)
{
InteractiveDurationEndEvent.Invoke();
}
if (((int)MyUpdatePhase & (int)UpdatePhaseComponent.EnterVisibleDuration) != 0)
{
VisibleDurationEndEvent.Invoke();
}
}
else if (current < end)
{
if (currentStats == DurationStats.BeforeBegin)
beginEvent.Invoke();
return DurationStats.BeforeEnd;
}
else if (currentStats == DurationStats.BeforeEnd)
{
endEvent.Invoke();
}
return DurationStats.After;
}
public enum JudgementLevel
{
None = -2,//No Judge
Default = -1,
BestLevel = 0,//Level0
ScoreLevel = 1,//Level1
Bad = 128,
}
public abstract JudgementLevel JudgementBehaviour(float timePoint);
#region Update Judgement Stats
private void DoUpdateJudgementStats(float currentTime)
{
// 可见区间
VisibleDurationStats = UpdateDurationStats(VisibleDuration.x, VisibleDurationBeforeEvent,
VisibleDurationBeginEvent, VisibleDuration.y, VisibleDurationEndEvent,
currentTime, VisibleDurationStats);
if (VisibleDurationStats != DurationStats.BeforeEnd)
return;
// 可判定区间
InteractiveDurationStats = UpdateDurationStats(InteractiveDuration.x, InteractiveDurationBeforeEvent,
InteractiveDurationBeginEvent, InteractiveDuration.y, InteractiveDurationEndEvent,
currentTime, InteractiveDurationStats);
if (InteractiveDurationStats != DurationStats.BeforeEnd)
return;
// 1级判定区间
InteractableScoreIntervalStats = UpdateDurationStats(InteractableScoreInterval.x, InteractableScoreIntervalBeforeEvent,
InteractableScoreIntervalBeginEvent, InteractableScoreInterval.y, InteractableScoreIntervalEndEvent,
currentTime, InteractableScoreIntervalStats);
if (InteractableScoreIntervalStats != DurationStats.BeforeEnd)
return;
// 0级判定区间
InteractableIntervalThatCanScoreBestStats = UpdateDurationStats(InteractableIntervalThatCanScoreBest.x, InteractableIntervalThatCanScoreBestBeforeEvent,
InteractableIntervalThatCanScoreBestBeginEvent, InteractableIntervalThatCanScoreBest.y, InteractableIntervalThatCanScoreBestEndEvent,
currentTime, InteractableIntervalThatCanScoreBestStats);
// 重置
if (MyCacheUpdateTick > currentTime)
{
MyUpdatePhase = UpdatePhase.BeforeVisibleDuration;
VisibleDurationBeforeEvent.Invoke();
InteractiveDurationBeforeEvent.Invoke();
InteractableScoreIntervalBeforeEvent.Invoke();
InteractableIntervalThatCanScoreBestBeforeEvent.Invoke();
MyJudgementLevel = JudgementLevel.None;
}
// 状态更新
{
// 在当前区间进行判断, 当前时间落入下一个区间时, 就进入下一个区间
switch (MyUpdatePhase)
{
case UpdatePhase.BeforeVisibleDuration:
if (currentTime > VisibleDuration.x)
{
MyUpdatePhase = UpdatePhase.EnterVisibleDuration;
VisibleDurationBeginEvent.Invoke();
}
break;
case UpdatePhase.EnterVisibleDuration:
if (currentTime > InteractiveDuration.x)
{
MyUpdatePhase = UpdatePhase.EnterInteractiveDuration;
InteractiveDurationBeginEvent.Invoke();
}
break;
case UpdatePhase.EnterInteractiveDuration:
if (currentTime > InteractableScoreInterval.x)
{
MyUpdatePhase = UpdatePhase.EnterInteractableScoreInterval;
InteractableScoreIntervalBeginEvent.Invoke();
}
break;
case UpdatePhase.EnterInteractableScoreInterval:
if (currentTime > InteractableIntervalThatCanScoreBest.x)
{
MyUpdatePhase = UpdatePhase.EnterInteractableIntervalThatCanScoreBest;
InteractableIntervalThatCanScoreBestBeginEvent.Invoke();
}
break;
// ---------------------------------------------------------
case UpdatePhase.EnterInteractableIntervalThatCanScoreBest:
if (currentTime > InteractableIntervalThatCanScoreBest.y)
{
MyUpdatePhase = UpdatePhase.AfterInteractableIntervalThatCanScoreBest;
InteractableIntervalThatCanScoreBestEndEvent.Invoke();
}
break;
case UpdatePhase.AfterInteractableIntervalThatCanScoreBest:
if (currentTime > InteractableScoreInterval.y)
{
MyUpdatePhase = UpdatePhase.AfterInteractableScoreInterval;
InteractableScoreIntervalEndEvent.Invoke();
}
break;
case UpdatePhase.AfterInteractableScoreInterval:
if (currentTime > InteractiveDuration.y)
{
MyUpdatePhase = UpdatePhase.AfterInteractiveDuration;
InteractiveDurationEndEvent.Invoke();
}
break;
case UpdatePhase.AfterInteractiveDuration:
if (currentTime > VisibleDuration.y)
{
MyUpdatePhase = UpdatePhase.AfterVisibleDuration;
VisibleDurationEndEvent.Invoke();
}
break;
default:
break;
}
}
// 记录
MyCacheUpdateTick = currentTime;
}
public override void ResetEnterGameStatus()
{
base.ResetEnterGameStatus();
DoUpdateJudgementStats(Mathf.NegativeInfinity);
}
#endregion
protected override void UpdateTicks(float currentTime, float deltaTime, TickType tickType)
{
base.UpdateTicks(currentTime, deltaTime, tickType);
// 预判断
if (VisibleDurationStats == DurationStats.Judgement)
return;
// 检定
InvokeJudgement(JudgementBehaviour(currentTime));
if (MyJudgementLevel == JudgementLevel.None)
{
InvokeJudgement(JudgementBehaviour(currentTime));
}
// 更新状态
DoUpdateJudgementStats(currentTime);
}

View File

@@ -33,6 +33,10 @@ namespace Demo.Game
public abstract Vector3 EvaluateClipToPosition(float time);
public abstract SplineSample EvaluateClipFrom(float time);
public abstract SplineSample EvaluateClipTo(float time);
public override IEnumerator LoadScript(string script)
{
yield return base.LoadScript(script);
@@ -188,5 +192,15 @@ namespace Demo.Game
{
return MySplineCore.MySplineComputer.EvaluatePosition(Evaluate(time).ClipTo);
}
public override SplineSample EvaluateClipFrom(float time)
{
return MySplineCore.MySplineComputer.Evaluate(Evaluate(time).ClipFrom);
}
public override SplineSample EvaluateClipTo(float time)
{
return MySplineCore.MySplineComputer.Evaluate(Evaluate(time).ClipTo);
}
}
}

View File

@@ -50,23 +50,52 @@ namespace Demo.Game
/// <summary>
/// 绑定到样条线渲染器上(必须已经加载),
/// 并设置位置为指定时间的时刻渲染器所生成的头部位置
/// 并设置跟随指定时间的时刻渲染器所生成的头部
/// </summary>
/// <param name="path">对象路径, 不存在时则立刻加载</param>
/// <param name="time">时刻</param>
/// <param name="isFollowPosition">是否跟随位置, 默认开启</param>
/// <param name="isFollowRotation">是否跟随旋转, 默认开启</param>
[ScriptableCall(@"
<summary>
绑定到样条线渲染器上(必须已经加载),
并设置位置为指定时间的时刻渲染器所生成的头部位置
并设置跟随指定时间的时刻渲染器所生成的头部
</summary>
<param name=""path"">对象路径, 不存在时则立刻加载</param>
<param name=""time"">时刻</param>
<param name=""isFollowPosition"">是否跟随位置, 默认开启</param>
<param name=""isFollowRotation"">是否跟随旋转, 默认开启</param>
")]
public void LoadSplineRenderer(string path, string time)
public void LoadSplineRenderer(string path, string time, string isFollowPosition = "true", string isFollowRotation = "true")
{
MySplineRenderer = this.LoadSplineRendererTool(path);
MySplineOffset = Parse(time);
Updater =()=> transform.position = MySplineRenderer.EvaluateClipToPosition(MySplineOffset);
bool bIsFollowPosition = ConvertValue<bool>(isFollowPosition);
bool bIsFollowRotation = ConvertValue<bool>(isFollowRotation);
if (bIsFollowPosition && bIsFollowRotation)
{
Updater = () =>
{
var result = MySplineRenderer.EvaluateClipTo(MySplineOffset);
transform.position = result.position;
transform.rotation = result.rotation;
};
}
else if (bIsFollowPosition)
{
Updater = () =>
{
transform.position = MySplineRenderer.EvaluateClipToPosition(MySplineOffset);
};
}
else
{
Updater = () =>
{
var result = MySplineRenderer.EvaluateClipTo(MySplineOffset);
transform.rotation = result.rotation;
};
}
}
}
}

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 8d4ee993e5ea3874994ad1fd06f9fe71
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,34 +1,34 @@
ManifestFileVersion: 0
CRC: 16709418
CRC: 2480162890
AssetBundleManifest:
AssetBundleInfos:
Info_0:
Name: epic_sky.skys
Dependencies: {}
Info_1:
Name: tube.materials
Dependencies: {}
Info_2:
Name: environment.ab
Dependencies: {}
Info_3:
Name: fantasy_sky.skys
Dependencies: {}
Info_4:
Name: line.materials
Dependencies: {}
Info_5:
Name: environment.materials
Dependencies: {}
Info_6:
Name: terrain1.ab
Dependencies: {}
Info_7:
Name: volumes.volume
Dependencies: {}
Info_8:
Name: city1.ab
Dependencies: {}
Info_9:
Name: particles.ab
Dependencies: {}
Info_1:
Name: environment.materials
Dependencies: {}
Info_2:
Name: tube.materials
Dependencies: {}
Info_3:
Name: city1.ab
Dependencies: {}
Info_4:
Name: environment.ab
Dependencies: {}
Info_5:
Name: line.materials
Dependencies: {}
Info_6:
Name: volumes.volume
Dependencies: {}
Info_7:
Name: terrain1.ab
Dependencies: {}
Info_8:
Name: fantasy_sky.skys
Dependencies: {}
Info_9:
Name: epic_sky.skys
Dependencies: {}

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 78eccd5a35d388f4ba91bc0ee2db7219
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 556aa8b548f6a564fa56ca93c2406130
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,15 +1,15 @@
ManifestFileVersion: 0
CRC: 1229762385
CRC: 1704390272
Hashes:
AssetFileHash:
serializedVersion: 2
Hash: b62d104498e2900e89811df3976966c9
Hash: 9f10f12512a676776f2fadeda5050727
TypeTreeHash:
serializedVersion: 2
Hash: 297415f9fc9b2188f70a45ce7f55acd2
IncrementalBuildHash:
serializedVersion: 2
Hash: b62d104498e2900e89811df3976966c9
Hash: 9f10f12512a676776f2fadeda5050727
HashAppended: 0
ClassTypes:
- Class: 1

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: e61d28399a7eb18489c029922e0b63b8
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 76516f9a6c87cf1489f75d6ceb4b2d3e
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,15 +1,15 @@
ManifestFileVersion: 0
CRC: 1986440130
CRC: 2981878786
Hashes:
AssetFileHash:
serializedVersion: 2
Hash: d2a071a163a7e89c60677df81241f305
Hash: fd56d9002443494192250c4c8edf70b1
TypeTreeHash:
serializedVersion: 2
Hash: d01f1d3b0a4645a295e4f7f8b996583d
IncrementalBuildHash:
serializedVersion: 2
Hash: d2a071a163a7e89c60677df81241f305
Hash: fd56d9002443494192250c4c8edf70b1
HashAppended: 0
ClassTypes:
- Class: 1

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 2247a70ad2bcbbd4b8983705d5a24f95
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 8d9a61d8fb3e9dc4ab16a1f402771155
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,15 +1,15 @@
ManifestFileVersion: 0
CRC: 1848077573
CRC: 3304778347
Hashes:
AssetFileHash:
serializedVersion: 2
Hash: c47868f971740d206acbe69412c7458c
Hash: 97353c7ae710e5e980be122aa6d96867
TypeTreeHash:
serializedVersion: 2
Hash: b30fce1a9ad74efb72be6c308c56e365
IncrementalBuildHash:
serializedVersion: 2
Hash: c47868f971740d206acbe69412c7458c
Hash: 97353c7ae710e5e980be122aa6d96867
HashAppended: 0
ClassTypes:
- Class: 21

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 8344ea84d9e98864fa0c3b5c07b2767a
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 1b76fda459e7dc0478b6ed775efb6836
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,15 +1,15 @@
ManifestFileVersion: 0
CRC: 1651137069
CRC: 3189568205
Hashes:
AssetFileHash:
serializedVersion: 2
Hash: 401017b2910ff48f708fbae377f7fa43
Hash: 389d6afb2d12fb2f74813fc03a2423c8
TypeTreeHash:
serializedVersion: 2
Hash: 88f4053155d2c8e8bdeb16c00867b658
IncrementalBuildHash:
serializedVersion: 2
Hash: 401017b2910ff48f708fbae377f7fa43
Hash: 389d6afb2d12fb2f74813fc03a2423c8
HashAppended: 0
ClassTypes:
- Class: 21
@@ -22,46 +22,43 @@ ClassTypes:
Script: {instanceID: 0}
SerializeReferenceClassIdentifiers: []
Assets:
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic_SunsetDark/Epic_SunsetDark
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic_SunsetDark/Epic_SunsetDark
Equirect.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic Sunset B/Epic Sunset
B 6Sided.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic Bright Sunset/Epic
Bright Sunset 6Sided.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic_SunsetGoldenLayers/Epic_SunsetGoldenLayers
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic Sunset B/Epic Sunset B 6Sided.mat
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic Bright Sunset/Epic Bright
Sunset 6Sided.mat
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic_SunsetGoldenLayers/Epic_SunsetGoldenLayers
Equirect.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic_BlueSunset/Epic_BlueSunset.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic Bright Sunset/Epic
Bright Sunset Cubmap.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic_CentreOfTheStorm/Epic_CentreOfTheStorm
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic_BlueSunset/Epic_BlueSunset.mat
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic Bright Sunset/Epic Bright
Sunset Cubmap.mat
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic_CentreOfTheStorm/Epic_CentreOfTheStorm
Equirect.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic_BrightIncomingStorm/Epic_BrightIncomingStorm.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic_NightStormMoonGlow/Epic_NightStormMoonGlow.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic_SunsetDark/Epic_SunsetDark.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic_Twilight/Epic_Twilight
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic_BrightIncomingStorm/Epic_BrightIncomingStorm.mat
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic_NightStormMoonGlow/Epic_NightStormMoonGlow.mat
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic_SunsetDark/Epic_SunsetDark.mat
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic_Twilight/Epic_Twilight Equirect.mat
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic_CentreOfTheStorm/Epic_CentreOfTheStorm.mat
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic_BlueSunset/Epic_BlueSunset
Equirect.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic_CentreOfTheStorm/Epic_CentreOfTheStorm.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic_BlueSunset/Epic_BlueSunset
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic_GloriousPink/Epic_GloriousPink
Equirect.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic_GloriousPink/Epic_GloriousPink
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic_BigCloudsSoft/Epic_BigCloudsSoft
Equirect.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic_BigCloudsSoft/Epic_BigCloudsSoft
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic_BrightIncomingStorm/Epic_BrightIncomingStorm
Equirect.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic_BrightIncomingStorm/Epic_BrightIncomingStorm
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic_BigCloudsSoft/Epic_BigCloudsSoft.mat
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic_TwilightStormGlow/Epic_TwilightStormGlow.mat
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic_TwilightStormGlow/Epic_TwilightStormGlow
Equirect.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic_BigCloudsSoft/Epic_BigCloudsSoft.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic_TwilightStormGlow/Epic_TwilightStormGlow.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic_TwilightStormGlow/Epic_TwilightStormGlow
Equirect.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic Night Turbulent Equirect/Epic
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic Night Turbulent Equirect/Epic
Night Turbulent Equirect.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic_NightStormMoonGlow/Epic_NightStormMoonGlow
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic_NightStormMoonGlow/Epic_NightStormMoonGlow
Equirect.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic Sunset B/Epic Sunset
B Equirect.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic_GloriousPink/Epic_GloriousPink.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic_Twilight/Epic_Twilight.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic_SunsetGoldenLayers/Epic_SunsetGoldenLayers.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Epic/Epic Night Turbulent Equirect/Epic
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic Sunset B/Epic Sunset B Equirect.mat
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic_GloriousPink/Epic_GloriousPink.mat
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic_Twilight/Epic_Twilight.mat
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic_SunsetGoldenLayers/Epic_SunsetGoldenLayers.mat
- Assets/Convention/Convention/[Assets]/Allsky/Epic/Epic Night Turbulent Equirect/Epic
Night Turbulent 6Sided.mat
Dependencies: []

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: d6564c5b2c37fc14a8d430434569f5af
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 42019f56569e435468c481650c892bf7
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,15 +1,15 @@
ManifestFileVersion: 0
CRC: 1635647003
CRC: 919822369
Hashes:
AssetFileHash:
serializedVersion: 2
Hash: 11c3a211a9e42eb8b862f35b673746c8
Hash: e9770f2a1d20e0e31a70fb454d08f38e
TypeTreeHash:
serializedVersion: 2
Hash: 88f4053155d2c8e8bdeb16c00867b658
IncrementalBuildHash:
serializedVersion: 2
Hash: 11c3a211a9e42eb8b862f35b673746c8
Hash: e9770f2a1d20e0e31a70fb454d08f38e
HashAppended: 0
ClassTypes:
- Class: 21
@@ -22,36 +22,36 @@ ClassTypes:
Script: {instanceID: 0}
SerializeReferenceClassIdentifiers: []
Assets:
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Fantasy/Fantasy Heavy/FantasySky_Heavy_1.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Fantasy/Fantasy Night 2/FantasySky_Night_2
- Assets/Convention/Convention/[Assets]/Allsky/Fantasy/Fantasy Heavy/FantasySky_Heavy_1.mat
- Assets/Convention/Convention/[Assets]/Allsky/Fantasy/Fantasy Night 2/FantasySky_Night_2
Equirect.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Fantasy/Fantasy Mid/AllSky_FantasySky_Mid
- Assets/Convention/Convention/[Assets]/Allsky/Fantasy/Fantasy Mid/AllSky_FantasySky_Mid
Equirect.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Fantasy/Fantasy High/FantasyClouds2_High.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Fantasy/Fantasy High/FantasyClouds2_High
- Assets/Convention/Convention/[Assets]/Allsky/Fantasy/Fantasy High/FantasyClouds2_High.mat
- Assets/Convention/Convention/[Assets]/Allsky/Fantasy/Fantasy High/FantasyClouds2_High
Equirect.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Fantasy/Fantasy Night/FantasySky_Night1.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Fantasy/Fantasy Low 2/FantasyClouds2_Low
- Assets/Convention/Convention/[Assets]/Allsky/Fantasy/Fantasy Night/FantasySky_Night1.mat
- Assets/Convention/Convention/[Assets]/Allsky/Fantasy/Fantasy Low 2/FantasyClouds2_Low
Equirect.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Fantasy/Fantasy Mid/AllSky_FantasySky_Mid.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Fantasy/Fantasy Low/FantasyClouds1_Low
- Assets/Convention/Convention/[Assets]/Allsky/Fantasy/Fantasy Mid/AllSky_FantasySky_Mid.mat
- Assets/Convention/Convention/[Assets]/Allsky/Fantasy/Fantasy Low/FantasyClouds1_Low
Equirect.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Fantasy/Fantasy Mid 2/AllSky_FantasySky_Mid_2.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Fantasy/Fantasy Night 2/FantasySky_Night_2.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Fantasy/Fantasy High 3/FantasyClouds_High3.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Fantasy/Fantasy Mid 2/AllSky_FantasySky_Mid_2
- Assets/Convention/Convention/[Assets]/Allsky/Fantasy/Fantasy Mid 2/AllSky_FantasySky_Mid_2.mat
- Assets/Convention/Convention/[Assets]/Allsky/Fantasy/Fantasy Night 2/FantasySky_Night_2.mat
- Assets/Convention/Convention/[Assets]/Allsky/Fantasy/Fantasy High 3/FantasyClouds_High3.mat
- Assets/Convention/Convention/[Assets]/Allsky/Fantasy/Fantasy Mid 2/AllSky_FantasySky_Mid_2
Equirect.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Fantasy/Fantasy Low/FantasyClouds1_Low.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Fantasy/Fantasy Low 2/FantasyClouds2_Low.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Fantasy/Fantasy Fire/SKY.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Fantasy/Fantasy Fire/FantasySky_Fire.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Fantasy/Fantasy Heavy/FantasySky_Heavy_1
- Assets/Convention/Convention/[Assets]/Allsky/Fantasy/Fantasy Low/FantasyClouds1_Low.mat
- Assets/Convention/Convention/[Assets]/Allsky/Fantasy/Fantasy Low 2/FantasyClouds2_Low.mat
- Assets/Convention/Convention/[Assets]/Allsky/Fantasy/Fantasy Fire/SKY.mat
- Assets/Convention/Convention/[Assets]/Allsky/Fantasy/Fantasy Fire/FantasySky_Fire.mat
- Assets/Convention/Convention/[Assets]/Allsky/Fantasy/Fantasy Heavy/FantasySky_Heavy_1
Equirect.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Fantasy/Fantasy High 3/FantasyClouds_High3
- Assets/Convention/Convention/[Assets]/Allsky/Fantasy/Fantasy High 3/FantasyClouds_High3
Equirect.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Fantasy/Fantasy Night/FantasySky_Night1
- Assets/Convention/Convention/[Assets]/Allsky/Fantasy/Fantasy Night/FantasySky_Night1
Equirect.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Fantasy/Fantasy Fire/FantasySky_Fire
- Assets/Convention/Convention/[Assets]/Allsky/Fantasy/Fantasy Fire/FantasySky_Fire
Equirect.mat
- Assets/Convention-Unity/Convention/[Assets]/Allsky/Fantasy/Fantasy Low 3/FantasyClouds1_Low3.mat
- Assets/Convention/Convention/[Assets]/Allsky/Fantasy/Fantasy Low 3/FantasyClouds1_Low3.mat
Dependencies: []

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: eb6b01e248856b246a920e0330475c4c
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: bec8c727cc0c7014689c2ebe2c1979d7
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,15 +1,15 @@
ManifestFileVersion: 0
CRC: 2681988468
CRC: 2796074816
Hashes:
AssetFileHash:
serializedVersion: 2
Hash: 3ecc189d26fb354ffbaf502999149fd3
Hash: 98cf87dd2f61c8bbb902cb2268e2f520
TypeTreeHash:
serializedVersion: 2
Hash: b30fce1a9ad74efb72be6c308c56e365
IncrementalBuildHash:
serializedVersion: 2
Hash: 3ecc189d26fb354ffbaf502999149fd3
Hash: 98cf87dd2f61c8bbb902cb2268e2f520
HashAppended: 0
ClassTypes:
- Class: 21

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: aaa7e9f38622a424784703788b29bd43
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 7c0bca430343ff44bbbaf68e50822689
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,15 +1,15 @@
ManifestFileVersion: 0
CRC: 4176033966
CRC: 3429927697
Hashes:
AssetFileHash:
serializedVersion: 2
Hash: 85302ae4b99c08ef56b45989b002914d
Hash: 7493851482b84a37ca6f56d32485c87c
TypeTreeHash:
serializedVersion: 2
Hash: 2852dc94952d37e840a290ce2382924d
IncrementalBuildHash:
serializedVersion: 2
Hash: 85302ae4b99c08ef56b45989b002914d
Hash: 7493851482b84a37ca6f56d32485c87c
HashAppended: 0
ClassTypes:
- Class: 1

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: a72b4d1b8399e674b86f298c9b1c6450
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 6d9e4e6a1383f7640ad04104996e6955
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,15 +1,15 @@
ManifestFileVersion: 0
CRC: 3418481720
CRC: 4023355229
Hashes:
AssetFileHash:
serializedVersion: 2
Hash: 6485a6d3726ce319bd6595726bae87b1
Hash: 63d343153f80737419c2adf5d24bd0d1
TypeTreeHash:
serializedVersion: 2
Hash: 67f184963c9c7d3b2aa08647f3df456a
IncrementalBuildHash:
serializedVersion: 2
Hash: 6485a6d3726ce319bd6595726bae87b1
Hash: 63d343153f80737419c2adf5d24bd0d1
HashAppended: 0
ClassTypes:
- Class: 1

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 51b0f003f8ed3e14b9cd5c9aa5f83982
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 2e9ae657c2fecbe46ba1bddcc6b8d962
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,15 +1,15 @@
ManifestFileVersion: 0
CRC: 3416097008
CRC: 1127867277
Hashes:
AssetFileHash:
serializedVersion: 2
Hash: 2de844c4ae94e8a1c44fc2d3b880a95d
Hash: 537d05b66bcdadae7a68764cb03cb51f
TypeTreeHash:
serializedVersion: 2
Hash: b30fce1a9ad74efb72be6c308c56e365
IncrementalBuildHash:
serializedVersion: 2
Hash: 2de844c4ae94e8a1c44fc2d3b880a95d
Hash: 537d05b66bcdadae7a68764cb03cb51f
HashAppended: 0
ClassTypes:
- Class: 21

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 22c7eca8877209f49a4d563ed56f4932
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: a70a082d8adcb2d4c8929972f7e93c9f
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,15 +1,15 @@
ManifestFileVersion: 0
CRC: 2235067353
CRC: 3531075741
Hashes:
AssetFileHash:
serializedVersion: 2
Hash: f3e400c927edaab4f7424ad0db8025bc
Hash: 2cbc0a1cd45072ffd537d52167e7b871
TypeTreeHash:
serializedVersion: 2
Hash: a458fd562eed9d175109a44ceae79df1
IncrementalBuildHash:
serializedVersion: 2
Hash: f3e400c927edaab4f7424ad0db8025bc
Hash: 2cbc0a1cd45072ffd537d52167e7b871
HashAppended: 0
ClassTypes:
- Class: 114

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 1f862115ef5569445a2538b3e4a0231e
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: c909a7be1e26bce42a4583710b75bfc9
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 3b03a8c502fbaaa4fa5bf62ca8b741e1
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 945ffb49d0714e24b9ff34b4c39f800e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,166 +0,0 @@
**教程**
---
# 项目
项目的位置全部位于Unity持久化文件夹的Project文件夹内, 如C:\Users\ASUS\AppData\LocalLow\LiuBai\Murmur-Resonance-Editor\Projects
## 打开
通过Tools中的Open打开已存在的项目在打开之前总是会先关闭当前打开的项目
## 新建
通过Tools中的Create新建项目在新建之前总是会先关闭当前打开的项目
## 配置
项目文件夹内的config.json文件即为配置文件其中包含property与find两个项目
property中包含的内容是已配置的内容将会被读取并使用
find中包含的内容是被尝试读取但不存在的内容值为读取时设定的默认值
一些重要的键值如song需要在新建项目后配置
**重要:在运行时可能会触发配置文件的保存,被保存的配置与你希望的可能并不一致,所以不要尝试在项目运行时编辑该项目的配置文件**
# 初次运行
在Unity持久化文件夹中会生成Helper文件夹, 包含可调用函数的注释
下载需要的AssetBundle到StreamingAssets/AssetBundle
## AssetBundle
内置了主题包,包括但不限于环境物体与材质
## Helper
其中包含了物体可使用的函数以宏的形式展现可以删除Helper文件夹来重新生成最新的Helper内容
## CMake辅助编辑
脚本风格默认采用c++风格因此利用CMake与.h文件关联应用可以快速编写物体脚本
如在Unity持久化文件夹, 添加以下文本到CMakeLists.txt, 使用vs打开即可
```
include_directories(Helper)
```
# 快捷键
## 音频播放控制快捷键
几乎所有快捷键都需要按住LeftCtrl下文中无特殊说明将会忽略该按键
组合快捷键中只有最后一个键被按下时才会触发前置的键只需要处于按下的状态包括隐藏的LeftCtrl
### 基础播放控制
- **P**
- 功能:播放/暂停音频
- 说明:如果音频正在播放则暂停,如果已暂停则开始播放
- **S**
- 功能:停止音频播放
- 说明:停止当前播放的音频并重置播放位置
### 时间轴控制
- **鼠标滚轮**
- 功能:滚动控制播放时间
- 说明:向上滚动前进时间,向下滚动后退时间,单位为一秒
- 特性:滚轮操作时会自动暂停播放
## 项目管理快捷键
### 项目刷新与重载
- **R**
- 功能:刷新当前项目
- 说明:重新加载当前打开的项目,用于应用代码更改
- 注意:只有在项目已加载且未处于刷新状态时才能使用
### 项目关闭
- **Tab**
- 功能:关闭当前项目
- 说明:关闭当前打开的项目并返回项目选择界面
## 相机控制快捷键
### 相机重置
- **LeftShift**
- 功能:重置相机旋转为水平状态
- 说明:将场景相机的旋转重置为水平状态
- **LeftShift + Z**
- 功能:完全重置相机
- 说明:将场景相机的位置和旋转都重置为初始状态
## 界面提示
编辑器界面中的某些按钮会显示对应的快捷键提示,例如:
- "Play(P)" - 播放按钮,对应 P 键
- "Pause(P)" - 暂停按钮,对应 P 键
- "Stop(S)" - 停止按钮,对应 S 键
- "Reset Rotation(LeftShift)" - 重置旋转对应左Shift键
- "Reset(LeftShift+Z)" - 完全重置对应左Shift+Z组合键
这些提示可以帮助您快速记忆和使用相应的快捷键功能。
# 物体脚本
项目中物体的行为被物体脚本(Script)控制,编辑脚本会更改其行为,
在项目运行时编辑,并通过更新热重载项目查看实时效果,
**重要:脚本的执行总是顺序的,先后顺序会影响实际行为**
不同的物体拥有的脚本函数请在Helper中查看
## CPP风格Helper
每个文件包含可调用的类成员函数include的头文件是父类可通过其查看其他可调用的父类成员函数
## ScriptableObject
所有类都从ScriptableObject派生了解其中的关键函数
之后便可以编写灵活的脚本以实现行为
```cpp
// 在任一ScriptableObject中设置Var变量为0,
// 此后在该脚本以及该处之后加载的子脚本都会含有Var=0的上下文
SetContext("Var", 0);
// 如在DDT中, 使用花括号包裹的正整型三元组表示时间点,
// 形式为: {该小节划分的节拍数, 小节数, 位于该小节的节拍数}
// 如在BPM=60的情况下, 下例将会被翻译为(4+1/8)*1s=4.125s
Add({8,4,1});
```
通过脚本实现模板对象
例如在
- root.cpp
- root
- TemplateLine.h(加载类型为SplineCore的脚本对象)
- TemplateLine
- ...(TemplateLine的子脚本)
- A-Anchor.h(加载类型为Anchor的脚本对象)
- B-Anchor.h(加载类型为Anchor的脚本对象)
```cpp
// A-Anchor.h
// 将自身在父脚本对象的坐标系中设置为x=-2的偏移
SetLocalPosition(-2,0,0);
// 设置上下文变量
...
// 加载
LoadSubScript(SplineCore, "TemplateLine.h")
```
```cpp
// B-Anchor.h
// 将自身在父脚本对象的坐标系中设置为x=2的偏移
SetLocalPosition(2,0,0);
// 设置上下文变量
...
// 也加载
LoadSubScript(SplineCore, "TemplateLine.h")
```
自此实现了以脚本TemplateLine.h为根的预制体

View File

@@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 8c9b1c22bdbff2d478a2b15141e9b943
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: