Merge pull request #2 from SepComet/2.8

添加对话系统
This commit is contained in:
SepComet 2026-02-09 13:54:18 +08:00 committed by GitHub
commit c011c48bfe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
116 changed files with 3223 additions and 170 deletions

8
.gitignore vendored
View File

@ -85,3 +85,11 @@ crashlytics-build.properties
/Assets/RawResources
/.vscode
# Excel temporary lock files
~$*.xls
~$*.xlsx
~$*.xlsm
~$*.xlsb
/数据表/__pycache__

View File

@ -0,0 +1,7 @@
# 对话标识表 筛选用数据
# Id Title UIMode ChapterId
# int string DialogUIMode int
# 对话编号 策划备注 对话标识 对话形式 章节编号
1001 第一章介绍 Chapter1_Intro Mask 1.001
1002 第一章主流程 Chapter1_Main BottomBox 1.002
1003 第一章玩法开始前闲聊 Chapter1_SmallTalk1 Bubble 1.003

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 788b17ff3aef4cd4fb6c808826c875e5
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,13 @@
# 对话内容表 筛选用数据
# Id SpeakerId Expression SpeakerName Direction Text Emphasis ChapterId DialogId
# int string ExpressionType string int string EmphasisType int int
# 对话行编号 策划备注 说话人Id 表情 显示人名 说话朝向 说话内容 演出效果 章节Id 对话Id
100100001 Id规则为 Null None Null 0 相传。 None 1.00100001 1001.00001
100100002 第1位数为章节Id Null None Null 0 Mask。 None 1.00100002 1001.00002
100100003 第2-4位数为对话Id Null None Null 0 很好。 None 1.00100003 1001.00003
100200001 第5-9位数为对话行Id Xu Normal 徐晟壹 0 你好,王。 None 1.00200001 1002.00001
100200002 Wang Normal 王可嘉 1 你好,徐。 None 1.00200002 1002.00002
100200003 Master Normal 李诫 1 你们好。 None 1.00200003 1002.00003
100300001 Npc1 None Null 0 这人谁啊? None 1.00300001 1003.00001
100300002 Npc2 None Null 0 不知道啊? None 1.00300002 1003.00002
100300003 Npc1 None Null 0 不知道你在这干嘛。 None 1.00300003 1003.00003

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 378604b840f56ae49831978cf0e0a6ea
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -5,4 +5,4 @@
1 菜单场景 Menu 1
2 战斗场景 Main 2
3 压力测试场景 StressTest 0
4 玩法A测试场景 GameplayA 0
4 GameplayA 0

View File

@ -6,4 +6,7 @@
100 主菜单 MenuForm Default False True
101 设置 SettingForm Default False True
102 关于 AboutForm Default False True
103 <09><><EFBFBD><EFBFBD><EFBFBD>淨A MVC<56><43><EFBFBD>Խ<EFBFBD><D4BD><EFBFBD> CombineForm Default False True
103 组装玩法UI CombineForm Default False False
104 Mask对话UI MaskDialogForm Default False False
105 Bottom对话UI BottomBoxDialogForm Default False False
106 Bubble对话UI BubbleDialogForm Default True False

View File

@ -15,10 +15,12 @@ public partial class GameEntry : MonoBehaviour
{
public static BuiltinDataComponent BuiltinData { get; private set; }
public static CombineComponent Combine { get; private set; }
public static DialogComponent Dialog { get; private set; }
private static void InitCustomComponents()
{
BuiltinData = UnityGameFramework.Runtime.GameEntry.GetComponent<BuiltinDataComponent>();
Combine = UnityGameFramework.Runtime.GameEntry.GetComponent<CombineComponent>();
Dialog = UnityGameFramework.Runtime.GameEntry.GetComponent<DialogComponent>();
}
}

View File

