StorySystem
This commit is contained in:
@@ -213,7 +213,7 @@ Material:
|
||||
- _Dst: 10
|
||||
- _DstBlend: 0
|
||||
- _DstBlendAlpha: 0
|
||||
- _EdgeValue: 0.9350733
|
||||
- _EdgeValue: 0.7629054
|
||||
- _EnvironmentReflections: 1
|
||||
- _FNLfanxiangkaiguan: 0
|
||||
- _Face: 1
|
||||
@@ -258,7 +258,7 @@ Material:
|
||||
- _Mask_scale: 1
|
||||
- _Metallic: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Opacity: 0.064926684
|
||||
- _Opacity: 0.23709458
|
||||
- _Parallax: 0.005
|
||||
- _Pass: 0
|
||||
- _QueueOffset: 0
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Assets/FR2_Cache.asset
LFS
BIN
Assets/FR2_Cache.asset
LFS
Binary file not shown.
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0486971babc04a1419e16413dfce980c
|
||||
guid: d5e986d3a0508cf4aae911cac5aab212
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
BIN
Assets/Localization/Message/Message Shared Data.asset
LFS
Normal file
BIN
Assets/Localization/Message/Message Shared Data.asset
LFS
Normal file
Binary file not shown.
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6c799daafc19ce54a8ba2d09737bc2aa
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Localization/Message/Message.asset
LFS
Normal file
BIN
Assets/Localization/Message/Message.asset
LFS
Normal file
Binary file not shown.
8
Assets/Localization/Message/Message.asset.meta
Normal file
8
Assets/Localization/Message/Message.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 88d982fd5c6bda04e8ea20350cd159aa
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Localization/Message/Message_en.asset
LFS
Normal file
BIN
Assets/Localization/Message/Message_en.asset
LFS
Normal file
Binary file not shown.
8
Assets/Localization/Message/Message_en.asset.meta
Normal file
8
Assets/Localization/Message/Message_en.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 61661a97b386b1b468a2f6eb6edbd219
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Localization/Message/Message_ja.asset
LFS
Normal file
BIN
Assets/Localization/Message/Message_ja.asset
LFS
Normal file
Binary file not shown.
8
Assets/Localization/Message/Message_ja.asset.meta
Normal file
8
Assets/Localization/Message/Message_ja.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0b436cb055982024d87c26e5dd006d98
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Localization/Message/Message_ko.asset
LFS
Normal file
BIN
Assets/Localization/Message/Message_ko.asset
LFS
Normal file
Binary file not shown.
8
Assets/Localization/Message/Message_ko.asset.meta
Normal file
8
Assets/Localization/Message/Message_ko.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de75c1b8ae3365341bbe21fc291dedba
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Localization/Message/Message_th.asset
LFS
Normal file
BIN
Assets/Localization/Message/Message_th.asset
LFS
Normal file
Binary file not shown.
8
Assets/Localization/Message/Message_th.asset.meta
Normal file
8
Assets/Localization/Message/Message_th.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 02149fcde1352dd499e840aca3a762aa
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Localization/Message/Message_vi-VN.asset
LFS
Normal file
BIN
Assets/Localization/Message/Message_vi-VN.asset
LFS
Normal file
Binary file not shown.
8
Assets/Localization/Message/Message_vi-VN.asset.meta
Normal file
8
Assets/Localization/Message/Message_vi-VN.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f8b371af239879499277d4b555cd69b
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Localization/Message/Message_zh-CN.asset
LFS
Normal file
BIN
Assets/Localization/Message/Message_zh-CN.asset
LFS
Normal file
Binary file not shown.
8
Assets/Localization/Message/Message_zh-CN.asset.meta
Normal file
8
Assets/Localization/Message/Message_zh-CN.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d7530d3dd169d2141a5207d0172e3a9b
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Localization/Message/Message_zh-TW.asset
LFS
Normal file
BIN
Assets/Localization/Message/Message_zh-TW.asset
LFS
Normal file
Binary file not shown.
8
Assets/Localization/Message/Message_zh-TW.asset.meta
Normal file
8
Assets/Localization/Message/Message_zh-TW.asset.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d51a896a1514cde44bcff62055b619f0
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
Binary file not shown.
1178
Assets/Prefabs/MessageBox.prefab
Normal file
1178
Assets/Prefabs/MessageBox.prefab
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,6 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cf843fc3f4fd10e499a6cc1b60bc1861
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
guid: a8e9cecf40a73474d8a5ffc9bada8c20
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
92
Assets/Prefabs/Story/Dialog/Character.prefab
Normal file
92
Assets/Prefabs/Story/Dialog/Character.prefab
Normal file
@@ -0,0 +1,92 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!1 &597743784740087054
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 7917580385239275621}
|
||||
- component: {fileID: 1310777969124757443}
|
||||
- component: {fileID: 6320712627302899334}
|
||||
- component: {fileID: 5305109034942869160}
|
||||
m_Layer: 5
|
||||
m_Name: Character
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &7917580385239275621
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 597743784740087054}
|
||||
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: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 760, y: 1350}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &1310777969124757443
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 597743784740087054}
|
||||
m_CullTransparentMesh: 1
|
||||
--- !u!114 &6320712627302899334
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 597743784740087054}
|
||||
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: 2736c74fecf99944a9977f12bf51f01c, 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!114 &5305109034942869160
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 597743784740087054}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 331609805c7de66409dba07cce2f3a28, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier: Assembly-CSharp::Ichni.Story.Dialogue.SpritePortraitRenderer
|
||||
_alphaActive: 1
|
||||
_alphaInactive: 0.7
|
||||
7
Assets/Prefabs/Story/Dialog/Character.prefab.meta
Normal file
7
Assets/Prefabs/Story/Dialog/Character.prefab.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 373499de58b10f34983c975fccad9f89
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -14,7 +14,7 @@ OcclusionCullingSettings:
|
||||
RenderSettings:
|
||||
m_ObjectHideFlags: 0
|
||||
serializedVersion: 10
|
||||
m_Fog: 1
|
||||
m_Fog: 0
|
||||
m_FogColor: {r: 0.09296818, g: 0.080870956, b: 0.29559743, a: 1}
|
||||
m_FogMode: 1
|
||||
m_FogDensity: 0.01
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,15 +21,19 @@ namespace Ichni.Story
|
||||
public class CharacterData : SerializedScriptableObject
|
||||
{
|
||||
[LabelText("Character ID")]
|
||||
[InfoBox("此 ID 需与 .yarn 文件中对应台词的 speaker 名完全一致。")]
|
||||
[Tooltip("此 ID 需与 .yarn 文件中对应台词的 speaker 名完全一致。")]
|
||||
public string characterId;
|
||||
|
||||
[LabelText("Display Name Key")]
|
||||
[InfoBox("Unity Localization String Table Key,用于多语言角色名显示。")]
|
||||
[Tooltip("Unity Localization String Table Key,用于多语言角色名显示。")]
|
||||
public string displayNameKey;
|
||||
|
||||
[LabelText("Portrait Style")]
|
||||
public PortraitStyle portraitStyle = PortraitStyle.Sprite;
|
||||
|
||||
[LabelText("Position Offset")]
|
||||
[Tooltip("立绘在舞台上的位置偏移(单位:映射百分比)")]
|
||||
public Vector2 positionOffset = new Vector2(0f, 0f);
|
||||
|
||||
// ── Sprite ──────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -46,7 +50,6 @@ namespace Ichni.Story
|
||||
[InfoBox("Live2D / Spine 立绘预制体,需挂载实现 IPortraitRenderer 接口的组件(阶段 3 制作)。")]
|
||||
public GameObject dynamicPortraitPrefab;
|
||||
|
||||
private bool IsDynamicPortrait =>
|
||||
portraitStyle == PortraitStyle.Live2D || portraitStyle == PortraitStyle.Spine;
|
||||
private bool IsDynamicPortrait => portraitStyle == PortraitStyle.Live2D || portraitStyle == PortraitStyle.Spine;
|
||||
}
|
||||
}
|
||||
|
||||
140
Assets/Scripts/NewStorySystem/Data/StoryVariables.cs
Normal file
140
Assets/Scripts/NewStorySystem/Data/StoryVariables.cs
Normal file
@@ -0,0 +1,140 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.Story
|
||||
{
|
||||
/// <summary>
|
||||
/// 全局剧情变量的统一数据枢纽。
|
||||
/// 所有外部系统(包括 Yarn、UI、小游戏)读写剧情变量的唯一官方入口。
|
||||
/// 自动桥接至 GameSaveManager 的 StorySaveModule 中持久化。
|
||||
/// </summary>
|
||||
public static class StoryVariables
|
||||
{
|
||||
// 应对游戏尚未初始化(或者单独测试场景)的内存兜底
|
||||
private static readonly StoryVariablesSave _fallback = new StoryVariablesSave();
|
||||
|
||||
private static StoryVariablesSave Variables
|
||||
{
|
||||
get
|
||||
{
|
||||
if (GameSaveManager.instance != null && GameSaveManager.instance.StorySaveModule != null)
|
||||
return GameSaveManager.instance.StorySaveModule.variables;
|
||||
return _fallback;
|
||||
}
|
||||
}
|
||||
|
||||
// ── 读取 ────────────────────────────────────────────────────────────────
|
||||
|
||||
public static float GetFloat(string key, float defaultValue = 0f)
|
||||
{
|
||||
StoryVariablesSave vars = Variables;
|
||||
if (vars.floatVariables.TryGetValue(key, out float f)) return f;
|
||||
if (vars.boolVariables.TryGetValue(key, out bool b)) return b ? 1f : 0f;
|
||||
if (vars.stringVariables.TryGetValue(key, out string s) && float.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out float p)) return p;
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public static int GetInt(string key, int defaultValue = 0)
|
||||
{
|
||||
StoryVariablesSave vars = Variables;
|
||||
if (vars.floatVariables.TryGetValue(key, out float f)) return Mathf.RoundToInt(f);
|
||||
if (vars.boolVariables.TryGetValue(key, out bool b)) return b ? 1 : 0;
|
||||
if (vars.stringVariables.TryGetValue(key, out string s) && float.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out float p)) return Mathf.RoundToInt(p);
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public static bool GetBool(string key, bool defaultValue = false)
|
||||
{
|
||||
StoryVariablesSave vars = Variables;
|
||||
if (vars.boolVariables.TryGetValue(key, out bool b)) return b;
|
||||
if (vars.floatVariables.TryGetValue(key, out float f)) return f != 0f;
|
||||
if (vars.stringVariables.TryGetValue(key, out string s) && bool.TryParse(s, out bool p)) return p;
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public static string GetString(string key, string defaultValue = "")
|
||||
{
|
||||
StoryVariablesSave vars = Variables;
|
||||
if (vars.stringVariables.TryGetValue(key, out string s)) return s;
|
||||
if (vars.floatVariables.TryGetValue(key, out float f)) return f.ToString(CultureInfo.InvariantCulture);
|
||||
if (vars.boolVariables.TryGetValue(key, out bool b)) return b.ToString();
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public static bool HasVariable(string key)
|
||||
{
|
||||
StoryVariablesSave vars = Variables;
|
||||
return vars.floatVariables.ContainsKey(key) || vars.boolVariables.ContainsKey(key) || vars.stringVariables.ContainsKey(key);
|
||||
}
|
||||
|
||||
// ── 写入 ────────────────────────────────────────────────────────────────
|
||||
|
||||
public static void SetFloat(string key, float value)
|
||||
{
|
||||
RemoveStaleEntries(key, keepFloat: true, keepString: false, keepBool: false);
|
||||
Variables.floatVariables[key] = value;
|
||||
}
|
||||
|
||||
public static void SetInt(string key, int value)
|
||||
{
|
||||
// 在 Yarn/存档底层中数字统一存为 float,避免双字典冗余
|
||||
SetFloat(key, value);
|
||||
}
|
||||
|
||||
public static void SetBool(string key, bool value)
|
||||
{
|
||||
RemoveStaleEntries(key, keepFloat: false, keepString: false, keepBool: true);
|
||||
Variables.boolVariables[key] = value;
|
||||
}
|
||||
|
||||
public static void SetString(string key, string value)
|
||||
{
|
||||
RemoveStaleEntries(key, keepFloat: false, keepString: true, keepBool: false);
|
||||
Variables.stringVariables[key] = value;
|
||||
}
|
||||
|
||||
public static void ClearAll()
|
||||
{
|
||||
StoryVariablesSave vars = Variables;
|
||||
vars.floatVariables.Clear();
|
||||
vars.stringVariables.Clear();
|
||||
vars.boolVariables.Clear();
|
||||
}
|
||||
|
||||
private static void RemoveStaleEntries(string name, bool keepFloat, bool keepString, bool keepBool)
|
||||
{
|
||||
StoryVariablesSave vars = Variables;
|
||||
if (!keepFloat) vars.floatVariables.Remove(name);
|
||||
if (!keepString) vars.stringVariables.Remove(name);
|
||||
if (!keepBool) vars.boolVariables.Remove(name);
|
||||
}
|
||||
|
||||
// ── 字典批量操作(内部供 Yarn Adapter 使用) ─────────────────────────────
|
||||
|
||||
internal static void SetAllVariables(Dictionary<string, float> floats, Dictionary<string, string> strings, Dictionary<string, bool> bools, bool clear = true)
|
||||
{
|
||||
StoryVariablesSave vars = Variables;
|
||||
if (clear)
|
||||
{
|
||||
vars.floatVariables.Clear();
|
||||
vars.stringVariables.Clear();
|
||||
vars.boolVariables.Clear();
|
||||
}
|
||||
|
||||
if (floats != null) foreach (var kv in floats) vars.floatVariables[kv.Key] = kv.Value;
|
||||
if (strings != null) foreach (var kv in strings) vars.stringVariables[kv.Key] = kv.Value;
|
||||
if (bools != null) foreach (var kv in bools) vars.boolVariables[kv.Key] = kv.Value;
|
||||
}
|
||||
|
||||
internal static (Dictionary<string, float> floats, Dictionary<string, string> strings, Dictionary<string, bool> bools) GetAllVariables()
|
||||
{
|
||||
StoryVariablesSave vars = Variables;
|
||||
return (
|
||||
new Dictionary<string, float>(vars.floatVariables),
|
||||
new Dictionary<string, string>(vars.stringVariables),
|
||||
new Dictionary<string, bool>(vars.boolVariables)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c69dde49931abdd40aeabc0dc35582f5
|
||||
93
Assets/Scripts/NewStorySystem/Dialogue/ChoiceButton.cs
Normal file
93
Assets/Scripts/NewStorySystem/Dialogue/ChoiceButton.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
using Sirenix.OdinInspector;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using Yarn.Unity;
|
||||
|
||||
namespace Ichni.Story.Dialogue
|
||||
{
|
||||
/// <summary>
|
||||
/// 单个对话选项按钮的显示与交互控制器。
|
||||
/// <para>
|
||||
/// <list type="bullet">
|
||||
/// <item><b>可用选项</b>:显示 <see cref="availableSprite"/>,点击时触发 <c>onSelected</c> 回调。</item>
|
||||
/// <item><b>不可用选项</b>:显示 <see cref="unavailableSprite"/>,点击无效(但 Button 的
|
||||
/// <c>interactable</c> 保持开启,以备未来扩展悬停提示等功能)。</item>
|
||||
/// </list>
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// 由 <see cref="VNDialoguePresenter"/> 统一调用 <see cref="Setup"/> / <see cref="Cleanup"/>。
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public class ChoiceButton : MonoBehaviour
|
||||
{
|
||||
[Tooltip("按钮组件引用(挂载在同 GameObject 上的 Button)。")]
|
||||
public Button button;
|
||||
|
||||
[Tooltip("按钮背景 Image,用于在 available / unavailable 状态间切换 Sprite。")]
|
||||
public Image buttonBackground;
|
||||
|
||||
[Tooltip("选项文本 TMP。")]
|
||||
public TMP_Text buttonText;
|
||||
|
||||
[SerializeField, HideInPlayMode]
|
||||
[Tooltip("选项可用时的背景 Sprite。")]
|
||||
private Sprite availableSprite;
|
||||
|
||||
[SerializeField, HideInPlayMode]
|
||||
[Tooltip("选项不可用时的背景 Sprite。")]
|
||||
private Sprite unavailableSprite;
|
||||
|
||||
// ── 运行时状态 ────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>当前绑定的选项是否可供玩家选择。</summary>
|
||||
private bool _isAvailable;
|
||||
|
||||
// ── 公共 API ─────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// 根据 <paramref name="option"/> 配置按钮并激活显示。
|
||||
/// </summary>
|
||||
/// <param name="option">Yarn 对话选项数据。<c>option.IsAvailable</c> 决定外观与交互行为。</param>
|
||||
/// <param name="onSelected">
|
||||
/// 玩家点击且选项可用时触发的回调。
|
||||
/// 不可用选项点击不会触发此回调,但按钮保持 <c>interactable=true</c>。
|
||||
/// </param>
|
||||
public void Setup(DialogueOption option, System.Action<DialogueOption> onSelected)
|
||||
{
|
||||
gameObject.SetActive(true);
|
||||
_isAvailable = option.IsAvailable;
|
||||
|
||||
// 设置选项文本
|
||||
if (buttonText != null)
|
||||
buttonText.text = option.Line.TextWithoutCharacterName.Text;
|
||||
|
||||
// 根据可用性切换背景图
|
||||
if (buttonBackground != null)
|
||||
buttonBackground.sprite = _isAvailable ? availableSprite : unavailableSprite;
|
||||
|
||||
// 注册点击监听:不可用选项点击静默忽略
|
||||
if (button != null)
|
||||
{
|
||||
button.onClick.RemoveAllListeners();
|
||||
button.onClick.AddListener(() =>
|
||||
{
|
||||
if (_isAvailable)
|
||||
onSelected?.Invoke(option);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除按钮监听并隐藏此按钮。
|
||||
/// 在 <see cref="VNDialoguePresenter.RunOptionsAsync"/> 结束后统一调用。
|
||||
/// </summary>
|
||||
public void Cleanup()
|
||||
{
|
||||
if (button != null)
|
||||
button.onClick.RemoveAllListeners();
|
||||
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 63c53d8a6dc173a4db3d6a8a1499b7e6
|
||||
59
Assets/Scripts/NewStorySystem/Dialogue/IPortraitRenderer.cs
Normal file
59
Assets/Scripts/NewStorySystem/Dialogue/IPortraitRenderer.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.Story.Dialogue
|
||||
{
|
||||
/// <summary>
|
||||
/// 立绘渲染器抽象接口。所有立绘渲染实现(Sprite / Live2D / Spine)均须实现此接口,
|
||||
/// 使 <see cref="VNPortraitStage"/> 和 Yarn 命令层无需感知底层渲染细节。
|
||||
/// </summary>
|
||||
public interface IPortraitRenderer
|
||||
{
|
||||
/// <summary>此渲染器在舞台上占用的 RectTransform(用于位置操控)。</summary>
|
||||
RectTransform RectTransform { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 以指定角色数据和情绪名显示立绘。若角色已在台上则更新情绪。
|
||||
/// </summary>
|
||||
void Show(CharacterData character, string emotion);
|
||||
|
||||
/// <summary>隐藏立绘(不销毁对象,留存以便复用)。</summary>
|
||||
void Hide();
|
||||
|
||||
/// <summary>切换当前情绪(角色数据不变)。</summary>
|
||||
void SetEmotion(string emotion);
|
||||
|
||||
/// <summary>
|
||||
/// 将立绘的 anchoredPosition 设为指定坐标(即时,无动画)。
|
||||
/// </summary>
|
||||
/// <param name="anchoredPos">目标 anchoredPosition(画布空间,像素单位)。</param>
|
||||
void SetPosition(Vector2 anchoredPos);
|
||||
|
||||
/// <summary>
|
||||
/// 控制说话者高亮状态:说话者 alpha = 1.0,旁观者 alpha = 0.7(可由实现自行定义)。
|
||||
/// </summary>
|
||||
void SetActiveVisual(bool isSpeaking);
|
||||
|
||||
/// <summary>
|
||||
/// 平滑移动到目标位置。
|
||||
/// </summary>
|
||||
/// <param name="anchoredPos">目标像素坐标</param>
|
||||
/// <param name="duration">持续时间</param>
|
||||
void MoveTo(Vector2 anchoredPos, float duration);
|
||||
|
||||
/// <summary>
|
||||
/// 原地跳跃动画。
|
||||
/// </summary>
|
||||
/// <param name="power">跳跃力度(高度)</param>
|
||||
/// <param name="numJumps">跳跃次数</param>
|
||||
/// <param name="duration">持续时间</param>
|
||||
void Jump(float power, int numJumps, float duration);
|
||||
|
||||
/// <summary>
|
||||
/// 左右震动动画。
|
||||
/// </summary>
|
||||
/// <param name="duration">持续时间</param>
|
||||
/// <param name="strength">震动力度(像素范围)</param>
|
||||
/// <param name="vibrato">震动频率</param>
|
||||
void Shake(float duration, float strength, int vibrato);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3dbfb11aa34a55942b604a15cbd65d50
|
||||
175
Assets/Scripts/NewStorySystem/Dialogue/SpritePortraitRenderer.cs
Normal file
175
Assets/Scripts/NewStorySystem/Dialogue/SpritePortraitRenderer.cs
Normal file
@@ -0,0 +1,175 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using DG.Tweening;
|
||||
|
||||
namespace Ichni.Story.Dialogue
|
||||
{
|
||||
/// <summary>
|
||||
/// 基于 <see cref="UnityEngine.UI.Image"/> 的 Sprite 立绘渲染器。
|
||||
/// <para>
|
||||
/// 挂载在 VN 对话 UI 内的立绘槽位 GameObject 上(Left / Center / Right 等),
|
||||
/// 每个槽位对应一个 <see cref="SpritePortraitRenderer"/> 实例。
|
||||
/// 当前阶段仅实现静态显示(Show / Hide / SetEmotion / SetPosition / SetActiveVisual),
|
||||
/// 后续阶段再叠加 DOTween 动画。
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Image))]
|
||||
public class SpritePortraitRenderer : MonoBehaviour, IPortraitRenderer
|
||||
{
|
||||
// ── 设置 ────────────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>说话者的不透明度(满值)。</summary>
|
||||
[SerializeField] private float _alphaActive = 1.0f;
|
||||
|
||||
/// <summary>非说话者的压暗不透明度。</summary>
|
||||
[SerializeField] private float _alphaInactive = 0.7f;
|
||||
|
||||
// ── 组件缓存 ─────────────────────────────────────────────────────────────
|
||||
|
||||
private Image _image;
|
||||
private RectTransform _rectTransform;
|
||||
|
||||
// ── 状态 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
private CharacterData _currentCharacter;
|
||||
|
||||
// ── IPortraitRenderer 实现 ───────────────────────────────────────────────
|
||||
|
||||
/// <inheritdoc/>
|
||||
public RectTransform RectTransform => _rectTransform;
|
||||
|
||||
// ── 生命周期 ──────────────────────────────────────────────────────────────
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_image = GetComponent<Image>();
|
||||
_rectTransform = GetComponent<RectTransform>();
|
||||
|
||||
// 初始隐藏
|
||||
SetGroupAlpha(0f);
|
||||
}
|
||||
|
||||
// ── 接口方法 ─────────────────────────────────────────────────────────────
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Show(CharacterData character, string emotion)
|
||||
{
|
||||
if (character == null)
|
||||
{
|
||||
Debug.LogWarning("[SpritePortraitRenderer] Show 传入了 null CharacterData。");
|
||||
return;
|
||||
}
|
||||
|
||||
_currentCharacter = character;
|
||||
ApplySprite(emotion);
|
||||
SetGroupAlpha(_alphaActive);
|
||||
gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Hide()
|
||||
{
|
||||
SetGroupAlpha(0f);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void SetEmotion(string emotion)
|
||||
{
|
||||
if (_currentCharacter == null)
|
||||
{
|
||||
Debug.LogWarning("[SpritePortraitRenderer] SetEmotion 时尚未绑定角色数据。");
|
||||
return;
|
||||
}
|
||||
|
||||
ApplySprite(emotion);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void SetPosition(Vector2 anchoredPos)
|
||||
{
|
||||
_rectTransform.anchoredPosition = anchoredPos;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void SetActiveVisual(bool isSpeaking)
|
||||
{
|
||||
SetGroupAlpha(isSpeaking ? _alphaActive : _alphaInactive);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void MoveTo(Vector2 anchoredPos, float duration)
|
||||
{
|
||||
_rectTransform.DOKill(complete: true);
|
||||
_rectTransform.DOAnchorPos(anchoredPos, duration).SetEase(Ease.InOutQuad).Play();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Jump(float power, int numJumps, float duration)
|
||||
{
|
||||
// 对于跳跃,先停止并完成先前的动画,避免错乱(特别是被快进时)
|
||||
_rectTransform.DOKill(complete: true);
|
||||
|
||||
// UI 的 DOJumpAnchorPos 非常适合这种表现,项目中要求手动调用 Play()
|
||||
_rectTransform.DOJumpAnchorPos(_rectTransform.anchoredPosition, power, numJumps, duration).Play();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Shake(float duration, float strength, int vibrato)
|
||||
{
|
||||
_rectTransform.DOKill(complete: true);
|
||||
|
||||
// 左右震动(限制在 X 轴或以特定强度震动),项目中要求手动调用 Play()
|
||||
_rectTransform.DOShakeAnchorPos(duration, new Vector2(strength, 0f), vibrato, 90, false, true).Play();
|
||||
}
|
||||
|
||||
// ── 内部辅助 ─────────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// 从 <see cref="CharacterData.emotionSprites"/> 中查找并赋值 Sprite。
|
||||
/// 找不到指定情绪时回退到"normal",再找不到则使用字典中第一个条目,
|
||||
/// 并在 Console 输出警告。
|
||||
/// </summary>
|
||||
private void ApplySprite(string emotion)
|
||||
{
|
||||
if (_currentCharacter.emotionSprites == null || _currentCharacter.emotionSprites.Count == 0)
|
||||
{
|
||||
Debug.LogWarning($"[SpritePortraitRenderer] 角色 '{_currentCharacter.characterId}' 没有配置任何情绪 Sprite。");
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. 精确匹配
|
||||
if (!string.IsNullOrEmpty(emotion) &&
|
||||
_currentCharacter.emotionSprites.TryGetValue(emotion, out Sprite target))
|
||||
{
|
||||
_image.sprite = target;
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 回退 normal
|
||||
if (_currentCharacter.emotionSprites.TryGetValue("normal", out Sprite fallback))
|
||||
{
|
||||
Debug.LogWarning($"[SpritePortraitRenderer] 角色 '{_currentCharacter.characterId}' 没有情绪 '{emotion}',回退到 'normal'。");
|
||||
_image.sprite = fallback;
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 使用第一个条目
|
||||
foreach (Sprite first in _currentCharacter.emotionSprites.Values)
|
||||
{
|
||||
Debug.LogWarning($"[SpritePortraitRenderer] 角色 '{_currentCharacter.characterId}' 也没有 'normal',使用第一张 Sprite。");
|
||||
_image.sprite = first;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetGroupAlpha(float alpha)
|
||||
{
|
||||
if (_image != null)
|
||||
{
|
||||
Color c = _image.color;
|
||||
c.a = alpha;
|
||||
_image.color = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 331609805c7de66409dba07cce2f3a28
|
||||
@@ -153,11 +153,17 @@ namespace Ichni.Story.Dialogue
|
||||
List<UnityAction> pending = new List<UnityAction>(dialogueEndActions);
|
||||
dialogueEndActions.Clear();
|
||||
foreach (UnityAction action in pending)
|
||||
{
|
||||
action?.Invoke();
|
||||
}
|
||||
|
||||
StoryMessageBoxUIPage.instance.FadeIn();
|
||||
}
|
||||
|
||||
if (storyUIPage != null)
|
||||
{
|
||||
storyUIPage.FadeIn();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,207 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using UnityEngine;
|
||||
using Yarn.Unity;
|
||||
|
||||
namespace Ichni.Story.Dialogue
|
||||
{
|
||||
/// <summary>
|
||||
/// 自定义 Yarn 变量存储。直接读写 <see cref="StorySaveModule.variables"/>(全局剧情变量),
|
||||
/// 让 Yarn 对话中的 <c><<set $var to ...>></c> 与故事树解锁条件共享同一份数据来源,
|
||||
/// 并借助存档模块的 ES3 序列化持久化。
|
||||
/// <para>变量名沿用 Yarn 约定(带 <c>$</c> 前缀);解锁条件中的变量名也应保持一致。</para>
|
||||
/// </summary>
|
||||
public class StoryVariableStorage : VariableStorageBehaviour
|
||||
{
|
||||
// GameSaveManager 尚未就绪(编辑器早期 / 场景未初始化)时的兜底容器
|
||||
private readonly StoryVariablesSave _fallback = new StoryVariablesSave();
|
||||
|
||||
/// <summary>当前生效的变量容器:优先取存档模块,缺失时用本地兜底容器。</summary>
|
||||
private StoryVariablesSave Variables
|
||||
{
|
||||
get
|
||||
{
|
||||
if (GameSaveManager.instance != null && GameSaveManager.instance.StorySaveModule != null)
|
||||
return GameSaveManager.instance.StorySaveModule.variables;
|
||||
return _fallback;
|
||||
}
|
||||
}
|
||||
|
||||
// ── IVariableStorage 实现 ────────────────────────────────────────────────
|
||||
|
||||
public override bool TryGetValue<T>(string variableName, out T result)
|
||||
{
|
||||
StoryVariablesSave vars = Variables;
|
||||
|
||||
if (vars.floatVariables.TryGetValue(variableName, out float f))
|
||||
return TryConvert(f, out result);
|
||||
|
||||
if (vars.boolVariables.TryGetValue(variableName, out bool b))
|
||||
return TryConvert(b, out result);
|
||||
|
||||
if (vars.stringVariables.TryGetValue(variableName, out string s))
|
||||
return TryConvert(s, out result);
|
||||
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void SetValue(string variableName, string stringValue)
|
||||
{
|
||||
RemoveStaleEntries(variableName, keepFloat: false, keepString: true, keepBool: false);
|
||||
Variables.stringVariables[variableName] = stringValue;
|
||||
NotifyVariableChanged(variableName, stringValue);
|
||||
}
|
||||
|
||||
public override void SetValue(string variableName, float floatValue)
|
||||
{
|
||||
RemoveStaleEntries(variableName, keepFloat: true, keepString: false, keepBool: false);
|
||||
Variables.floatVariables[variableName] = floatValue;
|
||||
NotifyVariableChanged(variableName, floatValue);
|
||||
}
|
||||
|
||||
public override void SetValue(string variableName, bool boolValue)
|
||||
{
|
||||
RemoveStaleEntries(variableName, keepFloat: false, keepString: false, keepBool: true);
|
||||
Variables.boolVariables[variableName] = boolValue;
|
||||
NotifyVariableChanged(variableName, boolValue);
|
||||
}
|
||||
|
||||
public override bool Contains(string variableName)
|
||||
{
|
||||
StoryVariablesSave vars = Variables;
|
||||
return vars.floatVariables.ContainsKey(variableName)
|
||||
|| vars.boolVariables.ContainsKey(variableName)
|
||||
|| vars.stringVariables.ContainsKey(variableName);
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
StoryVariablesSave vars = Variables;
|
||||
vars.floatVariables.Clear();
|
||||
vars.stringVariables.Clear();
|
||||
vars.boolVariables.Clear();
|
||||
}
|
||||
|
||||
public override void SetAllVariables(
|
||||
Dictionary<string, float> floats,
|
||||
Dictionary<string, string> strings,
|
||||
Dictionary<string, bool> bools,
|
||||
bool clear = true)
|
||||
{
|
||||
StoryVariablesSave vars = Variables;
|
||||
|
||||
if (clear)
|
||||
{
|
||||
vars.floatVariables.Clear();
|
||||
vars.stringVariables.Clear();
|
||||
vars.boolVariables.Clear();
|
||||
}
|
||||
|
||||
if (floats != null)
|
||||
foreach (KeyValuePair<string, float> kv in floats) vars.floatVariables[kv.Key] = kv.Value;
|
||||
if (strings != null)
|
||||
foreach (KeyValuePair<string, string> kv in strings) vars.stringVariables[kv.Key] = kv.Value;
|
||||
if (bools != null)
|
||||
foreach (KeyValuePair<string, bool> kv in bools) vars.boolVariables[kv.Key] = kv.Value;
|
||||
}
|
||||
|
||||
public override (Dictionary<string, float> FloatVariables,
|
||||
Dictionary<string, string> StringVariables,
|
||||
Dictionary<string, bool> BoolVariables) GetAllVariables()
|
||||
{
|
||||
StoryVariablesSave vars = Variables;
|
||||
return (
|
||||
new Dictionary<string, float>(vars.floatVariables),
|
||||
new Dictionary<string, string>(vars.stringVariables),
|
||||
new Dictionary<string, bool>(vars.boolVariables)
|
||||
);
|
||||
}
|
||||
|
||||
// ── 供故事树解锁条件复用的便捷读取 ────────────────────────────────────────
|
||||
|
||||
/// <summary>读取变量的整数近似值(float 四舍五入、bool 取 0/1);不存在返回 0。</summary>
|
||||
public int GetIntVariable(string variableName)
|
||||
{
|
||||
StoryVariablesSave vars = Variables;
|
||||
if (vars.floatVariables.TryGetValue(variableName, out float f))
|
||||
return Mathf.RoundToInt(f);
|
||||
if (vars.boolVariables.TryGetValue(variableName, out bool b))
|
||||
return b ? 1 : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>该变量是否存在于任一类型的存储中。</summary>
|
||||
public bool HasVariable(string variableName) => Contains(variableName);
|
||||
|
||||
// ── 内部 ────────────────────────────────────────────────────────────────
|
||||
|
||||
// 当变量被重新赋值为其它类型时,从旧类型字典移除,避免同名变量残留多份
|
||||
private void RemoveStaleEntries(string name, bool keepFloat, bool keepString, bool keepBool)
|
||||
{
|
||||
StoryVariablesSave vars = Variables;
|
||||
if (!keepFloat) vars.floatVariables.Remove(name);
|
||||
if (!keepString) vars.stringVariables.Remove(name);
|
||||
if (!keepBool) vars.boolVariables.Remove(name);
|
||||
}
|
||||
|
||||
// 将存储中的原始值转换为 Yarn 请求的类型(float / bool / string / int 之间互转)
|
||||
private static bool TryConvert<T>(object value, out T result)
|
||||
{
|
||||
if (value is T typed)
|
||||
{
|
||||
result = typed;
|
||||
return true;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (typeof(T) == typeof(float) || typeof(T) == typeof(double) || typeof(T) == typeof(int))
|
||||
{
|
||||
float f = value switch
|
||||
{
|
||||
float fv => fv,
|
||||
bool bv => bv ? 1f : 0f,
|
||||
string sv => float.TryParse(sv, NumberStyles.Any, CultureInfo.InvariantCulture, out float p) ? p : 0f,
|
||||
_ => 0f
|
||||
};
|
||||
result = (T)System.Convert.ChangeType(f, typeof(T), CultureInfo.InvariantCulture);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof(T) == typeof(bool))
|
||||
{
|
||||
bool b = value switch
|
||||
{
|
||||
bool bv => bv,
|
||||
float fv => fv != 0f,
|
||||
string sv => bool.TryParse(sv, out bool p) && p,
|
||||
_ => false
|
||||
};
|
||||
result = (T)(object)b;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof(T) == typeof(string))
|
||||
{
|
||||
string s = value switch
|
||||
{
|
||||
string sv => sv,
|
||||
float fv => fv.ToString(CultureInfo.InvariantCulture),
|
||||
bool bv => bv.ToString(),
|
||||
_ => value != null ? value.ToString() : string.Empty
|
||||
};
|
||||
result = (T)(object)s;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 转换失败时落到下方失败分支
|
||||
}
|
||||
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7dc7dc14d9f97c043bf6fb67c3a70877
|
||||
@@ -3,6 +3,7 @@ using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using Yarn.Unity;
|
||||
using Ichni.Story.UI;
|
||||
|
||||
namespace Ichni.Story.Dialogue
|
||||
{
|
||||
@@ -11,61 +12,21 @@ namespace Ichni.Story.Dialogue
|
||||
/// <para>
|
||||
/// 职责:
|
||||
/// <list type="bullet">
|
||||
/// <item>对话开始/结束时淡入/淡出 <see cref="panelGroup"/>。</item>
|
||||
/// <item><see cref="RunLineAsync"/>:逐字打字效果 + 点击推进。</item>
|
||||
/// <item><see cref="RunOptionsAsync"/>:显示选项按钮 + 等待玩家选择。</item>
|
||||
/// <item>对话流控制:打字机效果、点击推进、等待选项。</item>
|
||||
/// <item>将所有的 UI 引用委托给 <see cref="DialogUIPage"/> 进行管理。</item>
|
||||
/// </list>
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// 挂载位置:与 <see cref="DialogueRunner"/> 同一 GameObject(StoryDialogueRoot)。
|
||||
/// UI 引用字段需在 Inspector 中连接到 DialogPage 下的对应节点。
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public class VNDialoguePresenter : DialoguePresenterBase
|
||||
{
|
||||
// ── UI 引用 ─────────────────────────────────────────────────────────────
|
||||
|
||||
[Header("面板控制")]
|
||||
[Tooltip("对话面板整体的 CanvasGroup(DialogPage/DialogCanvas)。用于淡入/淡出及交互开关。")]
|
||||
[SerializeField] private CanvasGroup panelGroup;
|
||||
|
||||
[Header("台词区")]
|
||||
[Tooltip("台词主体文本 TMP(DialogContentFrame/Background/Text)。")]
|
||||
[SerializeField] private TextMeshProUGUI dialogueText;
|
||||
|
||||
[Tooltip("说话者名称的父容器 GameObject(DialogContentFrame/Speaker)。无说话者时整体隐藏。")]
|
||||
[SerializeField] private GameObject speakerContainer;
|
||||
|
||||
[Tooltip("说话者名称 TMP(DialogContentFrame/Speaker/Text)。")]
|
||||
[SerializeField] private TextMeshProUGUI speakerText;
|
||||
|
||||
[Header("推进按钮")]
|
||||
[Tooltip("点击此按钮推进对话。\n" +
|
||||
" • 打字效果进行中 → 加速(RequestHurryUpLine)显示全文。\n" +
|
||||
" • 打字已完成 → 进入下一行(RequestNextLine)。\n" +
|
||||
"推荐:将场景中 DialogContentFrame/Background 或 BackButton 的 Button 拖入此处。")]
|
||||
[SerializeField] private Button advanceButton;
|
||||
|
||||
[Header("选项区")]
|
||||
[Tooltip("选项按钮容器根节点(ChoiceFrame)。有选项时显示,无选项时隐藏。")]
|
||||
[SerializeField] private GameObject choiceFrame;
|
||||
|
||||
[Tooltip("选项按钮数组(最多 4 个,对应 ChoiceFrame 下的四个 GameObject)。")]
|
||||
[SerializeField] private Button[] choiceButtons = new Button[4];
|
||||
|
||||
[Tooltip("每个选项按钮上的文本 TMP,与 choiceButtons 按索引一一对应。")]
|
||||
[SerializeField] private TextMeshProUGUI[] choiceTexts = new TextMeshProUGUI[4];
|
||||
|
||||
// ── 打字 / 淡入淡出设置 ──────────────────────────────────────────────────
|
||||
[Header("UI 管理")]
|
||||
[Tooltip("负责当前对话界面的 UI Page 容器。如果为空,将尝试获取全局单例。")]
|
||||
[SerializeField] private DialogUIPage uiPage;
|
||||
|
||||
[Header("打字效果")]
|
||||
[Tooltip("每秒显示的字符数。设为 0 则瞬间显示全文。")]
|
||||
[SerializeField] private float lettersPerSecond = 40f;
|
||||
|
||||
[Header("淡入淡出")]
|
||||
[SerializeField] private float fadeInDuration = 0.2f;
|
||||
[SerializeField] private float fadeOutDuration = 0.15f;
|
||||
|
||||
// ── 私有状态 ─────────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
@@ -74,6 +35,11 @@ namespace Ichni.Story.Dialogue
|
||||
/// </summary>
|
||||
private bool _typewriterComplete;
|
||||
|
||||
/// <summary>
|
||||
/// 是否处于快进状态(遇到选项或玩家再次点击时会打断)。
|
||||
/// </summary>
|
||||
private bool _isFastForwarding;
|
||||
|
||||
/// <summary>
|
||||
/// 选项选择的异步结果来源。RunOptionsAsync 等待其 Task 完成,
|
||||
/// 点击按钮时 TrySetResult 触发完成。
|
||||
@@ -81,179 +47,180 @@ namespace Ichni.Story.Dialogue
|
||||
private YarnTaskCompletionSource<DialogueOption?> _optionTcs;
|
||||
|
||||
/// <summary>
|
||||
/// 对应 StoryDialogueRoot 上的 DialogueRunner,用于调用 RequestNextLine / RequestHurryUpLine。
|
||||
/// 在 Awake 中通过 GetComponent 取得。
|
||||
/// 对应 StoryDialogueRoot 上的 DialogueRunner。
|
||||
/// </summary>
|
||||
private DialogueRunner _runner;
|
||||
|
||||
private DialogUIPage Page => uiPage != null ? uiPage : DialogUIPage.instance;
|
||||
|
||||
// ── 生命周期 ─────────────────────────────────────────────────────────────
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// VNDialoguePresenter 需要与 DialogueRunner 同 GameObject,通过 GetComponent 获取引用。
|
||||
_runner = GetComponent<DialogueRunner>();
|
||||
if (_runner == null)
|
||||
Debug.LogWarning("[VNDialoguePresenter] 未在同 GameObject 上找到 DialogueRunner。" +
|
||||
"请确认 VNDialoguePresenter 挂载在 StoryDialogueRoot 上。");
|
||||
}
|
||||
|
||||
// 启动时隐藏面板(alpha=0, 不响应交互)
|
||||
SetPanelState(visible: false, instant: true);
|
||||
private void Start()
|
||||
{
|
||||
if (Page == null) return;
|
||||
|
||||
// 启动时隐藏选项容器
|
||||
if (choiceFrame != null) choiceFrame.SetActive(false);
|
||||
if (Page.choiceFrame != null) Page.choiceFrame.SetActive(false);
|
||||
|
||||
// 注册推进按钮回调
|
||||
if (advanceButton != null)
|
||||
advanceButton.onClick.AddListener(OnAdvanceButtonClicked);
|
||||
if (Page.advanceButton != null)
|
||||
Page.advanceButton.onClick.AddListener(OnAdvanceButtonClicked);
|
||||
|
||||
// 注册快进按钮回调
|
||||
if (Page.fastForwardButton != null)
|
||||
Page.fastForwardButton.onClick.AddListener(OnFastForwardButtonClicked);
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (advanceButton != null)
|
||||
advanceButton.onClick.RemoveListener(OnAdvanceButtonClicked);
|
||||
if (Page != null)
|
||||
{
|
||||
if (Page.advanceButton != null)
|
||||
Page.advanceButton.onClick.RemoveListener(OnAdvanceButtonClicked);
|
||||
if (Page.fastForwardButton != null)
|
||||
Page.fastForwardButton.onClick.RemoveListener(OnFastForwardButtonClicked);
|
||||
}
|
||||
}
|
||||
|
||||
// ── DialoguePresenterBase 实现 ───────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// 对话开始:将面板淡入到可见状态。
|
||||
/// 在 DialogueRunner 开始第一行前由 Yarn 调用。
|
||||
/// </summary>
|
||||
public override async YarnTask OnDialogueStartedAsync()
|
||||
{
|
||||
// 先令 CanvasGroup 可交互但 alpha=0(为淡入动画做准备)
|
||||
SetPanelState(visible: true, instant: false);
|
||||
|
||||
if (panelGroup != null)
|
||||
await Effects.FadeAlphaAsync(panelGroup, 0f, 1f, fadeInDuration, CancellationToken.None);
|
||||
if (Page != null)
|
||||
{
|
||||
var tcs = new YarnTaskCompletionSource<bool>();
|
||||
Page.PlayFadeIn(() => tcs.TrySetResult(true));
|
||||
await tcs.Task;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 呈现一行台词。
|
||||
/// <list type="number">
|
||||
/// <item>隐藏选项区,显示说话者名称(若有)。</item>
|
||||
/// <item>逐字打字效果,期间可被 <c>HurryUpToken</c> 中断(显示全文)。</item>
|
||||
/// <item>等待玩家点击推进(<c>NextContentToken</c> 由 <see cref="DialogueRunner.RequestNextLine"/> 取消)。</item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public override async YarnTask RunLineAsync(LocalizedLine line, LineCancellationToken token)
|
||||
{
|
||||
if (Page == null) return;
|
||||
|
||||
// 确保选项区不可见;台词区始终可见
|
||||
if (choiceFrame != null) choiceFrame.SetActive(false);
|
||||
if (Page.choiceFrame != null) Page.choiceFrame.SetActive(false);
|
||||
|
||||
// ── 说话者名称 ──
|
||||
bool hasSpeaker = !string.IsNullOrEmpty(line.CharacterName);
|
||||
if (speakerContainer != null) speakerContainer.SetActive(hasSpeaker);
|
||||
if (speakerText != null) speakerText.text = hasSpeaker ? line.CharacterName : string.Empty;
|
||||
if (Page.speakerContainer != null) Page.speakerContainer.SetActive(hasSpeaker);
|
||||
if (Page.speakerText != null) Page.speakerText.text = hasSpeaker ? line.CharacterName : string.Empty;
|
||||
|
||||
// ── 立绘高亮 ──
|
||||
Page.portraitStage?.HighlightSpeaker(line.CharacterName);
|
||||
|
||||
// ── 打字效果 ──
|
||||
string fullText = line.TextWithoutCharacterName.Text;
|
||||
_typewriterComplete = false;
|
||||
|
||||
if (dialogueText != null)
|
||||
if (Page.dialogueText != null)
|
||||
{
|
||||
// 先将全文赋给 TMP,再通过 maxVisibleCharacters 逐步显示
|
||||
// (避免每帧 Substring 产生大量 GC 分配)
|
||||
dialogueText.text = fullText;
|
||||
dialogueText.maxVisibleCharacters = 0;
|
||||
Page.dialogueText.text = fullText;
|
||||
Page.dialogueText.maxVisibleCharacters = 0;
|
||||
}
|
||||
|
||||
// 逐字播放;若 HurryUpToken 被取消(玩家第一次点击)则立即跳出循环
|
||||
await TypewriterAsync(fullText, token.HurryUpToken);
|
||||
if (_isFastForwarding)
|
||||
{
|
||||
// 瞬间显示全文
|
||||
if (Page.dialogueText != null) Page.dialogueText.maxVisibleCharacters = int.MaxValue;
|
||||
_typewriterComplete = true;
|
||||
|
||||
// 确保全文可见(无论正常完成还是被加速中断)
|
||||
if (dialogueText != null)
|
||||
dialogueText.maxVisibleCharacters = int.MaxValue;
|
||||
// 极短的延迟,防止瞬间刷过几百句话造成卡顿,也给玩家微小的视觉感知
|
||||
await YarnTask.Delay(50).SuppressCancellationThrow();
|
||||
|
||||
_typewriterComplete = true;
|
||||
if (_isFastForwarding && _runner != null)
|
||||
{
|
||||
_runner.RequestNextLine();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 正常逐字播放
|
||||
await TypewriterAsync(fullText, token.HurryUpToken);
|
||||
|
||||
// 确保全文可见
|
||||
if (Page.dialogueText != null)
|
||||
Page.dialogueText.maxVisibleCharacters = int.MaxValue;
|
||||
|
||||
_typewriterComplete = true;
|
||||
}
|
||||
|
||||
// ── 等待玩家推进 ──
|
||||
// token.NextContentToken 由外部 DialogueRunner.RequestNextLine() 取消,
|
||||
// SuppressCancellationThrow 确保不抛出 OperationCanceledException。
|
||||
await YarnTask.WaitUntilCanceled(token.NextContentToken).SuppressCancellationThrow();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 呈现选项列表,等待玩家选择。
|
||||
/// <list type="number">
|
||||
/// <item>显示选项容器,配置每个按钮的文本与点击监听。</item>
|
||||
/// <item>通过 <see cref="YarnTaskCompletionSource{T}"/> 异步等待玩家选择。</item>
|
||||
/// <item>返回玩家选择的 <see cref="DialogueOption"/>(对话被外部取消则返回 null)。</item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public override async YarnTask<DialogueOption?> RunOptionsAsync(
|
||||
DialogueOption[] options,
|
||||
LineCancellationToken token)
|
||||
{
|
||||
if (Page == null) return null;
|
||||
|
||||
// 遇到选项强制打断快进
|
||||
_isFastForwarding = false;
|
||||
|
||||
// 清空台词区,准备显示选项
|
||||
if (speakerContainer != null) speakerContainer.SetActive(false);
|
||||
if (dialogueText != null) dialogueText.text = string.Empty;
|
||||
if (Page.speakerContainer != null) Page.speakerContainer.SetActive(false);
|
||||
if (Page.dialogueText != null) Page.dialogueText.text = string.Empty;
|
||||
|
||||
// 显示选项容器
|
||||
if (choiceFrame != null) choiceFrame.SetActive(true);
|
||||
if (Page.choiceFrame != null) Page.choiceFrame.SetActive(true);
|
||||
|
||||
// 创建选项选择的异步结果来源
|
||||
_optionTcs = new YarnTaskCompletionSource<DialogueOption?>();
|
||||
|
||||
// 当 NextContentToken 被外部取消(对话被强制结束),提前将 TCS 置为 null 结果,
|
||||
// 使 await _optionTcs.Task 能正常退出而不死锁。
|
||||
WaitForExternalCancelAsync(token.NextContentToken).Forget();
|
||||
|
||||
// ── 配置每个选项按钮 ──
|
||||
for (int i = 0; i < choiceButtons.Length; i++)
|
||||
for (int i = 0; i < Page.choiceButtons.Length; i++)
|
||||
{
|
||||
// 只显示当前实际有效且可用的选项
|
||||
bool active = i < options.Length && options[i].IsAvailable;
|
||||
if (choiceButtons[i] != null)
|
||||
choiceButtons[i].gameObject.SetActive(active);
|
||||
if (Page.choiceButtons[i] == null) continue;
|
||||
|
||||
if (!active) continue;
|
||||
|
||||
// 设置按钮文本
|
||||
if (i < choiceTexts.Length && choiceTexts[i] != null)
|
||||
choiceTexts[i].text = options[i].Line.TextWithoutCharacterName.Text;
|
||||
|
||||
// 捕获循环变量,避免闭包捕获错误索引
|
||||
DialogueOption captured = options[i];
|
||||
choiceButtons[i].onClick.RemoveAllListeners();
|
||||
choiceButtons[i].onClick.AddListener(() => _optionTcs.TrySetResult(captured));
|
||||
if (i < options.Length)
|
||||
Page.choiceButtons[i].Setup(options[i], opt => _optionTcs.TrySetResult(opt));
|
||||
else
|
||||
Page.choiceButtons[i].Cleanup();
|
||||
}
|
||||
|
||||
// ── 等待玩家选择 ──
|
||||
DialogueOption? selected = await _optionTcs.Task;
|
||||
|
||||
// 清理按钮监听,隐藏选项容器
|
||||
foreach (Button btn in choiceButtons)
|
||||
if (btn != null) btn.onClick.RemoveAllListeners();
|
||||
// 清理所有按钮并隐藏选项容器
|
||||
foreach (ChoiceButton btn in Page.choiceButtons)
|
||||
btn?.Cleanup();
|
||||
|
||||
if (choiceFrame != null) choiceFrame.SetActive(false);
|
||||
if (Page.choiceFrame != null) Page.choiceFrame.SetActive(false);
|
||||
|
||||
return selected;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 对话结束:淡出并隐藏对话面板。
|
||||
/// 在 DialogueRunner 处理完最后一行/选项后由 Yarn 调用。
|
||||
/// </summary>
|
||||
public override async YarnTask OnDialogueCompleteAsync()
|
||||
{
|
||||
if (panelGroup != null)
|
||||
await Effects.FadeAlphaAsync(panelGroup, 1f, 0f, fadeOutDuration, CancellationToken.None);
|
||||
|
||||
SetPanelState(visible: false, instant: true);
|
||||
if (Page != null)
|
||||
{
|
||||
var tcs = new YarnTaskCompletionSource<bool>();
|
||||
Page.PlayFadeOut(() => tcs.TrySetResult(true));
|
||||
await tcs.Task;
|
||||
}
|
||||
}
|
||||
|
||||
// ── 内部方法 ─────────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// 推进按钮点击回调。
|
||||
/// <list type="bullet">
|
||||
/// <item>打字中 → RequestHurryUpLine(取消 HurryUpToken,立即显示全文)。</item>
|
||||
/// <item>打字完毕 → RequestNextLine(取消 NextContentToken,进入下一行)。</item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
private void OnAdvanceButtonClicked()
|
||||
{
|
||||
// 如果玩家在快进时点击屏幕/推进键,则打断快进状态并停止当前动作
|
||||
if (_isFastForwarding)
|
||||
{
|
||||
_isFastForwarding = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_runner == null) return;
|
||||
|
||||
if (!_typewriterComplete)
|
||||
@@ -262,55 +229,40 @@ namespace Ichni.Story.Dialogue
|
||||
_runner.RequestNextLine(); // 第二次点击:推进到下一行
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 控制对话面板 <see cref="panelGroup"/> 的显示状态。
|
||||
/// </summary>
|
||||
/// <param name="visible">是否可见且可交互。</param>
|
||||
/// <param name="instant">为 true 时立即设置 alpha;为 false 时仅设置 interactable/blocksRaycasts,
|
||||
/// alpha 留给外部的 <c>FadeAlphaAsync</c> 动画处理。</param>
|
||||
private void SetPanelState(bool visible, bool instant)
|
||||
private void OnFastForwardButtonClicked()
|
||||
{
|
||||
if (panelGroup == null) return;
|
||||
panelGroup.interactable = visible;
|
||||
panelGroup.blocksRaycasts = visible;
|
||||
if (instant) panelGroup.alpha = visible ? 1f : 0f;
|
||||
_isFastForwarding = true;
|
||||
|
||||
if (_runner == null) return;
|
||||
|
||||
// 立即跳过当前的等待状态
|
||||
if (!_typewriterComplete)
|
||||
_runner.RequestHurryUpLine();
|
||||
else
|
||||
_runner.RequestNextLine();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 逐字打字效果。
|
||||
/// 通过 <c>maxVisibleCharacters</c> 逐步显示文本(无 GC 分配)。
|
||||
/// 被 <paramref name="hurryUpToken"/> 取消时立即返回,调用方负责将 maxVisibleCharacters 设为 MaxValue。
|
||||
/// </summary>
|
||||
/// <param name="text">要逐字展示的完整文本(已预先赋值给 dialogueText.text)。</param>
|
||||
/// <param name="hurryUpToken">取消此 token 可跳过打字效果。</param>
|
||||
private async YarnTask TypewriterAsync(string text, CancellationToken hurryUpToken)
|
||||
{
|
||||
if (dialogueText == null) return;
|
||||
if (Page.dialogueText == null) return;
|
||||
|
||||
// lettersPerSecond <= 0 时瞬间显示全文
|
||||
if (lettersPerSecond <= 0f)
|
||||
{
|
||||
dialogueText.maxVisibleCharacters = int.MaxValue;
|
||||
Page.dialogueText.maxVisibleCharacters = int.MaxValue;
|
||||
return;
|
||||
}
|
||||
|
||||
int delayMs = Mathf.Max(1, Mathf.RoundToInt(1000f / lettersPerSecond));
|
||||
|
||||
// TMP 的 maxVisibleCharacters 控制可见字符数(不含 rich-text 标签)
|
||||
// 逐帧递增直到全文显示或被 hurryUpToken 中断
|
||||
for (int i = 1; i <= text.Length; i++)
|
||||
{
|
||||
if (hurryUpToken.IsCancellationRequested) return;
|
||||
dialogueText.maxVisibleCharacters = i;
|
||||
Page.dialogueText.maxVisibleCharacters = i;
|
||||
await YarnTask.Delay(delayMs, hurryUpToken).SuppressCancellationThrow();
|
||||
if (hurryUpToken.IsCancellationRequested) return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 监听外部取消信号(对话被强制终止),将 <see cref="_optionTcs"/> 设为 null 结果,
|
||||
/// 确保 <see cref="RunOptionsAsync"/> 的 await 能正常退出而不会死锁。
|
||||
/// </summary>
|
||||
private async YarnTask WaitForExternalCancelAsync(CancellationToken externalToken)
|
||||
{
|
||||
await YarnTask.WaitUntilCanceled(externalToken).SuppressCancellationThrow();
|
||||
|
||||
334
Assets/Scripts/NewStorySystem/Dialogue/VNPortraitStage.cs
Normal file
334
Assets/Scripts/NewStorySystem/Dialogue/VNPortraitStage.cs
Normal file
@@ -0,0 +1,334 @@
|
||||
using System.Collections.Generic;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.Story.Dialogue
|
||||
{
|
||||
/// <summary>
|
||||
/// VN 立绘舞台。管理当前对话中所有已上台角色的 <see cref="IPortraitRenderer"/> 实例。
|
||||
/// 依据用户的合理建议,为了支持未知数量的角色同时出现,本系统改为【动态生成与移除】机制:
|
||||
/// <list type="bullet">
|
||||
/// <item>当角色需要上台时,依据其 <see cref="CharacterData.portraitStyle"/> 动态实例化 Prefab。</item>
|
||||
/// <item>当角色下台时,直接销毁(Destroy)对应的 GameObject 释放内存。</item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public class VNPortraitStage : MonoBehaviour
|
||||
{
|
||||
public static VNPortraitStage Instance { get; private set; }
|
||||
|
||||
// ── 配置 ────────────────────────────────────────────────────────────────
|
||||
|
||||
[Header("Prefab Settings")]
|
||||
[Tooltip("默认的 Sprite 立绘预制体。当角色的 Portrait Style 为 Sprite 时使用此预制体进行实例化。" +
|
||||
"该预制体上必须挂载了实现 IPortraitRenderer 的组件(如 SpritePortraitRenderer)。")]
|
||||
[SerializeField]
|
||||
private GameObject _spritePortraitPrefab;
|
||||
|
||||
[Header("Canvas Reference")]
|
||||
[Tooltip("立绘容器的 RectTransform,作为所有生成立绘的父节点。也是坐标映射的基准(通常指向 DialogPage/PortraitContainer)。")]
|
||||
[SerializeField]
|
||||
private RectTransform _portraitContainer;
|
||||
|
||||
// ── 运行时状态 ───────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>当前已上台的活跃角色:characterId → 其对应的渲染器实例</summary>
|
||||
private readonly Dictionary<string, IPortraitRenderer> _activePortraits =
|
||||
new Dictionary<string, IPortraitRenderer>();
|
||||
|
||||
// ── 生命周期 ─────────────────────────────────────────────────────────────
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (Instance == this)
|
||||
{
|
||||
Instance = null;
|
||||
}
|
||||
}
|
||||
|
||||
// ── 公共 API ─────────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// 当前说话者角色 Id(由 Yarn 行数据驱动)。
|
||||
/// </summary>
|
||||
public string CurrentSpeakerId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// 显示角色立绘。如果角色已在台上则更新情绪和位置;
|
||||
/// 如果不在台上,则根据其渲染类型动态生成,并置于容器内。
|
||||
/// 这里的坐标是归一化坐标 (-100, 100),内部会自动加上该角色的 positionOffset。
|
||||
/// </summary>
|
||||
/// <param name="characterId">角色 ID(需在 CharacterRegistry 中存在)。</param>
|
||||
/// <param name="emotion">初始情绪名。</param>
|
||||
/// <param name="normalizedPosition">目标归一化坐标 [-100, 100]。</param>
|
||||
/// <returns>成功生成或更新返回 true,失败返回 false。</returns>
|
||||
public bool ShowPortrait(string characterId, string emotion, Vector2 normalizedPosition)
|
||||
{
|
||||
CharacterData data = GetCharacterData(characterId);
|
||||
if (data == null) return false;
|
||||
|
||||
// 1. 计算最终的像素坐标(应用 CharacterData 中配置的 positionOffset)
|
||||
Vector2 finalNormalizedPos = normalizedPosition + data.positionOffset;
|
||||
Vector2 pixelPos = NormalizedToAnchoredPosition(finalNormalizedPos.x, finalNormalizedPos.y);
|
||||
|
||||
// 2. 如果角色已在台上,直接更新情绪与位置
|
||||
if (_activePortraits.TryGetValue(characterId, out IPortraitRenderer existing))
|
||||
{
|
||||
existing.SetEmotion(emotion);
|
||||
existing.SetPosition(pixelPos);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 2. 如果不在台上,决定使用哪一个预制体进行动态生成
|
||||
GameObject prefabToInstantiate = null;
|
||||
|
||||
if (data.portraitStyle == PortraitStyle.Sprite)
|
||||
{
|
||||
prefabToInstantiate = _spritePortraitPrefab;
|
||||
if (prefabToInstantiate == null)
|
||||
{
|
||||
Debug.LogError("[VNPortraitStage] 未配置 _spritePortraitPrefab,无法动态生成 Sprite 立绘!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else // Live2D / Spine
|
||||
{
|
||||
prefabToInstantiate = data.dynamicPortraitPrefab;
|
||||
if (prefabToInstantiate == null)
|
||||
{
|
||||
Debug.LogError($"[VNPortraitStage] 角色 '{characterId}' 为动态立绘,但 CharacterData 中未配置 dynamicPortraitPrefab!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 动态实例化
|
||||
GameObject go = Instantiate(prefabToInstantiate, _portraitContainer);
|
||||
go.name = $"Portrait_{characterId}";
|
||||
|
||||
// 确保坐标系和缩放正确
|
||||
RectTransform rect = go.GetComponent<RectTransform>();
|
||||
if (rect != null)
|
||||
{
|
||||
rect.localScale = Vector3.one;
|
||||
rect.localRotation = Quaternion.identity;
|
||||
}
|
||||
|
||||
IPortraitRenderer renderer = go.GetComponent<IPortraitRenderer>();
|
||||
if (renderer == null)
|
||||
{
|
||||
Debug.LogError($"[VNPortraitStage] 生成的预制体 '{go.name}' 缺少实现 IPortraitRenderer 接口的组件!");
|
||||
Destroy(go);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 4. 显示并定位
|
||||
renderer.Show(data, emotion);
|
||||
renderer.SetPosition(pixelPos);
|
||||
|
||||
// 5. 登记到活跃立绘列表
|
||||
_activePortraits[characterId] = renderer;
|
||||
|
||||
// 6. 保持当前说话者的高亮状态一致
|
||||
renderer.SetActiveVisual(characterId == CurrentSpeakerId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除并销毁指定角色的立绘。
|
||||
/// </summary>
|
||||
public void HidePortrait(string characterId)
|
||||
{
|
||||
if (_activePortraits.TryGetValue(characterId, out IPortraitRenderer renderer))
|
||||
{
|
||||
if (renderer is MonoBehaviour mb && mb != null)
|
||||
{
|
||||
Destroy(mb.gameObject);
|
||||
}
|
||||
_activePortraits.Remove(characterId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空并销毁所有当前在台上的立绘。
|
||||
/// </summary>
|
||||
public void HideAll()
|
||||
{
|
||||
foreach (IPortraitRenderer renderer in _activePortraits.Values)
|
||||
{
|
||||
if (renderer is MonoBehaviour mb && mb != null)
|
||||
{
|
||||
Destroy(mb.gameObject);
|
||||
}
|
||||
}
|
||||
_activePortraits.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置或移动立绘位置,并可选择性地更新表情。如果角色不在台上,则会动态生成它。
|
||||
/// </summary>
|
||||
/// <param name="characterId">角色 ID。</param>
|
||||
/// <param name="normalizedPosition">目标归一化坐标 [-100, 100],会自动应用角色的 positionOffset。</param>
|
||||
/// <param name="emotion">可选表情。如果为 null 且角色已在台上,则保持当前表情;若角色不在台上,则默认使用 "normal"。</param>
|
||||
public void SetPortraitPosition(string characterId, Vector2 normalizedPosition, string emotion = null)
|
||||
{
|
||||
CharacterData data = GetCharacterData(characterId);
|
||||
if (data == null) return;
|
||||
|
||||
// 计算包含角色特定偏移量的最终像素坐标
|
||||
Vector2 finalNormalizedPos = normalizedPosition + data.positionOffset;
|
||||
Vector2 pixelPos = NormalizedToAnchoredPosition(finalNormalizedPos.x, finalNormalizedPos.y);
|
||||
|
||||
if (_activePortraits.TryGetValue(characterId, out IPortraitRenderer renderer))
|
||||
{
|
||||
renderer.SetPosition(pixelPos);
|
||||
if (!string.IsNullOrEmpty(emotion))
|
||||
{
|
||||
renderer.SetEmotion(emotion);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 不在台上,则用指定表情(空时默认 "normal")在目标位置生成它
|
||||
string targetEmotion = string.IsNullOrEmpty(emotion) ? "normal" : emotion;
|
||||
ShowPortrait(characterId, targetEmotion, normalizedPosition);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 说话者高亮压暗处理:当前说话者高亮,其余压暗。
|
||||
/// </summary>
|
||||
public void HighlightSpeaker(string characterId)
|
||||
{
|
||||
CurrentSpeakerId = characterId;
|
||||
|
||||
foreach (KeyValuePair<string, IPortraitRenderer> kv in _activePortraits)
|
||||
{
|
||||
kv.Value.SetActiveVisual(kv.Key == characterId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 仅改变角色的表情(角色必须已在台上)。
|
||||
/// </summary>
|
||||
public void SetPortraitEmotion(string characterId, string emotion)
|
||||
{
|
||||
if (_activePortraits.TryGetValue(characterId, out IPortraitRenderer renderer))
|
||||
{
|
||||
renderer.SetEmotion(emotion);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"[VNPortraitStage] 无法仅设置表情:角色 '{characterId}' 目前不在台上。");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 平滑移动立绘到目标归一化坐标。
|
||||
/// </summary>
|
||||
public void MovePortrait(string characterId, Vector2 normalizedPosition, float duration)
|
||||
{
|
||||
if (_activePortraits.TryGetValue(characterId, out IPortraitRenderer renderer))
|
||||
{
|
||||
CharacterData data = GetCharacterData(characterId);
|
||||
if (data != null)
|
||||
{
|
||||
Vector2 finalNormalizedPos = normalizedPosition + data.positionOffset;
|
||||
Vector2 pixelPos = NormalizedToAnchoredPosition(finalNormalizedPos.x, finalNormalizedPos.y);
|
||||
renderer.MoveTo(pixelPos, duration);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"[VNPortraitStage] 无法移动:角色 '{characterId}' 目前不在台上。");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 让指定角色的立绘跳跃。
|
||||
/// </summary>
|
||||
/// <param name="normalizedPower">跳跃高度(归一化坐标尺度)</param>
|
||||
public void JumpPortrait(string characterId, float normalizedPower, int numJumps, float duration)
|
||||
{
|
||||
if (_activePortraits.TryGetValue(characterId, out IPortraitRenderer renderer))
|
||||
{
|
||||
float pixelPower = NormalizedToPixelDistance(normalizedPower, false); // 跳跃基于 Y 轴高度
|
||||
renderer.Jump(pixelPower, numJumps, duration);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"[VNPortraitStage] 无法跳跃:角色 '{characterId}' 目前不在台上。");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 让指定角色的立绘震动。
|
||||
/// </summary>
|
||||
/// <param name="normalizedStrength">震动幅度(归一化坐标尺度)</param>
|
||||
public void ShakePortrait(string characterId, float duration, float normalizedStrength, int vibrato)
|
||||
{
|
||||
if (_activePortraits.TryGetValue(characterId, out IPortraitRenderer renderer))
|
||||
{
|
||||
float pixelStrength = NormalizedToPixelDistance(normalizedStrength, true); // 左右震动基于 X 轴宽度
|
||||
renderer.Shake(duration, pixelStrength, vibrato);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"[VNPortraitStage] 无法震动:角色 '{characterId}' 目前不在台上。");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将归一化坐标 (-100, 100) 映射为 anchoredPosition 像素坐标。
|
||||
/// </summary>
|
||||
public Vector2 NormalizedToAnchoredPosition(float normalizedX, float normalizedY)
|
||||
{
|
||||
if (_portraitContainer == null)
|
||||
{
|
||||
Debug.LogWarning("[VNPortraitStage] _portraitContainer 未配置,坐标映射使用 1920x1080 默认尺寸映射。");
|
||||
return new Vector2(normalizedX / 100f * 960f, normalizedY / 100f * 540f);
|
||||
}
|
||||
|
||||
Vector2 halfSize = _portraitContainer.rect.size * 0.5f;
|
||||
return new Vector2(normalizedX / 100f * halfSize.x, normalizedY / 100f * halfSize.y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将归一化距离映射为像素距离(用于动画幅度换算)。
|
||||
/// </summary>
|
||||
/// <param name="normalizedDistance">归一化长度</param>
|
||||
/// <param name="useXAxis">是否基于 X 轴进行映射(否则基于 Y 轴)</param>
|
||||
public float NormalizedToPixelDistance(float normalizedDistance, bool useXAxis = false)
|
||||
{
|
||||
if (_portraitContainer == null)
|
||||
{
|
||||
return normalizedDistance / 100f * (useXAxis ? 960f : 540f);
|
||||
}
|
||||
Vector2 halfSize = _portraitContainer.rect.size * 0.5f;
|
||||
return normalizedDistance / 100f * (useXAxis ? halfSize.x : halfSize.y);
|
||||
}
|
||||
|
||||
// ── 内部辅助 ─────────────────────────────────────────────────────────────
|
||||
|
||||
private CharacterData GetCharacterData(string characterId)
|
||||
{
|
||||
if (StoryManager.instance == null || StoryManager.instance.characterRegistry == null)
|
||||
{
|
||||
Debug.LogError("[VNPortraitStage] StoryManager 或 CharacterRegistry 未初始化!");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!StoryManager.instance.characterRegistry.TryGet(characterId, out CharacterData data))
|
||||
{
|
||||
Debug.LogWarning($"[VNPortraitStage] 在 CharacterRegistry 中找不到 ID 为 '{characterId}' 的 CharacterData 资产。");
|
||||
return null;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec4abf93d4e3d1d448630a311fe7c236
|
||||
@@ -9,7 +9,6 @@ namespace Ichni.Story.UI
|
||||
{
|
||||
public class StoryUIPage : UIPageBase
|
||||
{
|
||||
public MessageBox messageBox;
|
||||
public Button backButton;
|
||||
|
||||
protected override void Awake()
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3ec0b23c77de2764d9425add8f28ea00
|
||||
guid: 981c044487823304aade761b1adaf914
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2de1e277bcf059c42826353d1c086ccc
|
||||
guid: 0d5fd17f91f4f8049953f00fe242b32c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
71
Assets/Scripts/NewStorySystem/UI/DialogUIPage.cs
Normal file
71
Assets/Scripts/NewStorySystem/UI/DialogUIPage.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using Ichni.Story.Dialogue;
|
||||
using Ichni.UI;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Ichni.Story.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// 对话系统专用的 UI 页面容器。
|
||||
/// 接管整个对话面板的淡入淡出及交互状态控制,
|
||||
/// 将显示生命周期与对话流逻辑 (VNDialoguePresenter) 彻底解耦。
|
||||
/// </summary>
|
||||
public class DialogUIPage : UIPageBase
|
||||
{
|
||||
public static DialogUIPage instance;
|
||||
|
||||
[Header("立绘舞台")]
|
||||
public VNPortraitStage portraitStage;
|
||||
|
||||
[Header("台词区")]
|
||||
public TMPro.TextMeshProUGUI dialogueText;
|
||||
public GameObject speakerContainer;
|
||||
public TMPro.TextMeshProUGUI speakerText;
|
||||
|
||||
[Header("推进按钮")]
|
||||
public UnityEngine.UI.Button advanceButton;
|
||||
[Tooltip("点击后自动快进,直到遇到选项")]
|
||||
public UnityEngine.UI.Button fastForwardButton;
|
||||
|
||||
[Header("选项区")]
|
||||
public GameObject choiceFrame;
|
||||
public ChoiceButton[] choiceButtons = new ChoiceButton[4];
|
||||
|
||||
[Header("动态组件")]
|
||||
public DialogWheel dialogWheel;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
if (instance == null)
|
||||
{
|
||||
instance = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
|
||||
// 默认启动时强制隐藏
|
||||
if (mainCanvasGroup != null)
|
||||
{
|
||||
mainCanvasGroup.alpha = 0f;
|
||||
mainCanvasGroup.interactable = false;
|
||||
mainCanvasGroup.blocksRaycasts = false;
|
||||
mainCanvasGroup.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void PlayFadeIn(UnityAction onComplete = null)
|
||||
{
|
||||
FadeIn(0.2f, false, onComplete);
|
||||
}
|
||||
|
||||
public void PlayFadeOut(UnityAction onComplete = null)
|
||||
{
|
||||
FadeOut(0.2f, false, onComplete);
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/NewStorySystem/UI/DialogUIPage.cs.meta
Normal file
2
Assets/Scripts/NewStorySystem/UI/DialogUIPage.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0e1e4a2c0a479784e839bdf448215e19
|
||||
72
Assets/Scripts/NewStorySystem/UI/DialogWheel.cs
Normal file
72
Assets/Scripts/NewStorySystem/UI/DialogWheel.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
using DG.Tweening;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.Story.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// 对话时常驻转动的齿轮/轮盘,以及伴随浮动的指针。
|
||||
/// </summary>
|
||||
public class DialogWheel : MonoBehaviour
|
||||
{
|
||||
[Header("轮盘旋转")]
|
||||
[Tooltip("要旋转的 RectTransform。如果不填,默认获取自身。")]
|
||||
public RectTransform wheelRect;
|
||||
|
||||
[Tooltip("顺时针旋转一整圈(360度)所需的时间(秒)")]
|
||||
public float rotationCycleDuration = 5f;
|
||||
|
||||
[Header("指针浮动")]
|
||||
[Tooltip("常驻上下浮动的指针对象 (RectTransform)")]
|
||||
public RectTransform pointerRect;
|
||||
|
||||
[Tooltip("指针单向浮动的距离(像素)")]
|
||||
public float pointerFloatDistance = 5f;
|
||||
|
||||
[Tooltip("指针完成单向浮动所需的时间")]
|
||||
public float pointerFloatDuration = 0.3f;
|
||||
|
||||
private Tween _rotateTween;
|
||||
private Tween _pointerTween;
|
||||
private float _pointerStartY;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (wheelRect == null) wheelRect = GetComponent<RectTransform>();
|
||||
|
||||
if (pointerRect != null)
|
||||
{
|
||||
_pointerStartY = pointerRect.anchoredPosition.y;
|
||||
}
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
// 轮盘常驻匀速旋转
|
||||
if (wheelRect != null && rotationCycleDuration > 0f)
|
||||
{
|
||||
// SetRelative(true) 保证无论当前角度是多少,都在其基础上转 -360 度
|
||||
// LoopType.Restart 配合 Linear 缓动,实现无限丝滑旋转
|
||||
_rotateTween = wheelRect.DORotate(new Vector3(0, 0, -360f), rotationCycleDuration, RotateMode.FastBeyond360)
|
||||
.SetRelative(true)
|
||||
.SetLoops(-1, LoopType.Restart)
|
||||
.SetEase(Ease.Linear);
|
||||
_rotateTween.Play();
|
||||
}
|
||||
|
||||
// 指针常驻浮动,启动后永不停止
|
||||
if (pointerRect != null)
|
||||
{
|
||||
_pointerTween = pointerRect.DOAnchorPosY(_pointerStartY + pointerFloatDistance, pointerFloatDuration)
|
||||
.SetLoops(-1, LoopType.Yoyo)
|
||||
.SetEase(Ease.InOutSine);
|
||||
_pointerTween.Play();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
_rotateTween?.Kill();
|
||||
_pointerTween?.Kill();
|
||||
}
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/NewStorySystem/UI/DialogWheel.cs.meta
Normal file
2
Assets/Scripts/NewStorySystem/UI/DialogWheel.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 027bcd2c2d137f5458f8b12002234663
|
||||
143
Assets/Scripts/NewStorySystem/UI/StoryMessageBoxUIPage.cs
Normal file
143
Assets/Scripts/NewStorySystem/UI/StoryMessageBoxUIPage.cs
Normal file
@@ -0,0 +1,143 @@
|
||||
using System.Collections.Generic;
|
||||
using Ichni.Menu.UI;
|
||||
using Ichni.UI;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.Story.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// 用于在剧情系统中管理并顺序展示 MessageBox 的独立 UI 页面。
|
||||
/// 支持动态实例化给定的 MessageBox Prefab,并在所有消息展示完毕后进行大页面的 FadeOut。
|
||||
/// </summary>
|
||||
public class StoryMessageBoxUIPage : UIPageBase
|
||||
{
|
||||
public static StoryMessageBoxUIPage instance;
|
||||
|
||||
[Header("Prefabs & Containers")]
|
||||
[Tooltip("默认使用的 MessageBox 预制体(请从 Project 中拖拽,而非场景中的实例)")]
|
||||
public MessageBox defaultMessageBoxPrefab;
|
||||
|
||||
[Tooltip("生成的 MessageBox 挂载在哪?如果不填,默认挂载在自己身上")]
|
||||
public Transform messageContainer;
|
||||
|
||||
// 用于排队的内部消息数据结构
|
||||
private struct PendingMessage
|
||||
{
|
||||
public string title;
|
||||
public string content;
|
||||
public MessageBox customPrefab; // 支持未来传入不同种类的 Prefab
|
||||
}
|
||||
|
||||
private Queue<PendingMessage> _messageQueue = new Queue<PendingMessage>();
|
||||
private MessageBox _currentActiveBox;
|
||||
private bool _isPageActive = false;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
if (instance == null)
|
||||
{
|
||||
instance = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("[StoryMessageBoxUIPage] 场景中存在多个实例,正在销毁多余的实例。");
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
|
||||
if (messageContainer == null)
|
||||
{
|
||||
messageContainer = this.transform;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将歌曲解锁提示加入弹窗队列。
|
||||
/// </summary>
|
||||
public void ShowUnlockMessage(string songUnlockKey)
|
||||
{
|
||||
string title = "New Song Unlocked!";
|
||||
string content = $"You have unlocked the song: {songUnlockKey}!";
|
||||
EnqueueMessage(title, content, defaultMessageBoxPrefab);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将自定义文本提示加入弹窗队列。
|
||||
/// </summary>
|
||||
public void ShowCustomMessage(string title, string content)
|
||||
{
|
||||
EnqueueMessage(title, content, defaultMessageBoxPrefab);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将指定消息入队。如果是空闲状态,则唤醒大页面并开始处理队列。
|
||||
/// </summary>
|
||||
private void EnqueueMessage(string title, string content, MessageBox prefab)
|
||||
{
|
||||
if (prefab == null)
|
||||
{
|
||||
Debug.LogError("[StoryMessageBoxUIPage] 没有可用的 MessageBox 预制体!");
|
||||
return;
|
||||
}
|
||||
|
||||
_messageQueue.Enqueue(new PendingMessage
|
||||
{
|
||||
title = title,
|
||||
content = content,
|
||||
customPrefab = prefab
|
||||
});
|
||||
|
||||
// 如果当前页面没有在显示中,则开始整体流程
|
||||
if (!_isPageActive)
|
||||
{
|
||||
_isPageActive = true;
|
||||
|
||||
// 唤醒大页面(执行 UIPageBase 的渐入并拦截底层射线)
|
||||
this.FadeIn(0.5f, false, ShowNextInQueue);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从队列中取出一个并实例化显示。
|
||||
/// </summary>
|
||||
private void ShowNextInQueue()
|
||||
{
|
||||
if (_messageQueue.Count == 0)
|
||||
{
|
||||
// 队列处理完毕,大页面整体退场
|
||||
_currentActiveBox = null;
|
||||
_isPageActive = false;
|
||||
this.FadeOut();
|
||||
return;
|
||||
}
|
||||
|
||||
PendingMessage msg = _messageQueue.Dequeue();
|
||||
|
||||
// 实例化预制体
|
||||
_currentActiveBox = Instantiate(msg.customPrefab, messageContainer);
|
||||
|
||||
// 订阅“当这个消息框彻底结束关闭时”的事件
|
||||
_currentActiveBox.onAllMessagesClosed.AddListener(() =>
|
||||
{
|
||||
// 销毁旧实例
|
||||
if (_currentActiveBox != null)
|
||||
{
|
||||
Destroy(_currentActiveBox.gameObject);
|
||||
}
|
||||
|
||||
// 检查并显示下一个
|
||||
ShowNextInQueue();
|
||||
});
|
||||
|
||||
// 配置并启动 MessageBox
|
||||
_currentActiveBox.Clear();
|
||||
_currentActiveBox.AddInfo(msg.title, msg.content, null);
|
||||
|
||||
// MessageBox.SetUp() 内部会激活自己并执行自己的 FadeIn
|
||||
_currentActiveBox.gameObject.SetActive(true);
|
||||
_currentActiveBox.SetUp();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07f2a7ffd4b513d4e90d60a6587914cc
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31a6a9bf0919951489cacfb86fb715c9
|
||||
guid: 0700ab9bd015c9e4f8e5dcdc6f5f59ce
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -0,0 +1,30 @@
|
||||
using UnityEngine;
|
||||
using Yarn.Unity;
|
||||
|
||||
namespace Ichni.Story.YarnFunctions
|
||||
{
|
||||
public static class GeneralFunctions
|
||||
{
|
||||
[YarnCommand("log")]
|
||||
public static void Log(string message, string logType)
|
||||
{
|
||||
logType = logType.ToLower();
|
||||
|
||||
switch (logType)
|
||||
{
|
||||
case "info":
|
||||
Debug.Log(message);
|
||||
break;
|
||||
case "warning":
|
||||
Debug.LogWarning(message);
|
||||
break;
|
||||
case "error":
|
||||
Debug.LogError(message);
|
||||
break;
|
||||
default:
|
||||
Debug.Log(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1af4095ad0bedbe41b834a162253a0e8
|
||||
@@ -0,0 +1,69 @@
|
||||
using UnityEngine;
|
||||
using Yarn.Unity;
|
||||
|
||||
namespace Ichni.Story.YarnFunctions
|
||||
{
|
||||
/// <summary>
|
||||
/// 立绘动画控制相关的 Yarn 自定义命令静态注册器。
|
||||
/// 包含平移、跳跃、震动等 DOTween 动画表现。
|
||||
/// </summary>
|
||||
public static class PortraitAnimationCommands
|
||||
{
|
||||
// ── Yarn Commands ────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// 平滑移动角色立绘到目标位置。
|
||||
/// 格式: <<move_portrait characterId x y duration>>
|
||||
/// </summary>
|
||||
/// <param name="characterId">角色标识 ID</param>
|
||||
/// <param name="x">目标 X 坐标 [-100, 100]</param>
|
||||
/// <param name="y">目标 Y 坐标 [-100, 100]</param>
|
||||
/// <param name="duration">动画持续时间(秒)</param>
|
||||
[YarnCommand("move_portrait")]
|
||||
public static void MovePortrait(string characterId, float x, float y, float duration)
|
||||
{
|
||||
if (!EnsureStage()) return;
|
||||
Dialogue.VNPortraitStage.Instance.MovePortrait(characterId, new Vector2(x, y), duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 让角色立绘原地跳跃。
|
||||
/// 格式: <<jump_portrait characterId power numJumps duration>>
|
||||
/// </summary>
|
||||
/// <param name="characterId">角色标识 ID</param>
|
||||
/// <param name="power">跳跃高度(使用与坐标域相同的归一化尺度,如 10 表示 10% 高度)</param>
|
||||
/// <param name="numJumps">跳跃次数</param>
|
||||
/// <param name="duration">动画总持续时间(秒)</param>
|
||||
[YarnCommand("jump_portrait")]
|
||||
public static void JumpPortrait(string characterId, float power, int numJumps, float duration)
|
||||
{
|
||||
if (!EnsureStage()) return;
|
||||
Dialogue.VNPortraitStage.Instance.JumpPortrait(characterId, power, numJumps, duration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 让角色立绘产生左右震动效果。
|
||||
/// 格式: <<shake_portrait characterId duration strength vibrato>>
|
||||
/// </summary>
|
||||
/// <param name="characterId">角色标识 ID</param>
|
||||
/// <param name="duration">震动持续时间(秒)</param>
|
||||
/// <param name="strength">震动幅度(使用与坐标域相同的归一化尺度)</param>
|
||||
/// <param name="vibrato">震动频率</param>
|
||||
[YarnCommand("shake_portrait")]
|
||||
public static void ShakePortrait(string characterId, float duration, float strength, int vibrato)
|
||||
{
|
||||
if (!EnsureStage()) return;
|
||||
Dialogue.VNPortraitStage.Instance.ShakePortrait(characterId, duration, strength, vibrato);
|
||||
}
|
||||
|
||||
// ── 内部辅助 ─────────────────────────────────────────────────────────────
|
||||
|
||||
private static bool EnsureStage()
|
||||
{
|
||||
if (Dialogue.VNPortraitStage.Instance != null) return true;
|
||||
|
||||
Debug.LogError("[PortraitAnimationCommands] 未找到 VNPortraitStage 实例!请确保在当前场景中存在挂载了 VNPortraitStage 的游戏物体。");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 50b4898984f9bfc4da527dcd444f87b3
|
||||
112
Assets/Scripts/NewStorySystem/YarnFunctions/PortraitCommands.cs
Normal file
112
Assets/Scripts/NewStorySystem/YarnFunctions/PortraitCommands.cs
Normal file
@@ -0,0 +1,112 @@
|
||||
using UnityEngine;
|
||||
using Yarn.Unity;
|
||||
|
||||
namespace Ichni.Story.YarnFunctions
|
||||
{
|
||||
/// <summary>
|
||||
/// 立绘控制相关的 Yarn 自定义命令静态注册器。
|
||||
/// <para>
|
||||
/// 全局静态命令,不依赖于 GameObject 的挂载。所有方法都使用强类型的参数,
|
||||
/// 以更明确、简洁的指令名称区分不同应用场景,从而抛弃复杂的内部字符串解析判断。
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public static class PortraitCommands
|
||||
{
|
||||
// ── Yarn Commands ────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// 最基础、最全面的立绘指令:设置指定角色的坐标和表情。
|
||||
/// 若角色不在台上,会自动以指定的表情和位置实例化。
|
||||
/// 格式: <<set_portrait characterId x y [emotion]>>
|
||||
/// </summary>
|
||||
/// <param name="characterId">角色标识 ID。</param>
|
||||
/// <param name="x">归一化 X 坐标 [-100, 100]</param>
|
||||
/// <param name="y">归一化 Y 坐标 [-100, 100]</param>
|
||||
/// <param name="emotion">表情名称。如果不填,默认保持不变或初始化为 "normal"</param>
|
||||
[YarnCommand("set_portrait")]
|
||||
public static void SetPortrait(string characterId, float x, float y, string emotion = null)
|
||||
{
|
||||
if (!EnsureStage()) return;
|
||||
|
||||
// 传入归一化坐标,由 VNPortraitStage 内部自动应用 positionOffset 并转换为像素坐标
|
||||
Vector2 normalizedPos = new Vector2(x, y);
|
||||
Dialogue.VNPortraitStage.Instance.SetPortraitPosition(characterId, normalizedPos, emotion);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置当前说话角色的坐标和表情。
|
||||
/// 格式: <<set_portrait_current x y [emotion]>>
|
||||
/// </summary>
|
||||
[YarnCommand("set_portrait_current")]
|
||||
public static void SetPortraitCurrent(float x, float y, string emotion = null)
|
||||
{
|
||||
if (!EnsureStage()) return;
|
||||
|
||||
string characterId = Dialogue.VNPortraitStage.Instance.CurrentSpeakerId;
|
||||
if (string.IsNullOrEmpty(characterId))
|
||||
{
|
||||
Debug.LogWarning("[PortraitCommands] set_portrait_current: 当前没有活动的说话者,无法执行此命令!");
|
||||
return;
|
||||
}
|
||||
|
||||
SetPortrait(characterId, x, y, emotion);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 仅设置或移动指定角色的坐标(不改变当前表情)。
|
||||
/// 格式: <<set_portrait_position characterId x y>>
|
||||
/// </summary>
|
||||
[YarnCommand("set_portrait_position")]
|
||||
public static void SetPortraitPosition(string characterId, float x, float y)
|
||||
{
|
||||
// 通过传入 emotion = null,VNPortraitStage 在更新时将保持角色原有表情
|
||||
SetPortrait(characterId, x, y, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 仅改变指定角色的表情(角色必须已经上台)。
|
||||
/// 格式: <<set_portrait_emotion characterId emotion>>
|
||||
/// </summary>
|
||||
[YarnCommand("set_portrait_emotion")]
|
||||
public static void SetPortraitEmotion(string characterId, string emotion)
|
||||
{
|
||||
if (!EnsureStage()) return;
|
||||
|
||||
Dialogue.VNPortraitStage.Instance.SetPortraitEmotion(characterId, emotion);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 隐藏指定角色的立绘。
|
||||
/// 格式: <<hide_portrait characterId>>
|
||||
/// </summary>
|
||||
[YarnCommand("hide_portrait")]
|
||||
public static void HidePortrait(string characterId)
|
||||
{
|
||||
if (!EnsureStage()) return;
|
||||
|
||||
Dialogue.VNPortraitStage.Instance.HidePortrait(characterId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 隐藏当前所有在台上的立绘。
|
||||
/// 格式: <<hide_all_portraits>>
|
||||
/// </summary>
|
||||
[YarnCommand("hide_all_portraits")]
|
||||
public static void HideAllPortraits()
|
||||
{
|
||||
if (!EnsureStage()) return;
|
||||
|
||||
Dialogue.VNPortraitStage.Instance.HideAll();
|
||||
}
|
||||
|
||||
// ── 内部辅助 ─────────────────────────────────────────────────────────────
|
||||
|
||||
private static bool EnsureStage()
|
||||
{
|
||||
if (Dialogue.VNPortraitStage.Instance != null) return true;
|
||||
|
||||
Debug.LogError("[PortraitCommands] 未找到 VNPortraitStage 实例!请确保在当前场景中存在挂载了 VNPortraitStage 的游戏物体。");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d56251fa130b1334eab42a8d3069932f
|
||||
103
Assets/Scripts/NewStorySystem/YarnFunctions/StoryTreeCommands.cs
Normal file
103
Assets/Scripts/NewStorySystem/YarnFunctions/StoryTreeCommands.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using Ichni.Story.Dialogue;
|
||||
using Ichni.Story.UI;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Localization.Settings;
|
||||
using Yarn.Unity;
|
||||
|
||||
namespace Ichni.Story.YarnFunctions
|
||||
{
|
||||
/// <summary>
|
||||
/// 包含与故事树节点控制、全局进程、存档交互相关的 Yarn 自定义命令注册器。
|
||||
/// </summary>
|
||||
public static class StoryTreeCommands
|
||||
{
|
||||
// ── Yarn Commands ────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// 解锁一首新歌曲,并在当前这段对话结束(对话 UI 淡出)后,弹出 MessageBox 提示。
|
||||
/// 格式: <<unlock_song songUnlockKey>>
|
||||
/// </summary>
|
||||
/// <param name="songUnlockKey">要解锁的歌曲密钥/ID</param>
|
||||
[YarnCommand("unlock_song")]
|
||||
public static void UnlockSong(string songUnlockKey)
|
||||
{
|
||||
if (GameSaveManager.instance == null || GameSaveManager.instance.SongSaveModule == null)
|
||||
{
|
||||
Debug.LogError("[StoryTreeCommands] 无法解锁歌曲:GameSaveManager 或其 SongSaveModule 未初始化!");
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. 检查是否已经解锁
|
||||
if (GameSaveManager.instance.SongSaveModule.CheckStoryKey(songUnlockKey))
|
||||
{
|
||||
Debug.Log($"[StoryTreeCommands] 歌曲 {songUnlockKey} 已处于解锁状态。");
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 写入解锁状态并保存存档
|
||||
GameSaveManager.instance.SongSaveModule.storyUnlockKeys.Add(songUnlockKey);
|
||||
GameSaveManager.instance.SongSaveModule.SaveStoryUnlockKeys();
|
||||
Debug.Log($"[StoryTreeCommands] 已成功写入并保存歌曲解锁密钥:{songUnlockKey}");
|
||||
|
||||
// 3. 将 UI 弹窗提示加入到对话结束队列中
|
||||
if (StoryDialogueController.instance != null)
|
||||
{
|
||||
StoryDialogueController.instance.dialogueEndActions.Add(() =>
|
||||
{
|
||||
if (StoryMessageBoxUIPage.instance != null)
|
||||
{
|
||||
StoryMessageBoxUIPage.instance.ShowUnlockMessage(songUnlockKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("[StoryTreeCommands] 弹窗失败:场景中未找到 StoryMessageBoxUIPage 实例!");
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("[StoryTreeCommands] 弹窗队列注册失败:未找到 StoryDialogueController 实例!");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在对话结束后,弹出一个自定义 MessageBox 提示。
|
||||
/// 会尝试使用 Unity Localization 进行翻译,如果找不到对应条目则回退显示原文本(Key)。
|
||||
/// 格式: <<show_message titleKey contentKey [tableName]>>
|
||||
/// </summary>
|
||||
/// <param name="titleKey">标题文本或本地化键</param>
|
||||
/// <param name="contentKey">正文文本或本地化键</param>
|
||||
/// <param name="tableName">Unity Localization 中的 String Table 名称</param>
|
||||
[YarnCommand("show_message")]
|
||||
public static void ShowMessage(string titleKey, string contentKey, string tableName = "Message")
|
||||
{
|
||||
string translatedTitle = GetTranslatedText(tableName, titleKey);
|
||||
string translatedContent = GetTranslatedText(tableName, contentKey);
|
||||
Debug.Log($"[StoryTreeCommands] 准备在对话结束后显示自定义弹窗:标题='{translatedTitle}',内容='{translatedContent}'");
|
||||
StoryDialogueController.instance.dialogueEndActions.Add(() =>
|
||||
{
|
||||
StoryMessageBoxUIPage.instance.ShowCustomMessage(translatedTitle, translatedContent);
|
||||
});
|
||||
}
|
||||
|
||||
// ── 内部辅助 ─────────────────────────────────────────────────────────────
|
||||
|
||||
private static string GetTranslatedText(string tableName, string key)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key)) return string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
// 尝试从 Unity Localization 中获取翻译文本
|
||||
string translated = LocalizationSettings.StringDatabase.GetLocalizedString(tableName, key);
|
||||
// 若获取失败或为空,则直接原样返回 key 作为兜底文本
|
||||
return string.IsNullOrEmpty(translated) ? key : translated;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 如果表不存在或其他异常,返回原 key
|
||||
return key;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a048ef81fee2164b8c7ae9748690cfd
|
||||
@@ -0,0 +1,76 @@
|
||||
using UnityEngine;
|
||||
using Yarn.Unity;
|
||||
using Ichni.Story;
|
||||
|
||||
namespace Ichni.Story.YarnFunctions
|
||||
{
|
||||
/// <summary>
|
||||
/// 提供可以直接在 Yarn 脚本中调用的全局变量读写指令。
|
||||
/// 完全兼容旧系统中的自定义函数(避免旧的 .yarn 报错),
|
||||
/// 底层统一指向全新的 StoryVariables 枢纽。
|
||||
/// </summary>
|
||||
public static class VariableCommands
|
||||
{
|
||||
[YarnCommand("set_bool")]
|
||||
public static void SetBool(string key, bool value)
|
||||
{
|
||||
StoryVariables.SetBool(key, value);
|
||||
}
|
||||
|
||||
[YarnFunction("get_bool")]
|
||||
public static bool GetBool(string key)
|
||||
{
|
||||
return StoryVariables.GetBool(key);
|
||||
}
|
||||
|
||||
[YarnCommand("set_int")]
|
||||
public static void SetInt(string key, int value)
|
||||
{
|
||||
StoryVariables.SetInt(key, value);
|
||||
}
|
||||
|
||||
[YarnCommand("modify_int")]
|
||||
public static void ModifyInt(string key, int modification)
|
||||
{
|
||||
int currentValue = StoryVariables.GetInt(key);
|
||||
StoryVariables.SetInt(key, currentValue + modification);
|
||||
}
|
||||
|
||||
[YarnFunction("get_int")]
|
||||
public static int GetInt(string key)
|
||||
{
|
||||
return StoryVariables.GetInt(key);
|
||||
}
|
||||
|
||||
[YarnCommand("set_float")]
|
||||
public static void SetFloat(string key, float value)
|
||||
{
|
||||
StoryVariables.SetFloat(key, value);
|
||||
}
|
||||
|
||||
[YarnCommand("modify_float")]
|
||||
public static void ModifyFloat(string key, float modification)
|
||||
{
|
||||
float currentValue = StoryVariables.GetFloat(key);
|
||||
StoryVariables.SetFloat(key, currentValue + modification);
|
||||
}
|
||||
|
||||
[YarnFunction("get_float")]
|
||||
public static float GetFloat(string key)
|
||||
{
|
||||
return StoryVariables.GetFloat(key);
|
||||
}
|
||||
|
||||
[YarnCommand("set_string")]
|
||||
public static void SetString(string key, string value)
|
||||
{
|
||||
StoryVariables.SetString(key, value);
|
||||
}
|
||||
|
||||
[YarnFunction("get_string")]
|
||||
public static string GetString(string key)
|
||||
{
|
||||
return StoryVariables.GetString(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b9094628fd04644439b4afd553c7a6aa
|
||||
@@ -1,95 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using Yarn.Unity;
|
||||
|
||||
namespace SLSUtilities.Narrative
|
||||
{
|
||||
public static partial class YarnFunctions
|
||||
{
|
||||
[YarnCommand("set_bool")]
|
||||
public static void Yarn_SetBool(string key, bool value)
|
||||
{
|
||||
StorySystem.Variables.boolVariables[key] = value;
|
||||
}
|
||||
|
||||
[YarnFunction("get_bool")]
|
||||
public static bool Yarn_GetBool(string key)
|
||||
{
|
||||
return StorySystem.Variables.boolVariables.GetValueOrDefault(key, false);
|
||||
}
|
||||
|
||||
[YarnCommand("set_int")]
|
||||
public static void Yarn_SetInt(string key, int value)
|
||||
{
|
||||
StorySystem.Variables.intVariables[key] = value;
|
||||
}
|
||||
|
||||
[YarnCommand("modify_int")]
|
||||
public static void Yarn_ModifyInt(string key, int modification)
|
||||
{
|
||||
int currentValue = StorySystem.Variables.intVariables.GetValueOrDefault(key, 0);
|
||||
StorySystem.Variables.intVariables[key] = currentValue + modification;
|
||||
}
|
||||
|
||||
[YarnFunction("get_int")]
|
||||
public static int Yarn_GetInt(string key)
|
||||
{
|
||||
return StorySystem.Variables.intVariables.GetValueOrDefault(key, 0);
|
||||
}
|
||||
|
||||
[YarnCommand("set_float")]
|
||||
public static void Yarn_SetFloat(string key, float value)
|
||||
{
|
||||
StorySystem.Variables.floatVariables[key] = value;
|
||||
}
|
||||
|
||||
[YarnCommand("modify_float")]
|
||||
public static void Yarn_ModifyFloat(string key, float modification)
|
||||
{
|
||||
float currentValue = StorySystem.Variables.floatVariables.GetValueOrDefault(key, 0f);
|
||||
StorySystem.Variables.floatVariables[key] = currentValue + modification;
|
||||
}
|
||||
|
||||
[YarnFunction("get_float")]
|
||||
public static float Yarn_GetFloat(string key)
|
||||
{
|
||||
return StorySystem.Variables.floatVariables.GetValueOrDefault(key, 0f);
|
||||
}
|
||||
|
||||
[YarnCommand("set_string")]
|
||||
public static void Yarn_SetString(string key, string value)
|
||||
{
|
||||
StorySystem.Variables.stringVariables[key] = value;
|
||||
}
|
||||
|
||||
[YarnFunction("get_string")]
|
||||
public static string Yarn_GetString(string key)
|
||||
{
|
||||
return StorySystem.Variables.stringVariables.GetValueOrDefault(key, "");
|
||||
}
|
||||
}
|
||||
|
||||
public static partial class YarnFunctions
|
||||
{
|
||||
[YarnCommand("log")]
|
||||
public static void Log(string message, string logType)
|
||||
{
|
||||
logType = logType.ToLower();
|
||||
|
||||
switch (logType)
|
||||
{
|
||||
case "info":
|
||||
UnityEngine.Debug.Log(message);
|
||||
break;
|
||||
case "warning":
|
||||
UnityEngine.Debug.LogWarning(message);
|
||||
break;
|
||||
case "error":
|
||||
UnityEngine.Debug.LogError(message);
|
||||
break;
|
||||
default:
|
||||
UnityEngine.Debug.Log(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fd615694e3d8cc842a6c75bc3956a926
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b2c23056fb0ab4b45a8db11866018794
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,18 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class BeatmapStatusMark : MonoBehaviour
|
||||
{
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b547d2cc398393a46a2a4c503f128cac
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c234abdb2207c8459280e59152ba1c9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -2,7 +2,6 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using DG.Tweening;
|
||||
using I2.Loc;
|
||||
using Sirenix.OdinInspector;
|
||||
using SLSUtilities.WwiseAssistance;
|
||||
using TMPro;
|
||||
@@ -17,16 +16,16 @@ namespace Ichni.Menu.UI
|
||||
{
|
||||
public CanvasGroup canvasGroup;
|
||||
|
||||
[Tooltip("当该消息框结束所有消息并彻底淡出消失时触发。")]
|
||||
public UnityEvent onAllMessagesClosed = new UnityEvent();
|
||||
|
||||
public int infoIndex;
|
||||
public List<MessageBoxInfo> infos;
|
||||
|
||||
public Sprite defaultIcon;
|
||||
public Image iconImage;
|
||||
public Localize titleLocalize;
|
||||
public TMP_Text titleText;
|
||||
public Localize contentLocalize;
|
||||
public TMP_Text contentText;
|
||||
public LocalizationParamsManager parametersManager;
|
||||
|
||||
public Button receiveButton;
|
||||
|
||||
@@ -76,8 +75,8 @@ namespace Ichni.Menu.UI
|
||||
|
||||
infos[infoIndex].action?.Invoke();
|
||||
|
||||
titleLocalize.SetTerm(infos[infoIndex].title);
|
||||
contentLocalize.SetTerm(infos[infoIndex].content);
|
||||
if (titleText != null) titleText.text = infos[infoIndex].title;
|
||||
if (contentText != null) contentText.text = infos[infoIndex].content;
|
||||
|
||||
this.iconImage.sprite = infos[infoIndex].icon != null ? infos[infoIndex].icon : defaultIcon;
|
||||
infoIndex++;
|
||||
@@ -95,17 +94,10 @@ namespace Ichni.Menu.UI
|
||||
|
||||
public partial class MessageBox
|
||||
{
|
||||
public void SetParameter(string paramName, string paramValue, bool localize = false)
|
||||
{
|
||||
if (localize)
|
||||
{
|
||||
parametersManager.SetParameterValue(paramName, paramValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
parametersManager.SetParameterValue(paramName, paramValue, false);
|
||||
}
|
||||
}
|
||||
// 废弃对 I2.Loc 参数化功能的支持
|
||||
// public void SetParameter(string paramName, string paramValue, bool localize = false)
|
||||
// {
|
||||
// }
|
||||
}
|
||||
|
||||
public partial class MessageBox
|
||||
@@ -136,6 +128,7 @@ namespace Ichni.Menu.UI
|
||||
fadeTweener = canvasGroup.DOFade(0f, duration).OnComplete(() =>
|
||||
{
|
||||
canvasGroup.gameObject.SetActive(false);
|
||||
onAllMessagesClosed?.Invoke();
|
||||
});
|
||||
|
||||
if (ignoreTimeScale)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// ============================================================
|
||||
// ============================================================
|
||||
// Chapter 0 · Block A0
|
||||
// 命名约定:C{章节}_{BlockId}_{分段}
|
||||
// 入口节点:C0_A0
|
||||
@@ -12,26 +12,22 @@ position: 0,0
|
||||
// 变量声明(默认值;StoryVariableStorage 存有存档值时会自动覆盖)
|
||||
<<declare $asahi_knows_the_truth = false>>
|
||||
<<declare $asahi_remembers_origin = false>>
|
||||
|
||||
SLS: 勇士,你终于来了。我们等待你很久了。 #line:0c2e7ae
|
||||
<<set_portrait "Asahi" 33 0>>
|
||||
Asahi: ……这就是那个传说中的地方吗? #line:0871a99
|
||||
|
||||
// 条件分支:朝日是否已知晓真相(再访时触发)
|
||||
<<if $asahi_knows_the_truth>>
|
||||
SLS: 朝日,你已经了解实情了。那就省去许多解释。 #line:036f930
|
||||
<<jump C0_A0_truth_known>>
|
||||
<<else>>
|
||||
<<jump C0_A0_first_meeting>>
|
||||
<<endif>>
|
||||
<<jump C0_A0_first_meeting>>
|
||||
===
|
||||
|
||||
title: C0_A0_first_meeting
|
||||
position: -150,250
|
||||
---
|
||||
<<move_portrait "Asahi" -33 0 1.5>>
|
||||
SLS: 这里曾是一场被时间掩埋的战争的终结之地。 #line:0cdce7d
|
||||
SLS: 我们称之为"遗忘之地"。 #line:0fe1e57
|
||||
<<jump_portrait "Asahi" 5 2 0.8>>
|
||||
Asahi: 为什么叫这个名字? #line:068875f
|
||||
SLS: 因为死去的人希望被遗忘—— #line:04a17d7
|
||||
<<shake_portrait "Asahi" 1.0 2 10>>
|
||||
SLS: ——而活下来的人,却永远无法忘记。 #line:03e5d89
|
||||
Asahi: …… #line:0a4b2fc
|
||||
|
||||
@@ -41,6 +37,9 @@ Asahi: …… #line:0a4b2fc
|
||||
<<jump C0_A0_reveal>>
|
||||
-> 暂时不告诉朝日 #line:02b0524
|
||||
<<jump C0_A0_conceal>>
|
||||
-> 聊聊朝日的过去 <<if $asahi_remembers_origin>> #line:0e8d4c1
|
||||
Asahi: 那段记忆……我终于能开口谈了。 #line:0a3f9b7
|
||||
<<jump C0_A0_end>>
|
||||
===
|
||||
|
||||
title: C0_A0_reveal
|
||||
@@ -77,6 +76,7 @@ Asahi: 我已经准备好了。 #line:04617a4
|
||||
title: C0_A0_end
|
||||
position: 0,750
|
||||
---
|
||||
<<show_message "Test Title" "这是一条测试自定义信息的留言!">>
|
||||
SLS: 无论你作何选择,这段旅途都只属于你。 #line:00bf206
|
||||
SLS: 去吧,勇士。前方还有很长的路。 #line:03c5112
|
||||
Asahi: 我会一直陪着你的,不管去哪里。 #line:06d2a12
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,6 +1,6 @@
|
||||
ManifestFileVersion: 0
|
||||
UnityVersion: 6000.3.7f1
|
||||
CRC: 2623424500
|
||||
CRC: 429033785
|
||||
HashAppended: 0
|
||||
AssetBundleManifest:
|
||||
AssetBundleInfos:
|
||||
|
||||
Binary file not shown.
@@ -1,16 +1,16 @@
|
||||
ManifestFileVersion: 0
|
||||
UnityVersion: 6000.3.7f1
|
||||
CRC: 3927326319
|
||||
CRC: 1054575820
|
||||
Hashes:
|
||||
AssetFileHash:
|
||||
serializedVersion: 2
|
||||
Hash: 512dd2d788d66c7fe4fad82c9898ac5a
|
||||
Hash: 007f20ee8efa9449fd672739395d8b8b
|
||||
TypeTreeHash:
|
||||
serializedVersion: 2
|
||||
Hash: dfed41e3b38758e5f34df30221d719dc
|
||||
IncrementalBuildHash:
|
||||
serializedVersion: 2
|
||||
Hash: 11597e67617d09816dd570d9aea10af1
|
||||
Hash: d5b71e5a50fcc975f61f5696454edfd0
|
||||
HashAppended: 0
|
||||
ClassTypes:
|
||||
- Class: 1
|
||||
|
||||
Binary file not shown.
@@ -1,16 +1,16 @@
|
||||
ManifestFileVersion: 0
|
||||
UnityVersion: 6000.3.7f1
|
||||
CRC: 3130613331
|
||||
CRC: 3864940768
|
||||
Hashes:
|
||||
AssetFileHash:
|
||||
serializedVersion: 2
|
||||
Hash: 0782fed7ca84aeedfdeb1c740adc5b26
|
||||
Hash: 8b97cbc629946fe6dd535e8a6f698e0c
|
||||
TypeTreeHash:
|
||||
serializedVersion: 2
|
||||
Hash: 8cc3f86bb5dbc7fe3d0bf9f241837627
|
||||
Hash: 6dc25ede816b5f1e26e55c131592f792
|
||||
IncrementalBuildHash:
|
||||
serializedVersion: 2
|
||||
Hash: d8a4fa251b182c13d591514f02a84c6d
|
||||
Hash: 54ab974a222b103c89f3e0fe238ac426
|
||||
HashAppended: 0
|
||||
ClassTypes:
|
||||
- Class: 1
|
||||
@@ -37,6 +37,8 @@ ClassTypes:
|
||||
Script: {fileID: 11500000, guid: 0def5156137c6d14082064fa7b5d5247, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: 11500000, guid: 77ab80dc0820f9d4a8cd9fddbbc89057, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: 11500000, guid: 2cc178b2441bca14eb1321c83761ab6f, type: 3}
|
||||
- Class: 114
|
||||
Script: {fileID: 11500000, guid: 8ba3055fc57abcb41811796e6a0ed3aa, type: 3}
|
||||
- Class: 114
|
||||
@@ -83,6 +85,7 @@ SerializeReferenceClassIdentifiers:
|
||||
- AssemblyName: Sirenix.Serialization
|
||||
ClassName: Sirenix.Serialization.SerializationData
|
||||
Assets:
|
||||
- Assets/ThemeBundles/DepartureToMultiverse/Prefabs/Environment/DTM_CircleSpinTrails.prefab
|
||||
- Assets/ThemeBundles/DepartureToMultiverse/Prefabs/DTM_NoteVisualTap.prefab
|
||||
- Assets/ThemeBundles/DepartureToMultiverse/Materials/Skybox/DTM_Skybox_Starry.mat
|
||||
- Assets/ThemeBundles/DepartureToMultiverse/Prefabs/Environment/DTM_RandomGridTube.prefab
|
||||
|
||||
@@ -10,7 +10,7 @@ Hashes:
|
||||
Hash: 8ab77e54d824a64c30bc20496c5f5926
|
||||
IncrementalBuildHash:
|
||||
serializedVersion: 2
|
||||
Hash: 7593ca8fd4ac3c250191162c1a3f3194
|
||||
Hash: d713e609a88c186608032508763d02c3
|
||||
HashAppended: 0
|
||||
ClassTypes:
|
||||
- Class: 1
|
||||
|
||||
Binary file not shown.
@@ -1,6 +1,6 @@
|
||||
ManifestFileVersion: 0
|
||||
UnityVersion: 6000.3.7f1
|
||||
CRC: 4273076075
|
||||
CRC: 3383810862
|
||||
HashAppended: 0
|
||||
AssetBundleManifest:
|
||||
AssetBundleInfos:
|
||||
|
||||
Binary file not shown.
@@ -1,16 +1,16 @@
|
||||
ManifestFileVersion: 0
|
||||
UnityVersion: 6000.3.7f1
|
||||
CRC: 874269373
|
||||
CRC: 4039318435
|
||||
Hashes:
|
||||
AssetFileHash:
|
||||
serializedVersion: 2
|
||||
Hash: 8ecfb5459953077e6f509c9dc150eec6
|
||||
Hash: e59b40a27d3c2a868588952827b1934d
|
||||
TypeTreeHash:
|
||||
serializedVersion: 2
|
||||
Hash: 6dc25ede816b5f1e26e55c131592f792
|
||||
IncrementalBuildHash:
|
||||
serializedVersion: 2
|
||||
Hash: 5c3ae75a4cdbf2e6e5fc462d0226b21b
|
||||
Hash: 19e5914687b1150ef00de5f4923cced6
|
||||
HashAppended: 0
|
||||
ClassTypes:
|
||||
- Class: 1
|
||||
|
||||
@@ -108,7 +108,7 @@ ParticleSystem:
|
||||
m_RotationOrder: 4
|
||||
moveWithTransform: 0
|
||||
moveWithCustomTransform: {fileID: 0}
|
||||
scalingMode: 1
|
||||
scalingMode: 0
|
||||
randomSeed: 0
|
||||
InitialModule:
|
||||
serializedVersion: 3
|
||||
@@ -4816,7 +4816,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &6436623435409707789
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -4832,6 +4832,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -4853,9 +4858,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 2
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 0
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -4887,7 +4894,6 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
--- !u!1 &393908652242839112
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -4996,7 +5002,7 @@ ParticleSystem:
|
||||
m_RotationOrder: 4
|
||||
moveWithTransform: 0
|
||||
moveWithCustomTransform: {fileID: 0}
|
||||
scalingMode: 1
|
||||
scalingMode: 0
|
||||
randomSeed: 0
|
||||
InitialModule:
|
||||
serializedVersion: 3
|
||||
@@ -9740,7 +9746,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &5469123982439044343
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -9756,6 +9762,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -9777,9 +9788,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 1
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -9811,7 +9824,6 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
--- !u!1 &987757201259740425
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -9920,7 +9932,7 @@ ParticleSystem:
|
||||
m_RotationOrder: 4
|
||||
moveWithTransform: 0
|
||||
moveWithCustomTransform: {fileID: 0}
|
||||
scalingMode: 1
|
||||
scalingMode: 0
|
||||
randomSeed: 0
|
||||
InitialModule:
|
||||
serializedVersion: 3
|
||||
@@ -14664,7 +14676,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &7698517573709736333
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -14680,6 +14692,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -14701,9 +14718,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 4
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -14735,7 +14754,6 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
--- !u!1 &2649872400038691757
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -14844,7 +14862,7 @@ ParticleSystem:
|
||||
m_RotationOrder: 4
|
||||
moveWithTransform: 0
|
||||
moveWithCustomTransform: {fileID: 0}
|
||||
scalingMode: 1
|
||||
scalingMode: 0
|
||||
randomSeed: 0
|
||||
InitialModule:
|
||||
serializedVersion: 3
|
||||
@@ -19561,7 +19579,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &3804338172303829356
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -19577,6 +19595,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -19598,9 +19621,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 1
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 0
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -19632,7 +19657,6 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
--- !u!1 &4315719500094685406
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -19741,7 +19765,7 @@ ParticleSystem:
|
||||
m_RotationOrder: 4
|
||||
moveWithTransform: 0
|
||||
moveWithCustomTransform: {fileID: 0}
|
||||
scalingMode: 1
|
||||
scalingMode: 0
|
||||
randomSeed: 0
|
||||
InitialModule:
|
||||
serializedVersion: 3
|
||||
@@ -24574,7 +24598,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &3349403536436963533
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -24590,6 +24614,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -24611,9 +24640,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 1
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -24645,7 +24676,6 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
--- !u!1 &6152325990999234384
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -24754,7 +24784,7 @@ ParticleSystem:
|
||||
m_RotationOrder: 4
|
||||
moveWithTransform: 0
|
||||
moveWithCustomTransform: {fileID: 0}
|
||||
scalingMode: 1
|
||||
scalingMode: 0
|
||||
randomSeed: 0
|
||||
InitialModule:
|
||||
serializedVersion: 3
|
||||
@@ -29498,7 +29528,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &6804594070940386649
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -29514,6 +29544,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -29535,9 +29570,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 1
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -29569,7 +29606,6 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
--- !u!1 &7653901243468862591
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -29678,7 +29714,7 @@ ParticleSystem:
|
||||
m_RotationOrder: 4
|
||||
moveWithTransform: 0
|
||||
moveWithCustomTransform: {fileID: 0}
|
||||
scalingMode: 1
|
||||
scalingMode: 0
|
||||
randomSeed: 0
|
||||
InitialModule:
|
||||
serializedVersion: 3
|
||||
@@ -34511,7 +34547,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &3494879711755687896
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -34527,6 +34563,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -34548,9 +34589,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 1
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -34582,7 +34625,6 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
--- !u!1 &7916584198410465453
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -34698,7 +34740,7 @@ ParticleSystem:
|
||||
m_RotationOrder: 4
|
||||
moveWithTransform: 0
|
||||
moveWithCustomTransform: {fileID: 0}
|
||||
scalingMode: 1
|
||||
scalingMode: 0
|
||||
randomSeed: 0
|
||||
InitialModule:
|
||||
serializedVersion: 3
|
||||
@@ -39348,7 +39390,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &6411650891525449585
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -39364,6 +39406,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -39385,9 +39432,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 0
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -39419,4 +39468,3 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
|
||||
@@ -4758,7 +4758,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &9090909857404846383
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -4774,6 +4774,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -4795,9 +4800,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 1
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 1
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -4829,7 +4836,6 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
--- !u!1 &2070592205952932412
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -9588,7 +9594,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &9081262536151624848
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -9604,6 +9610,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -9625,9 +9636,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 2
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 0
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -9659,7 +9672,6 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
--- !u!1 &2261133155526879230
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -14485,7 +14497,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &6151027602389049168
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -14501,6 +14513,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -14522,9 +14539,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 1
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 0
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -14556,7 +14575,6 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
--- !u!1 &2376255500188663908
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -19315,7 +19333,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &1348402425390080252
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -19331,6 +19349,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -19352,9 +19375,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 2
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 0
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -19386,7 +19411,6 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
--- !u!1 &2943020494385716766
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -19501,7 +19525,7 @@ ParticleSystem:
|
||||
m_RotationOrder: 4
|
||||
moveWithTransform: 0
|
||||
moveWithCustomTransform: {fileID: 0}
|
||||
scalingMode: 1
|
||||
scalingMode: 0
|
||||
randomSeed: 0
|
||||
InitialModule:
|
||||
serializedVersion: 3
|
||||
@@ -24151,7 +24175,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &4188768693027638627
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -24167,6 +24191,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -24188,9 +24217,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 0
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -24222,7 +24253,6 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
--- !u!1 &6573924625455929684
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -28981,7 +29011,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &3563924814195315285
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -28997,6 +29027,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -29018,9 +29053,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 1
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 1
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -29052,7 +29089,6 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
--- !u!1 &6651680105352939543
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -33869,7 +33905,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &3958041096823129390
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -33885,6 +33921,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -33906,9 +33947,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 2
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 0
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -33940,4 +33983,3 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
|
||||
@@ -4950,7 +4950,7 @@ ParticleSystem:
|
||||
m_RotationOrder: 4
|
||||
moveWithTransform: 0
|
||||
moveWithCustomTransform: {fileID: 0}
|
||||
scalingMode: 1
|
||||
scalingMode: 0
|
||||
randomSeed: 0
|
||||
InitialModule:
|
||||
serializedVersion: 3
|
||||
|
||||
@@ -29255,7 +29255,7 @@ ParticleSystem:
|
||||
m_RotationOrder: 4
|
||||
moveWithTransform: 0
|
||||
moveWithCustomTransform: {fileID: 0}
|
||||
scalingMode: 1
|
||||
scalingMode: 0
|
||||
randomSeed: 0
|
||||
InitialModule:
|
||||
serializedVersion: 3
|
||||
|
||||
@@ -108,7 +108,7 @@ ParticleSystem:
|
||||
m_RotationOrder: 4
|
||||
moveWithTransform: 0
|
||||
moveWithCustomTransform: {fileID: 0}
|
||||
scalingMode: 1
|
||||
scalingMode: 0
|
||||
randomSeed: 0
|
||||
InitialModule:
|
||||
serializedVersion: 3
|
||||
@@ -4816,7 +4816,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &5640736116712977215
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -4832,6 +4832,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -4853,9 +4858,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 2
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 0
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -4887,7 +4894,6 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
--- !u!1 &5249990677744981946
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -4999,7 +5005,7 @@ ParticleSystem:
|
||||
m_RotationOrder: 4
|
||||
moveWithTransform: 0
|
||||
moveWithCustomTransform: {fileID: 0}
|
||||
scalingMode: 1
|
||||
scalingMode: 0
|
||||
randomSeed: 0
|
||||
InitialModule:
|
||||
serializedVersion: 3
|
||||
@@ -9649,7 +9655,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &4138720391616017682
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -9665,6 +9671,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -9686,9 +9697,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 0
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -9720,7 +9733,6 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
--- !u!1 &5931878544904699336
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -9829,7 +9841,7 @@ ParticleSystem:
|
||||
m_RotationOrder: 4
|
||||
moveWithTransform: 0
|
||||
moveWithCustomTransform: {fileID: 0}
|
||||
scalingMode: 1
|
||||
scalingMode: 0
|
||||
randomSeed: 0
|
||||
InitialModule:
|
||||
serializedVersion: 3
|
||||
@@ -14546,7 +14558,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &5870414974609834262
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -14562,6 +14574,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -14583,9 +14600,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 1
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 0
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -14617,7 +14636,6 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
--- !u!1 &8633588085551914740
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -14726,7 +14744,7 @@ ParticleSystem:
|
||||
m_RotationOrder: 4
|
||||
moveWithTransform: 0
|
||||
moveWithCustomTransform: {fileID: 0}
|
||||
scalingMode: 1
|
||||
scalingMode: 0
|
||||
randomSeed: 0
|
||||
InitialModule:
|
||||
serializedVersion: 3
|
||||
@@ -19452,7 +19470,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &1602668134873900334
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -19468,6 +19486,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -19489,9 +19512,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 4
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -19523,4 +19548,3 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
|
||||
@@ -108,7 +108,7 @@ ParticleSystem:
|
||||
m_RotationOrder: 4
|
||||
moveWithTransform: 0
|
||||
moveWithCustomTransform: {fileID: 0}
|
||||
scalingMode: 1
|
||||
scalingMode: 0
|
||||
randomSeed: 0
|
||||
InitialModule:
|
||||
serializedVersion: 3
|
||||
@@ -4825,7 +4825,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &4109529955070703249
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -4841,6 +4841,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -4862,9 +4867,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 1
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 0
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -4896,7 +4903,6 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
--- !u!1 &5480151176008203866
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -5005,7 +5011,7 @@ ParticleSystem:
|
||||
m_RotationOrder: 4
|
||||
moveWithTransform: 0
|
||||
moveWithCustomTransform: {fileID: 0}
|
||||
scalingMode: 1
|
||||
scalingMode: 0
|
||||
randomSeed: 0
|
||||
InitialModule:
|
||||
serializedVersion: 3
|
||||
@@ -9731,7 +9737,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &5640841965484054353
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -9747,6 +9753,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -9768,9 +9779,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 4
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -9802,7 +9815,6 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
--- !u!1 &8754511166712621810
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -9913,7 +9925,7 @@ ParticleSystem:
|
||||
m_RotationOrder: 4
|
||||
moveWithTransform: 0
|
||||
moveWithCustomTransform: {fileID: 0}
|
||||
scalingMode: 1
|
||||
scalingMode: 0
|
||||
randomSeed: 0
|
||||
InitialModule:
|
||||
serializedVersion: 3
|
||||
@@ -14563,7 +14575,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &1014060429300395170
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -14579,6 +14591,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -14600,9 +14617,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 0
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -14634,4 +14653,3 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
|
||||
@@ -108,7 +108,7 @@ ParticleSystem:
|
||||
m_RotationOrder: 4
|
||||
moveWithTransform: 0
|
||||
moveWithCustomTransform: {fileID: 0}
|
||||
scalingMode: 1
|
||||
scalingMode: 0
|
||||
randomSeed: 0
|
||||
InitialModule:
|
||||
serializedVersion: 3
|
||||
@@ -4825,7 +4825,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &3594631519425132185
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -4841,6 +4841,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -4862,9 +4867,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 1
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 0
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -4896,7 +4903,6 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
--- !u!1 &3240066047640847786
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -5005,7 +5011,7 @@ ParticleSystem:
|
||||
m_RotationOrder: 4
|
||||
moveWithTransform: 0
|
||||
moveWithCustomTransform: {fileID: 0}
|
||||
scalingMode: 1
|
||||
scalingMode: 0
|
||||
randomSeed: 0
|
||||
InitialModule:
|
||||
serializedVersion: 3
|
||||
@@ -9749,7 +9755,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &3141689248629385762
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -9765,6 +9771,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -9786,9 +9797,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 4
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -9820,7 +9833,6 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
--- !u!1 &7671123070809976812
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -9932,7 +9944,7 @@ ParticleSystem:
|
||||
m_RotationOrder: 4
|
||||
moveWithTransform: 0
|
||||
moveWithCustomTransform: {fileID: 0}
|
||||
scalingMode: 1
|
||||
scalingMode: 0
|
||||
randomSeed: 0
|
||||
InitialModule:
|
||||
serializedVersion: 3
|
||||
@@ -14582,7 +14594,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &8700396741641032723
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -14598,6 +14610,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -14619,9 +14636,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 0
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 0
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -14653,7 +14672,6 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
--- !u!1 &7986537471941685033
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -14762,7 +14780,7 @@ ParticleSystem:
|
||||
m_RotationOrder: 4
|
||||
moveWithTransform: 0
|
||||
moveWithCustomTransform: {fileID: 0}
|
||||
scalingMode: 1
|
||||
scalingMode: 0
|
||||
randomSeed: 0
|
||||
InitialModule:
|
||||
serializedVersion: 3
|
||||
@@ -19470,7 +19488,7 @@ ParticleSystem:
|
||||
vectorLabel1_3: W
|
||||
--- !u!199 &1832114136647296338
|
||||
ParticleSystemRenderer:
|
||||
serializedVersion: 6
|
||||
serializedVersion: 7
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
@@ -19486,6 +19504,11 @@ ParticleSystemRenderer:
|
||||
m_ReflectionProbeUsage: 0
|
||||
m_RayTracingMode: 0
|
||||
m_RayTraceProcedural: 0
|
||||
m_RayTracingAccelStructBuildFlagsOverride: 0
|
||||
m_RayTracingAccelStructBuildFlags: 1
|
||||
m_SmallMeshCulling: 1
|
||||
m_ForceMeshLod: -1
|
||||
m_MeshLodSelectionBias: 0
|
||||
m_RenderingLayerMask: 1
|
||||
m_RendererPriority: 0
|
||||
m_Materials:
|
||||
@@ -19507,9 +19530,11 @@ ParticleSystemRenderer:
|
||||
m_AutoUVMaxDistance: 0.5
|
||||
m_AutoUVMaxAngle: 89
|
||||
m_LightmapParameters: {fileID: 0}
|
||||
m_GlobalIlluminationMeshLod: 0
|
||||
m_SortingLayerID: 0
|
||||
m_SortingLayer: 0
|
||||
m_SortingOrder: 2
|
||||
m_MaskInteraction: 0
|
||||
m_RenderMode: 0
|
||||
m_MeshDistribution: 0
|
||||
m_SortMode: 0
|
||||
@@ -19541,4 +19566,3 @@ ParticleSystemRenderer:
|
||||
m_MeshWeighting1: 1
|
||||
m_MeshWeighting2: 1
|
||||
m_MeshWeighting3: 1
|
||||
m_MaskInteraction: 0
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user