2026-07-05 16:08:23 -04:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using Sirenix.OdinInspector;
|
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Ichni.Story
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 立绘渲染方式。当前使用 Sprite,预留 Live2D / Spine 扩展入口。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public enum PortraitStyle
|
|
|
|
|
|
{
|
|
|
|
|
|
Sprite,
|
|
|
|
|
|
Live2D,
|
|
|
|
|
|
Spine
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 单个角色的立绘数据(按角色单独创建 ScriptableObject 资产)。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[CreateAssetMenu(fileName = "CharacterData", menuName = "Ichni/Story/New/CharacterData")]
|
|
|
|
|
|
public class CharacterData : SerializedScriptableObject
|
|
|
|
|
|
{
|
|
|
|
|
|
[LabelText("Character ID")]
|
2026-07-07 01:28:27 -04:00
|
|
|
|
[Tooltip("此 ID 需与 .yarn 文件中对应台词的 speaker 名完全一致。")]
|
2026-07-05 16:08:23 -04:00
|
|
|
|
public string characterId;
|
|
|
|
|
|
|
|
|
|
|
|
[LabelText("Display Name Key")]
|
2026-07-07 01:28:27 -04:00
|
|
|
|
[Tooltip("Unity Localization String Table Key,用于多语言角色名显示。")]
|
2026-07-05 16:08:23 -04:00
|
|
|
|
public string displayNameKey;
|
|
|
|
|
|
|
|
|
|
|
|
[LabelText("Portrait Style")]
|
|
|
|
|
|
public PortraitStyle portraitStyle = PortraitStyle.Sprite;
|
2026-07-07 01:28:27 -04:00
|
|
|
|
|
|
|
|
|
|
[LabelText("Position Offset")]
|
|
|
|
|
|
[Tooltip("立绘在舞台上的位置偏移(单位:映射百分比)")]
|
|
|
|
|
|
public Vector2 positionOffset = new Vector2(0f, 0f);
|
2026-07-05 16:08:23 -04:00
|
|
|
|
|
|
|
|
|
|
// ── Sprite ──────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
[LabelText("Emotion Sprites")]
|
|
|
|
|
|
[ShowIf("portraitStyle", PortraitStyle.Sprite)]
|
|
|
|
|
|
[DictionaryDrawerSettings(KeyLabel = "Emotion Name", ValueLabel = "Sprite")]
|
|
|
|
|
|
[InfoBox("Key 为情绪名(如 normal / happy / angry),Value 为对应 Sprite 资产。")]
|
|
|
|
|
|
public Dictionary<string, Sprite> emotionSprites = new Dictionary<string, Sprite>();
|
|
|
|
|
|
|
|
|
|
|
|
// ── Dynamic (Live2D / Spine) ─────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
|
|
[LabelText("Dynamic Portrait Prefab")]
|
|
|
|
|
|
[ShowIf("IsDynamicPortrait")]
|
|
|
|
|
|
[InfoBox("Live2D / Spine 立绘预制体,需挂载实现 IPortraitRenderer 接口的组件(阶段 3 制作)。")]
|
|
|
|
|
|
public GameObject dynamicPortraitPrefab;
|
|
|
|
|
|
|
2026-07-07 01:28:27 -04:00
|
|
|
|
private bool IsDynamicPortrait => portraitStyle == PortraitStyle.Live2D || portraitStyle == PortraitStyle.Spine;
|
2026-07-05 16:08:23 -04:00
|
|
|
|
}
|
|
|
|
|
|
}
|