Merge branch 'feature/海浪动画调整' into 'develop'

Feature/海浪动画调整

See merge request aibis-dream/aibis-dream!710
This commit is contained in:
2026-05-26 07:51:08 +00:00
35 changed files with 1449 additions and 677 deletions
+9 -83
View File
@@ -143,15 +143,17 @@ MonoBehaviour:
text: {fileID: 6343862642438606438}
button: {fileID: 3624986506224747444}
arrow: {fileID: 2138736795402918014}
selectedSign: {fileID: 994585125679848239}
box: {fileID: 6027689100706873528}
colorBlock:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.4, g: 0.4, b: 0.4, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_NormalColor: {r: 0, g: 0, b: 0, a: 1}
m_HighlightedColor: {r: 0.11764706, g: 0.11764706, b: 0.11764706, a: 1}
m_PressedColor: {r: 0.039215688, g: 0.039215688, b: 0.039215688, a: 1}
m_SelectedColor: {r: 0, g: 0, b: 0, a: 1}
m_DisabledColor: {r: 0.039215688, g: 0.039215688, b: 0.039215688, a: 0.49019608}
m_ColorMultiplier: 0
m_FadeDuration: 0
exploredNormalColor: {r: 0.43137255, g: 0.43137255, b: 0.43137255, a: 1}
normalColor: {r: 1, g: 1, b: 1, a: 1}
--- !u!114 &9163890225660695161
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -192,81 +194,6 @@ MonoBehaviour:
m_EditorClassIdentifier:
m_HorizontalFit: 2
m_VerticalFit: 0
--- !u!1 &4507535836329041407
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2100970350256881776}
- component: {fileID: 2572548913308526007}
- component: {fileID: 994585125679848239}
m_Layer: 5
m_Name: SelectSign
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!224 &2100970350256881776
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4507535836329041407}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 8909982681958940574}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 0.5}
m_AnchorMax: {x: 1, y: 0.5}
m_AnchoredPosition: {x: 8, y: 0}
m_SizeDelta: {x: 16, y: 16}
m_Pivot: {x: 0, y: 0.5}
--- !u!222 &2572548913308526007
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4507535836329041407}
m_CullTransparentMesh: 1
--- !u!114 &994585125679848239
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4507535836329041407}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 21300000, guid: 566787ba43e2a5646bdabb62bd6845f2, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &4951730373337149047
GameObject:
m_ObjectHideFlags: 0
@@ -372,8 +299,7 @@ RectTransform:
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 2100970350256881776}
m_Children: []
m_Father: {fileID: 1274478104802664553}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
+4
View File
@@ -14667,6 +14667,10 @@ PrefabInstance:
propertyPath: m_Name
value: OnelineBox
objectReference: {fileID: 0}
- target: {fileID: 8352794458094198668, guid: 60f4427b2070be04f90c1486bb86062c, type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using AibisDream.Kit;
using UnityEngine;
using UnityEngine.Events;
@@ -11,6 +12,8 @@ namespace AibisDream
{
private DialogueRunner _dialogueRunner;
public DialogueRunner DialogueRunner => _dialogueRunner;
[SerializeField] private LineAdvanceInput lineAdvanceInput;
private void Start()
@@ -132,6 +135,37 @@ namespace AibisDream
#endregion
/// <summary>
/// 返回当前正在执行的节点名与节点 tags;尚未启动 / 异常时返回 (null, 空数组)。
/// </summary>
public (string nodeName, IReadOnlyList<string> tags) GetCurrentNodeContext()
{
if (_dialogueRunner == null)
{
return (null, Array.Empty<string>());
}
var dialogue = _dialogueRunner.Dialogue;
if (dialogue == null)
{
return (null, Array.Empty<string>());
}
var nodeName = dialogue.CurrentNode;
if (string.IsNullOrEmpty(nodeName))
{
return (null, Array.Empty<string>());
}
var tagsHeader = dialogue.GetHeaderValue(nodeName, "tags");
if (string.IsNullOrWhiteSpace(tagsHeader))
{
return (nodeName, Array.Empty<string>());
}
return (nodeName, tagsHeader.Split(Array.Empty<char>(), StringSplitOptions.RemoveEmptyEntries));
}
#region
public BindProperty<AdvanceMode> advanceMode = new(new AdvanceMode());
@@ -0,0 +1,236 @@
using System;
using System.Collections.Generic;
using System.Linq;
using AibisDream.Framework;
namespace AibisDream
{
/// <summary>
/// 选项已探索状态追踪(内存态,由 OptionView 私有持有)。
/// </summary>
public class OptionExploreTracker
{
private sealed class OptionRecord
{
public bool explored;
public string[] deps = Array.Empty<string>();
}
private static readonly string[] EmptyDeps = Array.Empty<string>();
private readonly Dictionary<string, OptionRecord> _records = new();
private readonly Dictionary<string, HashSet<string>> _varToOptions = new();
private string _currentExecutingLineId;
public void Bind()
{
EnumEventSystem.Global.Register<StorageEvent, VariableItem>(StorageEvent.VariableSet, OnVariableSet);
EnumEventSystem.Global.Register<DialogEventEnum, LineInfo>(DialogEventEnum.OptionSelected, OnOptionSelected);
EnumEventSystem.Global.Register(DialogEventEnum.OptionShow, OnOptionShow);
EnumEventSystem.Global.Register(GameLoopEnum.GameStart, Clear);
EnumEventSystem.Global.Register(GameLoopEnum.GameQuit, Clear);
EnumEventSystem.Global.Register(EventEnum.NextYarn, Clear);
}
public void Unbind()
{
EnumEventSystem.Global.UnRegister<StorageEvent, VariableItem>(StorageEvent.VariableSet, OnVariableSet);
EnumEventSystem.Global.UnRegister<DialogEventEnum, LineInfo>(DialogEventEnum.OptionSelected, OnOptionSelected);
EnumEventSystem.Global.UnRegister(DialogEventEnum.OptionShow, OnOptionShow);
EnumEventSystem.Global.UnRegister(GameLoopEnum.GameStart, Clear);
EnumEventSystem.Global.UnRegister(GameLoopEnum.GameQuit, Clear);
EnumEventSystem.Global.UnRegister(EventEnum.NextYarn, Clear);
}
public (bool isTrackable, bool isExplored) Evaluate(
string lineId,
IReadOnlyList<string> metadata,
string currentNodeName,
IReadOnlyList<string> nodeTags)
{
if (string.IsNullOrEmpty(lineId))
{
return (false, false);
}
ParseMetadata(metadata, out var forceTrack, out var forceNoTrack, out var deps);
var isTrackable = ResolveTrackable(forceTrack, forceNoTrack, deps, nodeTags);
if (!isTrackable)
{
return (false, false);
}
if (!_records.TryGetValue(lineId, out var rec))
{
rec = new OptionRecord { explored = false, deps = deps };
_records[lineId] = rec;
RegisterVarIndex(lineId, deps);
}
else
{
UpdateDeps(lineId, rec, deps);
}
return (true, rec.explored);
}
private void OnOptionSelected(LineInfo info)
{
if (!info.isOption || string.IsNullOrEmpty(info.lineId))
{
return;
}
if (_records.TryGetValue(info.lineId, out var rec))
{
rec.explored = true;
_currentExecutingLineId = info.lineId;
}
}
private void OnVariableSet(VariableItem item)
{
if (item.variableName == null || !_varToOptions.TryGetValue(item.variableName, out var lineIds))
{
return;
}
foreach (var lineId in lineIds)
{
if (lineId == _currentExecutingLineId)
{
continue;
}
if (_records.TryGetValue(lineId, out var rec))
{
rec.explored = false;
}
}
}
private void OnOptionShow()
{
_currentExecutingLineId = null;
}
private void Clear()
{
_records.Clear();
_varToOptions.Clear();
_currentExecutingLineId = null;
}
private static void ParseMetadata(
IReadOnlyList<string> metadata,
out bool forceTrack,
out bool forceNoTrack,
out string[] deps)
{
forceTrack = false;
forceNoTrack = false;
deps = EmptyDeps;
if (metadata == null)
{
return;
}
for (var i = 0; i < metadata.Count; i++)
{
var tag = metadata[i];
if (string.IsNullOrEmpty(tag))
{
continue;
}
if (tag == "track")
{
forceTrack = true;
}
else if (tag == "notrack")
{
forceNoTrack = true;
}
else if (tag.StartsWith("deps:", StringComparison.Ordinal))
{
deps = tag.Substring(5).Split(',')
.Select(v => v.Trim())
.Where(v => v.Length > 0)
.Select(NormalizeVariableName)
.ToArray();
}
}
}
private static string NormalizeVariableName(string name)
{
return name.StartsWith("$") ? name : $"${name}";
}
private static bool ResolveTrackable(
bool forceTrack,
bool forceNoTrack,
string[] deps,
IReadOnlyList<string> nodeTags)
{
if (forceNoTrack)
{
return false;
}
if (forceTrack || deps.Length > 0)
{
return true;
}
if (nodeTags == null)
{
return false;
}
for (var i = 0; i < nodeTags.Count; i++)
{
if (nodeTags[i] == "hub" || nodeTags[i] == "detour")
{
return true;
}
}
return false;
}
private void RegisterVarIndex(string lineId, string[] deps)
{
foreach (var dep in deps)
{
if (!_varToOptions.TryGetValue(dep, out var lineIds))
{
lineIds = new HashSet<string>();
_varToOptions[dep] = lineIds;
}
lineIds.Add(lineId);
}
}
private void UpdateDeps(string lineId, OptionRecord rec, string[] deps)
{
if (ReferenceEquals(rec.deps, deps) || (rec.deps.Length == deps.Length && rec.deps.SequenceEqual(deps)))
{
return;
}
foreach (var oldDep in rec.deps)
{
if (_varToOptions.TryGetValue(oldDep, out var oldSet))
{
oldSet.Remove(lineId);
}
}
rec.deps = deps;
RegisterVarIndex(lineId, deps);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a7c3e91f4b2d48c6a1f9056d8e3b7c42
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+27 -45
View File
@@ -1,5 +1,6 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using AibisDream.Framework;
@@ -10,12 +11,25 @@ namespace AibisDream
{
public class OptionView : DialoguePresenterBase
{
private HashSet<string> _selectedIds = new();
[SerializeField] private DefaultOptions defaultOptions;
[SerializeField] private CenterOptions centerOptions;
[SerializeField] private OnelineOptions onelineOptions;
[SerializeField] private DialogViewType defaultViewType = DialogViewType.StandardBubble;
private OptionExploreTracker? _tracker;
private void Awake()
{
_tracker = new OptionExploreTracker();
_tracker.Bind();
}
private void OnDestroy()
{
_tracker?.Unbind();
_tracker = null;
}
public override YarnTask OnDialogueStartedAsync()
{
return YarnTask.CompletedTask;
@@ -41,10 +55,17 @@ namespace AibisDream
{
EnumEventSystem.Global.Send(DialogEventEnum.OptionShow);
var optionSelectedSource = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
var options = DialogOption.GeneOptions(dialogueOptions, optionId =>
{
optionSelectedSource.TrySetResult(optionId);
}, _selectedIds);
var (nodeName, tags) = DialogController.Instance != null
? DialogController.Instance.GetCurrentNodeContext()
: (null, (IReadOnlyList<string>)Array.Empty<string>());
var options = DialogOption.GeneOptions(
dialogueOptions,
_tracker,
nodeName,
tags,
optionId => optionSelectedSource.TrySetResult(optionId));
var viewType = GetCurrentViewType(options);
@@ -101,45 +122,6 @@ namespace AibisDream
return optionViewType;
}
// --------------------------- 生命周期方法 ---------------------------
private void OnEnable()
{
RegisterEvent();
}
private void OnDisable()
{
UnRegisterEvent();
}
private void RegisterEvent()
{
// 进入游戏或者进入下一个Yarn的时候清空
EnumEventSystem.Global.Register(GameLoopEnum.GameStart, ClearSelectedIds);
EnumEventSystem.Global.Register(EventEnum.NextYarn, ClearSelectedIds);
// 选择选项的时候记录
EnumEventSystem.Global.Register<DialogEventEnum, LineInfo>(DialogEventEnum.OptionSelected, RecordSelectedId);
}
private void UnRegisterEvent()
{
EnumEventSystem.Global.UnRegister(GameLoopEnum.GameStart, ClearSelectedIds);
EnumEventSystem.Global.UnRegister(EventEnum.NextYarn, ClearSelectedIds);
EnumEventSystem.Global.UnRegister<DialogEventEnum, LineInfo>(DialogEventEnum.OptionSelected, RecordSelectedId);
}
private void ClearSelectedIds()
{
_selectedIds.Clear();
}
private void RecordSelectedId(LineInfo lineInfo)
{
_selectedIds.Add(lineInfo.lineId);
}
public void HideDialog()
{
defaultOptions.HideOptions();
@@ -147,4 +129,4 @@ namespace AibisDream
centerOptions.HideOptions();
}
}
}
}
@@ -1,6 +1,6 @@
using System;
using System.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using AibisDream.Framework;
using AibisDream.Kit;
using AibisDream.Utility;
@@ -15,7 +15,9 @@ namespace AibisDream
private DialogueOption _option;
public bool IsAvailable => _option.IsAvailable;
public bool IsSelected { get; private set; }
public bool IsTrackable { get; private set; }
public bool IsExplored { get; private set; }
public string LineId => _option.TextID;
public string Line => _option.Line.TextWithoutCharacterName.Text;
public CharacterVo Character => _option.Line.GetCharacterVo();
@@ -46,28 +48,34 @@ namespace AibisDream
};
}
public static DialogOption[] GeneOptions(DialogueOption[] dialogueOptions, Action<int> onOptionSelected)
public static DialogOption[] GeneOptions(
DialogueOption[] dialogueOptions,
OptionExploreTracker tracker,
string nodeName,
IReadOnlyList<string> nodeTags,
Action<int> onOptionSelected)
{
return dialogueOptions
.Select(item => new DialogOption { _option = item, _onOptionSelected = onOptionSelected }).ToArray();
}
var tags = nodeTags ?? Array.Empty<string>();
public static DialogOption[] GeneOptions(DialogueOption[] dialogueOptions, Action<int> onOptionSelected, HashSet<string> selectedIds)
{
var options = new List<DialogOption>();
foreach (var item in dialogueOptions)
return dialogueOptions.Select(item =>
{
var option = new DialogOption { _option = item, _onOptionSelected = onOptionSelected };
if (selectedIds.Contains(option._option.TextID))
var lineId = item.TextID;
var metadata = item.Line.Metadata ?? Array.Empty<string>();
var (isTrackable, isExplored) = tracker != null
? tracker.Evaluate(lineId, metadata, nodeName, tags)
: (false, false);
return new DialogOption
{
option.IsSelected = true;
}
options.Add(option);
}
return options.ToArray();
_option = item,
_onOptionSelected = onOptionSelected,
IsTrackable = isTrackable,
IsExplored = isExplored
};
}).ToArray();
}
}
[Serializable]
public struct TextParam
{
@@ -75,4 +83,4 @@ namespace AibisDream
public float lineSpace;
public int maxCharNum;
}
}
}
@@ -11,11 +11,15 @@ namespace AibisDream
[SerializeField] private TMP_Text text;
[SerializeField] private BaseButton button;
[SerializeField] private Image arrow;
[SerializeField] private Image selectedSign;
[SerializeField] private Image box;
[Header("颜色配置")]
[SerializeField] private ColorBlock colorBlock;
[Header("文字颜色")]
[SerializeField] private Color exploredNormalColor = new(0.45f, 0.45f, 0.45f, 1f);
[SerializeField] private Color normalColor = Color.white;
private DialogOption _option;
public void Init()
@@ -29,20 +33,20 @@ namespace AibisDream
if (!option.IsAvailable)
{
// 不可用,设置为不可选
button.interactable = false;
text.SetText($"<s>{option.Line}</s>");
return;
}
selectedSign.gameObject.SetActive(option.IsSelected);
button.interactable = true;
text.SetText(option.Line);
button.onClick.AddListener(() =>
{
option.Select();
hide?.Invoke();
});
OnStateTransition(SelectionType.Normal, true);
}
private void OnStateTransition(SelectionType state, bool instant)
@@ -50,33 +54,46 @@ namespace AibisDream
switch (state)
{
case SelectionType.Normal:
arrow.SetAlpha(0f);
SetColor(colorBlock.normalColor);
// arrow.SetAlpha(0f);
SetBoxColor(colorBlock.normalColor);
break;
case SelectionType.Highlighted:
arrow.SetAlpha(1f);
SetColor(colorBlock.highlightedColor);
// arrow.SetAlpha(1f);
SetBoxColor(colorBlock.highlightedColor);
break;
case SelectionType.Pressed:
arrow.SetAlpha(1f);
SetColor(colorBlock.pressedColor);
// arrow.SetAlpha(1f);
SetBoxColor(colorBlock.pressedColor);
break;
case SelectionType.Selected:
arrow.SetAlpha(1f);
SetColor(colorBlock.selectedColor);
// arrow.SetAlpha(1f);
SetBoxColor(colorBlock.selectedColor);
break;
case SelectionType.Disabled:
arrow.SetAlpha(0f);
SetColor(colorBlock.disabledColor);
// arrow.SetAlpha(0f);
SetBoxColor(colorBlock.disabledColor);
break;
}
SetTextColor(GetNormalColor());
}
private void SetColor(Color color)
private void SetBoxColor(Color color)
{
box.color = color;
}
private Color GetNormalColor()
{
return _option.IsTrackable && _option.IsExplored
? exploredNormalColor
: normalColor;
}
private void SetTextColor(Color color)
{
arrow.color = color;
text.color = color;
selectedSign.color = color;
}
}
}
}
+30 -2
View File
@@ -17,9 +17,19 @@ namespace AibisDream.UI
[SerializeField] private float holdTime = 1f;
[SerializeField] private float inoutTime = 0.5f;
private int _runVersion;
public void ForceStop()
{
_runVersion++;
ResetVisuals();
}
public IEnumerator TurnTimeTo(string originState, string targetState)
{
var version = ++_runVersion;
var originImage = originAnimator.GetComponent<Image>();
// 设置起始状态
targetAnimator.gameObject.SetActive(true);
originAnimator.gameObject.SetActive(true);
@@ -34,17 +44,35 @@ namespace AibisDream.UI
originImage.color = Color.white;
// 淡入
yield return canvasGroup.DOFade(1, inoutTime).WaitForCompletion();;
yield return canvasGroup.DOFade(1, inoutTime).WaitForCompletion();
if (version != _runVersion) yield break;
// 等待静止时间
yield return new WaitForSeconds(holdTime);
if (version != _runVersion) yield break;
// 淡出起始状态
yield return originAnimator.GetComponent<Image>().DOFade(0, fadeTime).WaitForCompletion();
yield return originImage.DOFade(0, fadeTime).WaitForCompletion();
if (version != _runVersion) yield break;
// 等待静止时间
yield return new WaitForSeconds(holdTime);
if (version != _runVersion) yield break;
// 淡出
yield return canvasGroup.DOFade(0, inoutTime).WaitForCompletion();
if (version != _runVersion) yield break;
ResetVisuals();
}
private void ResetVisuals()
{
canvasGroup.DOKill();
originAnimator.GetComponent<Image>().DOKill();
canvasGroup.alpha = 0;
originAnimator.GetComponent<Image>().color = Color.white;
targetAnimator.gameObject.SetActive(false);
originAnimator.gameObject.SetActive(false);
+16 -1
View File
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections;
using AibisDream.Framework;
using AibisDream.Kit;
@@ -35,6 +35,7 @@ namespace AibisDream.UI
private ModalWindow _warningWindow;
private SignBoard _signBoard;
private TimeTurner _timeTurner;
private int _timeFlowsVersion;
#endregion
@@ -211,18 +212,32 @@ namespace AibisDream.UI
private void HideAll()
{
_timeFlowsVersion++;
_fadeImage.DOKill();
_fadeImage.color = Color.clear;
_fadeImage.gameObject.SetActive(false);
_fullScreenImage.FadeOut(0.1f);
_showObjImage.FadeOut(0.1f);
_showObjPanel.SetActive(false);
_timeTurner.ForceStop();
}
// ------------------------------- 时间流转 -------------------------------
public IEnumerator TimeFlowsOn(string originState, string targetState)
{
var version = ++_timeFlowsVersion;
// 黑屏淡入
yield return _fadeImage.FadeInAsync(0.5f);
if (version != _timeFlowsVersion) yield break;
// 时间流转
yield return _timeTurner.TurnTimeTo(originState, targetState);
if (version != _timeFlowsVersion) yield break;
// 黑屏淡出
yield return _fadeImage.FadeOutAsync(0.5f);
}
@@ -1,5 +1,5 @@
{
"projectFileVersion": 2,
"projectFileVersion": 3,
"sourceFiles": [
"**/*.yarn"
],
@@ -1,5 +1,5 @@
{
"projectFileVersion": 2,
"projectFileVersion": 3,
"sourceFiles": [
"*.yarn"
],
@@ -1,5 +1,5 @@
{
"projectFileVersion": 2,
"projectFileVersion": 3,
"sourceFiles": [
"**/*.yarn"
],
+434 -384
View File
@@ -1,31 +1,12 @@
title: Start
tags:
position: 250,-2611
---
<<declare $started=false>>
<<declare $slept=false>>
<<declare $redSkySeen=false>>
<<declare $ppStage=0>>
<<declare $stStage=1>>
<<declare $pphChecked=false>>
<<declare $scj=0>>
<<declare $ym=0>>
<<declare $zs=0>>
<<declare $zlChecked=false>>
<<declare $swam=0>>
<<declare $wyjStage=0>>
<<declare $gameStage=0>>
//————————————————初始化参数————————————————
<<detour InitParams>>
<<jump 开场>>
===
title: 开场
tags: linear
---
<<fade_out 0>>
<<hide_dialog>>
@@ -61,7 +42,6 @@ jj: 那你要快点长大喔~小麦克斯韦妖。 #line:01c4501
->睁眼 #line:02e0a5f
<<set_music_param event:/Amb/amb_beachsample beach_sample_stage 0>>
me: …… #line:0162fb8
<<jump hs_教室>>
->…… #line:08fd9ad
???: 喂! #line:01ca3b4
<<set_music_param event:/Amb/amb_beachsample beach_sample_stage 0.1>>
@@ -73,18 +53,12 @@ jj: 那你要快点长大喔~小麦克斯韦妖。 #line:01c4501
->睁眼 #line:0be32a8
<<set_music_param event:/Amb/amb_beachsample beach_sample_stage 0>>
me: …… #line:0b085ea
<<jump hs_教室>>
<<jump hs_教室>>
<<jump 教室苏醒>>
===
title: hs_教室
tags:
position: 250,-2611
title: 教室苏醒
tags: linear
---
<<stop_music event:/Amb/amb_beachsample fade>>
<<set_global_param dream1Stage 0.6>>
<<show_sprite "D1S教室">>
@@ -119,327 +93,410 @@ me: 喂!等下…… #line:0724d32
<<jump 教室>>
===
title: 教室
tags:
position: 250,-2611
tags: hub
---
<<set_global_param Vol_general 1>>
<<detour 展示教室_Func>>
<<set_global_param dream1scene 0>>
<<show_sprite "D1S教室">>
//————————————————展示教室图片————————————————
<<detour 教室_入场>>
<i>你站在空荡荡的教室里。<br>教室里空无一人,只有轻轻飘动的窗帘发出的扑梭声。</i> #line:0557c68
->离开教室 #line:02cd7da
<<hide_sprite>>
<<jump 走廊>>
->观察 #line:0c9209f
->窗外 #line:07f8e7b
<i>刺眼的阳光照在你的眼睛上,你一下子什么也看不清了。</i> #line:0bf7a33
<i>忽然你感到什么东西在你的脸上掠过,你退了回来。</i> #line:0138c7d
<i>原来是窗帘啊。</i> #line:0d9556c
<<if $slept==true && $ym==0>>
<<set $ym=1>>
<i>窗台上的什么东西引起了你的注意。</i> #line:0e6015b
【你获得了:羽毛】 #line:03ea994
<<endif>>
->黑板 #line:0514970
<i>黑板上似乎还留着一些板书和记录。</i> #line:09a5060
<i>你认为这些内容应该很简单,仔细一读却什么也看不懂。</i> #line:078fb75
<i>你觉得有些心慌。</i> #line:0fce30a
->走廊<<if $gameStage==0>> #line:07a50e3
<i>走廊空荡荡的,时不时传来一些遥远的嬉闹声。</i> #line:03a2b9c
<i>一阵风掠过,窗户在窗框上振动,发出轻轻的铛铛声。</i> #line:02d8b46
<i>风停了。</i> #line:093de56
->花<<if $gameStage>0>> #line:0d5d3ab
<i>一盆鲜黄的、叫不出名字的花儿在阳光下轻轻摇动,鲜得有些不自然。</i> #line:0ade71a
<i>你靠近仔细辨认。这似乎是一盆假花。</i> #line:0186f9f
<<detour 观察>>
<<jump 教室>>
->趴回去再睡会 #line:0028a19
me: …… #line:00ab4f3
<<hide_sprite>>
<i>你尝试清空思绪。</i> #line:043d77c
<i>有两只鸟好像落在了窗户附近的树枝上,欢快地鸣叫。</i> #line:003e9cb
<i>阳光照在你身上,暖暖的。</i> #line:0d1cbab
->醒来 #line:08cbcd5
<<detour 趴回去再睡会>>
<<jump 教室>>
===
title: 教室_入场
tags: detour
---
<i>你站在空荡荡的教室里。<br>教室里空无一人,只有轻轻飘动的窗帘发出的扑梭声。</i> #line:0557c68
===
title: 观察
tags: detour
---
->窗外 #line:07f8e7b
<i>刺眼的阳光照在你的眼睛上,你一下子什么也看不清了。</i> #line:0bf7a33
<i>忽然你感到什么东西在你的脸上掠过,你退了回来。</i> #line:0138c7d
<i>原来是窗帘啊。</i> #line:0d9556c
<<once if $slept>>
<i>窗台上的什么东西引起了你的注意。</i> #line:0e6015b
【你获得了:羽毛】 #line:03ea994
<<endonce>>
->黑板 #line:0514970
<i>黑板上似乎还留着一些板书和记录。</i> #line:09a5060
<i>你认为这些内容应该很简单,仔细一读却什么也看不懂。</i> #line:078fb75
<i>你觉得有些心慌。</i> #line:0fce30a
->走廊 #line:07a50e3
<i>走廊空荡荡的,时不时传来一些遥远的嬉闹声。</i> #line:03a2b9c
<i>一阵风掠过,窗户在窗框上振动,发出轻轻的铛铛声。</i> #line:02d8b46
<i>风停了。</i> #line:093de56
===
title: 趴回去再睡会
tags: detour
---
me: …… #line:00ab4f3
<<hide_sprite>>
<i>你尝试清空思绪。</i> #line:043d77c
<i>有两只鸟好像落在了窗户附近的树枝上,欢快地鸣叫。</i> #line:003e9cb
<i>阳光照在你身上,暖暖的。</i> #line:0d1cbab
->醒来 #line:08cbcd5
me: …… #line:04dbccf
<<show_sprite "D1S教室">>
<i>你睁开眼睛,听到翅膀扑朔的声音。</i> #line:0407462
<i>鸟儿飞走了。</i> #line:01c2891
<<set $slept = true>>
<<jump 教室>>
<<detour 睡着_Set>>
===
title: 走廊
tags:
position: 250,-2611
tags: hub
---
<<set_global_param dream1scene 1>>
<<if $gameStage==1 && $pphChecked==false>>
<<once if $ppStage>=1 && $gameStage==0>>
<<set $pphChecked=true>>
<i>你走下楼梯,火红的夕阳透过玻璃,在整个走廊的空气里回荡。</i> #line:0dbf438
<<show_sprite "D1S走廊2">>
<<endif>>
<<if $gameStage==0>>
<<show_sprite "D1S走廊1">>
<<elseif $gameStage<3>>
<<show_sprite "D1S走廊2">>
<<set $gameStage=2>>
<<else>>
<<show_sprite "D1S走廊3">>
<<endif>>
<<if $ppStage!=3>>
<i>你站在一条长长的走廊。阳光看起来很不错。<br>一个穿着连帽卫衣的女孩正在玻璃上画画。</i> #line:0d69997
<<endif>>
->离开 #line:0719618
<<if $zlChecked==false>>
<i>你打量着这条走廊。在你身后,走廊通向一个楼梯间;<br>在你身前,走廊曲折地延伸出去,看不到尽头。</i> #line:0602eb0
<<set $zlChecked=true>>
<<endif>>
<<set $gameStage=1>>
<<endonce>>
<<detour 展示走廊_Func>>
<<detour 走廊_入场>>
->离开 #line:0719618 #deps:gameStage
<<detour 离开_打量>>
->向后进入楼梯间 #line:0dd8dc1
<<hide_sprite>>
<<set_global_param dream1scene 2>>
<<if $gameStage==0>>
<<show_sprite "D1S楼梯间1">>
<<elseif $gameStage<3>>
<<show_sprite "D1S楼梯间2">>
<<else>>
<<show_sprite "D1S楼梯间3">>
<<endif>>
<i>你站在满是灰尘的楼梯间,上面似乎就是天台。</i> #line:0c3fb6b
->向上 #line:04603ff
<<hide_sprite>>
<<jump 天台>>
// ->向下 #line:0618ded
// <<jump 泳池>>
->返回 #line:0f6c1f1
// ->向前探索 #line:0269007
// 你沿着走廊向前走。 #line:0322fa6
// <<hide_sprite>>
// 走廊很长…仿佛没有尽头…… #line:035a7a4
// <<jump 走廊深处>>
->女孩 #line:06c47ec
<<if $gameStage==0>>
<<show_sprite "D1S佩佩1">>
<i>女孩正在在玻璃上调试着颜色。<br>看到你靠近,她不好意思地停下了笔。</i> #line:0043186
<<elseif $gameStage<3>>
<<show_sprite "D1S佩佩2">>
<i>女孩正专注地向天空中添加红色,没有注意到你的靠近。</i> #line:0a76fb1
<<else>>
<<show_sprite "D1S佩佩3">>
<i>女孩正专注地向天空中添加颜色,没有注意到你的靠近。</i> #line:0d39c58
<<endif>>
???: …… #line:06cc492
->交谈 #line:0f5967d
<<if $ppStage==0>>
<<set $ppStage=1>>
me: 这是…在画什么? #line:079eea7
girl: 对不起…我这就擦掉。 #line:0deb6fb
me: 不不…我只是好奇。 #line:0203769
girl: 啊…我只是…在想天空的颜色。 #line:0125ea8
me: 天空的颜色?蓝色么不是。 #line:0ad6d74
girl: 没错,但是……蓝色也有很多种蓝呢。 #line:0a81ec2
girl: 天蓝色,湖蓝色,宝蓝色,海军蓝,矢车菊蓝…… #line:046d021
girl: 你说的对…应该是矢车菊的蓝才对呢。 #line:021390b
me: 我? #line:0ab7567
girl: 不管怎样…先把另一种颜色调出来吧。 #line:0d4cf1d
<i>女孩开始自顾自地调试起颜色。</i> #line:02e75b6
<<elseif $ppStage==1>>
girl: 嗯…应该再加一点白才对… #line:051929d
<i>女孩一边调试颜色一边自言自语。</i> #line:05b0c2f
<<elseif $ppStage==2>>
me: 这是…你画的? #line:03c63c9
girl: …是…但颜色还是不太对。 #line:031d1ac
girl: 矢车菊蓝…总还是差一点啊。 #line:07f05d1
<<if $scj==1>>
->矢车菊 #line:0f763eb
<<show_sprite "递出矢车菊夕阳">>
girl: 这是…给我的? #line:0fd6134
me: 希望这值得。 #line:00f67c4
girl: (笑)会的。 #line:063cdb2
<<set $gameStage=3>>
<<set $ppStage=3>>
girl: ……嗯…闭上眼睛吧。 #line:0dfb357
<<hide_sprite>>
girl: 好了。 #line:03a21b0
<<show_sprite "D1S佩佩3">>
<i>女孩看着自己的作品出神。</i> #line:09b6db4
me: 除了颜色…你能画些别的东西吗? #line:038e79e
girl: 别的东西? #line:0fd97ed
me: 比如说…一扇本该存在的门。 #line:018c2f5
girl: 啊,我知道你是什么意思。(笑) #line:04369ab
girl: 不过,门后面你要找的东西,我可画不出来喔。 #line:071eeb3
<i>你发现从这里正好可以透过玻璃看到天文台。</i> #line:026ad07
<i>女孩沾了沾颜料,一边哼歌一边继续涂画着。</i> #line:006fb3e
<<else>>
me: 除了颜色…你能画些别的东西吗? #line:061aeb0
<i>女孩似乎没有听见你说话。</i> #line:0cce274
<<endif>>
<<elseif $ppStage==3>>
girl: <i>女孩一边哼歌一边继续涂画着,没有听到你的声音。</i> #line:01ef1ed
<<endif>>
->走开 #line:09e6d06
->窗外<<if $gameStage < 2>> #line:03fa5f5
<<show_sprite "D1S走廊-小镇">>
<i>看起来是一个很普通小镇,远处是层层叠叠小楼。你有一阵熟悉的感觉,好像其中一幢就是你的家。</i> #line:0304d72
<i>阳光照在你身上,暖暖的。</i> #line:0650718
<<jump 走廊>>
<<jump 楼梯间>>
->女孩 #line:06c47ec #deps:ppStage,scj
<<detour 女孩>>
<<jump 走廊>>
->窗外<<if $gameStage == 0>> #line:03fa5f5
<<detour 走廊窗外>>
<<jump 走廊>>
===
title: 离开_打量
tags: detour
---
<<once>>
<i>你打量着这条走廊。在你身后,走廊通向一个楼梯间;<br>在你身前,走廊曲折地延伸出去,看不到尽头。</i> #line:0602eb0
<<endonce>>
===
title: 走廊_入场
tags: detour
---
<<if $ppStage!=2>>
<i>你站在一条长长的走廊。阳光看起来很不错。<br>一个穿着连帽卫衣的女孩正在玻璃上画画。</i> #line:0d69997
<<endif>>
===
title: 走廊窗外
tags: detour
---
<<show_sprite "D1S走廊-小镇">>
<i>看起来是一个很普通小镇,远处是层层叠叠小楼。你有一阵熟悉的感觉,好像其中一幢就是你的家。</i> #line:0304d72
<i>阳光照在你身上,暖暖的。</i> #line:0650718
===
title: 楼梯间
tags: hub
---
<<set_global_param dream1scene 2>>
<<hide_sprite>>
<<detour 展示楼梯间_Func>>
<<detour 楼梯间_入场>>
->向上 #line:04603ff
<<hide_sprite>>
<<jump 天台>>
->返回 #line:0f6c1f1
<<jump 走廊>>
===
title: 楼梯间_入场
tags: detour
---
<i>你站在满是灰尘的楼梯间,上面似乎就是天台。</i> #line:0c3fb6b
===
title: 女孩
tags: detour
---
<<detour 女孩_入场>>
???: …… #line:06cc492
->交谈 #line:0f5967d #deps:ppStage,scj
<<detour 女孩_交谈>>
->走开 #line:09e6d06
===
title: 女孩_入场
tags: detour
---
<<detour 展示佩佩_Func>>
<<if $gameStage==0>>
<i>女孩正在在玻璃上调试着颜色。<br>看到你靠近,她不好意思地停下了笔。</i> #line:0043186
<<elseif $gameStage==1>>
<i>女孩正专注地向天空中添加红色,没有注意到你的靠近。</i> #line:0a76fb1
<<else>>
<i>女孩正专注地向天空中添加颜色,没有注意到你的靠近。</i> #line:0d39c58
<<endif>>
===
title: 女孩_交谈
tags: detour
---
<<if $ppStage==0>>
<<detour 女孩_初次交谈>>
<<elseif $ppStage==1>>
<<detour 女孩_等待矢车菊>>
<<elseif $ppStage==2>>
<<detour 女孩_已完成>>
<<endif>>
===
title: 女孩_初次交谈
tags: detour
---
<<once>>
me: 这是…在画什么? #line:079eea7
girl: 对不起…我这就擦掉。 #line:0deb6fb
me: 不不…我只是好奇。 #line:0203769
girl: 啊…我只是…在想天空的颜色。 #line:0125ea8
me: 天空的颜色?蓝色么不是。 #line:0ad6d74
girl: 没错,但是……蓝色也有很多种蓝呢。 #line:0a81ec2
girl: 天蓝色,湖蓝色,宝蓝色,海军蓝,矢车菊蓝…… #line:046d021
girl: 你说的对…应该是矢车菊的蓝才对呢。 #line:021390b
me: 我? #line:0ab7567
girl: 不管怎样…先把另一种颜色调出来吧。 #line:0d4cf1d
<i>女孩开始自顾自地调试起颜色。</i> #line:02e75b6
<<else>>
girl: 嗯…应该再加一点白才对… #line:051929d
<i>女孩一边调试颜色一边自言自语。</i> #line:05b0c2f
<<endonce>>
===
title: 女孩_等待矢车菊
tags: detour
---
me: 这是…你画的? #line:03c63c9
girl: …是…但颜色还是不太对。 #line:031d1ac
girl: 矢车菊蓝…总还是差一点啊。 #line:07f05d1
<<if $scj==1>>
->矢车菊 #line:0f763eb
<<detour 递矢车菊>>
<<else>>
me: 除了颜色…你能画些别的东西吗? #line:061aeb0
<i>女孩似乎没有听见你说话。</i> #line:0cce274
<<endif>>
===
title: 递矢车菊
tags: detour
---
<<show_sprite "递出矢车菊夕阳">>
girl: 这是…给我的? #line:0fd6134
me: 希望这值得。 #line:00f67c4
girl: (笑)会的。 #line:063cdb2
<<detour 递矢车菊_Set>>
girl: ……嗯…闭上眼睛吧。 #line:0dfb357
<<hide_sprite>>
girl: 好了。 #line:03a21b0
<<show_sprite "D1S佩佩3">>
<i>女孩看着自己的作品出神。</i> #line:09b6db4
me: 除了颜色…你能画些别的东西吗? #line:038e79e
girl: 别的东西? #line:0fd97ed
me: 比如说…一扇本该存在的门。 #line:018c2f5
girl: 啊,我知道你是什么意思。(笑) #line:04369ab
girl: 不过,门后面你要找的东西,我可画不出来喔。 #line:071eeb3
<i>你发现从这里正好可以透过玻璃看到天文台。</i> #line:026ad07
<i>女孩沾了沾颜料,一边哼歌一边继续涂画着。</i> #line:006fb3e
===
title: 女孩_已完成
tags: detour
---
girl: <i>女孩一边哼歌一边继续涂画着,没有听到你的声音。</i> #line:01ef1ed
===
title: 天台
tags:
position: 250,-2611
tags: hub
---
<<set_global_param dream1scene 3>>
<<if $gameStage == 0>>
<<show_sprite "D1S天台1">>
<i>你站在教学楼的楼顶,视野开阔。<br>阳光照在头顶有些发烫,风也暖暖的。<br>天文台的环形走廊高高的,阿灿正靠在上面发呆。</i> #line:0d3ce27
boy: 喂!上来! #line:061bd66
me: 你刚才说…我们要修谁? #line:0fbf127
boy: 你睡糊涂了吧,你要修理谁?亏你还想做医生呢! #line:0292c23
me: 我… #line:032bd1e
me: 我睡糊涂了。 #line:02ac5f7
<<hide_dialog>>
<<wait 0.5>>
<i>阿灿指向了天文台。</i> #line:03ef5a4
boy: 你自己说的啊,要把这个修好。 #line:0321859
me: 天文台?为什么? #line:059af3c
boy: 拜托,你自己说的,你说要替她修好的。 #line:0b879a6
<<hide_dialog>>
<<wait 0.5>>
me: 她?这里…还是关于她的么…… #line:054776d
boy: 什么啊?什么梦啊,你在说什么啊? #line:04ceb1f
boy: 不过…它的入口在哪里呢…门怎么不存在了?奇怪。 #line:09585b5
boy: 这下可怎么进去啊…… #line:0f47162
<<set $gameStage = 1>>
<<set $ppStage=2>>
<<set $stStage=2>>
<<elseif $gameStage == 1>>
<<show_sprite "D1S天台1">>
<i>你站在教学楼的楼顶,视野开阔。<br>阳光照在头顶有些发烫,风也暖暖的。<br>天文台的环形走廊高高的,阿灿正靠在上面发呆。</i> #line:00681be
<<elseif $gameStage < 3>>
<<if $redSkySeen==false>>
<<set $redSkySeen=true>>
<<show_sprite "D1S天台-山2">>
<<if $pphChecked==false>>
<i>一眨眼的功夫,你发现天已经变成了火红色,像油墨画一样。</i> #line:0376342
<<else>>
<i>火红色的天,像油墨画一样。</i> #line:0c2c51b
<<endif>>
<<endif>>
<<show_sprite "D1S天台2">>
<i>你站在教学楼的楼顶,视野开阔。<br>空气中似乎有种熟悉的令人昏昏沉沉的气味……</i> #line:0325825
<<else>>
<<show_sprite "D1S天台3">>
<i>你站在教学楼的楼顶,视野开阔。<br>天蓝蓝的,风也有点儿冷了。<br>你感觉好像有人在喊你。</i> #line:0f4be5a
<<endif>>
<<detour 天台_入场>>
->检查 #line:0b329d5
->窗户 #line:03e43b8
<i>天文台下面有一排窗户。里面看起来是一个布满灰尘的走廊,走廊的两端没有门,也没有窗。</i> #line:06ee6b8
<i>很奇怪。似乎从来没有人进去过,也从来没有人能进去。</i> #line:0f4c9c2
->地上<<if $gameStage < 3>> #line:06fcea6
<<if $gameStage<2>>
<<if $scj == 0>>
<<show_sprite "D1S天台-地板矢车菊1">>
<<else>>
<<show_sprite "D1S天台-地板1">>
<<endif>>
<<else>>
<<if $scj == 0>>
<<show_sprite "D1S天台-地板矢车菊2">>
<<else>>
<<show_sprite "D1S天台-地板2">>
<<endif>>
<<endif>>
<i>地上排布着黑乎乎脏兮兮的隔热砖。太阳把地板晒得很烫。</i> #line:08d113b
<i>门在哪里呢?</i> #line:0bb74cd
boy: 你在找什么啊?入口怎么可能在地上啦。 #line:0de80f3
<<if $scj==0>>
<<set $scj=1>>
<i>你注意到了不起眼角落里的什么东西。</i> #line:0a5cf5d
<<if $gameStage<2>>
<<show_sprite "D1S天台-地板1">>
<<else>>
<<show_sprite "D1S天台-地板2">>
<<endif>>
【获得:矢车菊】 #line:0229f7b
<<set $gameStage=2>>
<<endif>>
<i>你直起腰。<br>背上的衣服沾满了汗,垂坠下来,带进凉飕飕的空气。</i> #line:0f99bb3
->远眺 #line:06a03c9
<<if $gameStage<2>>
<<show_sprite "D1S天台-山1">>
<<elseif $gameStage<3>>
<<show_sprite "D1S天台-山2">>
<<else>>
<<show_sprite "D1S天台-山3">>
<<endif>>
<i>小镇的尽头是一座绿绿的小山丘,小山丘的那边是另一座小山丘,小山丘的那边是另一座小山丘……</i> #line:0a12383
->上去<<if $gameStage<3>> #line:0e52171
<i>环形走廊很高,你走到阿灿身边。</i> #line:0545696
boy: 你找到门在哪里了吗? #line:00d0860
me: 还没呢。 #line:0eecfc0
boy: 啊?这下怎么办啊。我还怎么变成星星啊…… #line:021452a
->检查 #line:0b329d5 #deps:gameStage
<<detour 天台检查>>
<<jump 天台>>
->上去<<if $gameStage<2>> #line:0e52171
<<detour 上去_与阿灿_开场>>
->远眺 #line:0f60517
<<if $gameStage<2>>
<<show_sprite "D1S天台-山1">>
<<elseif $gameStage<3>>
<<show_sprite "D1S天台-山2">>
<<else>>
<<show_sprite "D1S天台-山3">>
<<endif>>
boy: 你看到那边那座山了吗? #line:0a53d71
me: 嗯哼。 #line:05e0384
boy: 你知道吗?山的南边就是大海。 #line:01d486a
me: 海不是在东边吗? #line:03b0c59
boy: 这只是一种比喻啦! #line:06984b6
boy: 山的南边的南边…只要你走的足够远,总会走到海边的。 #line:0314896
<i>你眯起眼睛使劲向远处往,但远处好象被什么雾笼盖住了。</i> #line:0fb72c4
boy: 不过,现在还是先找天文台的入口吧。 #line:0fb2c0b
<<detour 上去_远眺>>
<<jump 天台>>
->下去 #line:069555a
<<hide_sprite>>
<<jump 天台>>
->上去<<if $gameStage==3>> #line:0a361e8
<i>墙上洋洋洒洒地画着一扇金属门,门敞开着,里面似乎有人在呼唤你。</i> #line:0124137
<<set $gameStage =3>>
->上去<<if $gameStage==2>> #line:0a361e8
<<detour 上去_画门_描述>>
->进入天文台 #line:04adc32
//你进门又走上一圈旋转楼梯,进入了一个昏暗圆形的房间。 #line:0c07ecc
<<hide_sprite>>
<<jump 天文台>>
->下去 #line:0d7f5dc
<<jump 天台>>
// 修复点:修改判定条件为>2,防止在Stage 2时与上面的选项同时出现,导致跳过开门剧情
//->天文台<<if $gameStage>2>> #line:0dbb18a
//【环形走廊很高,金属架子随着你的脚步发出吱呀吱呀的声音。天文台里很黑,传出悉悉索索的金属声。】 #line:0f54d34
//->进入 #line:0bbee09
//你进门又走上一圈旋转楼梯,进入了一个昏暗圆形的房间。 #line:0d951ab
//<<jump 天文台>>
//->下去 #line:0cff9dc
<<jump 天台>>
->下楼 #line:0bf285a
<<hide_sprite>>
<<jump 走廊>>
<<jump 天台>>
===
title: 天台_入场
tags: detour
---
<<if $gameStage == 0>>
<<detour 展示天台_Func>>
<i>你站在教学楼的楼顶,视野开阔。<br>阳光照在头顶有些发烫,风也暖暖的。<br>天文台的环形走廊高高的,阿灿正靠在上面发呆。</i> #line:0d3ce27
<<once>>
boy: 喂!上来! #line:061bd66
me: 你刚才说…我们要修谁? #line:0fbf127
boy: 你睡糊涂了吧,你要修理谁?亏你还想做医生呢! #line:0292c23
me: 我… #line:032bd1e
me: 我睡糊涂了。 #line:02ac5f7
<<hide_dialog>>
<<wait 0.5>>
<i>阿灿指向了天文台。</i> #line:03ef5a4
boy: 你自己说的啊,要把这个修好。 #line:0321859
me: 天文台?为什么? #line:059af3c
boy: 拜托,你自己说的,你说要替她修好的。 #line:0b879a6
<<hide_dialog>>
<<wait 0.5>>
me: 她?这里…还是关于她的么…… #line:054776d
boy: 什么啊?什么梦啊,你在说什么啊? #line:04ceb1f
boy: 不过…它的入口在哪里呢…门怎么不存在了?奇怪。 #line:09585b5
boy: 这下可怎么进去啊…… #line:0f47162
<<detour 天台首次剧情_Set>>
<<endonce>>
<<elseif $gameStage == 1>>
<<once>>
<<show_sprite "D1S天台-山2">>
<<if $pphChecked==false>>
<i>一眨眼的功夫,你发现天已经变成了火红色,像油墨画一样。</i> #line:0376342
<<else>>
<i>火红色的天,像油墨画一样。</i> #line:0c2c51b
<<endif>>
<<endonce>>
<<detour 展示天台_Func>>
<i>你站在教学楼的楼顶,视野开阔。<br>空气中似乎有种熟悉的令人昏昏沉沉的气味……</i> #line:0325825
<<else>>
<<detour 展示天台_Func>>
<i>你站在教学楼的楼顶,视野开阔。<br>天蓝蓝的,风也有点儿冷了。<br>你感觉好像有人在喊你。</i> #line:0f4be5a
<<endif>>
===
title: 天台检查
tags: detour
---
->窗户 #line:03e43b8
<i>天文台下面有一排窗户。里面看起来是一个布满灰尘的走廊,走廊的两端没有门,也没有窗。</i> #line:06ee6b8
<i>很奇怪。似乎从来没有人进去过,也从来没有人能进去。</i> #line:0f4c9c2
->地上<<if $gameStage < 2>> #line:06fcea6 #deps:gameStage
<<if $gameStage==0>>
<<if $scj == 0>>
<<show_sprite "D1S天台-地板矢车菊1">>
<<else>>
<<show_sprite "D1S天台-地板1">>
<<endif>>
<<else>>
<<if $scj == 0>>
<<show_sprite "D1S天台-地板矢车菊2">>
<<else>>
<<show_sprite "D1S天台-地板2">>
<<endif>>
<<endif>>
<i>地上排布着黑乎乎脏兮兮的隔热砖。太阳把地板晒得很烫。</i> #line:08d113b
<i>门在哪里呢?</i> #line:0bb74cd
boy: 你在找什么啊?入口怎么可能在地上啦。 #line:0de80f3
<<if $scj==0>>
<i>你注意到了不起眼角落里的什么东西。</i> #line:0a5cf5d
<<detour 捡起矢车菊_Set>>
【获得:矢车菊】 #line:0229f7b
<<endif>>
<i>你直起腰。<br>背上的衣服沾满了汗,垂坠下来,带进凉飕飕的空气。</i> #line:0f99bb3
->远眺 #line:06a03c9
<<detour 展示山_Func>>
<i>小镇的尽头是一座绿绿的小山丘,小山丘的那边是另一座小山丘,小山丘的那边是另一座小山丘……</i> #line:0a12383
===
title: 上去_与阿灿_开场
tags: detour
---
<i>环形走廊很高,你走到阿灿身边。</i> #line:0545696
boy: 你找到门在哪里了吗? #line:00d0860
me: 还没呢。 #line:0eecfc0
boy: 啊?这下怎么办啊。我还怎么变成星星啊…… #line:021452a
===
title: 上去_远眺
tags: detour
---
<<if $gameStage==0>>
<<show_sprite "D1S天台-山1">>
<<elseif $gameStage==1>>
<<show_sprite "D1S天台-山2">>
<<endif>>
boy: 你看到那边那座山了吗? #line:0a53d71
me: 嗯哼。 #line:05e0384
boy: 你知道吗?山的南边就是大海。 #line:01d486a
me: 海不是在东边吗? #line:03b0c59
boy: 这只是一种比喻啦! #line:06984b6
boy: 山的南边的南边…只要你走的足够远,总会走到海边的。 #line:0314896
<i>你眯起眼睛使劲向远处往,但远处好象被什么雾笼盖住了。</i> #line:0fb72c4
boy: 不过,现在还是先找天文台的入口吧。 #line:0fb2c0b
===
title: 上去_画门_描述
tags: detour
---
<i>墙上洋洋洒洒地画着一扇金属门,门敞开着,里面似乎有人在呼唤你。</i> #line:0124137
===
title: 天文台
tags:
position: 250,-2611
tags: hub
---
<<set_global_param dream1scene 4>>
<<show_sprite "D1S天文台">>
<<detour 展示天文台_Func>>
<<detour 天文台_入场>>
->观察 #line:081897d #deps:wyjStage
<<detour 天文台观察>>
<<jump 天文台>>
->望远镜 #line:00798be #deps:wyjStage
<<detour 望远镜_开场>>
->安装目镜<<if $wyjStage == 2>> #line:04d4386
<<detour 安装目镜>>
->往里看 #line:0724b3e
<<jump 海边>>
->返回 #line:0c2845b
<<jump 天文台>>
->往里看<<if $wyjStage == 3>> #line:02f0aa3
<<hide_sprite>>
<<jump 海边>>
->往里看<<if $wyjStage != 3>> #line:02f0aa4
<<detour 往里看>>
<<jump 天文台>>
->出去 #line:09312e4
<<hide_sprite>>
<<jump 天台>>
===
title: 天文台_入场
tags: detour
---
<i>你站在一间昏暗的圆形房间里。房间的正中央是一台天文望远镜,看起来很久没人用了。房间一篇死寂,地上、桌上,遍布着灰尘。</i> #line:0a229cf
<<if $wyjStage == 1>>
<<set_global_param dream1Stage 2>>
@@ -448,92 +505,88 @@ position: 250,-2611
<<set_global_param dream1Stage 2.5>>
<i>空气仿佛正在变得模糊而潮湿。</i> #line:0a115bc
<<endif>>
<<if visited("天文台") == false>>
<<once>>
me: 阿灿? #line:0befebd
me: 人呢…… #line:0f822b4
<<endif>>
->观察 #line:081897d
->日历 #line:01894bd
<i>黄黄的日历的顶端印着几个数字,2后面跟着好多个0。</i> #line:0659b59
<i>你伸手一碰,那一页日历就像薄脆一样碎了。</i> #line:04f153a
<i>下面的一页上面也印着几个数字,看起来和上一页一样。</i> #line:0ce73c7
->便笺 #line:0fb3a58
<<if $wyjStage == 0>>
<i>望远镜上贴着一张黄色的便笺。</i> #line:0179879
hs: 你跑到哪里去了?我先上去,不等你啦 :P #line:0cbc819
<<elseif $wyjStage == 1>>
<i>望远镜上贴着一张褪色的便笺。</i> #line:0ff2298
hs: ……哪…去了…我先……不等…… #line:01ad7c7
<i>字迹模糊不清,看起来是很久很久以前写的。</i> #line:0529b64
<<else>>
<i>望远镜上贴着一张白色的便笺。</i> #line:092260e
<i>你碰了一下,便笺碎掉了。</i> #line:012a3a1
<<endif>>
->仪器 #line:007cbe4
<i>这些仪器看着很像你工作用的工具……</i> #line:0076043
<<if $wyjStage == 0>>
<i>……不对,你真的有那个工作吗?你只是一个学生吧。</i> #line:0256c87
<<elseif $wyjStage == 1>>
me: 只要…什么都能修好,对吧。你说的… #line:005b630
->翻找零件 #line:09c5690
<i>大部分零件你都不认识。不过你的运气不错。</i> #line:04bff73
->完好的压缩环 #line:06c0942
me: 这下应该可以了。 #line:01ed9bc
<<set $wyjStage = 2>>
<<endif>>
->望远镜 #line:00798be
<<if $wyjStage == 0>>
<i>望远镜很大,上面刻着你看不懂的参数和型号。</i> #line:04e4782
<<elseif $wyjStage == 1>>
<i>望远镜很大,不过比你想象的又要小一些。</i> #line:04d3d85
<<else>>
<i>望远镜上覆盖着厚厚的灰尘,螺丝钉锈迹斑斑。</i> #line:0154dea
<i>原来它有这么旧吗?</i> #line:0bbc574
<<endif>>
->安装目镜<<if $wyjStage == 2>> #line:04d4386
<i>你记得这很困难。但这比你印象中的轻松太多了。</i> #line:0edf096
me: 我修好了!对吧?我修好了…… #line:0e80e94
->往里看 #line:0724b3e
<<jump 海边>>
->返回 #line:0c2845b
->往里看 #line:02f0aa3
<<if $wyjStage == 0 || $wyjStage == 3>>
<i>灰尘的声音在望远镜的空腔中回荡。<br>你眯起眼睛,努力想要看清楚。</i> #line:08aff34
<<set_global_param dream1Stage 2.4>>
<<hide_sprite>>
<<if $wyjStage == 0>>
<i>咔哒一声,什么东西掉了下来。</i> #line:00f87b1
me: 哎呀… #line:07be273
->接住 #line:0f8dd82
<i>你的手上拿着望远镜的目镜,看起来就像小号的望远镜。</i> #line:0b032ff
<i>除此之外,还有一个断成两半的环。看起来是用来固定目镜的零件。</i> #line:0daf5f6
<<set $wyjStage = $wyjStage + 1>>
<<elseif $wyjStage == 2>>
<<set_global_param dream1Stage 2.7>>
<i>一种不属于这间密室的咸腥味,正顺着望远镜的钢管倒灌进你的鼻腔。</i> #line:05205fc
<i>尘埃不再干燥。它们在你的皮肤上凝结,变得沉重、粘稠。</i> #line:0348906
<<endif>>
<<elseif $wyjStage == 1 || $wyjStage == 2>>
<<set_global_param dream1Stage 3>>
<i>目镜原来在的位置上是一个黑漆漆的洞。</i> #line:02bcbcb
<i>往里面看去什么也没有,只能听到灰尘的声音。</i> #line:0c4d195
//TODO: 增加海浪音量
<<elseif $wyjStage == 3>>
<<hide_sprite>>
<<jump 海边>>
<<endif>>
->出去 #line:09312e4
<<hide_sprite>>
<<jump 天台>>
<<jump 天文台>>
<<endonce>>
===
title: 天文台观察
tags: detour
---
->日历 #line:01894bd
<i>黄黄的日历的顶端印着几个数字,2后面跟着好多个0。</i> #line:0659b59
<i>你伸手一碰,那一页日历就像薄脆一样碎了。</i> #line:04f153a
<i>下面的一页上面也印着几个数字,看起来和上一页一样。</i> #line:0ce73c7
->便笺 #line:0fb3a58
<<if $wyjStage == 0>>
<i>望远镜上贴着一张黄色的便笺。</i> #line:0179879
hs: 你跑到哪里去了?我先上去,不等你啦 :P #line:0cbc819
<<elseif $wyjStage == 1>>
<i>望远镜上贴着一张褪色的便笺。</i> #line:0ff2298
hs: ……哪…去了…我先……不等…… #line:01ad7c7
<i>字迹模糊不清,看起来是很久很久以前写的。</i> #line:0529b64
<<else>>
<i>望远镜上贴着一张白色的便笺。</i> #line:092260e
<i>你碰了一下,便笺碎掉了。</i> #line:012a3a1
<<endif>>
->仪器 #line:007cbe4 #deps:wyjStage
<i>这些仪器看着很像你工作用的工具……</i> #line:0076043
<<if $wyjStage == 0>>
<i>……不对,你真的有那个工作吗?你只是一个学生吧。</i> #line:0256c87
<<elseif $wyjStage == 1>>
me: 只要…什么都能修好,对吧。你说的… #line:005b630
->翻找零件 #line:09c5690
<i>大部分零件你都不认识。不过你的运气不错。</i> #line:04bff73
->完好的压缩环 #line:06c0942
me: 这下应该可以了。 #line:01ed9bc
<<detour 找到压缩环_Set>>
<<endif>>
===
title: 望远镜_开场
tags: detour
---
<<if $wyjStage == 0>>
<i>望远镜很大,上面刻着你看不懂的参数和型号。</i> #line:04e4782
<<elseif $wyjStage == 1>>
<i>望远镜很大,不过比你想象的又要小一些。</i> #line:04d3d85
<<else>>
<i>望远镜上覆盖着厚厚的灰尘,螺丝钉锈迹斑斑。</i> #line:0154dea
<i>原来它有这么旧吗?</i> #line:0bbc574
<<endif>>
===
title: 安装目镜
tags: detour
---
<i>你记得这很困难。但这比你印象中的轻松太多了。</i> #line:0edf096
me: 我修好了!对吧?我修好了…… #line:0e80e94
===
title: 往里看
tags: detour
---
<<if $wyjStage == 0>>
<i>灰尘的声音在望远镜的空腔中回荡。<br>你眯起眼睛,努力想要看清楚。</i> #line:08aff34
<<set_global_param dream1Stage 2.4>>
<<hide_sprite>>
<i>咔哒一声,什么东西掉了下来。</i> #line:00f87b1
me: 哎呀… #line:07be273
->接住 #line:0f8dd82
<i>你的手上拿着望远镜的目镜,看起来就像小号的望远镜。</i> #line:0b032ff
<i>除此之外,还有一个断成两半的环。看起来是用来固定目镜的零件。</i> #line:0daf5f6
<<detour 目镜掉落_Set>>
<<elseif $wyjStage == 1 || $wyjStage == 2>>
<<set_global_param dream1Stage 3>>
<i>目镜原来在的位置上是一个黑漆漆的洞。</i> #line:02bcbcb
<i>往里面看去什么也没有,只能听到灰尘的声音。</i> #line:0c4d195
//TODO: 增加海浪音量
<<endif>>
===
title: 海边
tags:
position: 250,-2611
tags: linear
---
<<stop_music event:/Music/mus_dream1 fade>>
<<hide_sprite>>
@@ -598,6 +651,3 @@ jj: 该醒来了,路斯。 #line:03c9e3c
// <i>你睁开眼睛,眼神平和而冷淡。</i> #line:0829e5d
<<NextYarn>>
===
@@ -1,7 +1,7 @@
{
"projectFileVersion": 2,
"projectFileVersion": 3,
"sourceFiles": [
"*.yarn"
"**/*.yarn"
],
"excludeFiles": [
"**/*~/*"
+125
View File
@@ -0,0 +1,125 @@
title: InitParams
tags: function
---
<<declare $slept=false>>
<<declare $ppStage=0>>
<<declare $pphChecked=false>>
<<declare $scj=0>>
<<declare $wyjStage=0>>
<<declare $gameStage=0>> // 0=白天 1=夕阳 2=门开
===
title: 展示教室_Func
tags: function
---
<<show_sprite "D1S教室">>
===
title: 展示走廊_Func
tags: function
---
<<if $gameStage==0>>
<<show_sprite "D1S走廊1">>
<<elseif $gameStage==1>>
<<show_sprite "D1S走廊2">>
<<else>>
<<show_sprite "D1S走廊3">>
<<endif>>
===
title: 展示楼梯间_Func
tags: function
---
<<if $gameStage==0>>
<<show_sprite "D1S楼梯间1">>
<<elseif $gameStage==1>>
<<show_sprite "D1S楼梯间2">>
<<else>>
<<show_sprite "D1S楼梯间3">>
<<endif>>
===
title: 展示佩佩_Func
tags: function
---
<<if $gameStage==0>>
<<show_sprite "D1S佩佩1">>
<<elseif $gameStage==1>>
<<show_sprite "D1S佩佩2">>
<<else>>
<<show_sprite "D1S佩佩3">>
<<endif>>
===
title: 递矢车菊_Set
tags: function
---
<<set $gameStage=2>>
<<set $ppStage=2>>
===
title: 展示天台_Func
tags: function
---
<<if $gameStage == 0>>
<<show_sprite "D1S天台1">>
<<elseif $gameStage == 1>>
<<show_sprite "D1S天台2">>
<<else>>
<<show_sprite "D1S天台3">>
<<endif>>
===
title: 天台首次剧情_Set
tags: function
---
<<set $ppStage=1>>
===
title: 展示山_Func
tags: function
---
<<if $gameStage==0>>
<<show_sprite "D1S天台-山1">>
<<elseif $gameStage==1>>
<<show_sprite "D1S天台-山2">>
<<else>>
<<show_sprite "D1S天台-山3">>
<<endif>>
===
title: 捡起矢车菊_Set
tags: function
---
<<set $scj=1>>
<<if $gameStage==0>>
<<show_sprite "D1S天台-地板1">>
<<else>>
<<show_sprite "D1S天台-地板2">>
<<endif>>
<<set $gameStage=1>>
===
title: 睡着_Set
tags: function
---
<<set $slept=true>>
===
title: 展示天文台_Func
tags: function
---
<<show_sprite "D1S天文台">>
===
title: 找到压缩环_Set
tags: function
---
<<set $wyjStage=2>>
===
title: 目镜掉落_Set
tags: function
---
<<set $wyjStage=$wyjStage+1>>
===
@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 25c8aebd730477a43b7f53b9e95e5a82
ScriptedImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 2
userData:
assetBundleName:
assetBundleVariant:
script: {fileID: 11500000, guid: 94073015eacc34c1d8fc6786e43d60ca, type: 3}
@@ -1,5 +1,5 @@
{
"projectFileVersion": 2,
"projectFileVersion": 3,
"sourceFiles": [
"*.yarn"
],
@@ -1,5 +1,5 @@
{
"projectFileVersion": 2,
"projectFileVersion": 3,
"sourceFiles": [
"*.yarn"
],
@@ -1,5 +1,5 @@
{
"projectFileVersion": 2,
"projectFileVersion": 3,
"sourceFiles": [
"**/*.yarn"
],
@@ -1,5 +1,5 @@
{
"projectFileVersion": 2,
"projectFileVersion": 3,
"sourceFiles": [
"*.yarn"
],
@@ -1,5 +1,5 @@
{
"projectFileVersion": 2,
"projectFileVersion": 3,
"sourceFiles": [
"**/*.yarn"
],
@@ -1,5 +1,5 @@
{
"projectFileVersion": 2,
"projectFileVersion": 3,
"sourceFiles": [
"**/*.yarn"
],
@@ -1,5 +1,5 @@
{
"projectFileVersion": 4,
"projectFileVersion": 3,
"sourceFiles": [
"**/*.yarn"
],
@@ -1,5 +1,5 @@
{
"projectFileVersion": 2,
"projectFileVersion": 3,
"sourceFiles": [
"**/*.yarn"
],
@@ -1,5 +1,5 @@
{
"projectFileVersion": 2,
"projectFileVersion": 3,
"sourceFiles": [
"**/*.yarn"
],
@@ -1,5 +1,5 @@
{
"projectFileVersion": 2,
"projectFileVersion": 3,
"sourceFiles": [
"**/*.yarn"
],
@@ -1,5 +1,5 @@
{
"projectFileVersion": 2,
"projectFileVersion": 3,
"sourceFiles": [
"**/*.yarn"
],
-103
View File
@@ -29,106 +29,3 @@ position: -267,-102
<<jump 检查_胃>>
<<endif>>
===
title: EngineSuccess
position: -1092,115
---
<<if $gameStage == 2>>
<<jump 调速后测速>>
<<elseif $gameStage == 6>>
<<jump 刻录调速>>
<<endif>>
===
title: AllGearsRunning
---
<<if $gameStage == 2 && $gearPopupCount == 1>>
<<jump 齿轮恢复后>>
<<elseif $gameStage == 2 && $gearPopupCount == 2>>
<<jump 齿轮第二次放回>>
<<elseif $gameStage == 2 && $allNewGear>>
<<jump 更换镍铬齿轮>>
<<endif>>
===
title: 插入冷却液
position: -809,327
---
<<if $gameStage == 5>>
<<jump 冷却液介绍>>
<<endif>>
===
title: 泵机运行
position: -1088,330
---
<<if $gameStage == 5>>
<<jump 泵机运行后>>
<<endif>>
===
title: 引擎过速
description: 引擎过速触发
position: -257,110
---
<<if $gameStage == 4>>
<<set $failTime = $failTime + 1 >>
<<if visited("调速popup_过速")==false>>
<<jump 调速popup_过速>>
<<elseif $failTime == 5>>
<<jump 调速popup_失败5次>>
<<elseif $failTime == 10>>
<<jump 调速popup_失败10次>>
<<elseif $failTime == 15>>
<<jump 调速popup_失败15次>>
<<elseif $failTime == 20>>
<<jump 调速popup_失败15次>>
<<elseif $failTime == 25>>
<<jump 调速popup_失败15次>>
<<elseif $failTime == 30>>
<<jump 调速popup_失败15次>>
<<endif>>
<<endif>>
===
title: 引擎掉速
description: 引擎掉速触发
position: -813,115
---
<<if $gameStage == 4>>
<<set $failTime = $failTime + 1 >>
<<if visited("调速popup_掉速")==false>>
<<jump 调速popup_掉速>>
<<elseif $failTime == 5>>
<<if visited("调速popup_过速")==false>>
<<jump 调速popup_失败5次但是都是掉速>>
<<else>>
<<jump 调速popup_失败5次>>
<<endif>>
<<elseif $failTime == 10>>
<<jump 调速popup_失败10次>>
<<elseif $failTime == 15>>
<<jump 调速popup_失败15次>>
<<elseif $failTime == 20>>
<<jump 调速popup_失败15次>>
<<elseif $failTime == 25>>
<<jump 调速popup_失败15次>>
<<elseif $failTime == 30>>
<<jump 调速popup_失败15次>>
<<endif>>
<<endif>>
===
title: 调整进气档位
description: 调整进气档位时触发
position: -532,113
---
<<if $gameStage == 4>>
<<jump 调速popup_调整进气档位>>
<<endif>>
===
@@ -1,5 +1,5 @@
{
"projectFileVersion": 2,
"projectFileVersion": 3,
"sourceFiles": [
"**/*.yarn"
],
+3 -3
View File
@@ -96,9 +96,9 @@ colorID: 1
<<endif>>
// 冷却液处理
<<if $gameStage == 5>>
<<jump 冷却液处理>>
<<endif>>
// <<if $gameStage == 5>>
// <<jump 冷却液处理>>
// <<endif>>
// 结束,进入下一个Yarn
<<if $gameStage >= 6>>
@@ -1,5 +1,5 @@
{
"projectFileVersion": 2,
"projectFileVersion": 3,
"sourceFiles": [
"**/*.yarn"
],
+1 -1
View File
@@ -50,7 +50,7 @@ Modular framework with Kit-pattern utilities:
## Critical Dependencies
### Unity Packages
- **Yarn Spinner** 2.4.2 (OpenUPM), **Addressables** 1.21.21, **Cinemachine** 2.9.7
- **Yarn Spinner** 3.2.2 (OpenUPM), **Addressables** 1.21.21, **Cinemachine** 2.9.7
- **URP** 14.0.8, **TextMesh Pro** 3.0.6, **Timeline** 1.7.5, **Localization** 1.4.5
- **Visual Effect Graph** 14.0.8, **Visual Scripting** 1.8.0
+276
View File
@@ -0,0 +1,276 @@
# Yarn 节点类型规范
## 1. 节点类型与跳转权限
| 标签 | 职责 | 跳转权限 | 内容限制 |
| ---------- | ---- | ----------------------- | ---------------------- |
| `hub` | 导航中枢 | **可 `<<jump>>` 多个节点** | 仅选项骨架,无叙事文本 |
| `linear` | 线性演出 | **仅可 `<<jump>>` 到一个节点** | 可有叙事文本和演出指令 |
| `detour` | 内容片段 | **禁止 `<<jump>>`** | 可有叙事文本、画面指令、局部选项 |
| `function` | 功能函数 | **禁止 `<<jump>>`** | **禁止任何文字内容,仅 Command** |
---
## 2. 命名规则
| 节点标签 | 命名示例 | 规则 |
| ----------------- | ----------------------- | ----------------- |
| `hub` | `教室``天台``走廊` | 场景名或状态名 |
| `linear` | `海边``开场动画` | 事件名或过场名 |
| `detour` | `观察``趴回去再睡会``女孩` | 中文动宾/名词短语 |
| `function`(只读) | `展示山_Func` | **`_Func` 后缀**;不修改 `$` 变量 |
| `function`(写入) | `捡起矢车菊_Set` | **`_Set` 后缀**;会修改 `$` 变量 |
| `function`(初始化特例) | `InitParams` | **无后缀**;仅 declare |
| `Start`(引擎入口特例) | `Start` | **固定命名,不属于四类标签** |
---
## 3. 各类型详细规范
### 3.0 Start 节点(引擎入口)
Yarn Spinner 默认从名为 `Start` 的节点开始运行。它**不属于** hub / linear / detour / function 四类,**不加**上述 `tags`,职责仅是启动流程,不写叙事。
```yarn
title: Start
---
<<detour InitParams>>
<<jump 开场>>
===
```
**约束清单:**
- **固定命名**:节点 title 必须为 `Start`
- **极简**:仅初始化 + 跳转到首个 linear(或首个 hub);不写 `<i>`、对话、选项
- **InitParams**:通过 `<<detour InitParams>>` 调用;变量声明集中在 `InitParams` function 节点,不散落在 Start
- **唯一出口**:末尾仅一个 `<<jump>>`,指向正式剧情入口(通常为 linear)
叙事、演出、分支选项一律放在 `Start` 之后的首个 linear(如 `开场`)及后续节点中。
---
### 3.1 hub 节点
唯一拥有多出口跳转权的节点类型,负责场景导航。
```yarn
title: 天台
tags: hub
---
<<set_global_param dream1scene 3>>
->检查
<<detour 天台检查>>
<<jump 天台>> # 允许:返回自身 hub
->上去 <<if $gameStage<3>>
<<detour 上去_没有门>>
<<jump 天台>> # 允许:返回自身 hub
->上楼
<<hide_sprite>>
<<jump 走廊>> # 允许:跳转到其他 hub
->进入天文台 <<if $gameStage==3>>
<<hide_sprite>>
<<jump 天文台>> # 允许:跳转到其他 hub
===
```
**约束清单:**
- 仅存放选项骨架和流程骨架,不写叙事文本
- 选项目标为 detour(内容)或 `<<jump>>` 到其他 hub/linear
- 循环回自身时必须显式 `<<jump 自身名>>`
---
### 3.2 linear 节点
仅允许一个出口,用于强制剧情推进。
```yarn
title: 海边
tags: linear
---
<<stop_music event:/Music/mus_dream1 fade>>
<<hide_sprite>>
<i>你的身体仿佛正在黑暗中褪去。</i>
# ... 大量线性叙事 ...
<<hide_dialog>>
<<wait 2>>
<<play_timeline 醒来>>
<<NextYarn>> # 仅一个出口
===
```
**约束清单:**
- 无分支选项(或仅有伪选项无实际分流)
- 末尾只能有一个 `<<jump>>` 目标(或 `<<NextYarn>>`
- 可包含演出指令和叙事文本
---
### 3.3 detour 节点
禁止任何 `<<jump>>`,执行完毕后控制权交还调用方。
```yarn
title: 天台检查
tags: detour
---
->窗户
<i>天文台下面有一排窗户...</i>
->地上 <<if $gameStage < 3>>
<i>地上排布着黑乎乎脏兮兮的隔热砖...</i>
<<if $scj==0>>
<<detour 捡起矢车菊_Set>>
<<endif>>
->远眺
<<detour 展示山_Func>>
===
```
**约束清单:**
- **禁止任何 `<<jump>>`**
- 允许内部嵌套选项(仅限局部选择,不影响全局导航)
- 允许调用其他 detour`<<detour 子内容>>`)和 function`<<detour 展示山_Func>>`
- 负责叙事文本、画面指令、局部状态变更
---
### 3.4 function 节点
纯指令容器,零文本。统一 `tags: function`,按是否修改 `$` 变量区分后缀:
| 后缀 | 职责 | 修改 `$` 变量? |
| ---- | ---- | ------------- |
| `_Func` | 只读:根据当前变量输出演出 | 禁止 |
| `_Set` | 写入:变更进度/状态(可含演出指令) | 允许 |
| 无后缀 | `InitParams`:全局变量声明 | 仅 `<<declare>>` |
`set_global_param`(场景、音量等展示上下文)不计入「修改 `$` 变量」。
**只读示例(`_Func`**
```yarn
title: 展示走廊_Func
tags: function
---
<<if $gameStage==0>>
<<show_sprite "D1S走廊1">>
<<elseif $gameStage==1>>
<<show_sprite "D1S走廊2">>
<<else>>
<<show_sprite "D1S走廊3">>
<<endif>>
===
```
**写入示例(`_Set`**
```yarn
title: 捡起矢车菊_Set
tags: function
---
<<set $scj=1>>
<<if $gameStage==0>>
<<show_sprite "D1S天台-地板1">>
<<else>>
<<show_sprite "D1S天台-地板2">>
<<endif>>
<<set $gameStage=1>>
===
```
**特例:InitParams**
`InitParams` 的职责是全局变量声明与初始值设定,属于项目启动时的根级配置,不加 `_Func` / `_Set` 后缀。
```yarn
title: InitParams
tags: function
---
<<declare $started=false>>
<<declare $gameStage=0>>
<<declare $ppStage=0>>
===
```
**约束清单:**
- **零文字**:禁止任何对话、旁白、选项文字
- **零跳转**:禁止任何 `<<jump>>`
- **纯 Command**:仅 `<<declare>>``<<set>>``<<set_global_param>>``<<show_sprite>>``<<play_sfx>>` 等指令
- **后缀语义**`_Func` 禁止 `<<set>>` / `<<declare>>``_Set` 必须含至少一处 `$` 变量写入
- **标签大写**`tags: function`(首字母大写)
---
## 4. 调用关系图
```
Start ──<<detour>>──> InitParams
│ <<jump>>
linear(如:开场)──>> hub / linear / NextYarn
┌─────────┐ <<jump>> ┌─────────┐
│ hub │ ─────────────────> │ hub │
│ (多出口) │ │ (多出口) │
└────┬────┘ └─────────┘
│ <<detour>> ┌─────────┐
└──────────────>│ detour │ ──>> 可嵌套调用其他 detour
│(无jump) │
└────┬────┘
自然返回调用方 hub
┌─────────┐ <<jump>> ┌─────────┐
│ hub │ ─────────────────>│ linear │
│ (多出口) │ │(单出口) │
└─────────┘ └────┬────┘
│ <<jump>> 到下一 hub/linear/NextYarn
┌─────────┐
│function │ 被 hub/detour/linear 通过 <<detour>> 调用
│(零文本) │
└─────────┘
```
---
## 5. 快速检查表
| 检查项 | Start | hub | linear | detour | function |
| --------------- | ----- | ----- | -------- | -------- | ---------------------- |
| 是否包含选项骨架? | 禁止 | 必须 | 禁止 | 仅局部 | 禁止 |
| 是否包含叙事文本? | 禁止 | 禁止 | 允许 | 允许 | **禁止** |
| 是否有 `<<jump>>`? | 仅一个出口 | 允许多出口 | 仅一个出口 | **禁止** | **禁止** |
| 后缀是否正确? | - | - | - | - | **`_Func` / `_Set`InitParams 无后缀** |
| 标签是否正确? | 无 tags | `hub` | `linear` | `detour` | `function` |
---
## 6. 设计原则
- **Start 负责启动**InitParams + 跳转入口,与叙事彻底分离
- **hub 负责路由**:打开任意 hub 即可一览场景结构,无需滚屏
- **linear 负责推进**:无分支过场,单向流动
- **detour 负责填充**:内容抽离后可被多处复用,修改不影响整体结构
- **function 负责纯逻辑**:零文本保证指令安全;`_Func` 只读、`_Set` 写入,后缀一眼识别副作用
+153
View File
@@ -0,0 +1,153 @@
# 选项已探索追踪说明
> **状态**:方案已定,运行时已实现(内存态)
> **读者**:剧情策划、关卡策划、写 Yarn 的同学
> **参考脚本**[FP_Day1_sleep.yarn](../Assets/Yarn/FP/FP_Day1_sleep/FP_Day1_sleep.yarn)
## 1. 用途
用于可反复探索的选项列表。玩家点过某个选项后,该选项会显示为**已探索**;如果相关剧情变量变化,选项可以重新变回未探索,提示玩家这里可能有新内容。
## 2. 基本规则
| 写法 | 含义 |
| --- | --- |
| `tags: hub` / `tags: detour` | 节点内选项默认追踪 |
| `tags: linear` / 无 tags | 节点内选项默认不追踪 |
| `#deps:变量名` | 变量变化后,取消该选项的已探索状态 |
| `#track` | 强制追踪 |
| `#notrack` | 强制不追踪,适合“返回 / 走开 / 下楼”等操作按钮 |
`#deps:` 里的变量名不写 `$`,多个变量用英文逗号分隔:
```yarn
->女孩 #deps:ppStage,scj
```
`<<if>>` 只控制选项是否显示;`#deps:` 才表示“变量变化后这里有新内容”。
```yarn
->地上 <<if $gameStage < 2>> #deps:gameStage
<<detour 检查地上>>
<<jump 天台>>
```
优先级:
```text
#notrack > #track / #deps:... > 节点 tags 默认规则
```
## 3. 常见写法
### 3.1 普通探索菜单
`hub` 里的选项默认会追踪,不需要额外写标记。
```yarn
title: 教室
tags: hub
---
->观察
<<detour 观察>>
<<jump 教室>>
->趴回去再睡会
<<detour 趴回去再睡会>>
<<jump 教室>>
->离开教室 #notrack
<<jump 走廊>>
===
```
### 3.2 内容随剧情阶段变化
如果选项内容会随变量变化,就写 `#deps:`
```yarn
title: 走廊
tags: hub
---
->女孩 #deps:ppStage,scj
<<detour 女孩>>
<<jump 走廊>>
->窗外 <<if $gameStage == 0>>
<<detour 走廊窗外>>
<<jump 走廊>>
===
```
这里“女孩”会在 `$ppStage``$scj` 变化后重新变成未探索;“窗外”只是受条件控制显示,不会因为 `$gameStage` 变化自动刷新已探索状态。
### 3.3 父入口和子选项
父入口不会自动汇总子选项。进入过“女孩”只代表外层“女孩”已探索,不代表里面的“交谈”也已探索。
```yarn
title: 走廊
tags: hub
---
->女孩 #deps:ppStage,scj
<<detour 女孩>>
<<jump 走廊>>
===
title: 女孩
tags: detour
---
->交谈 #deps:ppStage,scj
<<detour 女孩_交谈>>
->走开 #notrack
===
```
### 3.4 同名选项的不同分支
同一个选项文字在不同条件下可以代表不同内容。内容会变的分支写 `#deps:` 即可。
```yarn
title: 天文台
tags: hub
---
->往里看 <<if $wyjStage == 3>>
<<jump 海边>>
->往里看 <<if $wyjStage != 3>> #deps:wyjStage
<<detour 往里看_还不能进入>>
<<jump 天文台>>
===
```
### 3.5 线性剧情里的选择
`linear` 默认不追踪,适合一次性选择。
```yarn
title: 教室苏醒
tags: linear
---
->梦到机器人
me: 我梦见我是一个机器人......
->梦到我是医生
me: 我梦见我成了一个医生......
->不记得了
me: 我不记得梦的内容了。
<<jump 教室>>
===
```
如果线性节点里某个选项确实需要标记,可以单独加 `#track`
## 4. 写作检查
- 可反复返回的探索列表,优先放在 `hub``detour`
- 普通探索选项不用额外标记。
- 内容会随变量变化的选项,加 `#deps:变量名`
- `#deps:` 只写真正会让内容变新的变量,不要把所有相关变量都塞进去。
- `<<if>>` 管显示,`#deps:` 管刷新已探索状态。
- 纯操作按钮优先加 `#notrack`
- 父入口和子选项各自独立。
- 不要手写或复制 `#line:` 标签;行标签交给 Yarn / 本地化流程生成和维护。
## 5. 运行时补充
本期已探索状态只保存在内存里,不进存档。开始新的 Yarn project、回主界面、执行 `<<NextYarn>>` 或退出游戏时会清空。同一段探索内在 `hub` / `detour` 之间来回跳转不会清空。