@ -385,7 +385,7 @@ namespace CustomComponent
/// </summary>
private void RejectPlace(CombineDraggablePart part, string hint)
{
part.ReturnToSpawn();
part.ReturnToSpawnAnimated();
if (!string.IsNullOrEmpty(hint))
{

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 0103c893efce444d9c6fe671306746fe
guid: cc0388c578bec9746813380eee9038d4
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -0,0 +1,413 @@
using System.Collections.Generic;
using DataTable;
using Definition.Enum;
using Event;
using GameFramework.DataTable;
using GameFramework.Event;
using UI;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace CustomComponent
{
[DisallowMultipleComponent]
public class DialogComponent : GameFrameworkComponent
{
#region Property
[SerializeField] private float _playingSpeed = 1.0f;
private const int DialogChapterDivisor = 1000;
private const int LineChapterDivisor = 100000000;
private const int LineDialogDivisor = 100000;
private readonly Dictionary<int, DRDialog> _dialogMap = new();
private readonly Dictionary<int, List<DRDialogLine>> _dialogLinesMap = new();
private readonly Dictionary<int, int> _dialogFirstLineIdMap = new();
private IDataTable<DRDialog> _dtDialog;
private IDataTable<DRDialogLine> _dtDialogLine;
private DialogFormController _formController;
private DialogFormContext _formContext;
private int _currentChapterId;
private int _currentLineIndex = -1;
private bool _isInitialized;
private bool _isPlaying;
public float PlayingSpeed => _playingSpeed;
public bool IsInitialized => _isInitialized;
public bool IsPlaying => _isPlaying;
public int CurrentChapterId => _currentChapterId;
public int CurrentDialogId => _formContext != null ? _formContext.DialogId : 0;
public int CurrentLineId => _formContext != null ? _formContext.CurrentLineId : 0;
#endregion
private void Start()
{
GameEntry.Event.Subscribe(DialogNextLineRequestEventArgs.EventId, OnDialogNextLineRequest);
GameEntry.Event.Subscribe(DialogSkipRequestEventArgs.EventId, OnDialogSkipRequest);
GameEntry.Event.Subscribe(DialogStopRequestEventArgs.EventId, OnDialogStopRequest);
}
private void OnDestroy()
{
GameEntry.Event.Unsubscribe(DialogNextLineRequestEventArgs.EventId, OnDialogNextLineRequest);
GameEntry.Event.Unsubscribe(DialogSkipRequestEventArgs.EventId, OnDialogSkipRequest);
GameEntry.Event.Unsubscribe(DialogStopRequestEventArgs.EventId, OnDialogStopRequest);
}
public bool Init(int chapterId)
{
if (chapterId <= 0)
{
Log.Warning("Dialog init failed. chapterId must be positive.");
return false;
}
if (!EnsureDataTables())
{
return false;
}
StopDialog();
_dialogMap.Clear();
_dialogLinesMap.Clear();
_dialogFirstLineIdMap.Clear();
DRDialog[] dialogRows = _dtDialog.GetDataRows((a, b) => a.Id.CompareTo(b.Id));
for (int i = 0; i < dialogRows.Length; i++)
{
DRDialog dialogRow = dialogRows[i];
if (dialogRow == null)
{
continue;
}
if (ParseChapterIdFromDialogId(dialogRow.Id) != chapterId)
{
continue;
}
_dialogMap[dialogRow.Id] = dialogRow;
}
if (_dialogMap.Count == 0)
{
Log.Warning("Dialog init failed. No dialog rows found for chapter '{0}'.", chapterId.ToString());
return false;
}
DRDialogLine[] lineRows = _dtDialogLine.GetDataRows((a, b) => a.Id.CompareTo(b.Id));
for (int i = 0; i < lineRows.Length; i++)
{
DRDialogLine lineRow = lineRows[i];
if (lineRow == null)
{
continue;
}
if (ParseChapterIdFromLineId(lineRow.Id) != chapterId)
{
continue;
}
int dialogId = ParseDialogIdFromLineId(lineRow.Id);
if (!_dialogMap.ContainsKey(dialogId))
{
continue;
}
if (!_dialogLinesMap.TryGetValue(dialogId, out List<DRDialogLine> dialogLines))
{
dialogLines = new List<DRDialogLine>();
_dialogLinesMap.Add(dialogId, dialogLines);
}
dialogLines.Add(lineRow);
}
List<int> invalidDialogIds = new List<int>();
foreach (KeyValuePair<int, DRDialog> dialogPair in _dialogMap)
{
if (!_dialogLinesMap.TryGetValue(dialogPair.Key, out List<DRDialogLine> dialogLines) ||
dialogLines.Count == 0)
{
Log.Warning("Dialog init warning. Dialog '{0}' has no lines and will be ignored.",
dialogPair.Key.ToString());
invalidDialogIds.Add(dialogPair.Key);
continue;
}
dialogLines.Sort((a, b) => a.Id.CompareTo(b.Id));
_dialogFirstLineIdMap[dialogPair.Key] = dialogLines[0].Id;
}
for (int i = 0; i < invalidDialogIds.Count; i++)
{
_dialogMap.Remove(invalidDialogIds[i]);
}
if (_dialogMap.Count == 0)
{
Log.Warning("Dialog init failed. No valid dialog remains for chapter '{0}'.", chapterId.ToString());
return false;
}
EnsureFormController();
_formContext = null;
_currentChapterId = chapterId;
_currentLineIndex = -1;
_isInitialized = true;
_isPlaying = false;
return true;
}
public bool StartDialog(int dialogId)
{
if (!_isInitialized)
{
Log.Warning("Start dialog failed. Dialog component is not initialized.");
return false;
}
if (ParseChapterIdFromDialogId(dialogId) != _currentChapterId)
{
Log.Warning("Start dialog failed. Dialog '{0}' does not belong to chapter '{1}'.", dialogId.ToString(),
_currentChapterId.ToString());
return false;
}
if (!_dialogMap.TryGetValue(dialogId, out DRDialog dialogRow))
{
Log.Warning("Start dialog failed. Dialog '{0}' was not found in current chapter cache.",
dialogId.ToString());
return false;
}
if (!_dialogLinesMap.TryGetValue(dialogId, out List<DRDialogLine> dialogLines) || dialogLines.Count == 0)
{
Log.Warning("Start dialog failed. Dialog '{0}' has no playable lines.", dialogId.ToString());
return false;
}
if (_isPlaying)
{
StopDialog();
}
EnsureFormController();
if (_formContext == null)
{
_formContext = new DialogFormContext();
}
_formContext.ChapterId = _currentChapterId;
_formContext.DialogId = dialogRow.Id;
_formContext.DialogTitle = dialogRow.Title;
_formContext.DialogUIMode = dialogRow.UIMode;
_formContext.PlayingSpeed = Mathf.Max(0f, _playingSpeed);
_currentLineIndex = 0;
ApplyLineToContext(dialogLines[_currentLineIndex], _currentLineIndex, dialogLines.Count);
_isPlaying = true;
_formController.OpenUI(_formContext);
_formController.OnDialogStarted(_formContext);
_formController.OnDialogLineChanged(_formContext);
return true;
}
public bool NextLine()
{
if (!_isPlaying)
{
Log.Warning("Next line failed. No dialog is playing.");
return false;
}
if (!TryGetCurrentDialogLines(out List<DRDialogLine> dialogLines))
{
StopDialog();
return false;
}
int nextLineIndex = _currentLineIndex + 1;
if (nextLineIndex >= dialogLines.Count)
{
EndDialogInternal();
return true;
}
_currentLineIndex = nextLineIndex;
ApplyLineToContext(dialogLines[_currentLineIndex], _currentLineIndex, dialogLines.Count);
_formController.OnDialogLineChanged(_formContext);
return true;
}
public bool SkipDialog()
{
if (!_isPlaying)
{
Log.Warning("Skip dialog failed. No dialog is playing.");
return false;
}
EndDialogInternal();
return true;
}
public void StopDialog()
{
if (!_isPlaying)
{
return;
}
EndDialogInternal();
}
public void ClearRuntimeContext()
{
StopDialog();
_dialogMap.Clear();
_dialogLinesMap.Clear();
_dialogFirstLineIdMap.Clear();
_formContext = null;
_currentChapterId = 0;
_currentLineIndex = -1;
_isInitialized = false;
_isPlaying = false;
}
private bool EnsureDataTables()
{
_dtDialog = GameEntry.DataTable.GetDataTable<DRDialog>();
if (_dtDialog == null)
{
Log.Warning("Dialog init failed. Data table DRDialog is missing.");
return false;
}
_dtDialogLine = GameEntry.DataTable.GetDataTable<DRDialogLine>();
if (_dtDialogLine == null)
{
Log.Warning("Dialog init failed. Data table DRDialogLine is missing.");
return false;
}
return true;
}
private void EnsureFormController()
{
if (_formController == null)
{
_formController = new DialogFormController();
}
}
private bool TryGetCurrentDialogLines(out List<DRDialogLine> dialogLines)
{
dialogLines = null;
if (_formContext == null)
{
Log.Warning("Dialog state invalid. Form context is null.");
return false;
}
if (!_dialogLinesMap.TryGetValue(_formContext.DialogId, out dialogLines))
{
Log.Warning("Dialog state invalid. Dialog lines are missing for dialog '{0}'.",
_formContext.DialogId.ToString());
return false;
}
return true;
}
private void EndDialogInternal()
{
_isPlaying = false;
_currentLineIndex = -1;
_formController.OnDialogEnded(_formContext);
_formController.CloseUI();
}
private void ApplyLineToContext(DRDialogLine lineRow, int lineIndex, int totalLines)
{
_formContext.CurrentLineId = lineRow.Id;
_formContext.SpeakerId = lineRow.SpeakerId;
_formContext.SpeakerName = lineRow.SpeakerName;
_formContext.Expression = lineRow.Expression;
_formContext.Direction = lineRow.Direction;
_formContext.Text = lineRow.Text;
_formContext.Emphasis = lineRow.Emphasis;
_formContext.PlayingSpeed = Mathf.Max(0f, _playingSpeed);
_formContext.LineIndex = lineIndex;
_formContext.TotalLines = totalLines;
_formContext.IsLastLine = lineIndex >= totalLines - 1;
}
private static int ParseChapterIdFromDialogId(int dialogId)
{
return dialogId / DialogChapterDivisor;
}
private static int ParseChapterIdFromLineId(int lineId)
{
return lineId / LineChapterDivisor;
}
private static int ParseDialogIdFromLineId(int lineId)
{
return lineId / LineDialogDivisor;
}
#region Event Handlers
private void OnDialogNextLineRequest(object sender, GameEventArgs e)
{
if (!(e is DialogNextLineRequestEventArgs))
{
return;
}
NextLine();
}
private void OnDialogSkipRequest(object sender, GameEventArgs e)
{
if (!(e is DialogSkipRequestEventArgs))
{
return;
}
SkipDialog();
}
private void OnDialogStopRequest(object sender, GameEventArgs e)
{
if (!(e is DialogStopRequestEventArgs))
{
return;
}
StopDialog();
}
#endregion
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d6174838c30e460429e5628757bbf015
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using CustomUtility;
using Definition;
using GameFramework.Resource;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace CustomComponent
{
public class SpriteCacheComponent : GameFrameworkComponent
{
[SerializeField] private float _pixelsPerUnit = 100f;
[SerializeField] private Vector2 _defaultPivot = new(0.5f, 0.5f);
private Dictionary<string, Sprite> _spriteCache;
private ResourceComponent _resource;
void Start()
{
_spriteCache = new Dictionary<string, Sprite>();
_resource = GameEntry.Resource;
}
public void GetSprite(string assetName, Action<Sprite> callback)
{
if (_spriteCache.TryGetValue(assetName, out var sprite))
{
callback?.Invoke(sprite);
return;
}
else
{
_resource.LoadAsset
(
AssetUtility.GetUIDialogAsset(assetName),
Constant.AssetPriority.UIFormAsset,
new LoadAssetCallbacks(
(resourcePath, asset, duration, userData) =>
{
Log.Debug(resourcePath);
Texture2D texture = asset as Texture2D;
if (texture != null)
{
Sprite newSprite = Sprite.Create(
texture,
new Rect(0, 0, texture.width, texture.height),
_defaultPivot,
_pixelsPerUnit);
_spriteCache.Add(assetName, newSprite);
callback?.Invoke(newSprite);
}
},
(resourcePath, status, errorMessage, userData) =>
{
Log.Error("Can not load icon '{0}' from '{1}' with error message '{2}'.",
assetName,
resourcePath,
errorMessage);
}
)
);
}
}
private void OnDestroy()
{
_spriteCache.Clear();
_resource = null;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 42b4751aefa33c545a86f146a48536ee
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -9,7 +9,7 @@ using System;
using System.IO;
using UnityEngine;
namespace StarForce
namespace DataTable
{
public static class BinaryReaderExtension
{

View File

@ -0,0 +1,39 @@
using CustomUtility;
using Definition.Enum;
using UnityGameFramework.Runtime;
namespace DataTable
{
public class DRDialog : DataRowBase
{
private int m_Id;
/// <summary>
/// 获取对话编号。
/// </summary>
public override int Id => m_Id;
/// <summary>
/// 获取对话标识。
/// </summary>
public string Title { get; private set; }
/// <summary>
/// 获取对话形式。
/// </summary>
public DialogFormMode UIMode { get; private set; }
public override bool ParseDataRow(string dataRowString, object userData)
{
string[] fields = dataRowString.Split('\t');
int index = 1;
m_Id = int.Parse(fields[index++]);
index++;
Title = fields[index++];
UIMode = EnumUtility<DialogFormMode>.Get(fields[index++]);
return true;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fb12692f2a7e6174eae3b0d28c769e55
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,64 @@
using CustomUtility;
using Definition.Enum;
using UnityGameFramework.Runtime;
namespace DataTable
{
public class DRDialogLine : DataRowBase
{
private int m_Id;
/// <summary>
/// 获取对话行编号
/// </summary>
public override int Id => m_Id;
/// <summary>
/// 获取说话人 Id。
/// </summary>
public string SpeakerId { get; private set; }
/// <summary>
/// 获取说话人表情。
/// </summary>
public ExpressionType Expression { get; private set; }
/// <summary>
/// 获取说话人显示名。
/// </summary>
public string SpeakerName { get; private set; }
/// <summary>
/// 获取说话人朝向。
/// </summary>
public int Direction { get; private set; }
/// <summary>
/// 获取对话内容。
/// </summary>
public string Text { get; private set; }
/// <summary>
/// 获取对话效果。
/// </summary>
public EmphasisType Emphasis { get; private set; }
public override bool ParseDataRow(string dataRowString, object userData)
{
string[] fields = dataRowString.Split('\t');
int index = 0;
index++;
m_Id = int.Parse(fields[index++]);
index++;
SpeakerId = fields[index++];
Expression = EnumUtility<ExpressionType>.Get(fields[index++]);
SpeakerName = fields[index++];
Direction = int.Parse(fields[index++]);
Text = fields[index++];
Emphasis = EnumUtility<EmphasisType>.Get(fields[index++]);
return true;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fc6d3e8e61ab627488e22bb5fc28f95d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -16,7 +16,7 @@ using System.Text;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace StarForce
namespace DataTable
{
/// <summary>
/// 实体表。
@ -28,13 +28,7 @@ namespace StarForce
/// <summary>
/// 获取实体编号。
/// </summary>
public override int Id
{
get
{
return m_Id;
}
}
public override int Id => m_Id;
/// <summary>
/// 获取资源名称。

View File

@ -16,7 +16,7 @@ using System.Text;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace StarForce
namespace DataTable
{
/// <summary>
/// 音乐配置表。

View File

@ -1,22 +1,8 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
// 此文件由工具自动生成,请勿直接修改。
// 生成时间2021-06-16 21:54:35.610
//------------------------------------------------------------
using GameFramework;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO;
using System.Text;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace StarForce
namespace DataTable
{
/// <summary>
/// 场景配置表。

View File

@ -1,22 +1,8 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
// 此文件由工具自动生成,请勿直接修改。
// 生成时间2021-06-16 21:54:35.625
//------------------------------------------------------------
using GameFramework;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO;
using System.Text;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace StarForce
namespace DataTable
{
/// <summary>
/// 声音配置表。

View File

@ -1,14 +1,4 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
// 此文件由工具自动生成,请勿直接修改。
// 生成时间2021-06-16 21:54:35.652
//------------------------------------------------------------
using GameFramework;
using GameFramework;
using System;
using System.Collections.Generic;
using System.IO;
@ -16,7 +6,7 @@ using System.Text;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace StarForce
namespace DataTable
{
/// <summary>
/// 界面配置表。

View File

@ -1,14 +1,4 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
// 此文件由工具自动生成,请勿直接修改。
// 生成时间2021-06-16 21:54:35.666
//------------------------------------------------------------
using GameFramework;
using GameFramework;
using System;
using System.Collections.Generic;
using System.IO;
@ -16,7 +6,7 @@ using System.Text;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace StarForce
namespace DataTable
{
/// <summary>
/// 声音配置表。

View File

@ -1,20 +1,14 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework.DataTable;
using GameFramework.DataTable;
using System;
using Definition;
using UnityEngine;
using UnityGameFramework.Runtime;
namespace StarForce
namespace DataTable
{
public static class DataTableExtension
{
private const string DataRowClassPrefixName = "StarForce.DR";
private const string DataRowClassPrefixName = "DataTable.DR";
internal static readonly char[] DataSplitSeparators = new char[] { '\t' };
internal static readonly char[] DataTrimSeparators = new char[] { '\"' };

View File

@ -5,6 +5,7 @@
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using Definition;
using GameFramework.Debugger;
using GameFramework.Localization;
using UnityEngine;

View File

@ -5,7 +5,7 @@
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
namespace StarForce
namespace Definition
{
public static partial class Constant
{

View File

@ -7,7 +7,7 @@
using UnityEngine;
namespace StarForce
namespace Definition
{
public static partial class Constant
{

View File

@ -5,7 +5,7 @@
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
namespace StarForce
namespace Definition
{
public static partial class Constant
{

View File

@ -0,0 +1,22 @@
namespace Definition.Enum
{
public enum DialogFormMode
{
None = 0,
/// <summary>
/// 黑屏白字
/// </summary>
Mask = 1,
/// <summary>
/// 底部对话框
/// </summary>
BottomBox = 2,
/// <summary>
/// 对话气泡
/// </summary>
Bubble = 3
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7a10763d137f413d828c534b0233f2a6
timeCreated: 1770600423

View File

@ -0,0 +1,13 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Definition.Enum
{
public enum EmphasisType
{
None,
Shake,
Blink,
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 96908bdc885697e4d9cb0f6627d13230
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,14 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Definition.Enum
{
public enum ExpressionType
{
None,
Normal,
Shock,
Happy,
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 174e046d822a14d49843dc415067f13c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -38,5 +38,20 @@ namespace UI
/// 核心玩法A MVC测试界面。
/// </summary>
CombineForm = 103,
/// <summary>
/// 蒙版剧情对话界面。
/// </summary>
MaskDialogForm = 104,
/// <summary>
/// 底部剧情对话界面。
/// </summary>
BottomBoxDialogForm = 105,
/// <summary>
/// 气泡剧情对话界面。
/// </summary>
BubbleDialogForm = 106,
}
}

View File

@ -7,6 +7,8 @@
using GameFramework.DataTable;
using System;
using CustomUtility;
using DataTable;
using Entity;
using Entity.EntityData;
using UnityGameFramework.Runtime;

View File

@ -0,0 +1,21 @@
using GameFramework;
using GameFramework.Event;
namespace Event
{
public class DialogNextLineRequestEventArgs : GameEventArgs
{
public static readonly int EventId = typeof(DialogNextLineRequestEventArgs).GetHashCode();
public override int Id => EventId;
public static DialogNextLineRequestEventArgs Create()
{
return ReferencePool.Acquire<DialogNextLineRequestEventArgs>();
}
public override void Clear()
{
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: de8ad9563f91a584da8c775e9fa916b5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,21 @@
using GameFramework;
using GameFramework.Event;
namespace Event
{
public class DialogSkipRequestEventArgs : GameEventArgs
{
public static readonly int EventId = typeof(DialogSkipRequestEventArgs).GetHashCode();
public override int Id => EventId;
public static DialogSkipRequestEventArgs Create()
{
return ReferencePool.Acquire<DialogSkipRequestEventArgs>();
}
public override void Clear()
{
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: df023ccfed92923439c0f66ca1bd457c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,21 @@
using GameFramework;
using GameFramework.Event;
namespace Event
{
public class DialogStopRequestEventArgs : GameEventArgs
{
public static readonly int EventId = typeof(DialogStopRequestEventArgs).GetHashCode();
public override int Id => EventId;
public static DialogStopRequestEventArgs Create()
{
return ReferencePool.Acquire<DialogStopRequestEventArgs>();
}
public override void Clear()
{
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8d49a133afe91ef4e9bc7502e7adc71b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,10 +1,6 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using CustomUtility;
using DataTable;
using Definition;
using GameFramework.DataTable;
using GameFramework.Event;
using Scene;

View File

@ -1,12 +1,6 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework.Localization;
using GameFramework.Localization;
using System;
using Definition;
using StarForce;
using UnityGameFramework.Runtime;
using ProcedureOwner = GameFramework.Fsm.IFsm<GameFramework.Procedure.IProcedureManager>;

View File

@ -1,15 +1,10 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using GameFramework;
using GameFramework.Event;
using GameFramework.Resource;
using System.Collections.Generic;
using StarForce;
using CustomUtility;
using DataTable;
using Definition;
using TMPro;
using UI;
using UnityEngine;
@ -28,6 +23,8 @@ namespace Procedure
"Sound",
"UIForm",
"UISound",
"Dialog",
"DialogLine"
};
private Dictionary<string, bool> _loadedFlag = new Dictionary<string, bool>();

View File

@ -87,7 +87,11 @@ namespace Procedure
{
base.OnEnter(procedureOwner);
InitializeProcedureState();
//InitializeProcedureState();
GameEntry.Dialog.Init(1);
//GameEntry.Dialog.StartDialog(1001);
GameEntry.Dialog.StartDialog(1002);
}
/// <summary>
@ -109,12 +113,16 @@ namespace Procedure
{
base.OnUpdate(procedureOwner, elapseSeconds, realElapseSeconds);
if (TryUpdateRound(realElapseSeconds))
if (GameEntry.Dialog.IsInitialized)
{
return;
}
TryRestartScene(procedureOwner, realElapseSeconds);
}
// if (TryUpdateRound(realElapseSeconds))
// {
// return;
// }
//
// TryRestartScene(procedureOwner, realElapseSeconds);
}
#endregion

View File

@ -5,6 +5,9 @@
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using CustomUtility;
using DataTable;
using Definition;
using Entity;
using GameFramework;
using GameFramework.DataTable;

View File

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

View File

@ -340,7 +340,7 @@ namespace UI
.SetUpdate(true);
}
private void ReturnToSpawnAnimated()
public void ReturnToSpawnAnimated()
{
if (_spawnParent == null)
{

View File

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

View File

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

View File

@ -0,0 +1,26 @@
using Definition.Enum;
namespace UI
{
public class DialogFormContext : UIContext
{
public float PlayingSpeed = 1f;
public int ChapterId = 0;
public int DialogId = 0;
public string DialogTitle = string.Empty;
public DialogFormMode DialogUIMode = DialogFormMode.None;
public int CurrentLineId = 0;
public string SpeakerId = string.Empty;
public string SpeakerName = string.Empty;
public ExpressionType Expression = ExpressionType.None;
public int Direction = 0;
public string Text = string.Empty;
public EmphasisType Emphasis = EmphasisType.None;
public int LineIndex = -1;
public int TotalLines = 0;
public bool IsLastLine = false;
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 38341401b5804de47bb0a9a1c79d20d8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -0,0 +1,168 @@
using System;
using Definition.Enum;
using GameFramework.Event;
using UnityGameFramework.Runtime;
namespace UI
{
public class DialogFormController : IFormController<DialogFormContext>
{
private DialogFormContext _context;
private DialogFormBase _dialogForm;
private int? _formSerialId;
private bool _pendingRefresh;
public DialogFormController()
{
GameEntry.Event.Subscribe(OpenUIFormSuccessEventArgs.EventId, OnOpenUIFormSuccess);
GameEntry.Event.Subscribe(CloseUIFormCompleteEventArgs.EventId, OnCloseUIFormComplete);
}
public int? OpenUI(DialogFormContext context)
{
if (context == null)
{
Log.Warning("DialogFormController open failed. context is null.");
return null;
}
_context = context;
UIFormId targetFormId = MapDialogFormId(context.DialogUIMode);
if (targetFormId == UIFormId.Undefined)
{
Log.Warning("DialogFormController open failed. Unsupported mode '{0}'.", context.DialogUIMode.ToString());
return null;
}
if (_dialogForm != null && _dialogForm.UIMode == context.DialogUIMode)
{
_dialogForm.StartDialog(context);
return _formSerialId;
}
CloseUI();
_pendingRefresh = true;
_formSerialId = GameEntry.UI.OpenUIForm(targetFormId, context);
return _formSerialId;
}
public void CloseUI()
{
_pendingRefresh = false;
if (_formSerialId.HasValue)
{
GameEntry.UI.CloseUIForm(_formSerialId.Value);
return;
}
if (_dialogForm != null)
{
_dialogForm.Close();
}
}
public void OnDialogStarted(DialogFormContext context)
{
_context = context;
TryRefreshUI();
}
public void OnDialogLineChanged(DialogFormContext context)
{
_context = context;
TryRefreshUI();
}
public void OnDialogEnded(DialogFormContext context)
{
_context = context;
}
~DialogFormController()
{
GameEntry.Event.Unsubscribe(OpenUIFormSuccessEventArgs.EventId, OnOpenUIFormSuccess);
GameEntry.Event.Unsubscribe(CloseUIFormCompleteEventArgs.EventId, OnCloseUIFormComplete);
}
private void TryRefreshUI()
{
if (_context == null)
{
return;
}
if (_dialogForm == null)
{
_pendingRefresh = true;
return;
}
_dialogForm.StartDialog(_context);
_pendingRefresh = false;
}
private static UIFormId MapDialogFormId(DialogFormMode mode)
{
switch (mode)
{
case DialogFormMode.Mask:
return UIFormId.MaskDialogForm;
case DialogFormMode.BottomBox:
return UIFormId.BottomBoxDialogForm;
case DialogFormMode.Bubble:
throw new NotImplementedException("BubbleBox 对话框尚未实现");
default:
return UIFormId.Undefined;
}
}
private void OnOpenUIFormSuccess(object sender, GameEventArgs e)
{
if (!(e is OpenUIFormSuccessEventArgs args))
{
return;
}
if (!_formSerialId.HasValue)
{
return;
}
if (args.UIForm == null || args.UIForm.SerialId != _formSerialId.Value || args.UserData != _context)
{
return;
}
_dialogForm = args.UIForm.Logic as DialogFormBase;
if (_dialogForm == null)
{
Log.Warning("DialogFormController open success but form logic is invalid.");
return;
}
if (_pendingRefresh)
{
TryRefreshUI();
}
}
private void OnCloseUIFormComplete(object sender, GameEventArgs e)
{
if (!(e is CloseUIFormCompleteEventArgs args))
{
return;
}
if (args.SerialId != _formSerialId)
{
return;
}
_dialogForm = null;
_formSerialId = null;
_pendingRefresh = false;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 52cc4e85f8030334689fdcff90748161
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@ -0,0 +1,280 @@
using DG.Tweening;
using Definition.Enum;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using UnityGameFramework.Runtime;
namespace UI
{
public class BottomDialogForm : DialogFormBase
{
public override DialogFormMode UIMode => DialogFormMode.BottomBox;
[SerializeField] private GameObject _speakerArea;
[SerializeField] private TMP_Text _speakerNameText;
[SerializeField] private TMP_Text _contentText;
[SerializeField] private Image _leftSprite;
[SerializeField] private Image _rightSprite;
[SerializeField] private int _leftSpritePosition = 450;
[SerializeField] private int _rightSpritePosition = -450;
[SerializeField] private float _moveDuration = 0.25f;
[SerializeField] private Ease _moveEase = Ease.OutCubic;
private readonly int _singleSpeakerCenterPosition = Screen.width / 2;
private string _leftSpeakerToken = string.Empty;
private string _rightSpeakerToken = string.Empty;
private Sequence _layoutSequence;
public override void StartDialog(DialogFormContext context)
{
if (context == null)
{
Log.Warning("BottomDialogForm start failed. context is null.");
return;
}
_context = context;
string speakerName = context.SpeakerName;
if (_speakerArea != null)
{
_speakerArea.SetActive(!string.IsNullOrEmpty(speakerName));
}
if (_speakerNameText != null)
{
_speakerNameText.text = speakerName;
}
PlayTypewriter(_contentText, context.Text, context.PlayingSpeed);
if (string.IsNullOrEmpty(speakerName))
{
ClearSpeakerState();
ApplySpeakerLayout(false, false, true);
return;
}
bool isRightSpeaker = context.Direction > 0;
if (isRightSpeaker)
{
_rightSpeakerToken = speakerName;
}
else
{
_leftSpeakerToken = speakerName;
}
bool hasLeftSpeaker = !string.IsNullOrEmpty(_leftSpeakerToken);
bool hasRightSpeaker = !string.IsNullOrEmpty(_rightSpeakerToken);
ApplySpeakerLayout(hasLeftSpeaker, hasRightSpeaker, false);
}
protected override void OnClose(bool isShutdown, object userData)
{
ClearSpeakerState();
KillLayoutTween();
ApplySpeakerLayout(false, false, true);
base.OnClose(isShutdown, userData);
}
private void ClearSpeakerState()
{
_leftSpeakerToken = string.Empty;
_rightSpeakerToken = string.Empty;
}
private void KillLayoutTween()
{
if (_layoutSequence != null)
{
_layoutSequence.Kill();
_layoutSequence = null;
}
}
private void ApplySpeakerLayout(bool hasLeftSpeaker, bool hasRightSpeaker, bool instant)
{
if (_leftSprite == null || _rightSprite == null)
{
return;
}
bool leftCurrentlyVisible = _leftSprite.gameObject.activeSelf;
bool rightCurrentlyVisible = _rightSprite.gameObject.activeSelf;
bool leftTargetVisible = hasLeftSpeaker;
bool rightTargetVisible = hasRightSpeaker;
float leftTargetX = GetTargetX(true, hasLeftSpeaker, hasRightSpeaker);
float rightTargetX = GetTargetX(false, hasLeftSpeaker, hasRightSpeaker);
KillLayoutTween();
PrepareStartState(
leftCurrentlyVisible,
rightCurrentlyVisible,
leftTargetVisible,
rightTargetVisible,
hasLeftSpeaker,
hasRightSpeaker);
if (instant || _moveDuration <= 0f)
{
SetSpritePosition(_leftSprite.rectTransform, leftTargetX);
SetSpritePosition(_rightSprite.rectTransform, rightTargetX);
SetSpriteVisible(_leftSprite, leftTargetVisible);
SetSpriteVisible(_rightSprite, rightTargetVisible);
return;
}
_layoutSequence = DOTween.Sequence();
Tween leftTween = CreateMoveTween(_leftSprite.rectTransform, leftTargetX);
if (leftTween != null)
{
_layoutSequence.Join(leftTween);
}
Tween rightTween = CreateMoveTween(_rightSprite.rectTransform, rightTargetX);
if (rightTween != null)
{
_layoutSequence.Join(rightTween);
}
if (_layoutSequence.active && _layoutSequence.Duration(false) > 0f)
{
_layoutSequence.OnComplete(() =>
{
SetSpriteVisible(_leftSprite, leftTargetVisible);
SetSpriteVisible(_rightSprite, rightTargetVisible);
_layoutSequence = null;
});
}
else
{
SetSpritePosition(_leftSprite.rectTransform, leftTargetX);
SetSpritePosition(_rightSprite.rectTransform, rightTargetX);
SetSpriteVisible(_leftSprite, leftTargetVisible);
SetSpriteVisible(_rightSprite, rightTargetVisible);
_layoutSequence.Kill();
_layoutSequence = null;
}
}
private void PrepareStartState(
bool leftCurrentlyVisible,
bool rightCurrentlyVisible,
bool leftTargetVisible,
bool rightTargetVisible,
bool hasLeftSpeaker,
bool hasRightSpeaker)
{
if (leftTargetVisible && !leftCurrentlyVisible)
{
float leftStartX = GetAppearStartX(true, rightCurrentlyVisible, hasLeftSpeaker, hasRightSpeaker);
SetSpritePosition(_leftSprite.rectTransform, leftStartX);
SetSpriteVisible(_leftSprite, true);
}
if (rightTargetVisible && !rightCurrentlyVisible)
{
float rightStartX = GetAppearStartX(false, leftCurrentlyVisible, hasLeftSpeaker, hasRightSpeaker);
SetSpritePosition(_rightSprite.rectTransform, rightStartX);
SetSpriteVisible(_rightSprite, true);
}
if (leftCurrentlyVisible && !leftTargetVisible)
{
SetSpriteVisible(_leftSprite, true);
}
if (rightCurrentlyVisible && !rightTargetVisible)
{
SetSpriteVisible(_rightSprite, true);
}
}
private float GetAppearStartX(bool isLeft, bool otherCurrentlyVisible, bool hasLeftSpeaker,
bool hasRightSpeaker)
{
if (hasLeftSpeaker && hasRightSpeaker)
{
// single -> multi: hidden side starts from center, then both move to side positions.
if (otherCurrentlyVisible)
{
return _singleSpeakerCenterPosition;
}
return isLeft ? _leftSpritePosition : _rightSpritePosition;
}
// single appears: active side starts from its side and moves to center.
return isLeft ? _leftSpritePosition : _rightSpritePosition;
}
private float GetTargetX(bool isLeft, bool hasLeftSpeaker, bool hasRightSpeaker)
{
if (hasLeftSpeaker && hasRightSpeaker)
{
return isLeft ? _leftSpritePosition : _rightSpritePosition;
}
if (hasLeftSpeaker || hasRightSpeaker)
{
// multi -> single: both move to center first, then inactive side hides.
return _singleSpeakerCenterPosition;
}
return isLeft ? _leftSpritePosition : _rightSpritePosition;
}
private Tween CreateMoveTween(RectTransform rectTransform, float targetX)
{
if (rectTransform == null)
{
return null;
}
if (Mathf.Abs(rectTransform.anchoredPosition.x - targetX) < 0.01f)
{
return null;
}
return rectTransform.DOAnchorPosX(targetX, _moveDuration).SetEase(_moveEase);
}
private static void SetSpriteVisible(Image spriteImage, bool visible)
{
if (spriteImage == null)
{
return;
}
spriteImage.gameObject.SetActive(visible);
}
private static void SetSpritePosition(RectTransform rectTransform, float xPosition)
{
if (rectTransform == null)
{
return;
}
Vector2 anchoredPosition = rectTransform.anchoredPosition;
anchoredPosition.x = xPosition;
rectTransform.anchoredPosition = anchoredPosition;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ea6f55294a4cd2946a83649e7be82314
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,146 @@
using System.Collections;
using Definition.Enum;
using Event;
using TMPro;
using UnityEngine;
namespace UI
{
public abstract class DialogFormBase : UGuiForm
{
protected DialogFormContext _context;
private Coroutine _typingCoroutine;
private TMP_Text _typingTargetText;
private bool _isTypewriting;
public abstract DialogFormMode UIMode { get; }
public abstract void StartDialog(DialogFormContext context);
protected override void OnOpen(object userData)
{
base.OnOpen(userData);
if (!(userData is DialogFormContext context))
{
return;
}
_context = context;
StartDialog(context);
}
protected override void OnClose(bool isShutdown, object userData)
{
StopTypewriter();
_context = null;
base.OnClose(isShutdown, userData);
}
public void OnClickNextLine()
{
if (CompleteTypewriterIfRunning())
{
return;
}
GameEntry.Event.Fire(this, DialogNextLineRequestEventArgs.Create());
}
public void OnClickSkipDialog()
{
GameEntry.Event.Fire(this, DialogSkipRequestEventArgs.Create());
}
public void OnClickStopDialog()
{
GameEntry.Event.Fire(this, DialogStopRequestEventArgs.Create());
}
protected void PlayTypewriter(TMP_Text targetText, string text, float charsPerSecond)
{
StopTypewriter();
if (targetText == null)
{
return;
}
string finalText = text ?? string.Empty;
_typingTargetText = targetText;
if (charsPerSecond <= 0f || string.IsNullOrEmpty(finalText))
{
targetText.text = finalText;
targetText.maxVisibleCharacters = int.MaxValue;
_isTypewriting = false;
return;
}
_isTypewriting = true;
_typingCoroutine = StartCoroutine(TypewriterRoutine(targetText, finalText, charsPerSecond));
}
protected void StopTypewriter()
{
if (_typingCoroutine != null)
{
StopCoroutine(_typingCoroutine);
_typingCoroutine = null;
}
_typingTargetText = null;
_isTypewriting = false;
}
private bool CompleteTypewriterIfRunning()
{
if (!_isTypewriting || _typingTargetText == null)
{
return false;
}
_typingTargetText.maxVisibleCharacters = int.MaxValue;
StopTypewriter();
return true;
}
private IEnumerator TypewriterRoutine(TMP_Text targetText, string finalText, float charsPerSecond)
{
targetText.text = finalText;
targetText.ForceMeshUpdate();
int totalCharacters = targetText.textInfo.characterCount;
if (totalCharacters <= 0)
{
targetText.maxVisibleCharacters = int.MaxValue;
_typingCoroutine = null;
_typingTargetText = null;
_isTypewriting = false;
yield break;
}
targetText.maxVisibleCharacters = 0;
float elapsed = 0f;
int visibleCharacters = 0;
while (visibleCharacters < totalCharacters)
{
elapsed += Time.unscaledDeltaTime;
int nextVisible = Mathf.Min(totalCharacters, Mathf.FloorToInt(elapsed * charsPerSecond));
if (nextVisible != visibleCharacters)
{
visibleCharacters = nextVisible;
targetText.maxVisibleCharacters = visibleCharacters;
}
yield return null;
}
targetText.maxVisibleCharacters = int.MaxValue;
_typingCoroutine = null;
_typingTargetText = null;
_isTypewriting = false;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: aafc42873758b514282b3a75e3ba4665
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,35 @@
using Definition.Enum;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using UnityGameFramework.Runtime;
namespace UI
{
public class MaskDialogForm : DialogFormBase
{
public override DialogFormMode UIMode => DialogFormMode.Mask;
[SerializeField] private Image _maskImage;
[SerializeField] private TMP_Text _text;
public override void StartDialog(DialogFormContext context)
{
if (context == null)
{
Log.Warning("MaskDialogForm start failed. context is null.");
return;
}
_context = context;
if (_maskImage != null)
{
_maskImage.gameObject.SetActive(true);
}
PlayTypewriter(_text, context.Text, context.PlayingSpeed);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5a63462640e70af40972b9841beafe6c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,13 +1,9 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework.DataTable;
using GameFramework.DataTable;
using GameFramework.UI;
using System.Collections;
using CustomUtility;
using DataTable;
using Definition;
using Procedure;
using StarForce;
using UnityEngine;

View File

@ -7,7 +7,7 @@
using GameFramework;
namespace StarForce
namespace CustomUtility
{
public static class AssetUtility
{
@ -65,5 +65,10 @@ namespace StarForce
{
return Utility.Text.Format("Assets/GameMain/UI/UISounds/{0}.wav", assetName);
}
public static string GetUIDialogAsset(string assetName)
{
return Utility.Text.Format("Assets/GameMain/UI/Dialogs/{0}.prefab", assetName);
}
}
}

View File

@ -0,0 +1,27 @@
using System.Collections.Generic;
using UnityGameFramework.Runtime;
namespace CustomUtility
{
public static class EnumUtility<T> where T : struct, System.Enum
{
private static readonly Dictionary<string, T> _enumCache = new();
public static T Get(string value)
{
if (!_enumCache.TryGetValue(value, out T result))
{
if (System.Enum.TryParse(value, true, out result))
{
_enumCache[value] = result;
}
else
{
Log.Error($"Enum 解析失败:类型:{typeof(T).Name} 不包含值 {value}");
}
}
return result;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d0591e8f95955014f8c2f8d9ba3c9247
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -9,7 +9,7 @@ using GameFramework;
using LitJson;
using System;
namespace StarForce
namespace CustomUtility
{
/// <summary>
/// LitJSON 函数集辅助器。

View File

@ -1,13 +1,6 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System;
using System;
namespace StarForce
namespace CustomUtility
{
public static class WebUtility
{

View File

@ -0,0 +1,937 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &577377382380353288
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 478704929657922221}
- component: {fileID: 3708131469420921886}
- component: {fileID: 1177229253130277070}
- component: {fileID: 8970091190510382761}
m_Layer: 5
m_Name: NextLineButton
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &478704929657922221
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 577377382380353288}
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: 4703471767818675053}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &3708131469420921886
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 577377382380353288}
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: 0}
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: 0}
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!222 &1177229253130277070
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 577377382380353288}
m_CullTransparentMesh: 1
--- !u!114 &8970091190510382761
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 577377382380353288}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Navigation:
m_Mode: 3
m_WrapAround: 0
m_SelectOnUp: {fileID: 0}
m_SelectOnDown: {fileID: 0}
m_SelectOnLeft: {fileID: 0}
m_SelectOnRight: {fileID: 0}
m_Transition: 0
m_Colors:
m_NormalColor: {r: 1, g: 1, b: 1, a: 1}
m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1}
m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1}
m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608}
m_ColorMultiplier: 1
m_FadeDuration: 0.1
m_SpriteState:
m_HighlightedSprite: {fileID: 0}
m_PressedSprite: {fileID: 0}
m_SelectedSprite: {fileID: 0}
m_DisabledSprite: {fileID: 0}
m_AnimationTriggers:
m_NormalTrigger: Normal
m_HighlightedTrigger: Highlighted
m_PressedTrigger: Pressed
m_SelectedTrigger: Selected
m_DisabledTrigger: Disabled
m_Interactable: 1
m_TargetGraphic: {fileID: 3708131469420921886}
m_OnClick:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 2327325990879817607}
m_TargetAssemblyTypeName: UI.DialogFormBase, Assembly-CSharp
m_MethodName: OnClickNextLine
m_Mode: 1
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument:
m_BoolArgument: 0
m_CallState: 2
--- !u!1 &1001066407702705397
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3708143324325626536}
- component: {fileID: 6873615243070434848}
- component: {fileID: 6431296888118130931}
m_Layer: 5
m_Name: ContentText
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &3708143324325626536
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1001066407702705397}
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: 7192457896265437741}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: -200, y: -100}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &6873615243070434848
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1001066407702705397}
m_CullTransparentMesh: 1
--- !u!114 &6431296888118130931
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1001066407702705397}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 0
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: "\u674E\u8BEB"
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 99d811b0183246646a2ce8df996f4bca, type: 2}
m_sharedMaterial: {fileID: -1106088975554028259, guid: 99d811b0183246646a2ce8df996f4bca,
type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4293980400
m_fontColor: {r: 0.9411765, g: 0.9411765, b: 0.9411765, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 70
m_fontSizeBase: 70
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 1
m_VerticalAlignment: 256
m_textAlignment: 65535
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_enableWordWrapping: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 1
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!1 &1966594047748998563
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7192457896265437741}
m_Layer: 5
m_Name: ContentArea
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &7192457896265437741
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1966594047748998563}
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:
- {fileID: 8762364413705962150}
- {fileID: 3708143324325626536}
m_Father: {fileID: 2330152971407905255}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: -50}
m_SizeDelta: {x: 0, y: -100}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!1 &2526382269717144677
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4594737505273760298}
- component: {fileID: 1858592913377441272}
- component: {fileID: 7945103967507868302}
m_Layer: 5
m_Name: LeftSpeaker
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!224 &4594737505273760298
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2526382269717144677}
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: 6089528910385973127}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0.5}
m_AnchorMax: {x: 0, y: 0.5}
m_AnchoredPosition: {x: 450, y: -200}
m_SizeDelta: {x: 900, y: 1205.4878}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &1858592913377441272
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2526382269717144677}
m_CullTransparentMesh: 1
--- !u!114 &7945103967507868302
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2526382269717144677}
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: 0
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 0}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &3736358320082617150
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 6089528910385973127}
m_Layer: 5
m_Name: SpeakerArea
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &6089528910385973127
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3736358320082617150}
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:
- {fileID: 4594737505273760298}
- {fileID: 1023330169278438415}
m_Father: {fileID: 4703471767818675053}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!1 &3752068138017298928
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1792700702723432816}
- component: {fileID: 6515285980419930672}
- component: {fileID: 8566667250576683572}
m_Layer: 5
m_Name: bg
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1792700702723432816
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3752068138017298928}
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: 5100528644975002445}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &6515285980419930672
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3752068138017298928}
m_CullTransparentMesh: 1
--- !u!114 &8566667250576683572
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3752068138017298928}
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: 0
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 0}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &4403804830056219076
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5100528644975002445}
m_Layer: 5
m_Name: NameArea
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &5100528644975002445
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4403804830056219076}
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:
- {fileID: 1792700702723432816}
- {fileID: 8619101080858191825}
m_Father: {fileID: 2330152971407905255}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 250, y: -50}
m_SizeDelta: {x: 500, y: 100}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!1 &4514918814497795030
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 8762364413705962150}
- component: {fileID: 2347793963973952820}
- component: {fileID: 7254061520918156868}
m_Layer: 5
m_Name: bg
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &8762364413705962150
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4514918814497795030}
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: 7192457896265437741}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &2347793963973952820
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4514918814497795030}
m_CullTransparentMesh: 1
--- !u!114 &7254061520918156868
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4514918814497795030}
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: 0.39215687, g: 0.39215687, b: 0.39215687, a: 0.39215687}
m_RaycastTarget: 0
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 0}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &4995567450066526950
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4703471767818675053}
- component: {fileID: 4643264964412212504}
- component: {fileID: 2327325990879817607}
m_Layer: 5
m_Name: BottomBoxDialogForm
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &4703471767818675053
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4995567450066526950}
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:
- {fileID: 6089528910385973127}
- {fileID: 2330152971407905255}
- {fileID: 478704929657922221}
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!223 &4643264964412212504
Canvas:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4995567450066526950}
m_Enabled: 1
serializedVersion: 3
m_RenderMode: 0
m_Camera: {fileID: 0}
m_PlaneDistance: 100
m_PixelPerfect: 0
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_VertexColorAlwaysGammaSpace: 0
m_AdditionalShaderChannelsFlag: 25
m_UpdateRectTransformForStandalone: 0
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
--- !u!114 &2327325990879817607
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 4995567450066526950}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ea6f55294a4cd2946a83649e7be82314, type: 3}
m_Name:
m_EditorClassIdentifier:
_playSpeed: 0
_speakerArea: {fileID: 3736358320082617150}
_speakerNameText: {fileID: 2470970474825277305}
_contentText: {fileID: 6431296888118130931}
_leftSprite: {fileID: 7945103967507868302}
_rightSprite: {fileID: 5385698520020721016}
_leftSpritePosition: 450
_rightSpritePosition: -450
_moveDuration: 0.25
_moveEase: 9
--- !u!1 &7381337123922490182
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 8619101080858191825}
- component: {fileID: 5148587339817138371}
- component: {fileID: 2470970474825277305}
m_Layer: 5
m_Name: NameText
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &8619101080858191825
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7381337123922490182}
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: 5100528644975002445}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 100, y: 0}
m_SizeDelta: {x: -200, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &5148587339817138371
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7381337123922490182}
m_CullTransparentMesh: 1
--- !u!114 &2470970474825277305
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7381337123922490182}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 0
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: "\u674E\u8BEB"
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 99d811b0183246646a2ce8df996f4bca, type: 2}
m_sharedMaterial: {fileID: -1106088975554028259, guid: 99d811b0183246646a2ce8df996f4bca,
type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4280163870
m_fontColor: {r: 0.11764706, g: 0.11764706, b: 0.11764706, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 50
m_fontSizeBase: 50
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 18
m_fontSizeMax: 72
m_fontStyle: 0
m_HorizontalAlignment: 2
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: 0
m_lineSpacingMax: 0
m_paragraphSpacing: 0
m_charWidthMaxAdj: 0
m_enableWordWrapping: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 1
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!1 &7436457223957886746
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1023330169278438415}
- component: {fileID: 23627497045646178}
- component: {fileID: 5385698520020721016}
m_Layer: 5
m_Name: RightSpeaker
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!224 &1023330169278438415
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7436457223957886746}
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: 6089528910385973127}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 0.5}
m_AnchorMax: {x: 1, y: 0.5}
m_AnchoredPosition: {x: -450, y: -200}
m_SizeDelta: {x: 900, y: 1205.4878}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &23627497045646178
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7436457223957886746}
m_CullTransparentMesh: 1
--- !u!114 &5385698520020721016
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7436457223957886746}
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: 0
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_Sprite: {fileID: 0}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &7992201661324843749
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2330152971407905255}
m_Layer: 5
m_Name: DialogBox
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &2330152971407905255
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7992201661324843749}
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:
- {fileID: 7192457896265437741}
- {fileID: 5100528644975002445}
m_Father: {fileID: 4703471767818675053}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 0}
m_AnchoredPosition: {x: 0, y: 300}
m_SizeDelta: {x: 0, y: 600}
m_Pivot: {x: 0.5, y: 0.5}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 75da5a4ba56425747be081b9b396ba4e
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More