11 Commits

Author SHA1 Message Date
MrUnknownDE a3eb6cf71f fix: git credentials manager issue 2026-05-05 20:00:09 +02:00
MrUnknownDE a3a23902ab fix: crash issues on push 2026-05-05 19:43:54 +02:00
MrUnknownDE e89eb856ca remove old sync project from dependen 2026-05-05 19:37:35 +02:00
MrUnknownDE 689ceca124 add AudioLink BPM Detector 2026-04-11 10:44:03 +02:00
MrUnknownDE 185f1cc96a remove sync project ^^ 2026-04-10 22:08:08 +02:00
MrUnknownDE 32a428502d add audio source fade 2026-04-10 22:05:33 +02:00
MrUnknownDE 50017d40c8 Merge branch 'main' of github.com:MrUnknownDE/unity-gittool 2026-04-10 21:36:28 +02:00
MrUnknownDE 5490b72e5d add ProTV Room Zone Script :D 2026-04-10 21:35:01 +02:00
MrUnknownDE 9250fc71ed Fix formatting in usage section of README
Updated usage instructions for GIT Version Control.
2026-04-07 16:27:53 +02:00
MrUnknownDE 8318bd6a6e add generation packages inventar list 2026-04-07 16:26:30 +02:00
MrUnknownDE 0c613129f5 start livesync panel ^^ 2026-04-07 13:27:01 +02:00
6 changed files with 545 additions and 81 deletions
+64
View File
@@ -0,0 +1,64 @@
using UdonSharp;
using UnityEngine;
using AudioLink;
public class AudioLinkBeatDetector : UdonSharpBehaviour
{
public AudioLink.AudioLink audioLinkInstance;
[Header("Settings")]
[Range(0, 1)] public float threshold = 0.5f;
public float minBpm = 70f;
public float maxBpm = 210f; // Alles darüber wird als Fehler ignoriert
[Header("Output")]
public float bpm = 128f;
public float instantBpm = 128f;
public bool isBeat;
private float lastBeatTime;
void Update()
{
if (audioLinkInstance == null || !audioLinkInstance.AudioDataIsAvailable()) return;
Vector2 bassPos = AudioLink.AudioLink.GetALPassAudioBass();
Vector4 data = audioLinkInstance.GetDataAtPixel((int)bassPos.x, (int)bassPos.y);
float currentLevel = data.x;
// Prüfen auf Threshold
if (currentLevel > threshold)
{
float currentTime = Time.time;
float timeDiff = currentTime - lastBeatTime;
// Der "Debounce" Check:
// 0.27s entspricht ca. 222 BPM. Alles was schneller kommt, ist Rauschen.
if (timeDiff > 0.27f)
{
if (lastBeatTime > 0)
{
float detected = 60f / timeDiff;
// Nur plausible Werte übernehmen
if (detected >= minBpm && detected <= maxBpm)
{
instantBpm = detected;
// Glättung: 0.5 sorgt für schnelles Folgen, aber filtert Ausreißer
bpm = Mathf.Lerp(bpm, instantBpm, 0.5f);
}
}
lastBeatTime = currentTime;
isBeat = true;
}
else
{
isBeat = false;
}
}
else
{
isBeat = false;
}
}
}
+43
View File
@@ -0,0 +1,43 @@
using UdonSharp;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class BeatDetectorDisplay : UdonSharpBehaviour
{
public AudioLinkBeatDetector engine;
public TextMeshProUGUI bpmText;
public Image beatIndicator;
public Color activeColor = Color.cyan;
private float flashTimer;
void Update()
{
if (engine == null) return;
// Wenn die Engine einen Beat erkennt...
if (engine.isBeat)
{
// ...aktualisieren wir SOFORT den Text mit der instantBpm
if (bpmText != null)
{
bpmText.text = engine.instantBpm.ToString("F0"); // "F0" für ganze Zahlen ohne Lag-Gefühl
}
// Visueller Kick
flashTimer = 0.1f;
if (beatIndicator != null) beatIndicator.color = activeColor;
}
// Timer für das Abklingen der LED
if (flashTimer > 0)
{
flashTimer -= Time.deltaTime;
if (flashTimer <= 0 && beatIndicator != null)
{
beatIndicator.color = new Color(0.1f, 0.1f, 0.1f, 1f);
}
}
}
}
+255 -39
View File
@@ -35,6 +35,11 @@ public class GitPanel : EditorWindow
private string webUrlOverride = ""; private string webUrlOverride = "";
private string prefsKey = ""; private string prefsKey = "";
private double lastRefreshTime = -999;
private bool isLoading = false;
private string loadingMessage = "";
private struct CommitInfo { public string hash; public string date; public string message; } private struct CommitInfo { public string hash; public string date; public string message; }
private List<CommitInfo> commitHistory = new List<CommitInfo>(); private List<CommitInfo> commitHistory = new List<CommitInfo>();
@@ -47,15 +52,51 @@ public class GitPanel : EditorWindow
private void OnEnable() private void OnEnable()
{ {
EditorApplication.update += OnEditorUpdate;
prefsKey = $"GitTool_WebUrl_{Application.dataPath.GetHashCode()}"; prefsKey = $"GitTool_WebUrl_{Application.dataPath.GetHashCode()}";
webUrlOverride = EditorPrefs.GetString(prefsKey, ""); webUrlOverride = EditorPrefs.GetString(prefsKey, "");
RefreshData(); RefreshData();
} }
private void OnFocus() { RefreshData(); } private void OnDisable()
{
EditorApplication.update -= OnEditorUpdate;
}
private void OnEditorUpdate()
{
if (isLoading) Repaint();
}
private void RunNetworkCommand(string message, System.Func<string> work, System.Action<string> onDone)
{
if (isLoading) return;
isLoading = true;
loadingMessage = message;
Repaint();
System.Threading.ThreadPool.QueueUserWorkItem(_ =>
{
string result = work();
EditorApplication.delayCall += () =>
{
isLoading = false;
loadingMessage = "";
onDone(result);
Repaint();
};
});
}
private void OnFocus()
{
if (EditorApplication.timeSinceStartup - lastRefreshTime > 2.0)
RefreshData();
}
public void RefreshData() public void RefreshData()
{ {
lastRefreshTime = EditorApplication.timeSinceStartup;
CheckGitInstallation(); CheckGitInstallation();
CheckUnitySettings(); CheckUnitySettings();
@@ -115,6 +156,21 @@ public class GitPanel : EditorWindow
private void OnGUI() private void OnGUI()
{ {
if (isLoading)
{
EditorGUI.DrawRect(new Rect(0, 0, position.width, position.height), new Color(0.15f, 0.15f, 0.15f, 1f));
string[] frames = { "|", "/", "-", "\\" };
string spinner = frames[(int)(EditorApplication.timeSinceStartup * 8) % 4];
GUIStyle style = new GUIStyle(EditorStyles.boldLabel)
{
alignment = TextAnchor.MiddleCenter,
fontSize = 13,
normal = { textColor = Color.white }
};
GUI.Label(new Rect(0, position.height / 2 - 20, position.width, 40), $"{spinner} {loadingMessage}", style);
return;
}
GUILayout.Space(10); GUILayout.Space(10);
GUILayout.Label("GIT Version Control System", EditorStyles.boldLabel); GUILayout.Label("GIT Version Control System", EditorStyles.boldLabel);
if (hasRepo) GUILayout.Label($"Active Branch: {currentBranchName}", EditorStyles.miniLabel); if (hasRepo) GUILayout.Label($"Active Branch: {currentBranchName}", EditorStyles.miniLabel);
@@ -137,7 +193,7 @@ public class GitPanel : EditorWindow
if (!isGitInstalled) { RenderGitMissingUI(); return; } if (!isGitInstalled) { RenderGitMissingUI(); return; }
if (!hasRepo) { RenderInitUI(); return; } if (!hasRepo) { RenderInitUI(); return; }
showSettings = EditorGUILayout.Foldout(showSettings, "⚙️ Repository Settings"); showSettings = EditorGUILayout.Foldout(showSettings, "Repository Settings");
if (showSettings) if (showSettings)
{ {
EditorGUILayout.BeginVertical("box"); EditorGUILayout.BeginVertical("box");
@@ -148,6 +204,13 @@ public class GitPanel : EditorWindow
{ {
EditorPrefs.SetString(prefsKey, webUrlOverride.Trim()); EditorPrefs.SetString(prefsKey, webUrlOverride.Trim());
} }
GUILayout.Space(10);
GUILayout.Label("Inventory Management", EditorStyles.miniBoldLabel);
if (GUILayout.Button("Sync Package Inventory (Unity & VRChat)", GUILayout.Height(25)))
{
ExportPackageInventory();
}
EditorGUILayout.EndVertical(); EditorGUILayout.EndVertical();
GUILayout.Space(5); GUILayout.Space(5);
} }
@@ -230,25 +293,31 @@ public class GitPanel : EditorWindow
GUI.backgroundColor = new Color(0.2f, 0.4f, 0.8f); GUI.backgroundColor = new Color(0.2f, 0.4f, 0.8f);
if (GUILayout.Button("✓ Push", GUILayout.Height(30))) if (GUILayout.Button("✓ Push", GUILayout.Height(30)))
{ {
UnityEngine.Debug.Log("Git-Tool: Saving Scenes and Assets before push..."); // Unity APIs must stay on the main thread
UnityEditor.SceneManagement.EditorSceneManager.SaveOpenScenes(); UnityEditor.SceneManagement.EditorSceneManager.SaveOpenScenes();
AssetDatabase.SaveAssets(); AssetDatabase.SaveAssets();
if (string.IsNullOrWhiteSpace(commitMessage)) SetDefaultCommitMessage(); if (string.IsNullOrWhiteSpace(commitMessage)) SetDefaultCommitMessage();
RunGitCommand("add .", true); string msgSnapshot = commitMessage;
RunGitCommand($"commit -m \"{commitMessage}\"", true);
string pushResult = RunGitCommand("push -u origin HEAD", true); RunNetworkCommand("Committing and pushing... (a browser window may open for authentication)",
if (pushResult.Contains("rejected") || pushResult.Contains("fetch first")) () =>
{ {
UnityEngine.Debug.LogError("Git-Tool: PUSH REJECTED! Jemand anderes hat Änderungen hochgeladen. Bitte klicke zuerst auf 'Pull'."); ExportPackageInventory();
} RunGitCommand("add .", true);
else RunGitCommand($"commit -m \"{msgSnapshot}\"", true);
{ return RunGitCommand("push -u origin HEAD", true, 180000);
UnityEngine.Debug.Log("Git-Tool: Changes successfully pushed!"); },
commitMessage = ""; result =>
} {
RefreshData(); if (result.Contains("rejected") || result.Contains("fetch first"))
UnityEngine.Debug.LogError("Git-Tool: PUSH REJECTED! Someone else pushed changes. Please click 'Pull' first.");
else
{
UnityEngine.Debug.Log("Git-Tool: Changes successfully pushed!");
commitMessage = "";
}
RefreshData();
});
} }
GUI.backgroundColor = new Color(0.8f, 0.6f, 0.2f); GUI.backgroundColor = new Color(0.8f, 0.6f, 0.2f);
@@ -257,15 +326,18 @@ public class GitPanel : EditorWindow
UnityEditor.SceneManagement.EditorSceneManager.SaveOpenScenes(); UnityEditor.SceneManagement.EditorSceneManager.SaveOpenScenes();
AssetDatabase.SaveAssets(); AssetDatabase.SaveAssets();
string pullResult = RunGitCommand("pull", true); RunNetworkCommand("Pulling from remote... (a browser window may open for authentication)",
AssetDatabase.Refresh(); () => RunGitCommand("pull", true, 180000),
result =>
if (pullResult.Contains("CONFLICT")) {
{ AssetDatabase.Refresh();
UnityEngine.Debug.LogError("Git-Tool: MERGE CONFLICT! Bitte in VS Code auflösen!"); if (result.Contains("CONFLICT"))
EditorUtility.DisplayDialog("Merge Conflict", "Es gibt Konflikte mit den Server-Daten!\n\nGit konnte die Änderungen nicht automatisch zusammenführen. Bitte öffne die roten Dateien in deinem Code-Editor und löse den Konflikt manuell auf.", "OK"); {
} UnityEngine.Debug.LogError("Git-Tool: MERGE CONFLICT! Please resolve conflicts in your code editor.");
RefreshData(); EditorUtility.DisplayDialog("Merge Conflict", "There are conflicts with the remote changes.\n\nGit could not merge automatically. Please open the conflicting files in your code editor and resolve them manually.", "OK");
}
RefreshData();
});
} }
GUI.backgroundColor = new Color(0.8f, 0.3f, 0.3f); GUI.backgroundColor = new Color(0.8f, 0.3f, 0.3f);
@@ -409,35 +481,179 @@ public class GitPanel : EditorWindow
if (!File.Exists(path)) File.WriteAllText(path, ".idea\n.vs\nbin\nobj\n/Library\n/Temp\n/UserSettings\n/Configs\n/*.csproj\n/*.sln\n/Logs\n/Packages/*\n!/Packages/manifest.json\n!/Packages/packages-lock.json\n~UnityDirMonSyncFile~*"); if (!File.Exists(path)) File.WriteAllText(path, ".idea\n.vs\nbin\nobj\n/Library\n/Temp\n/UserSettings\n/Configs\n/*.csproj\n/*.sln\n/Logs\n/Packages/*\n!/Packages/manifest.json\n!/Packages/packages-lock.json\n~UnityDirMonSyncFile~*");
} }
// FIX: Methode ist wieder static! private void ExportPackageInventory()
public static string RunGitCommand(string args, bool logAction = false) { {
try { string rootPath = Path.GetFullPath(Path.Combine(Application.dataPath, ".."));
ProcessStartInfo si = new ProcessStartInfo("git", args) { string outputPath = Path.Combine(rootPath, "PACKAGES.md");
string unityManifest = Path.Combine(rootPath, "Packages", "manifest.json");
string vpmManifest = Path.Combine(rootPath, "Packages", "vpm-manifest.json");
List<string> mdLines = new List<string>();
mdLines.Add("# 📦 Project Dependencies Inventory");
mdLines.Add($"\n*Last Update: {System.DateTime.Now:yyyy-MM-dd HH:mm:ss}*");
mdLines.Add("\n> [!TIP]\n> This list helps to restore the workspace if the Creator Companion or Unity fails to auto-resolve dependencies.\n");
int totalFound = 0;
totalFound += ParseManifest(unityManifest, "Unity Standard & Scoped Dependencies", mdLines);
totalFound += ParseManifest(vpmManifest, "VRChat Package Manager (VPM) Dependencies", mdLines);
try {
File.WriteAllLines(outputPath, mdLines, System.Text.Encoding.UTF8);
RunGitCommand($"add \"{outputPath}\"");
UnityEngine.Debug.Log($"Git-Tool: PACKAGES.md updated. {totalFound} entries found.");
} catch (System.Exception e) {
UnityEngine.Debug.LogError("Git-Tool: Failed to write PACKAGES.md: " + e.Message);
}
}
private int ParseManifest(string path, string sectionTitle, List<string> outputList)
{
if (!File.Exists(path)) return 0;
int count = 0;
try {
string content = File.ReadAllText(path);
// 1. Find the start of the "dependencies" block
int startIndex = content.IndexOf("\"dependencies\"");
if (startIndex == -1) return 0;
// Find the first opening brace after the key
startIndex = content.IndexOf("{", startIndex);
if (startIndex == -1) return 0;
// 2. Extract exactly this block by counting braces
int openBraces = 0;
int endIndex = startIndex;
for (int i = startIndex; i < content.Length; i++) {
if (content[i] == '{') openBraces++;
if (content[i] == '}') {
openBraces--;
if (openBraces == 0) {
endIndex = i;
break;
}
}
}
if (endIndex <= startIndex) return 0;
outputList.Add($"## {sectionTitle}");
outputList.Add("| Package Name | Version / Source |");
outputList.Add("| :--- | :--- |");
// 3. Parse the isolated block line by line
string dependenciesBlock = content.Substring(startIndex, endIndex - startIndex + 1);
string[] blockLines = dependenciesBlock.Split(new[] { '\r', '\n' }, System.StringSplitOptions.RemoveEmptyEntries);
string currentVpmPackage = "";
foreach (string line in blockLines) {
string trimmed = line.Trim();
if (trimmed == "{" || trimmed == "}" || trimmed == "},") continue;
if (trimmed.StartsWith("\"")) {
string[] parts = trimmed.Split(new char[] { ':' }, 2);
if (parts.Length == 2) {
string key = parts[0].Replace("\"", "").Trim();
string rawValue = parts[1].Trim();
if (rawValue.StartsWith("{")) {
// VPM package start, e.g. "com.vrchat.base": {
currentVpmPackage = key;
}
else if (key == "version") {
// VPM package version, e.g. "version": "3.10.2"
string val = rawValue.Replace("\"", "").Replace(",", "").Trim();
if (!string.IsNullOrEmpty(currentVpmPackage)) {
outputList.Add($"| `{currentVpmPackage}` | {val} |");
count++;
currentVpmPackage = "";
}
}
else if (!rawValue.StartsWith("{")) {
// Flat Unity package, e.g. "com.unity.timeline": "1.2.3"
string val = rawValue.Replace("\"", "").Replace(",", "").Trim();
outputList.Add($"| `{key}` | {val} |");
count++;
}
}
}
}
} catch (System.Exception e) {
UnityEngine.Debug.LogWarning($"Git-Tool: Could not read {Path.GetFileName(path)}: {e.Message}");
}
if (count == 0) {
outputList.Add("| - | No entries found |");
}
outputList.Add("");
return count;
}
public static string RunGitCommand(string args, bool logAction = false, int timeoutMs = 10000)
{
try
{
ProcessStartInfo si = new ProcessStartInfo("git", args)
{
WorkingDirectory = Path.GetFullPath(Path.Combine(Application.dataPath, "..")), WorkingDirectory = Path.GetFullPath(Path.Combine(Application.dataPath, "..")),
UseShellExecute = false, UseShellExecute = false,
RedirectStandardOutput = true, RedirectStandardOutput = true,
RedirectStandardError = true, RedirectStandardError = true,
CreateNoWindow = true CreateNoWindow = true
}; };
// Block stdin prompts (no TTY in Unity), but force GCM to use browser/GUI auth
si.EnvironmentVariables["GIT_TERMINAL_PROMPT"] = "0";
si.EnvironmentVariables["GCM_INTERACTIVE"] = "always";
si.EnvironmentVariables["GIT_SSH_COMMAND"] = "ssh -o BatchMode=yes -o ConnectTimeout=15";
using (Process p = Process.Start(si)) { var stdout = new System.Text.StringBuilder();
string o = p.StandardOutput.ReadToEnd(); var stderr = new System.Text.StringBuilder();
string e = p.StandardError.ReadToEnd();
using (Process p = Process.Start(si))
{
// Async reading prevents the stdout/stderr pipe-buffer deadlock
p.OutputDataReceived += (_, e) => { if (e.Data != null) stdout.AppendLine(e.Data); };
p.ErrorDataReceived += (_, e) => { if (e.Data != null) stderr.AppendLine(e.Data); };
p.BeginOutputReadLine();
p.BeginErrorReadLine();
bool finished = p.WaitForExit(timeoutMs);
if (!finished)
{
p.Kill();
p.WaitForExit();
string timeoutNote = $"[{System.DateTime.Now:HH:mm:ss}] > git {args}\n⚠ TIMEOUT after {timeoutMs / 1000}s\n\n";
UnityEngine.Debug.LogWarning($"Git-Tool: Command timed out ({timeoutMs / 1000}s): git {args}");
if (logAction) gitLogOutput = timeoutNote + gitLogOutput;
return "";
}
// Second WaitForExit (no timeout) flushes async output handlers
p.WaitForExit(); p.WaitForExit();
string result = o + (string.IsNullOrWhiteSpace(e) ? "" : "\n" + e);
if (logAction) { string result = stdout.ToString() + (stderr.Length > 0 ? "\n" + stderr : "");
string time = System.DateTime.Now.ToString("HH:mm:ss");
string entry = $"[{time}] > git {args}\n"; if (logAction)
{
string entry = $"[{System.DateTime.Now:HH:mm:ss}] > git {args}\n";
if (!string.IsNullOrWhiteSpace(result)) entry += result.Trim() + "\n\n"; if (!string.IsNullOrWhiteSpace(result)) entry += result.Trim() + "\n\n";
gitLogOutput = entry + gitLogOutput; gitLogOutput = entry + gitLogOutput;
if (gitLogOutput.Length > 10000) gitLogOutput = gitLogOutput.Substring(0, 10000); if (gitLogOutput.Length > 10000) gitLogOutput = gitLogOutput.Substring(0, 10000);
} }
return result; return result;
} }
} catch { return ""; } }
catch (System.Exception ex)
{
UnityEngine.Debug.LogWarning($"Git-Tool: Exception running git {args}: {ex.Message}");
return "";
}
} }
} }
@@ -1,16 +0,0 @@
{
"name": "de.mrunknownde.gittool.Editor",
"rootNamespace": "",
"references": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
+157
View File
@@ -0,0 +1,157 @@
/*
* ============================================================================
* ProTV Room Zone Manager
* ============================================================================
* Ein autarkes Trigger-Modul zur ressourcenschonenden Steuerung von
* ProTV / AVPro Instanzen in VRChat
*
* written by MrUnknownDE
* https://mrunknown.de
* ============================================================================
*/
using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;
public class ProTVRoomZone : UdonSharpBehaviour
{
[Header("Der Videoplayer für diesen Raum")]
public GameObject localVideoPlayer;
[Space(10)]
[Header("Fade Settings")]
[Tooltip("Wie lange soll das Ein-/Ausblenden in Sekunden dauern?")]
public float fadeDuration = 1.5f;
[Tooltip("Ziehe hier die AudioSources des ProTVs rein - damit die Lautstärke smooth gefadet wird.")]
public AudioSource[] audioSources;
private BoxCollider roomCollider;
private float fadeProgress = 0f;
private int fadeState = 0;
// Hier speichern wir die echte Lautstärke, bevor sie verfälscht wird
private float[] savedVolumes;
void Start()
{
roomCollider = GetComponent<BoxCollider>();
// Arrays initialisieren und Basis-Lautstärke beim Start sichern
if (audioSources != null && audioSources.Length > 0)
{
savedVolumes = new float[audioSources.Length];
for (int i = 0; i < audioSources.Length; i++)
{
if (audioSources[i] != null) savedVolumes[i] = audioSources[i].volume;
}
}
SendCustomEventDelayedSeconds(nameof(CheckSpawnPosition), 2.0f);
}
public void CheckSpawnPosition()
{
VRCPlayerApi player = Networking.LocalPlayer;
if (!Utilities.IsValid(player)) return;
if (roomCollider != null && roomCollider.bounds.Contains(player.GetPosition()))
{
if (localVideoPlayer != null) localVideoPlayer.SetActive(true);
fadeProgress = 1f;
}
else
{
UpdateSavedVolumes();
if (localVideoPlayer != null) localVideoPlayer.SetActive(false);
fadeProgress = 0f;
}
}
public override void OnPlayerTriggerEnter(VRCPlayerApi player)
{
if (!Utilities.IsValid(player) || !player.isLocal) return;
if (localVideoPlayer != null) localVideoPlayer.SetActive(true);
fadeProgress = 0f;
fadeState = 1;
}
public override void OnPlayerTriggerExit(VRCPlayerApi player)
{
if (!Utilities.IsValid(player) || !player.isLocal) return;
UpdateSavedVolumes();
fadeProgress = 1f;
fadeState = -1; // Starte Fade Out
}
void Update()
{
if (fadeState == 0) return;
if (fadeState == 1) // FADE IN
{
fadeProgress += Time.deltaTime / fadeDuration;
if (fadeProgress >= 1f)
{
fadeProgress = 1f;
fadeState = 0;
}
ApplyFadedVolume();
}
else if (fadeState == -1) // FADE OUT
{
fadeProgress -= Time.deltaTime / fadeDuration;
if (fadeProgress <= 0f)
{
fadeProgress = 0f;
fadeState = 0;
// DER PRO-TV FIX:
RestoreOriginalVolume();
if (localVideoPlayer != null) localVideoPlayer.SetActive(false);
}
else
{
ApplyFadedVolume();
}
}
}
private void UpdateSavedVolumes()
{
if (audioSources == null) return;
for (int i = 0; i < audioSources.Length; i++)
{
if (audioSources[i] != null && audioSources[i].volume > 0.05f)
{
savedVolumes[i] = audioSources[i].volume;
}
}
}
private void ApplyFadedVolume()
{
if (audioSources == null || savedVolumes == null) return;
for (int i = 0; i < audioSources.Length; i++)
{
if (audioSources[i] != null)
{
audioSources[i].volume = savedVolumes[i] * fadeProgress;
}
}
}
private void RestoreOriginalVolume()
{
if (audioSources == null || savedVolumes == null) return;
for (int i = 0; i < audioSources.Length; i++)
{
if (audioSources[i] != null)
{
audioSources[i].volume = savedVolumes[i];
}
}
}
}
+1 -1
View File
@@ -55,7 +55,7 @@ This tool is installed manually directly into your Unity project.
Once installed, you can access the tools via the top menu bar in Unity: Once installed, you can access the tools via the top menu bar in Unity:
`Tools` -> `MrUnknownDE` -> `GIT Version Control` `Tools` -> `MrUnknownDE` -> `GIT Version Control`<br>
`Tools` -> `MrUnknownDE` -> `Discord RPC` `Tools` -> `MrUnknownDE` -> `Discord RPC`
The tools will open as floating windows. You can easily dock them into your custom Unity layout (e.g., right next to the Inspector or Console). The tools will open as floating windows. You can easily dock them into your custom Unity layout (e.g., right next to the Inspector or Console).