260 lines
8.5 KiB
C#
260 lines
8.5 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
public static class BlinkController
|
|
{
|
|
// Èíòåðâàë ìèãàíèÿ ïî óìîë÷àíèþ (â ñåêóíäàõ)
|
|
public static float DefaultInterval = 0.5f;
|
|
|
|
// Âíóòðåííèé ðàííåð äëÿ çàïóñêà êîðóòèí (äèíàìè÷åñêè ñîçäà¸òñÿ ïðè ïåðâîì èñïîëüçîâàíèè)
|
|
private class Runner : MonoBehaviour {
|
|
// Ïðè âûõîäå èç ïðèëîæåíèÿ âûêëþ÷àåì âñå ïîäñâåòêè
|
|
private void OnApplicationQuit()
|
|
{
|
|
BlinkController.TurnAllOff();
|
|
}
|
|
}
|
|
private static Runner _runner;
|
|
|
|
// Õðàíèëèùå çàïóùåííûõ êîðóòèí: êëþ÷ ôîðìèðóåì êàê "A_1" (òèï_èãðîê)
|
|
private static readonly Dictionary<string, Coroutine> _coroutines = new Dictionary<string, Coroutine>();
|
|
|
|
// Óáåäèìñÿ, ÷òî ðàííåð ñóùåñòâóåò è æèâ¸ò íà ñöåíå
|
|
private static void EnsureRunner()
|
|
{
|
|
if (_runner != null) return;
|
|
var go = new GameObject("_BlinkControllerRunner");
|
|
Object.DontDestroyOnLoad(go);
|
|
_runner = go.AddComponent<Runner>();
|
|
go.hideFlags = HideFlags.HideAndDontSave;
|
|
}
|
|
|
|
// ---- Àäðåñíûå êîìàíäû äëÿ ïîäñâåòîê A è B (ïî èãðîêó) ----
|
|
public static void LightAOn(int playerId) => ComWrapper.Send("2171", playerId);
|
|
public static void LightAOff(int playerId) => ComWrapper.Send("2170", playerId);
|
|
|
|
public static void LightBOn(int playerId) => ComWrapper.Send("2131", playerId);
|
|
public static void LightBOff(int playerId) => ComWrapper.Send("2130", playerId);
|
|
|
|
// ---- Ãëîáàëüíàÿ ïîäñâåòêà C (broadcast) ----
|
|
public static void LightCOn() => ComWrapper.Send("401");
|
|
public static void LightCOff() => ComWrapper.Send("400");
|
|
|
|
// ---- Start/Stop ìèãàíèÿ ----
|
|
public static void StartBlinkA(int playerId, float interval = -1f)
|
|
{
|
|
// Îñòàâëÿåì îáðàòíóþ ñîâìåñòèìîñòü: áåñêîíå÷íîå ìèãàíèå
|
|
StartBlinkATimes(playerId, -1, interval);
|
|
}
|
|
|
|
// Ìèãàíèå N ðàç (N <= 0 = áåñêîíå÷íî)
|
|
public static void StartBlinkATimes(int playerId, int times, float interval = -1f)
|
|
{
|
|
StopBlinkA(playerId);
|
|
EnsureRunner();
|
|
string key = KeyFor("A", playerId);
|
|
var coro = _runner.StartCoroutine(BlinkRoutinePlayer(key, playerId, "2170", "2171", interval > 0 ? interval : DefaultInterval, times));
|
|
_coroutines[key] = coro;
|
|
}
|
|
|
|
public static void StopBlinkA(int playerId)
|
|
{
|
|
string key = KeyFor("A", playerId);
|
|
StopAndRemove(key);
|
|
LightAOff(playerId);
|
|
}
|
|
|
|
public static void StartBlinkB(int playerId, float interval = -1f)
|
|
{
|
|
// Îñòàâëÿåì îáðàòíóþ ñîâìåñòèìîñòü: áåñêîíå÷íîå ìèãàíèå
|
|
StartBlinkBTimes(playerId, -1, interval);
|
|
}
|
|
|
|
// Ìèãàíèå N ðàç (N <= 0 = áåñêîíå÷íî)
|
|
public static void StartBlinkBTimes(int playerId, int times, float interval = -1f)
|
|
{
|
|
StopBlinkB(playerId);
|
|
EnsureRunner();
|
|
string key = KeyFor("B", playerId);
|
|
var coro = _runner.StartCoroutine(BlinkRoutinePlayer(key, playerId, "2130", "2131", interval > 0 ? interval : DefaultInterval, times));
|
|
_coroutines[key] = coro;
|
|
}
|
|
|
|
public static void StopBlinkB(int playerId)
|
|
{
|
|
string key = KeyFor("B", playerId);
|
|
StopAndRemove(key);
|
|
LightBOff(playerId);
|
|
}
|
|
|
|
// Ãëîáàëüíàÿ C
|
|
public static void StartBlinkC(float interval = -1f)
|
|
{
|
|
// Îñòàâëÿåì îáðàòíóþ ñîâìåñòèìîñòü: áåñêîíå÷íîå ìèãàíèå
|
|
StartBlinkCTimes(-1, interval);
|
|
}
|
|
|
|
// Ìèãàíèå N ðàç ãëîáàëüíî (N <= 0 = áåñêîíå÷íî)
|
|
public static void StartBlinkCTimes(int times, float interval = -1f)
|
|
{
|
|
StopBlinkC();
|
|
EnsureRunner();
|
|
string key = KeyFor("C", 0);
|
|
var coro = _runner.StartCoroutine(BlinkRoutineGlobal(key, "400", "401", interval > 0 ? interval : DefaultInterval, times));
|
|
_coroutines[key] = coro;
|
|
}
|
|
|
|
public static void StopBlinkC()
|
|
{
|
|
string key = KeyFor("C", 0);
|
|
StopAndRemove(key);
|
|
LightCOff();
|
|
}
|
|
|
|
private static void StopAndRemove(string key)
|
|
{
|
|
if (_coroutines.TryGetValue(key, out Coroutine c))
|
|
{
|
|
if (_runner != null && c != null) _runner.StopCoroutine(c);
|
|
_coroutines.Remove(key);
|
|
}
|
|
}
|
|
|
|
private static string KeyFor(string type, int playerId) => $"{type}_{playerId}";
|
|
|
|
private static IEnumerator BlinkRoutinePlayer(string key, int playerId, string onCmd, string offCmd, float interval, int repeatCount)
|
|
{
|
|
// repeatCount <= 0 => áåñêîíå÷íî
|
|
if (repeatCount <= 0)
|
|
{
|
|
while (true)
|
|
{
|
|
ComWrapper.Send(onCmd, playerId);
|
|
yield return new WaitForSeconds(interval);
|
|
ComWrapper.Send(offCmd, playerId);
|
|
yield return new WaitForSeconds(interval);
|
|
}
|
|
}
|
|
|
|
// Ïîâòîðÿåì çàäàííîå êîëè÷åñòâî ðàç
|
|
for (int i = 0; i < repeatCount; i++)
|
|
{
|
|
ComWrapper.Send(onCmd, playerId);
|
|
yield return new WaitForSeconds(interval);
|
|
ComWrapper.Send(offCmd, playerId);
|
|
// Ìåæäó èòåðàöèÿìè äåëàåì ïàóçó, êàê â îáû÷íîì ìèãàíèè, êðîìå ïîñëåäíåé
|
|
if (i < repeatCount - 1) yield return new WaitForSeconds(interval);
|
|
}
|
|
|
|
// Ãàðàíòèðóåì, ÷òî êîìàíäà âûêëþ÷åíèÿ ïîñëàíà
|
|
ComWrapper.Send(offCmd, playerId);
|
|
|
|
// Óäàëÿåì çàïèñü î êîðóòèíå
|
|
try { _coroutines.Remove(key); } catch { }
|
|
}
|
|
|
|
private static IEnumerator BlinkRoutineGlobal(string key, string onCmd, string offCmd, float interval, int repeatCount)
|
|
{
|
|
if (repeatCount <= 0)
|
|
{
|
|
while (true)
|
|
{
|
|
ComWrapper.Send(onCmd);
|
|
yield return new WaitForSeconds(interval);
|
|
ComWrapper.Send(offCmd);
|
|
yield return new WaitForSeconds(interval);
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < repeatCount; i++)
|
|
{
|
|
ComWrapper.Send(onCmd);
|
|
yield return new WaitForSeconds(interval);
|
|
ComWrapper.Send(offCmd);
|
|
if (i < repeatCount - 1) yield return new WaitForSeconds(interval);
|
|
}
|
|
|
|
ComWrapper.Send(offCmd);
|
|
try { _coroutines.Remove(key); } catch { }
|
|
}
|
|
|
|
// Âñïîìîãàòåëüíûå: ìãíîâåííûé âêë/âûêë âñåõ
|
|
public static void StopAll()
|
|
{
|
|
var keys = new List<string>(_coroutines.Keys);
|
|
foreach (var k in keys) StopAndRemove(k);
|
|
}
|
|
|
|
// Âêëþ÷èòü âñå ïîäñâåòêè (A è B — äëÿ îáîèõ èãðîêîâ, C — ãëîáàëüíî)
|
|
public static void TurnAllOn()
|
|
{
|
|
Debug.Log("BlinkController: TurnAllOn");
|
|
// A è B àäðåñíûå — äëÿ èãðîêîâ 1 è 2
|
|
LightAOn(1);
|
|
LightAOn(2);
|
|
LightBOn(1);
|
|
LightBOn(2);
|
|
// C — ãëîáàëüíî
|
|
LightCOn();
|
|
}
|
|
|
|
// Âûêëþ÷èòü âñå ïîäñâåòêè (è îñòàíîâèòü êîðóòèíû)
|
|
public static void TurnAllOff()
|
|
{
|
|
Debug.Log("BlinkController: TurnAllOff");
|
|
// Îñòàíîâèì âñå ìèãàíèÿ
|
|
StopAll();
|
|
|
|
// Îòïðàâèì êîìàíäû âûêëþ÷åíèÿ àäðåñíî äëÿ èãðîêîâ 1 è 2
|
|
try
|
|
{
|
|
LightAOff(1);
|
|
LightAOff(2);
|
|
LightBOff(1);
|
|
LightBOff(2);
|
|
// C — ãëîáàëüíî
|
|
LightCOff();
|
|
}
|
|
catch (System.Exception e)
|
|
{
|
|
Debug.LogWarning($"BlinkController: îøèáêà ïðè TurnAllOff: {e.Message}");
|
|
}
|
|
}
|
|
|
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
|
|
private static void OnRuntimeInitialized()
|
|
{
|
|
// Ïîäïèñûâàåìñÿ íà ñîáûòèå èíèöèàëèçàöèè ComWrapper — âêëþ÷èì ïîäñâåòêè, êîãäà COM áóäåò ãîòîâ
|
|
try
|
|
{
|
|
ComWrapper.OnInitialize += TurnAllOn;
|
|
// Ïîäïèñûâàåìñÿ, ÷òîáû âûêëþ÷èòü ïîäñâåòêè ÄÎ çàêðûòèÿ ïîðòîâ
|
|
ComWrapper.OnBeforeClose += TurnAllOff;
|
|
}
|
|
catch
|
|
{
|
|
// Åñëè ComWrapper åù¸ íå ñóùåñòâóåò èëè íå îïðåäåë¸í, ïðîèãíîðèðóåì — âûçîâ ïðîèçîéä¸ò ïðè èíèöèàëèçàöèè
|
|
}
|
|
|
|
// Ñîçäà¸ì ðàííåð çàðàíåå, ÷òîáû îí áûë äîñòóïåí è ãàðàíòèðîâàííî ñóùåñòâîâàë
|
|
EnsureRunner();
|
|
|
|
// Ïîäïèøåìñÿ íà ñîáûòèå âûõîäà ïðèëîæåíèÿ — ãàðàíòèðîâàííî âûêëþ÷èò ïîäñâåòêè è ïî÷èñòèò ïîäïèñêè
|
|
Application.quitting += OnApplicationQuitting;
|
|
}
|
|
|
|
// Îáðàáîò÷èê âûõîäà ïðèëîæåíèÿ: îòïèñûâàåìñÿ îò ñîáûòèé ComWrapper
|
|
private static void OnApplicationQuitting()
|
|
{
|
|
try { ComWrapper.OnInitialize -= TurnAllOn; } catch { }
|
|
try { ComWrapper.OnBeforeClose -= TurnAllOff; } catch { }
|
|
try { TurnAllOff(); } catch { }
|
|
if (_runner != null)
|
|
{
|
|
Object.Destroy(_runner.gameObject);
|
|
_runner = null;
|
|
}
|
|
}
|
|
}
|