Files
ichni_Official/Assets/Scripts/NewStorySystem/YarnFunctions/PortraitCommands.cs
SoulliesOfficial 7b7d069b84 StorySystem
2026-07-07 01:28:27 -04:00

113 lines
4.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using UnityEngine;
using Yarn.Unity;
namespace Ichni.Story.YarnFunctions
{
/// <summary>
/// 立绘控制相关的 Yarn 自定义命令静态注册器。
/// <para>
/// 全局静态命令,不依赖于 GameObject 的挂载。所有方法都使用强类型的参数,
/// 以更明确、简洁的指令名称区分不同应用场景,从而抛弃复杂的内部字符串解析判断。
/// </para>
/// </summary>
public static class PortraitCommands
{
// ── Yarn Commands ────────────────────────────────────────────────────────
/// <summary>
/// 最基础、最全面的立绘指令:设置指定角色的坐标和表情。
/// 若角色不在台上,会自动以指定的表情和位置实例化。
/// 格式: &lt;&lt;set_portrait characterId x y [emotion]&gt;&gt;
/// </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>
/// 设置当前说话角色的坐标和表情。
/// 格式: &lt;&lt;set_portrait_current x y [emotion]&gt;&gt;
/// </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>
/// 仅设置或移动指定角色的坐标(不改变当前表情)。
/// 格式: &lt;&lt;set_portrait_position characterId x y&gt;&gt;
/// </summary>
[YarnCommand("set_portrait_position")]
public static void SetPortraitPosition(string characterId, float x, float y)
{
// 通过传入 emotion = nullVNPortraitStage 在更新时将保持角色原有表情
SetPortrait(characterId, x, y, null);
}
/// <summary>
/// 仅改变指定角色的表情(角色必须已经上台)。
/// 格式: &lt;&lt;set_portrait_emotion characterId emotion&gt;&gt;
/// </summary>
[YarnCommand("set_portrait_emotion")]
public static void SetPortraitEmotion(string characterId, string emotion)
{
if (!EnsureStage()) return;
Dialogue.VNPortraitStage.Instance.SetPortraitEmotion(characterId, emotion);
}
/// <summary>
/// 隐藏指定角色的立绘。
/// 格式: &lt;&lt;hide_portrait characterId&gt;&gt;
/// </summary>
[YarnCommand("hide_portrait")]
public static void HidePortrait(string characterId)
{
if (!EnsureStage()) return;
Dialogue.VNPortraitStage.Instance.HidePortrait(characterId);
}
/// <summary>
/// 隐藏当前所有在台上的立绘。
/// 格式: &lt;&lt;hide_all_portraits&gt;&gt;
/// </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;
}
}
}