feat: 场景
This commit is contained in:
@@ -1,9 +1,129 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine; // 假设在Unity环境中使用Debug.LogError
|
||||
|
||||
namespace HitFeedback
|
||||
{
|
||||
public class Config
|
||||
{
|
||||
public KeyCode hotKey = KeyCode.F8;
|
||||
public Dictionary<string, float> probability = new Dictionary<string, float>();
|
||||
|
||||
public void LoadConfig(string filename)
|
||||
{
|
||||
if (!File.Exists(filename))
|
||||
{
|
||||
Debug.LogError($"Config file not found: {filename}");
|
||||
return; // 如果文件不存在,就没必要继续了
|
||||
}
|
||||
|
||||
// 清空旧的概率数据,确保每次加载都是从新开始
|
||||
probability.Clear();
|
||||
|
||||
try
|
||||
{
|
||||
using (var sr = new StreamReader(filename))
|
||||
{
|
||||
string line;
|
||||
var lineNumber = 0; // 用于错误报告
|
||||
while ((line = sr.ReadLine()) != null)
|
||||
{
|
||||
lineNumber++;
|
||||
line = line.Trim(); // 移除行首尾的空白字符
|
||||
|
||||
// 忽略空行和注释行
|
||||
if (string.IsNullOrEmpty(line) || line.StartsWith(";") || line.StartsWith("#"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// 查找等号
|
||||
var separatorIndex = line.IndexOf('=');
|
||||
if (separatorIndex == -1)
|
||||
{
|
||||
Debug.LogWarning($"Skipping malformed line in config file '{filename}' at line {lineNumber}: No '=' found. Line: '{line}'");
|
||||
continue;
|
||||
}
|
||||
|
||||
var key = line.Substring(0, separatorIndex).Trim();
|
||||
var valueStr = line.Substring(separatorIndex + 1).Trim();
|
||||
|
||||
// 解析 hotKey
|
||||
if (key.Equals("hotKey", System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
try
|
||||
{
|
||||
hotKey = (KeyCode)System.Enum.Parse(typeof(KeyCode), valueStr, true);
|
||||
}
|
||||
catch (System.ArgumentException)
|
||||
{
|
||||
Debug.LogError($"Invalid KeyCode '{valueStr}' in config file '{filename}' at line {lineNumber}. Using default F8.");
|
||||
hotKey = KeyCode.F8; // 设置为默认值或保持不变
|
||||
}
|
||||
}
|
||||
// 解析 probability 字典项
|
||||
else
|
||||
{
|
||||
if (float.TryParse(valueStr, out var probValue))
|
||||
{
|
||||
probability[key] = probValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning($"Invalid float value '{valueStr}' for key '{key}' in config file '{filename}' at line {lineNumber}. Skipping entry.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.LogError($"Error reading config file '{filename}': {ex.Message}");
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 将当前配置存储到指定INI文件。
|
||||
/// </summary>
|
||||
/// <param name="filename">要保存的INI文件的路径。</param>
|
||||
public void SaveConfig(string filename)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 确保目录存在
|
||||
var directory = Path.GetDirectoryName(filename);
|
||||
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
using (var sw = new StreamWriter(filename))
|
||||
{
|
||||
sw.WriteLine("; HitFeedback Configuration File");
|
||||
sw.WriteLine("; Generated by HitFeedback.Config class");
|
||||
sw.WriteLine(); // 空行
|
||||
sw.WriteLine("[General]");
|
||||
sw.WriteLine($"hotKey = {hotKey.ToString()}");
|
||||
sw.WriteLine();
|
||||
if (probability.Count > 0)
|
||||
{
|
||||
sw.WriteLine("[Probabilities]");
|
||||
foreach (var kvp in probability)
|
||||
{
|
||||
// 使用 InvariantCulture 确保浮点数的格式在不同区域设置下都一致
|
||||
sw.WriteLine($"{kvp.Key} = {kvp.Value.ToString(System.Globalization.CultureInfo.InvariantCulture)}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sw.WriteLine("; No probabilities currently configured.");
|
||||
}
|
||||
sw.WriteLine();
|
||||
}
|
||||
Debug.Log($"Config saved to: {filename}");
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.LogError($"Error saving config file '{filename}': {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,13 +14,17 @@ namespace HitFeedback
|
||||
public class ModBehaviour:Duckov.Modding.ModBehaviour
|
||||
{
|
||||
public const string AudioFolderName = "audio";
|
||||
public const string ConfigFileName = "config.ini";
|
||||
public string audioFolderPath;
|
||||
public string configFilePath;
|
||||
|
||||
public List<string> audioFilePath = new List<string>();
|
||||
public Dictionary<string,float> audioFilePath = new Dictionary<string,float>();
|
||||
|
||||
public Health health;
|
||||
|
||||
public Config config=new Config();
|
||||
|
||||
public float totalWeight;
|
||||
|
||||
private void Update()
|
||||
{
|
||||
@@ -34,12 +38,46 @@ namespace HitFeedback
|
||||
{
|
||||
LevelManager.OnLevelInitialized += OnSceneLoaded;
|
||||
audioFolderPath=Path.Combine(info.path,AudioFolderName);
|
||||
configFilePath=Path.Combine(info.path, ConfigFileName);
|
||||
FindWavFiles();
|
||||
config.LoadConfig(configFilePath);
|
||||
ApplyConfig();
|
||||
foreach (var f in audioFilePath)
|
||||
{
|
||||
totalWeight+=f.Value;
|
||||
}
|
||||
}
|
||||
protected override void OnBeforeDeactivate()
|
||||
{
|
||||
|
||||
LevelManager.OnLevelInitialized -= OnSceneLoaded;
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
private void ApplyConfig()
|
||||
{
|
||||
foreach (var f in config.probability)
|
||||
{
|
||||
if (audioFilePath.ContainsKey(f.Key))
|
||||
{
|
||||
audioFilePath[f.Key] = f.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveConfig()
|
||||
{
|
||||
config.probability.Clear();
|
||||
foreach (var f in audioFilePath)
|
||||
{
|
||||
config.probability.Add(f.Key, f.Value);
|
||||
}
|
||||
|
||||
config.SaveConfig(configFilePath);
|
||||
}
|
||||
private void FindWavFiles()
|
||||
{
|
||||
@@ -55,7 +93,7 @@ namespace HitFeedback
|
||||
{
|
||||
foreach (string filePath in files)
|
||||
{
|
||||
audioFilePath.Add(filePath);
|
||||
audioFilePath.Add(Path.GetFileName(filePath), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -101,16 +139,21 @@ namespace HitFeedback
|
||||
{
|
||||
if (audioFilePath.Count > 0)
|
||||
{
|
||||
var randomIndex = Random.Range(0, audioFilePath.Count);
|
||||
var filePath = audioFilePath[randomIndex];
|
||||
AudioManager.PostCustomSFX(filePath);
|
||||
var randomIndex = Random.Range(0, totalWeight);
|
||||
foreach (var f in audioFilePath)
|
||||
{
|
||||
randomIndex -= f.Value;
|
||||
if (randomIndex <= 0)
|
||||
{
|
||||
AudioManager.PostCustomSFX(Path.Combine(audioFolderPath, f.Key));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("Mod Feedback: No audio clips loaded to play.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
|
||||
22
HitFeedback/obj/Debug/HitFeedback.AssemblyInfo.cs
Normal file
22
HitFeedback/obj/Debug/HitFeedback.AssemblyInfo.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("HitFeedback")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+0206a83f56b5a794fe2f173b4a047cc4f0d4cd90")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("HitFeedback")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("HitFeedback")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
// 由 MSBuild WriteCodeFragment 类生成。
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
0e8871f70d957c8690d2d7e899b7c26cc6fec6a1db85ba1988bdbe458697eb11
|
||||
@@ -0,0 +1,8 @@
|
||||
is_global = true
|
||||
build_property.RootNamespace = HitFeedback
|
||||
build_property.ProjectDir = D:\vs_project\DuckovMods\HitFeedback\
|
||||
build_property.EnableComHosting =
|
||||
build_property.EnableGeneratedComInterfaceComImportInterop =
|
||||
build_property.CsWinRTUseWindowsUIXamlProjections = false
|
||||
build_property.EffectiveAnalysisLevelStyle =
|
||||
build_property.EnableCodeStyleSeverity =
|
||||
BIN
HitFeedback/obj/Debug/HitFeedback.assets.cache
Normal file
BIN
HitFeedback/obj/Debug/HitFeedback.assets.cache
Normal file
Binary file not shown.
BIN
HitFeedback/obj/Debug/HitFeedback.csproj.AssemblyReference.cache
Normal file
BIN
HitFeedback/obj/Debug/HitFeedback.csproj.AssemblyReference.cache
Normal file
Binary file not shown.
@@ -13,7 +13,7 @@ using System.Reflection;
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("HitFeedback")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+2b7943339c8fff4147e07028e81b3fff19ff0d80")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+0206a83f56b5a794fe2f173b4a047cc4f0d4cd90")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("HitFeedback")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("HitFeedback")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
@@ -1 +1 @@
|
||||
1ef47fdca68bb8ba079c984a562e35f7d221eeaabc5c5290fb8b33cc52111227
|
||||
044e9b3ac36cbf242c64f55f40a9077d40727cb97e540d335e1e29dbc7dccff1
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user