浮动小游戏已经基本搞好

新做了两个设置界面
一些bug修复和优化
This commit is contained in:
FloatGaming
2025-12-28 04:55:18 +08:00
parent eb9b6ba78a
commit 0963263ff4
557 changed files with 296886 additions and 487 deletions
+80
View File
@@ -0,0 +1,80 @@
using UnityEngine;
using UnityEngine.UI;
public class audioMerger : MonoBehaviour
{
[Header("sv object")]
public GameObject sv_audioSettings;
[Header("所有声音给我站一边")]
[Tooltip("因为静音键我要出现")]
public Toggle enableGlobalMute_toggle;
[Header("一堆slider")]
public Slider mainVolumn_slider;
public Slider noteHit_slider;
public Slider musicInGame_slider;
public Slider musicOutGame_slider;
public Slider skillEffect_slider;
public Slider uiInteration_slider;
public Slider cvVolumn_slider;
[Header("配套的一堆text")]
public Text mainVolumn_text;
public Text noteHit_text;
public Text musicInGame_text;
public Text musicOutGame_text;
public Text skillEffect_text;
public Text uiInteration_text;
public Text cvVolumn_text;
// PlayerPrefs key for storing the toggle state
const string PlayerPrefKey_EnableGlobalMute = "EnableGlobalMute";
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
// Load saved state (default: false)
bool isOn = PlayerPrefs.GetInt(PlayerPrefKey_EnableGlobalMute, 0) == 1;
// Apply to toggle (if available) and sv_audioSettings
if (enableGlobalMute_toggle != null)
{
// Prevent accidentally invoking listeners while initializing
enableGlobalMute_toggle.onValueChanged.RemoveAllListeners();
enableGlobalMute_toggle.isOn = isOn;
enableGlobalMute_toggle.onValueChanged.AddListener(OnEnableGlobalMuteChanged);
}
if (sv_audioSettings != null)
{
// 非模式:当 toggle 为开启 (isOn == true) 时,禁用 sv_audioSettings
sv_audioSettings.SetActive(!isOn);
}
}
void OnDestroy()
{
if (enableGlobalMute_toggle != null)
{
enableGlobalMute_toggle.onValueChanged.RemoveListener(OnEnableGlobalMuteChanged);
}
}
// Listener called when the toggle value changes
void OnEnableGlobalMuteChanged(bool isOn)
{
// Save to PlayerPrefs
PlayerPrefs.SetInt(PlayerPrefKey_EnableGlobalMute, isOn ? 1 : 0);
PlayerPrefs.Save();
// 应用非模式:当 toggle 为开启时,禁用 sv_audioSettings
if (sv_audioSettings != null)
{
sv_audioSettings.SetActive(!isOn);
}
}
// Update is called once per frame
void Update()
{
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 2ee999443e0788e4ba1f60dec644e601
+213
View File
@@ -0,0 +1,213 @@
using UnityEngine;
using UnityEngine.UI;
using System.IO;
using System.Text.RegularExpressions;
using System;
using System.Text;
using System.Runtime.InteropServices;
public class readDeviceInfo : MonoBehaviour
{
public Button reread_button;
public Button export_button;
public Text deviceInfo_text;
void Start()
{
if (reread_button != null)
{
reread_button.onClick.AddListener(read_deviceInfo);
}
if (export_button != null)
{
export_button.onClick.AddListener(ExportToFile);
}
if (deviceInfo_text != null)
deviceInfo_text.supportRichText = true;
read_deviceInfo();
}
void OnDestroy()
{
if (reread_button != null)
reread_button.onClick.RemoveListener(read_deviceInfo);
if (export_button != null)
export_button.onClick.RemoveListener(ExportToFile);
}
void Update()
{
}
private void read_deviceInfo()
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
void AddEntry(string title, object value)
{
string str;
if (value == null) str = "";
else if (value is bool b) str = b ? "启用" : "禁用";
else str = value.ToString();
sb.AppendLine($"<b>{title}</b>");
sb.AppendLine(str);
sb.AppendLine();
}
AddEntry("平台", Application.platform.ToString());
AddEntry("运行目录", Application.dataPath);
AddEntry("persistent 数据路径", Application.persistentDataPath);
AddEntry("操作系统", SystemInfo.operatingSystem);
AddEntry("设备名称", SystemInfo.deviceName);
AddEntry("设备型号", SystemInfo.deviceModel);
AddEntry("设备唯一ID", SystemInfo.deviceUniqueIdentifier);
AddEntry("CPU", SystemInfo.processorType);
AddEntry("CPU核心数", SystemInfo.processorCount);
AddEntry("系统内存 (MB)", SystemInfo.systemMemorySize);
AddEntry("图形设备名称", SystemInfo.graphicsDeviceName);
AddEntry("图形设备供应商", SystemInfo.graphicsDeviceVendor);
AddEntry("DirectX", SystemInfo.graphicsDeviceType.ToString());
AddEntry("显存 (MB)", SystemInfo.graphicsMemorySize);
AddEntry("屏幕分辨率", $"{Screen.currentResolution.width} x {Screen.currentResolution.height} @ {Screen.currentResolution.refreshRate}Hz");
AddEntry("屏幕DPI", Screen.dpi);
AddEntry("显示模式", Screen.fullScreenMode.ToString());
try
{
AddEntry("电池电量", $"{SystemInfo.batteryLevel * 100:F0}%");
}
catch
{
AddEntry("电池状态", "不支持");
}
AddEntry("浮动·本索尼克谱面编辑器", "v1.1h02e");
AddEntry("浮动·浮动小游戏引擎", "v1.301");
AddEntry("本游戏版本号", "code::testingVersion1062");
AddEntry("登录渠道", "Steam Client");
AddEntry(".NET Framework", "8.0 +");
AddEntry("最大纹理尺寸", SystemInfo.maxTextureSize);
AddEntry("禁用后台运行", Application.runInBackground);
AddEntry("多线程渲染", SystemInfo.graphicsMultiThreaded);
string output = sb.ToString();
if (deviceInfo_text != null)
{
deviceInfo_text.text = output;
}
}
void ExportToFile()
{
if (deviceInfo_text == null)
{
return;
}
string path = ShowSaveFileDialog();
if (string.IsNullOrEmpty(path))
{
return;
}
try
{
string raw = deviceInfo_text.text;
// Remove <b> tags and add colon after title
string cleaned = Regex.Replace(raw, "<b>(.*?)</b>", "$1:");
File.WriteAllText(path, cleaned);
}
catch (System.Exception)
{
}
}
string ShowSaveFileDialog()
{
#if UNITY_EDITOR
string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string path = UnityEditor.EditorUtility.SaveFilePanel("保存设备信息", desktop, "device_info", "txt");
return string.IsNullOrEmpty(path) ? null : path;
#elif UNITY_STANDALONE_WIN
try
{
// Use native Windows SaveFile dialog via comdlg32 GetSaveFileName
OpenFileName ofn = new OpenFileName();
ofn.structSize = Marshal.SizeOf(ofn);
ofn.filter = "Text files (*.txt)\0*.txt\0All files (*.*)\0*.*\0";
ofn.file = new string('\0', 260);
ofn.maxFile = ofn.file.Length;
ofn.fileTitle = new string('\0', 260);
ofn.maxFileTitle = ofn.fileTitle.Length;
ofn.initialDir = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
ofn.title = "保存设备信息";
ofn.defExt = "txt";
ofn.flags = OpenFileNameFlags.OFN_OVERWRITEPROMPT;
if (GetSaveFileName(ofn))
{
// Trim any trailing nulls
return ofn.file.TrimEnd('\0');
}
}
catch (Exception)
{
}
return null;
#else
string defaultPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "device_info.txt");
return defaultPath;
#endif
}
#if UNITY_STANDALONE_WIN
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private class OpenFileName
{
public int structSize = 0;
public IntPtr dlgOwner = IntPtr.Zero;
public IntPtr instance = IntPtr.Zero;
public string filter = null;
public string customFilter = null;
public int maxCustFilter = 0;
public int filterIndex = 0;
public string file = null;
public int maxFile = 0;
public string fileTitle = null;
public int maxFileTitle = 0;
public string initialDir = null;
public string title = null;
public int flags = 0;
public short fileOffset = 0;
public short fileExtension = 0;
public string defExt = null;
public IntPtr custData = IntPtr.Zero;
public IntPtr hook = IntPtr.Zero;
public string templateName = null;
public IntPtr reservedPtr = IntPtr.Zero;
public int reservedInt = 0;
public int flagsEx = 0;
}
private static class OpenFileNameFlags
{
public const int OFN_OVERWRITEPROMPT = 0x00000002;
}
[DllImport("comdlg32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool GetSaveFileName([In, Out] OpenFileName ofn);
#endif
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 9af26f04de2ee934ab267f3448336566
@@ -0,0 +1,215 @@
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
using System.Collections.Generic;
public class selectSettingsOptions : MonoBehaviour
{
[Header("用户")]
public Button userSettingsButton;
public GameObject userSettingsGameObject;
public Image userSettings_selectedMark;
[Header("画面设置")]
public Button graphicSettingsButton;
public GameObject graphicSettingsGameObject;
public Image graphicSettings_selectedMark;
[Header("声音设置")]
public Button audioSettingsButton;
public GameObject audioSettingsGameObject;
public Image audioSettings_selectedMark;
[Header("操作设置")]
public Button controlSettingsButton;
public GameObject controlSettingsGameObject;
public Image controlSettings_selectedMark;
[Header("游戏设置")]
public Button gameSettingsButton;
public GameObject gameSettingsGameObject;
public Image gameSettings_selectedMark;
[Header("关于")]
public Button aboutUsButton;
public GameObject aboutUsGameObject;
public Image aboutUs_selectedMark;
[Header("设备信息")]
public Button deviceInfoButton;
public GameObject deviceInfoGameObject;
public Image deviceInfo_selectedMark;
[Header("Fade Settings")]
[Tooltip("时间(秒)")] public float fadeDuration = 0.25f;
[Tooltip("Hover alpha when mouse over (0-1)")] public float hoverAlpha = 0.75f;
[Tooltip("Alpha when selected (常亮)")] public float selectedAlpha = 1f;
// internal state
private class OptionEntry
{
public Button button;
public GameObject panel;
public Image mark;
public Coroutine fadeCoroutine;
public bool selected;
}
private List<OptionEntry> options = new List<OptionEntry>();
private OptionEntry currentSelected = null;
void Awake()
{
options.Clear();
AddOption(userSettingsButton, userSettingsGameObject, userSettings_selectedMark);
AddOption(graphicSettingsButton, graphicSettingsGameObject, graphicSettings_selectedMark);
AddOption(audioSettingsButton, audioSettingsGameObject, audioSettings_selectedMark);
AddOption(controlSettingsButton, controlSettingsGameObject, controlSettings_selectedMark);
AddOption(gameSettingsButton, gameSettingsGameObject, gameSettings_selectedMark);
AddOption(aboutUsButton, aboutUsGameObject, aboutUs_selectedMark);
AddOption(deviceInfoButton, deviceInfoGameObject, deviceInfo_selectedMark);
}
void Start()
{
// default select userSettings
if (userSettingsButton != null)
SelectOptionByButton(userSettingsButton);
}
void OnDestroy()
{
foreach (var opt in options)
{
if (opt.button != null)
opt.button.onClick.RemoveAllListeners();
RemoveEventTrigger(opt.button);
}
}
void AddOption(Button btn, GameObject panel, Image mark)
{
var entry = new OptionEntry { button = btn, panel = panel, mark = mark, selected = false, fadeCoroutine = null };
options.Add(entry);
if (btn != null)
{
btn.onClick.AddListener(() => OnOptionClicked(entry));
EnsureEventTrigger(btn, entry);
}
if (mark != null)
{
var c = mark.color;
c.a = 0f;
mark.color = c;
mark.enabled = false;
}
if (panel != null)
panel.SetActive(false);
}
void EnsureEventTrigger(Button btn, OptionEntry entry)
{
if (btn == null) return;
EventTrigger trig = btn.GetComponent<EventTrigger>();
if (trig == null) trig = btn.gameObject.AddComponent<EventTrigger>();
// pointer enter
var entryEnter = new EventTrigger.Entry { eventID = EventTriggerType.PointerEnter };
entryEnter.callback.AddListener((data) => { OnOptionPointerEnter(entry); });
trig.triggers.Add(entryEnter);
// pointer exit
var entryExit = new EventTrigger.Entry { eventID = EventTriggerType.PointerExit };
entryExit.callback.AddListener((data) => { OnOptionPointerExit(entry); });
trig.triggers.Add(entryExit);
}
void RemoveEventTrigger(Button btn)
{
if (btn == null) return;
var trig = btn.GetComponent<EventTrigger>();
if (trig != null) Destroy(trig);
}
void OnOptionPointerEnter(OptionEntry entry)
{
if (entry == null) return;
if (entry.selected) return;
StartFade(entry, hoverAlpha);
}
void OnOptionPointerExit(OptionEntry entry)
{
if (entry == null) return;
if (entry.selected) return;
StartFade(entry, 0f);
}
void OnOptionClicked(OptionEntry entry)
{
if (entry == null) return;
SelectEntry(entry);
}
void SelectOptionByButton(Button btn)
{
var entry = options.Find(o => o.button == btn);
if (entry != null) SelectEntry(entry);
}
void SelectEntry(OptionEntry entry)
{
if (entry == null) return;
if (currentSelected != null && currentSelected != entry)
{
currentSelected.selected = false;
StartFade(currentSelected, 0f);
if (currentSelected.panel != null) currentSelected.panel.SetActive(false);
}
currentSelected = entry;
currentSelected.selected = true;
if (currentSelected.panel != null) currentSelected.panel.SetActive(true);
StartFade(currentSelected, selectedAlpha);
}
void StartFade(OptionEntry entry, float targetAlpha)
{
if (entry == null || entry.mark == null) return;
entry.mark.enabled = true;
if (entry.fadeCoroutine != null) StopCoroutine(entry.fadeCoroutine);
entry.fadeCoroutine = StartCoroutine(FadeImage(entry.mark, targetAlpha, fadeDuration, () =>
{
if (Mathf.Approximately(targetAlpha, 0f))
{
if (!entry.selected)
entry.mark.enabled = false;
}
}));
}
IEnumerator FadeImage(Image img, float targetAlpha, float duration, System.Action onComplete = null)
{
if (img == null) yield break;
float start = img.color.a;
float t = 0f;
while (t < duration)
{
t += Time.unscaledDeltaTime;
float a = Mathf.Lerp(start, targetAlpha, duration <= 0f ? 1f : (t / duration));
var c = img.color;
c.a = a;
img.color = c;
yield return null;
}
var fc = img.color;
fc.a = targetAlpha;
img.color = fc;
onComplete?.Invoke();
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: e27c16de0caf79944b0631760576ae31
+39
View File
@@ -0,0 +1,39 @@
using UnityEngine;
using UnityEngine.UI;
public class userSettings : MonoBehaviour
{
[Header("登陆渠道")]
[Tooltip("渠道")]
public Text user_login_source_text;
[Tooltip("渠道ID")]
public Text user_source_uid_text;
[Header("语言设置")]
[Tooltip("当前语言")]
public Dropdown language_dropdown;
[Header("存档管理")]
[Tooltip("导出存档")]
public Button export_saveData_button;
[Tooltip("导入存档")]
public Button import_saveData_button;
[Tooltip("清理存档")]
public Button clearup_saveData_button;
[Header("查看详细高光")]
[Tooltip("查看按钮")]
public Button view_detailedHighlight_button;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 0ff926d5dac4bae45a8e098937f5ae52