StorySystem
This commit is contained in:
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user