FMOD功能迁移

This commit is contained in:
2025-03-07 22:28:12 +08:00
parent 99a2e78466
commit dad6c087fd
336 changed files with 1597 additions and 3230 deletions
+2 -1
View File
@@ -3,6 +3,7 @@ using UnityEngine.EventSystems;
using UnityEngine.UI;
using DG.Tweening;
using AibisDream;
using AibisDream.Kit;
public class ClueSlotBase : MonoBehaviour, IDropHandler
{
@@ -59,7 +60,7 @@ public class ClueSlotBase : MonoBehaviour, IDropHandler
currentClueItem = clueItem;
isOccupied = true;
punchTapeImage.enabled=true;
AudioManager.RandomPlayInteraction("punchtape");
// AudioManager.RandomPlayInteraction("punchtape");
StartFilmAnimation();
punchTapeImage.rectTransform.DOAnchorPosY(-473f,4f)
.OnComplete(() =>
@@ -44,7 +44,6 @@ namespace AibisDream
{
HideDialog();
yield return SceneLoader.Instance.LoadSceneAsync(sceneName);
AudioManager.PlayAmb2Audio("amb_general");
}
[YarnCommand("unload_scene")]
@@ -147,7 +147,6 @@ namespace AibisDream
{
if (!DialogCanvasManager.Instance.TrySkipLine())
{
AudioManager.Instance.StopVoice();
DialogCanvasManager.Instance.NextStep();
}
}
+4 -21
View File
@@ -10,10 +10,8 @@ namespace AibisDream
public override void RunLine(LocalizedLine dialogueLine, Action onDialogueLineFinished)
{
EnumEventSystem.Global.Send(DialogEventEnum.LineStart, DialogText.GetLine(dialogueLine));
Action jumpVoice = SkipVoice;
HandleLineOutput(dialogueLine, jumpVoice, onDialogueLineFinished);
HandleVoiceOutput(dialogueLine);
HandleLineOutput(dialogueLine, onDialogueLineFinished);
if (DialogController.Instance.quickRunMode)
{
@@ -21,25 +19,10 @@ namespace AibisDream
}
}
private void HandleLineOutput(LocalizedLine dialogueLine, Action onTextShowed, Action onDialogueLineFinished)
private void HandleLineOutput(LocalizedLine dialogueLine, Action onDialogueLineFinished)
{
DialogCanvasManager.Instance.ShowLine(dialogueLine.TextWithoutCharacterName.Text,
dialogueLine.GetCharacterVo(), onDialogueLineFinished, onTextShowed, dialogueLine.IsAutoSkipLine());
}
private void HandleVoiceOutput(LocalizedLine dialogueLine)
{
// 播放语音
var voicePath = dialogueLine.GetCharacterVo().voicePath;
if (!string.IsNullOrWhiteSpace(voicePath))
{
AudioManager.Instance.RandomPlayVoice(voicePath);
}
}
private void SkipVoice()
{
AudioManager.Instance.StopVoice();
dialogueLine.GetCharacterVo(), onDialogueLineFinished, dialogueLine.IsAutoSkipLine());
}
public override void RunOptions(DialogueOption[] dialogueOptions, Action<int> onOptionSelected)
+3 -2
View File
@@ -1,6 +1,7 @@
using AibisDream;
using UnityEngine;
using System;
using AibisDream.Kit;
public class Socket : MonoBehaviour, ISocket
{
@@ -45,7 +46,7 @@ public class Socket : MonoBehaviour, ISocket
IsAvailable = false;
}
AudioManager.RandomPlayInteraction("plug_in");
FmodManager.Instance.PlaySfx("event:/FollowInput/plugin");
plug = p;
plug.CableRef.End = plug.transform;
// 可插入就可以触发对话
@@ -54,7 +55,7 @@ public class Socket : MonoBehaviour, ISocket
public void RemovePlug(Plug p)
{
IsAvailable = true;
AudioManager.RandomPlayInteraction("plug_out");
FmodManager.Instance.PlaySfx("event:/FollowInput/plugout");
if (plug != null)
{
plug.CableRef.End = plug.transform.GetChild(0).transform;
@@ -1,13 +1,10 @@
//using System.Drawing;
using UnityEngine;
using UnityEngine.UI;
using Yarn.Unity;
using DG.Tweening;
using System.Collections.Generic;
using System.Collections;
using AibisDream;
using AibisDream.FixSystem;
using AibisDream.Kit;
public class HeatMapController : MonoBehaviour
{
@@ -83,10 +80,7 @@ public class HeatMapController : MonoBehaviour
public void HideHeatMap()
{
var draggableUI = heatmapGameobject.GetComponent<DraggableUI>();
heatmapGameobject.transform.DOLocalMove(outPos, 1f).OnComplete(() =>
{
draggableUI.UnlockDrag();
});
heatmapGameobject.transform.DOLocalMove(outPos, 1f).OnComplete(() => { draggableUI.UnlockDrag(); });
heatmapGameobject.SetActive(false);
}
@@ -115,9 +109,9 @@ public class HeatMapController : MonoBehaviour
Debug.Log("降温成功");
float duration = 3.5f;
SetTemptureSmooth(0, duration);
AudioManager.RandomPlayInteraction("cooler_cooling");
FmodManager.Instance.PlaySfx("event:/FollowInput/cooler_cooling");
yield return new WaitForSeconds(duration);
rotationTween.Kill();
rotationTween.Kill();
imageToRotate.localRotation = Quaternion.identity;
// 恢复初始状态
imageToMove.DOLocalMove(imageInitialPos, 1f);
@@ -139,32 +133,25 @@ public class HeatMapController : MonoBehaviour
// 恢复初始状态
imageToMove.DOLocalMove(imageInitialPos, 1f);
}
void Start()
{
bodyModuleSystem=FindObjectOfType<BodyModuleSystem>();
bodyModuleSystem = FindObjectOfType<BodyModuleSystem>();
// // 初始调用,设置初始位置
//tempture=1;
// // 初始化数据,这里是示例,你可以根据实际需求设置
SetDataToMaterial();
}
// public void SetTemture(float value)
// {
// tempture=value;
// }
public void SetDataToMaterial()
{
if (tempture >=0&&tempture<=1)
if (tempture >= 0 && tempture <= 1)
{
uftempture = Mathf.Lerp(1.5f, 2.8f, tempture ); // 线性插值
uftempture = Mathf.Lerp(1.5f, 2.8f, tempture); // 线性插值
modulesTempture = Mathf.Lerp(1.5f, 1.8f, tempture);
backtemture = Mathf.Lerp(1.5f, 2.25f, tempture);
}
else if (tempture >= 1&&tempture<=2)
else if (tempture >= 1 && tempture <= 2)
{
uftempture = Mathf.Lerp(2.8f, 3.2f, tempture - 1);
modulesTempture = Mathf.Lerp(1.8f, 2.3f, tempture - 1);
@@ -181,8 +168,7 @@ public class HeatMapController : MonoBehaviour
for (int i = 0; i < 7; i++)
{
//RectTransform transform=Pos[i].GetComponent<RectTransform>();
Transform currentTransform=Pos[i].GetComponent<Transform>();
Debug.Log($"Point {i}: {points[i]}");
Transform currentTransform = Pos[i].GetComponent<Transform>();
if (i == 0)
{
@@ -194,22 +180,24 @@ public class HeatMapController : MonoBehaviour
}
else
{
points[i] = new Vector4(Pos[i].position.x, Pos[i].position.y, modulesTempture, 0); // (x, y, z, temperature)
points[i] = new Vector4(Pos[i].position.x, Pos[i].position.y, modulesTempture,
0); // (x, y, z, temperature)
}
}
Sprite currentSprite=currentTransform.GetComponent<SpriteRenderer>().sprite;
properties[i] = new Vector4(currentSprite.bounds.size.x, currentSprite.bounds.size.y, 0.0f, 0.0f); // (boxsize x, boxsize y, unused, unused)
Debug.Log($"Point {i}: {currentSprite.bounds.size.x}");
Sprite currentSprite = currentTransform.GetComponent<SpriteRenderer>().sprite;
properties[i] =
new Vector4(currentSprite.bounds.size.x, currentSprite.bounds.size.y, 0.0f,
0.0f); // (boxsize x, boxsize y, unused, unused)
//properties[i] = new Vector4(transform.rect.width*1, transform.rect.height*1, 0.0f, 0.0f); // (boxsize x, boxsize y, unused, unused)
//properties[i] = new Vector4(transform.rect.width*1, transform.rect.height*1, 0.0f, 0.0f); // (boxsize x, boxsize y, unused, unused)
}
// 将数据传递给 Shader
heatMaterial.SetVectorArray("_Points", points);
heatMaterial.SetVectorArray("_Properties", properties);
}
public void SetTemptureDirect(float value)
public void SetTemptureDirect(float value)
{
Tempture = value;
}
@@ -223,5 +211,4 @@ public class HeatMapController : MonoBehaviour
{
return minTarget + (value - minSource) * (maxTarget - minTarget) / (maxSource - minSource);
}
}
}
+2 -1
View File
@@ -7,6 +7,7 @@ using AibisDream;
using System.Linq;
using DG.Tweening;
using AibisDream.FixSystem;
using AibisDream.Kit;
[System.Serializable]
public class LineSegmentInfo
@@ -110,7 +111,7 @@ public class LineManager : MonoBehaviour
return;
}
AudioManager.RandomPlayInteraction("wire_cut");
FmodManager.Instance.PlaySfx("event:/Scriptal/wire_cut");
// Create the first new line segment
GameObject firstLineSegmentObject = Instantiate(physicLineSegmentPrefab, transform);
+1 -37
View File
@@ -22,26 +22,7 @@ public class MessageBox : MonoBehaviour
//DontDestroyOnLoad(gameObject); // 可选:保持在场景加载之间
}
}
// Yarn Command处理方法
// [YarnCommand("messagebox")]
// public void HandleMessageBoxCommand(string type, string message)
// {
// switch (type.ToLower())
// {
// case "warning":
// SetWarning(message);
// break;
// case "normal":
// SetNormal(message);
// break;
// case "null":
// SetNull();
// break;
// default:
// Debug.LogError("Invalid message type for messagebox command: " + type);
// break;
// }
// }
private void Start()
{
SetNull();
@@ -76,21 +57,4 @@ public class MessageBox : MonoBehaviour
text.color = Color.white; // 默认文本颜色
//StopCoroutine(FlashWarning()); // 停止闪烁效果(如果正在闪烁)
}
// 闪烁警告效果
private IEnumerator FlashWarning()
{
AudioManager.SetinteractionSourceVolume(0.35f);
AudioManager.RandomPlayInteraction("beep_warning");
for (int i = 0; i < 2; i++)
{
state.enabled = false;
yield return new WaitForSeconds(0.3f); // 闪烁间隔
state.enabled = true;
yield return new WaitForSeconds(0.3f); // 闪烁间隔
}
AudioManager.SetinteractionSourceVolume(1f);
state.enabled = true; // 确保闪烁后状态仍然可见
}
}
@@ -1,4 +1,5 @@
using AibisDream.Framework;
using AibisDream.Kit;
using AibisDream.Utility;
using DG.Tweening;
using MeadowGames.UINodeConnect4.GraphicRenderer;
@@ -73,7 +74,7 @@ namespace AibisDream.FixSystem
// 处理插槽插入
targetSocket.PlugIn();
AudioManager.RandomPlayInteraction("plug_in");
FmodManager.Instance.PlaySfx("event:/FollowInput/plugin");
_sprite.enabled = false;
_cableSystem.curSocket = targetSocket;
@@ -94,10 +95,10 @@ namespace AibisDream.FixSystem
_cableSystem.CableRef.SetEndPos(_plugRootPos);
_cableSystem.curSocket?.PlugOut();
AudioManager.RandomPlayInteraction("plug_out");
FmodManager.Instance.PlaySfx("event:/FollowInput/plugout");
_sprite.enabled = true;
if (_cableSystem.curSocket is BodyModule bodyModule)
if (_cableSystem.curSocket is BodyModule)
{
// 从模块拔出时触发事件
EnumEventSystem.Global.Send(EventEnum.PlugOut);
@@ -6,6 +6,7 @@ using AibisDream.FixSystem;
using UnityEngine.UI;
using Unity.VisualScripting;
using AibisDream;
using AibisDream.Kit;
public class PunchTapeSystem : MonoBehaviour
{
@@ -47,7 +48,7 @@ public class PunchTapeSystem : MonoBehaviour
{
// Move the printer to x = 2 over 1 second
yield return punchTapeMachine.DOAnchorPos(new Vector2(-1252f, punchTapeMachine.anchoredPosition.y), 1f).WaitForCompletion();
AudioManager.RandomPlayInteraction("typing");
FmodManager.Instance.PlaySfx("event:/Scriptal/typing");
// Gradually move the punch tape to x = -3.8 with rhythmic pattern
Vector2 targetPosition = new Vector2(796f, punchTape.anchoredPosition.y);
int patternIndex = 0;
@@ -11,9 +11,6 @@ namespace AibisDream.FixSystem
{
SystemDic ??= new IOCContainer();
// TODO 这个回头要改
AudioManager.PlayAmb1Audio("amb_room");
// 初始化状态机
StateMachine = new FixStateMachine();
StartCoroutine(StateMachine.SwitchState(FixState.Clinic));
@@ -168,8 +168,7 @@ namespace AibisDream.FixSystem
#region
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, Action onTextShowed = null,
bool isAutoSkip = false)
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, bool isAutoSkip = false)
{
ShowTitle(character.GetActorName());
StartCoroutine(ShowText(dialogLine));
@@ -1,306 +0,0 @@
using System.Collections;
using AibisDream.Kit;
using UnityEngine;
using Yarn.Unity;
namespace AibisDream
{
public class AudioManager : Singleton<AudioManager>
{
private const string LoopSource = "Loop";
private const string LoopSource2 = "Loop2";
private const string LoopSource3 = "Loop3";
private const string InteractionSource = "Interaction";
private const string VoiceSource = "Voice";
private const string MemorySource = "Memery";
private const string Amb1Source = "Amb1";
private const string Amb2Source = "Amb2";
private AudioSource _loopSource;
private AudioSource _loopSource2;
private AudioSource _loopSource3;
private AudioSource _interactionSource;
private AudioSource _voiceSource;
private AudioSource _memorySource;
private AudioSource _amb1Source;
private AudioSource _amb2Source;
public float fadeTime;
public override void OnSingletonInit()
{
_loopSource = transform.Find(LoopSource).GetComponent<AudioSource>();
_loopSource2 = transform.Find(LoopSource2).GetComponent<AudioSource>();
_loopSource3 = transform.Find(LoopSource3).GetComponent<AudioSource>();
_interactionSource = transform.Find(InteractionSource).GetComponent<AudioSource>();
_voiceSource = transform.Find(VoiceSource).GetComponent<AudioSource>();
_memorySource = transform.Find(MemorySource).GetComponent<AudioSource>();
_amb1Source = transform.Find(Amb1Source).GetComponent<AudioSource>();
_amb2Source = transform.Find(Amb2Source).GetComponent<AudioSource>();
}
#region
public void RandomPlayVoice(string voicePath)
{
AudioClip clip = RandomLoadAudioClip(3, $"Audio/{voicePath}");
_voiceSource.clip = clip;
_voiceSource.Play();
}
[YarnCommand("mute")]
public static void MuteInteract(bool isMute)
{
Instance._interactionSource.mute=isMute;
}
[YarnCommand("random_play_interaction")]
public static void RandomPlayInteraction(string interactionName)
{
AudioClip clip = Instance.RandomLoadAudioClip(3, $"Audio/{interactionName}");
if (clip == null)
{
clip = Resources.Load<AudioClip>($"Audio/{interactionName}");
}
Instance._interactionSource.clip = clip;
Instance._interactionSource.Play();
}
[YarnCommand("play_interaction")]
public static void PlayInteraction(string name)
{
var clip = Resources.Load<AudioClip>($"Audio/{name}");
Instance._interactionSource.clip = clip;
Instance._interactionSource.Play();
}
public void StopVoice()
{
if (_voiceSource.isPlaying)
{
_voiceSource.Stop();
}
}
[YarnCommand("stop_interaction")]
public static void StopInteraction()
{
Instance._interactionSource.Stop();
}
#endregion
#region
[YarnCommand("play_loop_audio")]
public static void PlayLoopAudio(string audioName)
{
AudioClip clip = Resources.Load<AudioClip>($"Audio/{audioName}");
if (clip == null)
{
clip = Instance.RandomLoadAudioClip(3, $"Audio/{audioName}");
}
Instance._loopSource.clip = clip;
Instance._loopSource.Play();
}
[YarnCommand("pause_loop_audio")]
public static void PauseLoopAudio()
{
Instance._loopSource.Pause();
}
[YarnCommand("play_loop2_audio")]
public static void PlayLoop2Audio(string audioName)
{
AudioClip clip = Resources.Load<AudioClip>($"Audio/{audioName}");
if (clip == null)
{
clip = Instance.RandomLoadAudioClip(3, $"Audio/{audioName}");
}
Instance._loopSource2.clip = clip;
Instance._loopSource2.Play();
}
[YarnCommand("pause_loop2_audio")]
public static void PauseLoop2Audio()
{
Instance._loopSource2.Pause();
}
[YarnCommand("play_loop3_audio")]
public static void PlayLoop3Audio(string audioName)
{
AudioClip clip = Resources.Load<AudioClip>($"Audio/{audioName}");
if (clip == null)
{
clip = Instance.RandomLoadAudioClip(3, $"Audio/{audioName}");
}
Instance._loopSource3.clip = clip;
Instance._loopSource3.Play();
}
[YarnCommand("pause_loop3_audio")]
public static void PauseLoop3Audio()
{
Instance._loopSource3.Pause();
}
public void ContinueLoopAudio()
{
_loopSource.UnPause();
}
public bool IsLoopPlaying()
{
return _loopSource.isPlaying;
}
#endregion
#region
[YarnCommand("play_amb1_audio")]
public static void PlayAmb1Audio(string audioName)
{
Instance._amb1Source.Stop();
AudioClip clip = Resources.Load<AudioClip>($"Audio/{audioName}");
Instance._amb1Source.clip = clip;
Instance._amb1Source.volume = 0f;
Instance._amb1Source.Play();
Instance.StartCoroutine(Instance.FadeTo(1.0f, Instance.fadeTime, Instance._amb1Source));
}
[YarnCommand("pause_amb1_audio")]
public static void PauseAmb1Audio()
{
Instance._amb1Source.Pause();
}
[YarnCommand("fade_out_amb1_audio")]
public static void FadeOutAmb1Audio()
{
Instance.StartCoroutine(Instance.FadeTo(0.0f, Instance.fadeTime, Instance._amb1Source));
}
public void ContinueAmb1Audio()
{
_amb1Source.volume = 0.0f;
_amb1Source.UnPause();
StartCoroutine(FadeTo(1.0f, fadeTime, _amb1Source));
}
[YarnCommand("play_amb2_audio")]
public static void PlayAmb2Audio(string audioName)
{
Instance._amb2Source.Stop();
AudioClip clip = Resources.Load<AudioClip>($"Audio/{audioName}");
Instance._amb2Source.clip = clip;
Instance._amb2Source.volume = 0f;
Instance._amb2Source.Play();
Instance.StartCoroutine(Instance.FadeTo(1.0f, Instance.fadeTime, Instance._amb2Source));
}
[YarnCommand("pause_amb2_audio")]
public static void PauseAmb2Audio()
{
Instance._amb2Source.Pause();
}
[YarnCommand("fade_out_amb2_audio")]
public static void FadeOutAmb2Audio()
{
Instance.StartCoroutine(Instance.FadeTo(0.0f, Instance.fadeTime, Instance._amb2Source));
}
public void ContinueAmb2Audio()
{
_amb2Source.volume = 0.0f;
_amb2Source.UnPause();
StartCoroutine(FadeTo(1.0f, fadeTime, _amb2Source));
}
#endregion
#region
public static void PlayMemoryAudio(string memoryName)
{
// Instance.StartCoroutine(AsyncPlayMemoryAudio(memoryName));
AudioClip loop = Resources.Load<AudioClip>($"Audio/{memoryName}");
Instance._memorySource.clip = loop;
Instance._memorySource.loop = true;
Instance._memorySource.Play();
}
public static void PauseMemoryAudio()
{
Instance._memorySource.Pause();
}
public void ContinueMemoryAudio()
{
_memorySource.volume = 0.0f;
_memorySource.Play();
StartCoroutine(FadeTo(1.0f, fadeTime, _memorySource));
}
#endregion
public void FadeInLoopAudio(string audioName)
{
AudioClip clip = Resources.Load<AudioClip>(audioName);
_loopSource.clip = clip;
_loopSource.volume = 0.0f;
_loopSource.Play();
StartCoroutine(FadeTo(1.0f, 5f, _loopSource));
}
private IEnumerator FadeTo(float targetVolume, float duration, AudioSource audioSource)
{
float startVolume = audioSource.volume;
float timeElapsed = 0f;
while (timeElapsed < duration)
{
timeElapsed += Time.deltaTime;
audioSource.volume = Mathf.Lerp(startVolume, targetVolume, timeElapsed / duration);
yield return null;
}
audioSource.volume = targetVolume;
}
private AudioClip RandomLoadAudioClip(int audioSize, string path)
{
int randomIndex = Random.Range(0, audioSize) + 1;
return Resources.Load<AudioClip>($"{path}_{randomIndex}");
}
private static IEnumerator AsyncPlayMemoryAudio(string memoryName)
{
AudioClip intro = Resources.Load<AudioClip>($"Audio/mem_play");
AudioClip loop = Resources.Load<AudioClip>($"Audio/{memoryName}");
Instance._memorySource.clip = intro;
Instance._memorySource.loop = false;
Instance._memorySource.Play();
yield return new WaitForSeconds(intro.length);
Instance._memorySource.clip = loop;
Instance._memorySource.loop = true;
Instance._memorySource.Play();
}
public static void SetLoopSourceVolume(float num)
{
Instance._loopSource.volume=num;
}
public static void SetinteractionSourceVolume(float num)
{
Instance._interactionSource.volume=num;
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: d02d13e0ef27eb544b62d5a8d296f2ee
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -9,9 +9,9 @@ namespace AibisDream.Kit
private static IAudioManager AudioManager => FmodManager.Instance;
[YarnCommand("play_music")]
public static void PlayMusic(string eventName)
public static void PlayMusic(string eventName, string audioKey = null)
{
AudioManager.PlayMusic(eventName);
AudioManager.PlayMusic(eventName, audioKey);
}
[YarnCommand("stop_music")]
@@ -34,9 +34,9 @@ namespace AibisDream.Kit
}
[YarnCommand("play_sfx")]
public static void PlaySfx(string eventName)
public static void PlaySfx(string eventName, string audioKey = null)
{
AudioManager.PlaySfx(eventName);
AudioManager.PlaySfx(eventName, audioKey);
}
[YarnCommand("stop_sfx")]
@@ -89,36 +89,36 @@ namespace AibisDream.Kit
#region
public void PlayMusic(string eventName)
public void PlayMusic(string eventName, string audioKey = null)
{
var eventPath = FormatEventPath(eventName);
if (_musicDict.TryGetValue(eventPath, out var oldMusic))
var key = string.IsNullOrEmpty(audioKey) ? eventName : audioKey;
if (_musicDict.TryGetValue(key, out var oldMusic))
{
oldMusic.start();
}
else
{
var newMusic = RuntimeManager.CreateInstance(eventPath);
_musicDict[eventPath] = newMusic;
newMusic.start();
oldMusic.stop(STOP_MODE.IMMEDIATE);
oldMusic.release();
_musicDict.Remove(key);
}
var newMusic = RuntimeManager.CreateInstance(eventPath);
_musicDict[key] = newMusic;
newMusic.start();
}
public void StopMusic(string eventName, STOP_MODE stopMode)
public void StopMusic(string key, STOP_MODE stopMode)
{
var eventPath = FormatEventPath(eventName);
if (_musicDict.TryGetValue(eventPath, out var oldMusic))
if (_musicDict.TryGetValue(key, out var oldMusic))
{
oldMusic.stop(stopMode);
oldMusic.release();
_musicDict.Remove(eventPath);
_musicDict.Remove(key);
}
}
public void SetMusicParam(string eventName, string param, float paramValue)
public void SetMusicParam(string key, string param, float paramValue)
{
var eventPath = FormatEventPath(eventName);
if (_musicDict.TryGetValue(eventPath, out var music))
if (_musicDict.TryGetValue(key, out var music))
{
music.setParameterByName(param, paramValue);
}
@@ -152,40 +152,39 @@ namespace AibisDream.Kit
}
}
public void PlaySfx(string eventName)
public void PlaySfx(string eventName, string audioKey = null)
{
var eventPath = FormatEventPath(eventName);
if (_sfxDict.TryGetValue(eventPath, out var oldSfx))
var key = string.IsNullOrEmpty(audioKey) ? eventName : audioKey;
if (_sfxDict.TryGetValue(key, out var oldSfx))
{
oldSfx.start();
oldSfx.stop(STOP_MODE.IMMEDIATE);
oldSfx.release();
_sfxDict.Remove(key);
}
else
var newSfx = RuntimeManager.CreateInstance(eventPath);
if (newSfx.GetDescription().isOneshot(out var isOneshot) != RESULT.OK || !isOneshot)
{
var newSfx = RuntimeManager.CreateInstance(eventPath);
if (newSfx.GetDescription().isOneshot(out var isOneshot) != RESULT.OK || !isOneshot)
{
_sfxDict[eventPath] = newSfx;
}
_sfxDict[key] = newSfx;
}
newSfx.start();
}
newSfx.start();
}
public void StopSfx(string eventName, STOP_MODE stopMode)
public void StopSfx(string key, STOP_MODE stopMode)
{
var eventPath = FormatEventPath(eventName);
if (_sfxDict.TryGetValue(eventPath, out var oldSfx))
if (_sfxDict.TryGetValue(key, out var oldSfx))
{
oldSfx.stop(stopMode);
oldSfx.release();
_musicDict.Remove(eventPath);
_musicDict.Remove(key);
}
}
public void SetSfxParam(string eventName, string paramName, float paramValue)
public void SetSfxParam(string key, string paramName, float paramValue)
{
var eventPath = FormatEventPath(eventName);
if (_sfxDict.TryGetValue(eventPath, out var sfx))
if (_sfxDict.TryGetValue(key, out var sfx))
{
sfx.setParameterByName(paramName, paramValue);
}
@@ -195,7 +194,7 @@ namespace AibisDream.Kit
private static string FormatEventPath(string eventName)
{
return $"event:/{eventName}";
return eventName.StartsWith("event:/") ? eventName : $"event:/{eventName}";
}
private static AmbState MatchAmbState(string key)
@@ -234,7 +233,7 @@ namespace AibisDream.Kit
public interface IAudioManager
{
// Yarn音频接口
public void PlayMusic(string eventName);
public void PlayMusic(string eventName, string audioKey);
public void StopMusic(string eventName, STOP_MODE stopMode);
public void SetMusicParam(string eventName, string paramName, float paramValue);
@@ -247,7 +246,7 @@ namespace AibisDream.Kit
public void OnLineShown();
// 交互相关
public void PlaySfx(string eventName);
public void PlaySfx(string eventName, string audioKey);
public void StopSfx(string eventName, STOP_MODE stopMode);
public void SetSfxParam(string eventName, string paramName, float paramValue);
}
+1 -1
View File
@@ -51,7 +51,7 @@ namespace AibisDream.Kit
{
get
{
if (!voicePath.StartsWith("event:/"))
if (!string.IsNullOrEmpty(voicePath) && !voicePath.StartsWith("event:/"))
{
return "event:/" + voicePath;
}
@@ -90,8 +90,6 @@ namespace AibisDream
/// <returns>动画序列</returns>
public Tween OpenCover()
{
AudioManager.PlayLoop2Audio("amb_shitou_engine");
var sq = DOTween.Sequence();
// 盖板上移
var moveDis = new Vector3(0, coverMoveDistance, 0);
@@ -111,7 +109,6 @@ namespace AibisDream
/// <returns>动画序列</returns>
public Tween CloseCover()
{
AudioManager.PauseLoop2Audio();
var sq = DOTween.Sequence();
sq.Join(_cover.DOFade(1, coverMoveDuration));
@@ -143,15 +143,6 @@ namespace AibisDream
public void CheckGearSystemState()
{
if (_isTargetReached)
{
AudioManager.PlayLoop3Audio("gears_running");
}
else
{
AudioManager.PauseLoop3Audio();
}
if (_shaftGraph.AllRunning())
{
if (_shaftGraph.AllNewGear())
@@ -184,7 +175,6 @@ namespace AibisDream
public IEnumerator OpenCover()
{
AudioManager.PlayLoop2Audio("amb_gearbox");
// 旋转拉杆
yield return _coverStick.DORotate(new Vector3(0, 0, -90), 1.5f).WaitForCompletion();
// 开盖
@@ -198,9 +188,6 @@ namespace AibisDream
public IEnumerator CloseCover()
{
isAvailable = false;
AudioManager.PauseLoopAudio();
AudioManager.PauseLoop2Audio();
AudioManager.PauseLoop3Audio();
// 关盖
var sq = DOTween.Sequence();
sq.Join(_cover.transform.DOLocalMove(coverDownPos, 1.5f));
-11
View File
@@ -101,12 +101,6 @@ namespace AibisDream
private void OnGearPlugIn()
{
// 插入音效
if (!CommonUtil.IsZero(speed) && IsBroken)
{
AudioManager.PlayLoopAudio("gearbox_bad");
}
// 破损齿轮插进来就发一次事件,交给yarn处理
if (IsBroken)
{
@@ -124,11 +118,6 @@ namespace AibisDream
public void PlugOutGear()
{
if (IsBroken)
{
AudioManager.PauseLoopAudio();
}
// 拔出时齿轮停转
childGear.UpdateRotation(0, _speedScale);
@@ -5,6 +5,7 @@ using UnityEngine.Playables;
using DG.Tweening; // 引入 DoTween 命名空间
using Yarn.Unity;
using AibisDream;
using AibisDream.Kit;
public class LineInteraction : MonoBehaviour
{
@@ -115,7 +116,7 @@ public class LineInteraction : MonoBehaviour
void ContinueTimeline()
{
AudioManager.RandomPlayInteraction("wire_cut");
FmodManager.Instance.PlaySfx("event:/Scriptal/wire_cut");
timelineDirector.Play();
}
}
@@ -191,7 +191,7 @@ public class EyeSystem : MonoBehaviour
{
if (currentTarget != null)
{
AudioManager.RandomPlayInteraction("colorimagine");
// AudioManager.RandomPlayInteraction("colorimagine");
eyeStateEffect?.ApplyFocusedEffect(currentTarget);
}
@@ -203,7 +203,7 @@ public class EyeSystem : MonoBehaviour
{
if (currentTarget != null)
{
AudioManager.RandomPlayInteraction("colorimagine");
// AudioManager.RandomPlayInteraction("colorimagine");
eyeStateEffect?.ApplyUnfocusedEffect(currentTarget);
}
@@ -399,7 +399,7 @@ public class EyeSystem : MonoBehaviour
memorySequence.Insert(4.5f, memoryMaterial.DOFloat(0f, "_FullDistortionFade", 0.5f).OnComplete(() =>
{
memoryRender.gameObject.SetActive(false);
AudioManager.RandomPlayInteraction("water_drip");
// AudioManager.RandomPlayInteraction("water_drip");
}));
// 等待序列完成
+49 -30
View File
@@ -12,6 +12,7 @@ using VolFx;
using System.Drawing.Text; // 引入 DoTween 命名空间
using UnityEngine.Rendering.Universal;
using System;
using AibisDream.Kit;
public class UFSystem : MonoBehaviour
{
@@ -51,31 +52,37 @@ public class UFSystem : MonoBehaviour
CameraKit.Instance.RegisterCamera(CameraEnum.UF, virtualCam);
eyeSystem = FindObjectOfType<EyeSystem>();
}
public void TweenWeight(Volume postProcessingVolume, float targetWeight, float duration)
{
// 动态调整权重
DOTween.To(() => postProcessingVolume.weight, x => postProcessingVolume.weight = x, targetWeight, duration);
}
[YarnCommand("UF_spriteIn")]
public IEnumerator UF_spriteIn(float duration = 1.5f)
{
if (eyeSystem.CurrentTarget != null)
{
AudioManager.RandomPlayInteraction("colorimagine");
FmodManager.Instance.PlaySfx("event:/ActionFB/color_imagine");
eyeSystem.CurrentTarget.ImageIn(duration);
}
yield return new WaitForSeconds(duration);
}
[YarnCommand("UF_spriteOut")]
public IEnumerator UF_spriteOut(float duration = 1.5f)
{
if (eyeSystem.CurrentTarget != null)
{
AudioManager.RandomPlayInteraction("colorimagine");
FmodManager.Instance.PlaySfx("event:/ActionFB/color_imagine");
eyeSystem.CurrentTarget.ImageOut(duration);
}
yield return new WaitForSeconds(duration);
}
[YarnCommand("UF_AllspriteIn")]
public IEnumerator UF_AllspriteIn(float duration = 1.5f)
{
@@ -83,8 +90,10 @@ public class UFSystem : MonoBehaviour
{
target.ImageIn(duration);
}
yield return new WaitForSeconds(duration);
}
[YarnCommand("UF_AllspriteOut")]
public IEnumerator UF_AllspriteOut(float duration = 1.5f)
{
@@ -92,19 +101,22 @@ public class UFSystem : MonoBehaviour
{
target.ImageOut(duration);
}
yield return new WaitForSeconds(duration);
}
[YarnCommand("UF_faceIn")]
public IEnumerator UF_faceIn(float duration = 1.5f)
{
face.gameObject.SetActive(true);
face.DOFade(1f,duration);
face.DOFade(1f, duration);
yield return new WaitForSeconds(duration);
}
[YarnCommand("UF_faceOut")]
public IEnumerator UF_faceOut(float duration = 1.5f)
{
face.DOFade(0f,duration);
face.DOFade(0f, duration);
yield return new WaitForSeconds(duration);
face.gameObject.SetActive(false);
}
@@ -112,52 +124,57 @@ public class UFSystem : MonoBehaviour
[YarnCommand("UF_ImaginationEffectIn")]
public IEnumerator UF_ImaginationEffectIn(float duration = 1.5f)
{
AudioManager.RandomPlayInteraction("colorimagine");
FmodManager.Instance.PlaySfx("event:/ActionFB/color_imagine");
TweenWeight(imageVolume, 1, duration);
yield return new WaitForSeconds(0);
}
[YarnCommand("UF_ImaginationEffectOut")]
[YarnCommand("UF_ImaginationEffectOut")]
public IEnumerator UF_ImaginationEffectOut(float duration = 1.5f)
{
TweenWeight(imageVolume, 0, duration);
AudioManager.RandomPlayInteraction("colorimagine");
FmodManager.Instance.PlaySfx("event:/ActionFB/color_imagine");
yield return new WaitForSeconds(0);
}
[YarnCommand("UF_MemoryEffectIn")]
public IEnumerator UF_MemoryEffectIn(float duration = 1.5f)
{
AudioManager.RandomPlayInteraction("colorimagine");
FmodManager.Instance.PlaySfx("event:/ActionFB/color_imagine");
TweenWeight(finalVolume, 1, duration);
yield return new WaitForSeconds(0);
}
[YarnCommand("UF_MemoryEffectOut")]
[YarnCommand("UF_MemoryEffectOut")]
public IEnumerator UF_MemoryEffectOut(float duration = 1.5f)
{
TweenWeight(finalVolume, 0, duration);
AudioManager.RandomPlayInteraction("colorimagine");
FmodManager.Instance.PlaySfx("event:/ActionFB/color_imagine");
yield return new WaitForSeconds(0);
}
[YarnCommand("UF_EyeTargetAscillIn")]
public IEnumerator UF_EyeTargetAscillIn(float duration = 1.5f)
{
AudioManager.RandomPlayInteraction("colorimagine");
FmodManager.Instance.PlaySfx("event:/ActionFB/color_imagine");
TweenWeight(imageAscillVolume, 1, duration);
yield return new WaitForSeconds(0);
}
[YarnCommand("UF_EyeTargetAscillOut")]
public IEnumerator UF_EyeTargetAscillOut(float duration = 1.5f)
{
TweenWeight(imageAscillVolume, 0, duration);
AudioManager.RandomPlayInteraction("colorimagine");
FmodManager.Instance.PlaySfx("event:/ActionFB/color_imagine");
yield return new WaitForSeconds(0);
}
[YarnCommand("UF_SetBorkenValue")]
public void UF_Borken(int value)
{
public void UF_Borken(int value)
{
FullAscillVolume.profile.TryGet<AsciiVol>(out ascii);
ascii.m_Depth.value=value;
ascii.m_Ascii.value=Color.red;
ascii.m_Depth.value = value;
ascii.m_Ascii.value = Color.red;
}
@@ -172,23 +189,25 @@ public class UFSystem : MonoBehaviour
{
isLoopImage = false;
}
[YarnCommand("UF_fightEffect")]
public void UF_fightEffect()
{
scaleTween = DOTween.To(() => 0f, t =>
{
// 根据 t(0 到 1 的变化)更新多个值
imageVolume.weight = Mathf.Lerp(0f, 1f, t); // 例如:imageVolume 的 weight
imageAscillVolume.weight = Mathf.Lerp(0f, 1f, t); // 假设 saturation 是另一个值
finalVolume.weight = Mathf.Lerp(1f, 0f, t); // 假设 contrast 是另一个值
}, 1f, 1f)
.SetEase(Ease.InOutSine) // 平滑缓动
.SetLoops(-1, LoopType.Yoyo); // 无限循环
{
// 根据 t(0 到 1 的变化)更新多个值
imageVolume.weight = Mathf.Lerp(0f, 1f, t); // 例如:imageVolume 的 weight
imageAscillVolume.weight = Mathf.Lerp(0f, 1f, t); // 假设 saturation 是另一个值
finalVolume.weight = Mathf.Lerp(1f, 0f, t); // 假设 contrast 是另一个值
}, 1f, 1f)
.SetEase(Ease.InOutSine) // 平滑缓动
.SetLoops(-1, LoopType.Yoyo); // 无限循环
}
[YarnCommand("UF_StopfightEffect")]
public void UF_StopfightEffect()
{
scaleTween.Kill();
scaleTween.Kill();
}
public IEnumerator UFImageLoopProcess()
@@ -210,13 +229,14 @@ public class UFSystem : MonoBehaviour
StartCoroutine(UF_MemoryEffectOut(0.5f));
index++;
// 如果到达列表末尾,则回到开头
if (index >= eyeSystem.Targets.Count-2)
if (index >= eyeSystem.Targets.Count - 2)
{
index = 0;
}
//yield return new WaitForSeconds(1f); // 每隔1秒打印一次
}
}
public void OpenUFView()
{
if (!FullAscillVolume.gameObject.activeInHierarchy)
@@ -225,7 +245,6 @@ public class UFSystem : MonoBehaviour
imageAscillVolume.weight = 1;
imageVolume.weight = 0;
finalVolume.weight = 0;
}
}
@@ -274,21 +293,21 @@ public class UFSystem : MonoBehaviour
switch (state)
{
case UFState.UF:
AudioManager.RandomPlayInteraction("colorimagine");
FmodManager.Instance.PlaySfx("event:/ActionFB/color_imagine");
TweenWeight(imageAscillVolume, 1, duration);
TweenWeight(imageVolume, 0, duration);
TweenWeight(finalVolume, 0, duration);
break;
case UFState.imagination:
AudioManager.RandomPlayInteraction("colorimagine");
FmodManager.Instance.PlaySfx("event:/ActionFB/color_imagine");
TweenWeight(imageAscillVolume, 0, duration);
TweenWeight(imageVolume, 1, duration);
TweenWeight(finalVolume, 0, duration);
break;
case UFState.memory:
AudioManager.RandomPlayInteraction("colorimagine");
FmodManager.Instance.PlaySfx("event:/ActionFB/color_imagine");
TweenWeight(imageAscillVolume, 0, duration);
TweenWeight(imageVolume, 0, duration);
TweenWeight(finalVolume, 1, duration);
+142 -140
View File
@@ -10,7 +10,7 @@ using AibisDream;
public class ParallaxLayerConfig
{
public GameObject layer; // 背景层的游戏对象
[SerializeField, Range(0.01f, 1f)]public float scrollSpeed; // 每层的滚动速度
[SerializeField, Range(0.01f, 1f)] public float scrollSpeed; // 每层的滚动速度
public float scrollOffset; // 每层的滚动偏移量
}
@@ -19,7 +19,7 @@ public class ParallaxManager : MonoBehaviour
public float speedMultiplier = 1; // 加速系数
public ParallaxLayerConfig[] layerConfigs; // 背景层配置数组
public ParallaxObjectCategoryConfig[] categoryConfigs; // 多种物体配置类别
public GameObject tunnelSprite; // 隧道的 Sprite 对象
public SpriteRenderer sisterSpriteRender; // 隧道的 Sprite 对象
@@ -35,40 +35,42 @@ public class ParallaxManager : MonoBehaviour
private float previousSpeedMultiplier; // 用于记录上一次的值
[YarnCommand("EnterTunnel")]
public void EnterTunnel()
public void EnterTunnel()
{
if (tunnelSprite != null && !isInTunnel)
{
tunnelSprite.transform.position=tunnelEnterPosition;
tunnelSprite.transform.position = tunnelEnterPosition;
isInTunnel = true;
// 使用 DOTween 播放隧道进入动画
sisterSpriteRender.DOFade(0.4f,tunnelDuration);
sisterSpriteRender.DOFade(0.4f, tunnelDuration);
tunnelSprite.transform.DOMove(tunnelKeepPosition, tunnelDuration)
.SetEase(Ease.Linear)
.OnStart(() => Debug.Log("开始进入隧道"))
.OnKill(() => {
Debug.Log("已完成进入隧道");
ToggleCategoryVisibility("隧洞灯",true);
.OnKill(() =>
{
Debug.Log("已完成进入隧道");
ToggleCategoryVisibility("隧洞灯", true);
});
}
}
[YarnCommand("ExitTunnel")]
public void ExitTunnel()
{
if (tunnelSprite != null && isInTunnel)
{
isInTunnel = false;
ToggleCategoryVisibility("隧洞灯",false);
sisterSpriteRender.DOFade(0,tunnelDuration);
ToggleCategoryVisibility("隧洞灯", false);
sisterSpriteRender.DOFade(0, tunnelDuration);
// 使用 DOTween 播放隧道退出动画
tunnelSprite.transform.DOMove(tunnelExitPosition, tunnelDuration)
.SetEase(Ease.Linear)
.OnStart(() => Debug.Log("开始退出隧道"))
.OnKill(() => {
Debug.Log("已完成退出隧道");
ToggleCategoryVisibility("隧洞灯",false);
tunnelSprite.transform.position=tunnelEnterPosition;
.OnKill(() =>
{
Debug.Log("已完成退出隧道");
ToggleCategoryVisibility("隧洞灯", false);
tunnelSprite.transform.position = tunnelEnterPosition;
});
}
}
@@ -82,9 +84,10 @@ public class ParallaxManager : MonoBehaviour
previousSpeedMultiplier = speedMultiplier; // 记录当前值
Debug.Log($"运行时修改 DOTween.timeScale 为 {speedMultiplier}");
}
if(Input.GetKeyDown(KeyCode.E))
if (Input.GetKeyDown(KeyCode.E))
{
if(isInTunnel)
if (isInTunnel)
{
ExitTunnel();
}
@@ -92,15 +95,15 @@ public class ParallaxManager : MonoBehaviour
{
EnterTunnel();
}
}
}
private void OnValidate()
{
// 当新速度值变化时,实时更新背景层和物体的速度
foreach (var config in layerConfigs)
{
StartLayerScroll(config); // 重新启动背景层滚动
StartLayerScroll(config); // 重新启动背景层滚动
}
foreach (var category in categoryConfigs)
@@ -117,15 +120,12 @@ public class ParallaxManager : MonoBehaviour
// }
// }
}
}
}
void Start()
{
AudioManager.PlayAmb1Audio("amb_subway");
AudioManager.PlayAmb1Audio("music_subway");
// 初始化记录的值
Color color = sisterSpriteRender.color;
color.a = 0;
@@ -152,7 +152,7 @@ public class ParallaxManager : MonoBehaviour
{
// 按照距离生成
StartCoroutine(ManageObjectGenerationByDistance(category));
}
}
}
}
@@ -167,6 +167,7 @@ public class ParallaxManager : MonoBehaviour
pool.Add(obj);
obj.SetActive(false); // 初始时禁用物体
}
objectPools[categoryConfig.categoryName] = pool;
Debug.Log($"为分类 {categoryConfig.categoryName} 初始化池子,池中物体数:{pool.Count}");
@@ -176,11 +177,11 @@ public class ParallaxManager : MonoBehaviour
private void StartLayerScroll(ParallaxLayerConfig config)
{
Vector3 startPosition = config.layer.transform.position;
float endPositionX = - config.scrollOffset;
float endPositionX = -config.scrollOffset;
// 计算需要的时间,基于速度和距离
float distance = Mathf.Abs(endPositionX - startPosition.x);
float duration = distance / config.scrollSpeed; // 使用速度来计算时间
float duration = distance / config.scrollSpeed; // 使用速度来计算时间
// 背景层滚动时不受 speedMultiplier 影响
config.layer.transform.DOLocalMoveX(endPositionX, duration)
@@ -198,87 +199,90 @@ public class ParallaxManager : MonoBehaviour
}
// 管理物体生成:按时间间隔生成
public IEnumerator ManageObjectGeneration(ParallaxObjectCategoryConfig categoryConfig)
{
if (!objectPools.ContainsKey(categoryConfig.categoryName))
public IEnumerator ManageObjectGeneration(ParallaxObjectCategoryConfig categoryConfig)
{
Debug.LogError($"没有为分类 {categoryConfig.categoryName} 初始化对象池!");
yield break;
}
var pool = objectPools[categoryConfig.categoryName];
int batchSize = categoryConfig.batchSize; // 每次生成的物体数量
float batchInterval = categoryConfig.batchInterval; // 每个物体之间的生成间隔
float delayAfterBatch = categoryConfig.delayAfterBatch; // 每组生成后的等待时间
// 启动首个物体
GameObject firstObject = pool[0];
if (!firstObject.activeInHierarchy)
{
firstObject.transform.position = firstObject.transform.position; // 保持编辑器中的初始位置
firstObject.SetActive(true); // 启用物体
StartObjectMoveAnimation(firstObject, categoryConfig);
Debug.Log($"初始化并激活首个物体: {firstObject.name}, 位置: {firstObject.transform.position}");
ToggleCategoryVisibility(categoryConfig.categoryName,categoryConfig.isEnabled);
}
while (true)
{
// 连续生成多个物体
for (int i = 0; i < batchSize; i++)
if (!objectPools.ContainsKey(categoryConfig.categoryName))
{
GameObject obj = GetInactiveObjectFromPool(categoryConfig.categoryName);
if (obj != null)
{
SpawnObject(obj, categoryConfig);
Debug.Log($"生成物体: {obj.name}, 当前池大小: {pool.Count}");
}
else
{
Debug.LogWarning($"对象池 {categoryConfig.categoryName} 中没有可用物体!可能需要增加池中物体数量。");
}
// 每个物体之间的间隔
yield return new WaitForSeconds(Random.Range(batchInterval-1f,batchInterval+1f) / speedMultiplier); // 使用 speedMultiplier 来控制生成速率
Debug.LogError($"没有为分类 {categoryConfig.categoryName} 初始化对象池!");
yield break;
}
// 等待一段时间后再开始下一组生成
yield return new WaitForSeconds(Random.Range(delayAfterBatch-1f,delayAfterBatch+1.5f) / speedMultiplier); // 使用 speedMultiplier 来控制生成间隔
var pool = objectPools[categoryConfig.categoryName];
int batchSize = categoryConfig.batchSize; // 每次生成的物体数量
float batchInterval = categoryConfig.batchInterval; // 每个物体之间的生成间隔
float delayAfterBatch = categoryConfig.delayAfterBatch; // 每组生成后的等待时间
// 启动首个物体
GameObject firstObject = pool[0];
if (!firstObject.activeInHierarchy)
{
firstObject.transform.position = firstObject.transform.position; // 保持编辑器中的初始位置
firstObject.SetActive(true); // 启用物体
StartObjectMoveAnimation(firstObject, categoryConfig);
Debug.Log($"初始化并激活首个物体: {firstObject.name}, 位置: {firstObject.transform.position}");
ToggleCategoryVisibility(categoryConfig.categoryName, categoryConfig.isEnabled);
}
while (true)
{
// 连续生成多个物体
for (int i = 0; i < batchSize; i++)
{
GameObject obj = GetInactiveObjectFromPool(categoryConfig.categoryName);
if (obj != null)
{
SpawnObject(obj, categoryConfig);
Debug.Log($"生成物体: {obj.name}, 当前池大小: {pool.Count}");
}
else
{
Debug.LogWarning($"对象池 {categoryConfig.categoryName} 中没有可用物体!可能需要增加池中物体数量。");
}
// 每个物体之间的间隔
yield return
new WaitForSeconds(Random.Range(batchInterval - 1f, batchInterval + 1f) /
speedMultiplier); // 使用 speedMultiplier 来控制生成速率
}
// 等待一段时间后再开始下一组生成
yield return new WaitForSeconds(
Random.Range(delayAfterBatch - 1f, delayAfterBatch + 1.5f) /
speedMultiplier); // 使用 speedMultiplier 来控制生成间隔
}
}
}
// 管理物体生成(基于距离)
public IEnumerator ManageObjectGenerationByDistance(ParallaxObjectCategoryConfig categoryConfig)
{
var pool = objectPools[categoryConfig.categoryName];
GameObject firstObject = pool[0];
if (!firstObject.activeInHierarchy)
public IEnumerator ManageObjectGenerationByDistance(ParallaxObjectCategoryConfig categoryConfig)
{
firstObject.transform.position = categoryConfig.objects[0].transform.position;
firstObject.SetActive(true); // 启用物体
StartObjectMoveAnimation(firstObject, categoryConfig);
ToggleCategoryVisibility(categoryConfig.categoryName,categoryConfig.isEnabled);
Debug.Log($"生成了第一个物体: {firstObject.name}, 位置: {firstObject.transform.position}");
}
GameObject lastObject = firstObject;
while (true)
{
// 检查是否需要生成新物体
if (lastObject == null || lastObject.transform.position.x < -categoryConfig.generationThreshold)
var pool = objectPools[categoryConfig.categoryName];
GameObject firstObject = pool[0];
if (!firstObject.activeInHierarchy)
{
GameObject obj = GetInactiveObjectFromPool(categoryConfig.categoryName);
if (obj != null)
firstObject.transform.position = categoryConfig.objects[0].transform.position;
firstObject.SetActive(true); // 启用物体
StartObjectMoveAnimation(firstObject, categoryConfig);
ToggleCategoryVisibility(categoryConfig.categoryName, categoryConfig.isEnabled);
Debug.Log($"生成了第一个物体: {firstObject.name}, 位置: {firstObject.transform.position}");
}
GameObject lastObject = firstObject;
while (true)
{
// 检查是否需要生成新物体
if (lastObject == null || lastObject.transform.position.x < -categoryConfig.generationThreshold)
{
SpawnObject(obj, categoryConfig);
lastObject = obj;
GameObject obj = GetInactiveObjectFromPool(categoryConfig.categoryName);
if (obj != null)
{
SpawnObject(obj, categoryConfig);
lastObject = obj;
}
}
yield return null;
}
yield return null;
}
}
// 获取池中未激活的物体
private GameObject GetInactiveObjectFromPool(string categoryName)
@@ -294,32 +298,32 @@ public IEnumerator ManageObjectGenerationByDistance(ParallaxObjectCategoryConfig
return inactiveObjects[Random.Range(0, inactiveObjects.Count)];
}
}
return null; // 如果没有未激活的对象
}
// 生成物体逻辑
private void SpawnObject(GameObject obj, ParallaxObjectCategoryConfig categoryConfig)
{
float xStart = categoryConfig.xSpawnRange;
obj.transform.localPosition = new Vector3(xStart, obj.transform.localPosition.y, obj.transform.localPosition.z);
obj.SetActive(true);
ToggleCategoryVisibility(categoryConfig.categoryName, categoryConfig.isEnabled);
StartObjectMoveAnimation(obj, categoryConfig);
float xStart = categoryConfig.xSpawnRange;
obj.transform.localPosition = new Vector3(xStart, obj.transform.localPosition.y, obj.transform.localPosition.z);
obj.SetActive(true);
ToggleCategoryVisibility(categoryConfig.categoryName,categoryConfig.isEnabled);
StartObjectMoveAnimation(obj, categoryConfig);
Debug.Log($"生成物体 {obj.name} 并开始移动, 初始位置: {obj.transform.position}");
Debug.Log($"生成物体 {obj.name} 并开始移动, 初始位置: {obj.transform.position}");
}
// 启动物体移动动画
private void StartObjectMoveAnimation(GameObject obj, ParallaxObjectCategoryConfig categoryConfig)
{
// 计算目标位置
Vector3 targetPosition = new Vector3(-categoryConfig.xSpawnRange, obj.transform.position.y, obj.transform.position.z);
Vector3 targetPosition =
new Vector3(-categoryConfig.xSpawnRange, obj.transform.position.y, obj.transform.position.z);
// 计算当前位置与目标位置的水平距离
float distance = Mathf.Abs(obj.transform.position.x - targetPosition.x);
// 计算动画的持续时间:距离 / 速度
float duration = distance / categoryConfig.speed;
@@ -331,56 +335,54 @@ public IEnumerator ManageObjectGenerationByDistance(ParallaxObjectCategoryConfig
// 物体移动完成后处理
private void HandleObjectCompletion(GameObject obj, ParallaxObjectCategoryConfig categoryConfig)
{
obj.SetActive(false); // 隐藏物体
obj.SetActive(false); // 隐藏物体
Debug.Log($"物体 {obj.name} 移动完成,回收到池中");
}
// 控制分类的显示与隐藏
public void ToggleCategoryVisibility(string categoryName, bool isEnabled)
{
var category = System.Array.Find(categoryConfigs, config => config.categoryName == categoryName);
if (category != null)
{
category.isEnabled = isEnabled;
// 遍历该分类的所有物体,并根据 isEnabled 控制它们的显示状态
foreach (var obj in objectPools[categoryName])
var category = System.Array.Find(categoryConfigs, config => config.categoryName == categoryName);
if (category != null)
{
// 检查父物体是否有 SpriteRenderer
var renderer = obj.GetComponent<SpriteRenderer>();
// 如果父物体没有 SpriteRenderer,检查所有子物体
if (renderer == null)
category.isEnabled = isEnabled;
// 遍历该分类的所有物体,并根据 isEnabled 控制它们的显示状态
foreach (var obj in objectPools[categoryName])
{
var childRenderers = obj.GetComponentsInChildren<SpriteRenderer>();
if (childRenderers.Length > 0)
// 检查父物体是否有 SpriteRenderer
var renderer = obj.GetComponent<SpriteRenderer>();
// 如果父物体没有 SpriteRenderer,检查所有子物体
if (renderer == null)
{
// 如果找到子物体的 SpriteRenderer,修改它们的显示状态
foreach (var childRenderer in childRenderers)
var childRenderers = obj.GetComponentsInChildren<SpriteRenderer>();
if (childRenderers.Length > 0)
{
childRenderer.enabled = isEnabled;
// 如果找到子物体的 SpriteRenderer,修改它们的显示状态
foreach (var childRenderer in childRenderers)
{
childRenderer.enabled = isEnabled;
}
}
else
{
// 如果父物体和子物体都没有 SpriteRenderer,输出警告
Debug.LogWarning($"物体 {obj.name} 及其子物体均未找到 SpriteRenderer");
}
}
else
{
// 如果父物体和子物体都没有 SpriteRenderer输出警告
Debug.LogWarning($"物体 {obj.name} 及其子物体均未找到 SpriteRenderer");
// 如果父物体有 SpriteRenderer直接修改父物体的显示状态
renderer.enabled = isEnabled;
}
}
else
{
// 如果父物体有 SpriteRenderer,直接修改父物体的显示状态
renderer.enabled = isEnabled;
}
Debug.Log($"分类 {categoryName} 已{(isEnabled ? "" : "")}");
}
else
{
Debug.LogWarning($"未找到名为 {categoryName} 的分类");
}
Debug.Log($"分类 {categoryName} 已{(isEnabled ? "" : "")}");
}
else
{
Debug.LogWarning($"未找到名为 {categoryName} 的分类");
}
}
}
}
+4 -3
View File
@@ -4,6 +4,7 @@ using Yarn.Unity;
using System.Collections;
using DG.Tweening;
using AibisDream;
using AibisDream.Kit;
public class WindowManager : MonoBehaviour
{
@@ -30,7 +31,7 @@ public class WindowManager : MonoBehaviour
[YarnCommand("OpenSingleButtonWindow")]
public IEnumerator OpenSingleButtonWindow(string title, string description, bool ispanelActive = true)
{
AudioManager.PlayInteraction("ui");
FmodManager.Instance.PlaySfx("event:/Scriptal/Ui");
bool isConfirmed = false;
singleButtonWindowPrefab.transform.GetChild(0).gameObject.SetActive(ispanelActive);
@@ -49,7 +50,7 @@ public class WindowManager : MonoBehaviour
[YarnCommand("OpenMutiSingleButtonWindow")]
public IEnumerator OpenMutiSingleButtonWindow(string title, string description, int number)
{
AudioManager.PlayInteraction("ui");
FmodManager.Instance.PlaySfx("event:/Scriptal/Ui");
bool isConfirmed = false;
singleButtonWindowPrefab.transform.GetChild(0).gameObject.SetActive(false);
@@ -68,7 +69,7 @@ public class WindowManager : MonoBehaviour
[YarnCommand("OpenProgressWindow")]
public IEnumerator OpenProgressWindow(string title, string description, float duration)
{
AudioManager.PlayInteraction("ui");
FmodManager.Instance.PlaySfx("event:/Scriptal/Ui");
progressWindowPrefab.TitleValue = title;
progressWindowPrefab.DescriptionValue = description;
float currentProgress = 0;
+17 -15
View File
@@ -6,6 +6,7 @@ using Yarn.Unity;
using System.Linq; // 添加这个 using 语句
using DG.Tweening;
using AibisDream;
using AibisDream.Kit;
public class TaskEntry
@@ -23,40 +24,41 @@ public class TaskEntry
SubTasks = new List<TaskEntry>();
}
}
public class TaskManager : MonoBehaviour
{
public GameObject taskTextPrefab; // 用于显示任务的文本预制体
public Transform taskListParent; // 任务列表的父物体
public Transform taskListParent; // 任务列表的父物体
private List<TaskEntry> tasks = new List<TaskEntry>();
private RectTransform pos;
public void Awake()
{
pos=GetComponent<RectTransform>();
pos = GetComponent<RectTransform>();
}
[YarnCommand("task_moveIn")]
public void Task_moveIn()
{
AudioManager.PlayInteraction("task_inout");
pos.DOAnchorPosY(-170f,1f);
}
public void Task_moveIn()
{
FmodManager.Instance.PlaySfx("event:/Scriptal/taskmanager");
pos.DOAnchorPosY(-170f, 1f);
}
[YarnCommand("task_moveOut")]
public void Task_moveOut()
{
AudioManager.PlayInteraction("task_inout");
pos.DOAnchorPosY(175,1f);
}
{
FmodManager.Instance.PlaySfx("event:/Scriptal/taskmanager");
pos.DOAnchorPosY(175, 1f);
}
[YarnCommand("add_task")]
public void AddTask(string text, string parentTaskText = null)
{
TaskEntry newTask = new TaskEntry(text);
if (!string.IsNullOrEmpty(parentTaskText))
{
TaskEntry parentTask = FindTaskByText(tasks, parentTaskText);
@@ -70,7 +72,7 @@ public class TaskManager : MonoBehaviour
Debug.LogError("Parent task not found");
}
}
else if(FindTaskByText(tasks, text)!=null)
else if (FindTaskByText(tasks, text) != null)
{
Debug.LogWarning("Allreday Added");
}
@@ -93,7 +95,7 @@ public class TaskManager : MonoBehaviour
}
else
{
Debug.LogWarning("Task" +taskText +"not found");
Debug.LogWarning("Task" + taskText + "not found");
}
}
@@ -150,4 +152,4 @@ public class TaskManager : MonoBehaviour
CreateTaskUI(subTask);
}
}
}
}
+1 -2
View File
@@ -21,8 +21,7 @@ namespace AibisDream
_ => HideDialog());
}
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, Action onTextShowed = null,
bool isAutoSkip = false)
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, bool isAutoSkip = false)
{
Debug.Log("CenterOption只显示选项");
}
+1 -3
View File
@@ -44,8 +44,7 @@ namespace AibisDream
});
}
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, Action onTextShowed = null,
bool isAutoSkip = false)
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, bool isAutoSkip = false)
{
// 把原有对话清掉
ClearBox();
@@ -56,7 +55,6 @@ namespace AibisDream
// 自动跳过的回调很难独立Remove,只能全部清空再注册,下策
_dialogText.onTextShowed.RemoveAllListeners();
_dialogText.onTextShowed.AddListener(() => onTextShowed?.Invoke());
_dialogText.onTextShowed.AddListener(() => EnumEventSystem.Global.Send(DialogEventEnum.LineShown));
_nextStep = nextStep;
+1 -3
View File
@@ -87,8 +87,7 @@ namespace AibisDream
/// <param name="nextStep">下一步</param>
/// <param name="onTextShowed">文字展示结束后触发</param>
/// <param name="isAutoSkip">是否自动跳过,默认为false</param>
public virtual void ShowLine(string dialogLine, CharacterVo character, Action nextStep, Action onTextShowed,
bool isAutoSkip = false)
public virtual void ShowLine(string dialogLine, CharacterVo character, Action nextStep, bool isAutoSkip = false)
{
gameObject.SetActive(true);
@@ -104,7 +103,6 @@ namespace AibisDream
// 自动跳过的回调很难独立Remove,只能全部清空再注册,下策
_dialogText.onTextShowed.RemoveAllListeners();
_dialogText.onTextShowed.AddListener(() => _nextArray.gameObject.SetActive(true));
_dialogText.onTextShowed.AddListener(() => onTextShowed?.Invoke());
_dialogText.onTextShowed.AddListener(() => EnumEventSystem.Global.Send(DialogEventEnum.LineShown));
_nextStep = nextStep;
@@ -38,8 +38,7 @@ namespace AibisDream
_dialogViews.ForEach(item => item.HideDialog());
}
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, Action onTextShowed,
bool isAutoSkip = false)
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, bool isAutoSkip = false)
{
gameObject.SetActive(true);
// 根据角色信息气泡
@@ -47,7 +46,7 @@ namespace AibisDream
// 处理其他泡泡
ProcessOtherBox();
// 显示对话
_currentView.ShowLine(dialogLine, character, nextStep, onTextShowed, isAutoSkip);
_currentView.ShowLine(dialogLine, character, nextStep, isAutoSkip);
}
public void ShowOptions(DialogOption[] options)
@@ -119,8 +119,7 @@ namespace AibisDream
#region
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, Action onTextShowed = null,
bool isAutoSkip = false)
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, bool isAutoSkip = false)
{
// 根据DialogViewType确定在哪个对话框显示
if (character.dialogViewType == DialogViewType.Default)
@@ -132,7 +131,7 @@ namespace AibisDream
_lastShowView = _curView;
// 没有指定对话框,就用当前激活的
_curView.ShowLine(dialogLine, character, nextStep, onTextShowed, isAutoSkip);
_curView.ShowLine(dialogLine, character, nextStep, isAutoSkip);
}
else if (_dialogViewDict.TryGetValue(character.dialogViewType, out var view))
{
@@ -143,7 +142,7 @@ namespace AibisDream
_lastShowView = view;
// 对于指定了对话框的,就在指定对话框显示
view.ShowLine(dialogLine, character, nextStep, onTextShowed, isAutoSkip);
view.ShowLine(dialogLine, character, nextStep, isAutoSkip);
}
else
{
+1 -2
View File
@@ -10,8 +10,7 @@ namespace AibisDream
{
public interface IDialogView
{
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, Action onTextShowed = null,
bool isAutoSkip = false);
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, bool isAutoSkip = false);
public void ShowOptions(DialogOption[] dialogueOptions);
+1 -1
View File
@@ -28,7 +28,7 @@ namespace AibisDream.Framework
public void ShowLine(string line, Action onTextEnd)
{
_typewriter.ShowText("");
_typewriter.TextAnimator.SetText("");
gameObject.SetActive(true);
var formattedLine = CommonUtil.SplitString(line, maxCharNum);
_typewriter.ShowText(formattedLine);
@@ -15,7 +15,6 @@ namespace AibisDream
private bool _skipLineDelay;
private Action _nextStep;
private Action _onTextShowed;
private bool _isAutoSkip;
private ActorRole _curRole;
@@ -55,8 +54,7 @@ namespace AibisDream
#endregion
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, Action onTextShowed = null,
bool isAutoSkip = false)
public void ShowLine(string dialogLine, CharacterVo character, Action nextStep, bool isAutoSkip = false)
{
gameObject.SetActive(true);
@@ -80,7 +78,6 @@ namespace AibisDream
// 保留信息
_nextStep = nextStep;
_onTextShowed = onTextShowed;
_isAutoSkip = isAutoSkip;
_curRole = character.role;
}
@@ -131,8 +128,6 @@ namespace AibisDream
{
// 触发事件
EnumEventSystem.Global.Send(DialogEventEnum.LineShown);
// 停止语音
_onTextShowed?.Invoke();
// 执行自动跳过结局
if (_isAutoSkip)