185 lines
5.4 KiB
C#
185 lines
5.4 KiB
C#
/*
|
|
* @Author: 白哉
|
|
* @Description:
|
|
* @Date: 2025年05月22日 星期四 14:05:32
|
|
* @Modify:
|
|
*/
|
|
|
|
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
|
|
namespace Logic.Audio
|
|
{
|
|
public class AudioManager
|
|
{
|
|
public static AudioManager Instance = new AudioManager();
|
|
|
|
private AudioPlayer _musicPlayer;
|
|
private List<AudioPlayer> _allPlayer;
|
|
private Dictionary<string, AudioClip> _clips;
|
|
private GameObject AudioRoot;
|
|
|
|
|
|
public void Init()
|
|
{
|
|
_allPlayer = new List<AudioPlayer>();
|
|
_clips = new Dictionary<string, AudioClip>();
|
|
_clips["Main"] = Resources.Load<AudioClip>("Audio/Main");
|
|
_clips["RemiliaEgyptian"] = Resources.Load<AudioClip>("Audio/RemiliaEgyptian");
|
|
_clips["SatoriIndian"] = Resources.Load<AudioClip>("Audio/SatoriIndian");
|
|
_clips["KanakoGermany"] = Resources.Load<AudioClip>("Audio/KanakoGermany");
|
|
_clips["KaguyaFrench"] = Resources.Load<AudioClip>("Audio/KaguyaFrench");
|
|
|
|
if (!AudioRoot) AudioRoot = new GameObject();
|
|
AudioRoot.name = "AudioRoot";
|
|
var cfg = Object.FindObjectOfType<AudioClipConfig>();
|
|
if (cfg != null) foreach (var clip in cfg.Clips) _clips[clip.name] = clip;
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
foreach (var player in _allPlayer) player.Update();
|
|
}
|
|
|
|
public void PlayMusic(string musicName, float fadeIn, float fadeOut, bool isLoop)
|
|
{
|
|
if (!_clips.ContainsKey(musicName)) return;
|
|
if (_musicPlayer != null && _musicPlayer.State == PlayerState.Playing) _musicPlayer.Stop();
|
|
_musicPlayer = GetPlayer();
|
|
_musicPlayer.Clip = _clips[musicName];
|
|
_musicPlayer.IsLoop = isLoop;
|
|
_musicPlayer.Length = _clips[musicName].length;
|
|
_musicPlayer.FadeInDuration = fadeIn;
|
|
_musicPlayer.FadeOutDuration = fadeOut;
|
|
_musicPlayer.Play();
|
|
}
|
|
|
|
public void StopMusic()
|
|
{
|
|
_musicPlayer?.Stop();
|
|
}
|
|
|
|
public void PlayAudio(string musicName, float fadeIn, float fadeOut, bool isLoop)
|
|
{
|
|
if (!_clips.ContainsKey(musicName)) return;
|
|
var player = GetPlayer();
|
|
player.Clip = _clips[musicName];
|
|
player.IsLoop = isLoop;
|
|
player.Length = _clips[musicName].length;
|
|
player.FadeInDuration = fadeIn;
|
|
player.FadeOutDuration = fadeOut;
|
|
player.Play();
|
|
}
|
|
|
|
private AudioPlayer GetPlayer()
|
|
{
|
|
foreach (var player in _allPlayer)
|
|
{
|
|
if (player.State == PlayerState.Finished || player.State == PlayerState.Prepare) return player;
|
|
}
|
|
|
|
var sourceObj = new GameObject();
|
|
sourceObj.transform.SetParent(AudioRoot.transform);
|
|
var source = sourceObj.AddComponent<AudioSource>();
|
|
var newPlayer = new AudioPlayer(source);
|
|
_allPlayer.Add(newPlayer);
|
|
return newPlayer;
|
|
}
|
|
}
|
|
|
|
|
|
public enum PlayerState
|
|
{
|
|
Prepare,
|
|
FadeIn,
|
|
FadeOut,
|
|
Playing,
|
|
Finished,
|
|
}
|
|
|
|
|
|
public class AudioPlayer
|
|
{
|
|
public AudioSource Source;
|
|
public AudioClip Clip;
|
|
public bool IsLoop;
|
|
public float Length;
|
|
public float FadeInDuration;
|
|
public float FadeOutDuration;
|
|
|
|
public float StartTime;
|
|
public float EndTime;
|
|
public PlayerState State;
|
|
|
|
|
|
public AudioPlayer(AudioSource source)
|
|
{
|
|
Source = source;
|
|
State = PlayerState.Prepare;
|
|
}
|
|
|
|
public void Play()
|
|
{
|
|
StartTime = Time.time;
|
|
Source.clip = Clip;
|
|
Source.volume = 0;
|
|
Source.loop = IsLoop;
|
|
Source.Play();
|
|
State = PlayerState.FadeIn;
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
if (Source == null || !Source.isPlaying) return;
|
|
UpdateSourceVolume();
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
State = PlayerState.FadeOut;
|
|
EndTime = Time.time;
|
|
}
|
|
|
|
private void UpdateSourceVolume()
|
|
{
|
|
if (State == PlayerState.Finished || State == PlayerState.Prepare) return;
|
|
if (State == PlayerState.FadeIn)
|
|
{
|
|
if (Time.time - StartTime < FadeInDuration)
|
|
{
|
|
Source.volume = (Time.time - StartTime) / FadeInDuration;
|
|
}
|
|
else
|
|
{
|
|
Source.volume = 1;
|
|
State = PlayerState.Playing;
|
|
}
|
|
}
|
|
|
|
if (State == PlayerState.Playing && !IsLoop)
|
|
{
|
|
if (Time.time - StartTime >= Length - FadeOutDuration)
|
|
{
|
|
EndTime = Time.time;
|
|
State = PlayerState.FadeOut;
|
|
}
|
|
}
|
|
|
|
if (State == PlayerState.FadeOut)
|
|
{
|
|
if (Time.time - EndTime >= FadeOutDuration)
|
|
{
|
|
Source.volume = 0;
|
|
Source.Stop();
|
|
State = PlayerState.Finished;
|
|
}
|
|
else
|
|
{
|
|
Source.volume = (FadeOutDuration - Time.time + EndTime) / FadeOutDuration;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |