Files
2026-04-18 13:57:19 -04:00

115 lines
4.1 KiB
C#
Raw Permalink 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 System;
using System.Collections.Generic;
using System.Linq;
using Sirenix.OdinInspector;
using UniRx;
using UnityEngine;
namespace SLSUtilities.Feedback
{
/// <summary>
/// 单个反馈序列的完整数据定义,是 Feedback 系统的核心 ScriptableObject。
/// 包含多条轨道Track每条轨道包含按时间排列的片段Clip
/// </summary>
[CreateAssetMenu(fileName = "NewFeedbackData", menuName = "SLS/Feedback/FeedbackData")]
public partial class FeedbackData : SerializedScriptableObject
{
/// <summary>
/// 父级集合引用,由 FeedbackDataCollection 自动维护。
/// </summary>
[ReadOnly, ShowInInspector]
public FeedbackDataCollection parentCollection;
/// <summary>
/// 用于字典索引的名称,在 FeedbackDataCollection 中按此名称查找。
/// </summary>
[Title("Editor Settings")]
public string feedbackName;
/// <summary>
/// 全局默认的时间设置。Clip 可选择覆盖此设置。
/// </summary>
public FeedbackTimeSettings defaultTimeSettings = new FeedbackTimeSettings();
/// <summary>
/// 反馈轨道列表,多条轨道天然并行播放。
/// </summary>
[Title("Feedback Tracks")]
[ListDrawerSettings(ShowFoldout = true, ListElementLabelName = "trackName")]
public List<FeedbackTrack> tracks = new List<FeedbackTrack>();
/// <summary>
/// 所有轨道的最大时长。
/// </summary>
public float TotalDuration => tracks.Count > 0 ? tracks.Max(t => t.TotalDuration) : 0f;
/// <summary>
/// 运行时预览:通过 FeedbackManager 播放此反馈。
/// 仅在 Play 模式下可用。
/// </summary>
[Button("Preview", ButtonSizes.Medium)]
[EnableIf("@UnityEngine.Application.isPlaying")]
public void Preview()
{
if (!Application.isPlaying)
{
Debug.LogWarning("[FeedbackData] Preview is only available in Play mode.");
return;
}
if (FeedbackManager.Instance == null)
{
Debug.LogWarning("[FeedbackData] Preview failed: FeedbackManager not found in scene. " +
"Add a GameObject with FeedbackManager component.");
return;
}
FeedbackPlayer player = FeedbackManager.Instance.Play(this);
Debug.Log($"[FeedbackData] Previewing '{feedbackName}' (Duration: {TotalDuration:F2}s)");
}
}
public partial class FeedbackData
{
public FeedbackTrack Track(string name)
{
FeedbackTrack track = tracks.FirstOrDefault(t => t.trackName == name);
if (track == null)
{
Debug.LogWarning($"[FeedbackData] Track '{name}' not found in FeedbackData '{feedbackName}'.");
}
return track;
}
public FeedbackClip Clip(string trackName, Func<FeedbackClip, bool> predicate)
{
FeedbackTrack track = Track(trackName);
if (track == null) return null;
FeedbackClip clip = track.clips.FirstOrDefault(predicate);
if (clip == null)
{
Debug.LogWarning($"[FeedbackData] Clip matching predicate not found in Track '{trackName}' of FeedbackData '{feedbackName}'.");
}
return clip;
}
public FeedbackClip Clip<T>(string trackName) where T : FeedbackActionBase
{
return Clip(trackName, c => c.action.GetType() == typeof(T));
}
public FeedbackClip Clip(string trackName, string clipName)
{
return Clip(trackName, c => c.clipName == clipName);
}
public T Action<T>(string trackName) where T : FeedbackActionBase
{
FeedbackTrack track = Track(trackName);
FeedbackClip clip = track?.clips.FirstOrDefault(c => c.action.GetType() == typeof(T));
return clip?.action as T;
}
}
}