功能批量实现 优化 服务端 新浮动小游戏框架 新界面UI
This commit is contained in:
@@ -1,79 +1,326 @@
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
[CreateAssetMenu(fileName = "NewGalSO", menuName = "Galgame/galSO")]
|
||||
public class ingame_galgame_so : ScriptableObject
|
||||
{
|
||||
[System.Serializable]
|
||||
[Serializable]
|
||||
public class DialogueText
|
||||
{
|
||||
public enum ImagePosition
|
||||
{
|
||||
Left,
|
||||
Right
|
||||
}
|
||||
|
||||
public enum StepMethod
|
||||
{
|
||||
ClickToNext,
|
||||
WaitForDuration
|
||||
}
|
||||
|
||||
public enum TimeAction
|
||||
{
|
||||
None,
|
||||
SlowMotion,
|
||||
Pause
|
||||
}
|
||||
|
||||
public enum EndAction
|
||||
{
|
||||
NextText,
|
||||
PauseQueue,
|
||||
EndPerformance
|
||||
}
|
||||
|
||||
[TextArea(3, 10)]
|
||||
[Tooltip("文本内容")]
|
||||
public string content; // 文本内容
|
||||
[Tooltip("当前对话实际显示的文本内容。")]
|
||||
public string content;
|
||||
|
||||
[Tooltip("队列中第几个文本")]
|
||||
public int textNumber; // 队列中第几个文本
|
||||
[Tooltip("文本编号,仅用于人工整理,不作为运行时唯一依据。")]
|
||||
public int textNumber;
|
||||
|
||||
[Tooltip("从 speakersDataSO 中选择发言者")]
|
||||
public int senderIndex = -1; // 改为索引,通过下拉选择
|
||||
[Tooltip("发言人索引,来自 speakersDataSO 的 speakers 列表。-1 表示系统或旁白。")]
|
||||
public int senderIndex = -1;
|
||||
|
||||
public enum ImagePosition { Left, Right }
|
||||
[Tooltip("对象图片左右位置")]
|
||||
public ImagePosition imagePos; // 对象图片左右位置
|
||||
[Tooltip("对象图片是否水平翻转")]
|
||||
[Tooltip("角色图片显示在左侧还是右侧。")]
|
||||
public ImagePosition imagePos = ImagePosition.Left;
|
||||
|
||||
[Tooltip("角色图片是否水平翻转。")]
|
||||
public bool flipX;
|
||||
|
||||
[Tooltip("文本出现时间")]
|
||||
public float appearTime; // 文本出现时间
|
||||
[Tooltip("文本持续时间")]
|
||||
public float duration; // 文本持续时间
|
||||
[Tooltip("该条文本在所选时间轴上的出现时间。")]
|
||||
public float appearTime;
|
||||
|
||||
public enum StepMethod { ClickToNext, WaitForDuration }
|
||||
[Tooltip("文本步进方法:点击后下一步 / 等待时长结束")]
|
||||
public StepMethod stepMethod; // 文本步进方法
|
||||
[Tooltip("自动播放时的停留时间,仅在 WaitForDuration 下生效。")]
|
||||
public float duration = 1f;
|
||||
|
||||
public enum TimeAction { None, SlowMotion, Pause }
|
||||
[Tooltip("文本出现时动作:无/慢动作/暂停")]
|
||||
public TimeAction timeAction; // 文本出现时动作
|
||||
[Tooltip("当前文本如何推进到下一条。")]
|
||||
public StepMethod stepMethod = StepMethod.ClickToNext;
|
||||
|
||||
[Tooltip("文本播放期间时间流速,0为暂停")]
|
||||
[Tooltip("文本播放期间对游戏时间流做的动作。")]
|
||||
public TimeAction timeAction = TimeAction.None;
|
||||
|
||||
[Tooltip("当 timeAction 为 SlowMotion 时使用的 Time.timeScale。")]
|
||||
[Range(0f, 1f)]
|
||||
public float slowMotionScale = 0.5f; // 慢动作允许TimeScale设置值
|
||||
public float slowMotionScale = 0.5f;
|
||||
|
||||
public enum EndAction { NextText, PauseQueue, EndPerformance }
|
||||
[Tooltip("文本结束动作")]
|
||||
public EndAction endAction; // 文本结束动作
|
||||
[Tooltip("当前文本结束后的队列行为。")]
|
||||
public EndAction endAction = EndAction.NextText;
|
||||
|
||||
public DialogueText Clone()
|
||||
{
|
||||
return new DialogueText
|
||||
{
|
||||
content = content,
|
||||
textNumber = textNumber,
|
||||
senderIndex = senderIndex,
|
||||
imagePos = imagePos,
|
||||
flipX = flipX,
|
||||
appearTime = appearTime,
|
||||
duration = duration,
|
||||
stepMethod = stepMethod,
|
||||
timeAction = timeAction,
|
||||
slowMotionScale = slowMotionScale,
|
||||
endAction = endAction
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
[Serializable]
|
||||
public class DialogueElement
|
||||
{
|
||||
public enum PositionTag { RoleHost, RoleHint, Narration, HintOrLyrics }
|
||||
public enum PositionTag
|
||||
{
|
||||
RoleHost,
|
||||
RoleHint,
|
||||
Narration,
|
||||
HintOrLyrics
|
||||
}
|
||||
|
||||
[Header("显示模式")]
|
||||
[Tooltip("决定本段文本使用哪种对话框样式。")]
|
||||
public PositionTag positionTag = PositionTag.RoleHost;
|
||||
|
||||
[Header("位置配置")]
|
||||
public PositionTag positionTag;
|
||||
[HideInInspector]
|
||||
public List<Vector2> customPositions;
|
||||
public List<Vector2> customPositions = new List<Vector2>();
|
||||
|
||||
[Header("文本内容配置")]
|
||||
public List<DialogueText> textList; // 文字列表
|
||||
[Header("文本列表")]
|
||||
[Tooltip("该段落下的实际文本播放列表。")]
|
||||
public List<DialogueText> textList = new List<DialogueText>();
|
||||
|
||||
public DialogueElement Clone()
|
||||
{
|
||||
var clone = new DialogueElement
|
||||
{
|
||||
positionTag = positionTag,
|
||||
customPositions = customPositions != null ? new List<Vector2>(customPositions) : new List<Vector2>(),
|
||||
textList = new List<DialogueText>()
|
||||
};
|
||||
|
||||
if (textList != null)
|
||||
{
|
||||
for (int i = 0; i < textList.Count; i++)
|
||||
{
|
||||
if (textList[i] != null)
|
||||
{
|
||||
clone.textList.Add(textList[i].Clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
|
||||
public enum TimelineBase { MusicTime, SceneStartTime, CustomTimer }
|
||||
public enum TriggerMethod { CodeTrigger, TimerTrigger, MixedTrigger }
|
||||
public enum DialogueType { Galgame, Lyrics }
|
||||
public enum TimelineBase
|
||||
{
|
||||
MusicTime,
|
||||
SceneStartTime,
|
||||
CustomTimer
|
||||
}
|
||||
|
||||
public enum TriggerMethod
|
||||
{
|
||||
CodeTrigger,
|
||||
TimerTrigger,
|
||||
MixedTrigger
|
||||
}
|
||||
|
||||
public enum DialogueType
|
||||
{
|
||||
Galgame,
|
||||
Lyrics
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class JsonDefinition
|
||||
{
|
||||
public int version = 1;
|
||||
public DialogueType dialogueType = DialogueType.Galgame;
|
||||
public TriggerMethod triggerMethod = TriggerMethod.TimerTrigger;
|
||||
public TimelineBase timelineStandard = TimelineBase.SceneStartTime;
|
||||
public List<DialogueElement> dialogueList = new List<DialogueElement>();
|
||||
|
||||
public JsonDefinition Clone()
|
||||
{
|
||||
var clone = new JsonDefinition
|
||||
{
|
||||
version = version,
|
||||
dialogueType = dialogueType,
|
||||
triggerMethod = triggerMethod,
|
||||
timelineStandard = timelineStandard,
|
||||
dialogueList = new List<DialogueElement>()
|
||||
};
|
||||
|
||||
if (dialogueList != null)
|
||||
{
|
||||
for (int i = 0; i < dialogueList.Count; i++)
|
||||
{
|
||||
if (dialogueList[i] != null)
|
||||
{
|
||||
clone.dialogueList.Add(dialogueList[i].Clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
|
||||
[Header("全局配置")]
|
||||
[Tooltip("对话类型")]
|
||||
public DialogueType dialogueType;
|
||||
[Tooltip("触发方式")]
|
||||
public TriggerMethod triggerMethod;
|
||||
[Tooltip("时间线基准")]
|
||||
public TimelineBase timelineStandard;
|
||||
[Tooltip("当前脚本化演出是普通对话还是歌词模式。")]
|
||||
public DialogueType dialogueType = DialogueType.Galgame;
|
||||
|
||||
[Tooltip("运行时由代码触发、按时间轴触发,还是两者混合。")]
|
||||
public TriggerMethod triggerMethod = TriggerMethod.TimerTrigger;
|
||||
|
||||
[Tooltip("appearTime 使用哪一种时间基准。")]
|
||||
public TimelineBase timelineStandard = TimelineBase.SceneStartTime;
|
||||
|
||||
[Header("角色数据")]
|
||||
[Tooltip("引用 Speaker 配置 ScriptableObject")]
|
||||
[Tooltip("发言人配置来源。")]
|
||||
public galgame_speakers_so speakersDataSO;
|
||||
|
||||
[Header("JSON 覆盖")]
|
||||
[Tooltip("如果拖入 JSON 文本资源,运行时会优先使用 JSON 内容,而不是当前 Inspector 里的对话配置。")]
|
||||
public TextAsset jsonDefinitionAsset;
|
||||
|
||||
[Header("对话内容")]
|
||||
public List<DialogueElement> dialogueList = new List<DialogueElement>();
|
||||
|
||||
public bool HasJsonOverride => jsonDefinitionAsset != null && !string.IsNullOrWhiteSpace(jsonDefinitionAsset.text);
|
||||
|
||||
public JsonDefinition BuildDefinitionFromInspector()
|
||||
{
|
||||
var definition = new JsonDefinition
|
||||
{
|
||||
dialogueType = dialogueType,
|
||||
triggerMethod = triggerMethod,
|
||||
timelineStandard = timelineStandard,
|
||||
dialogueList = new List<DialogueElement>()
|
||||
};
|
||||
|
||||
if (dialogueList != null)
|
||||
{
|
||||
for (int i = 0; i < dialogueList.Count; i++)
|
||||
{
|
||||
if (dialogueList[i] != null)
|
||||
{
|
||||
definition.dialogueList.Add(dialogueList[i].Clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return definition;
|
||||
}
|
||||
|
||||
public bool TryParseJsonOverride(out JsonDefinition definition)
|
||||
{
|
||||
definition = null;
|
||||
if (!HasJsonOverride)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
definition = JsonUtility.FromJson<JsonDefinition>(jsonDefinitionAsset.text);
|
||||
if (definition == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (definition.dialogueList == null)
|
||||
{
|
||||
definition.dialogueList = new List<DialogueElement>();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"[ingame_galgame_so] JSON 解析失败: {ex.Message}", this);
|
||||
definition = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public JsonDefinition GetResolvedDefinition()
|
||||
{
|
||||
if (TryParseJsonOverride(out JsonDefinition fromJson))
|
||||
{
|
||||
return fromJson;
|
||||
}
|
||||
|
||||
return BuildDefinitionFromInspector();
|
||||
}
|
||||
|
||||
public string ExportCurrentDefinitionToJson(bool prettyPrint = true)
|
||||
{
|
||||
return JsonUtility.ToJson(BuildDefinitionFromInspector(), prettyPrint);
|
||||
}
|
||||
|
||||
public void ApplyDefinitionToInspector(JsonDefinition definition)
|
||||
{
|
||||
if (definition == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dialogueType = definition.dialogueType;
|
||||
triggerMethod = definition.triggerMethod;
|
||||
timelineStandard = definition.timelineStandard;
|
||||
|
||||
dialogueList ??= new List<DialogueElement>();
|
||||
dialogueList.Clear();
|
||||
|
||||
if (definition.dialogueList == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < definition.dialogueList.Count; i++)
|
||||
{
|
||||
DialogueElement element = definition.dialogueList[i];
|
||||
if (element != null)
|
||||
{
|
||||
dialogueList.Add(element.Clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryApplyJsonOverrideToInspector(out string errorMessage)
|
||||
{
|
||||
errorMessage = string.Empty;
|
||||
if (!TryParseJsonOverride(out JsonDefinition definition))
|
||||
{
|
||||
errorMessage = HasJsonOverride ? "JSON 解析失败" : "未配置 JSON 覆盖源";
|
||||
return false;
|
||||
}
|
||||
|
||||
ApplyDefinitionToInspector(definition);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user