Избавление от инициализаций на Start()'ах. Попутная чистка кода

This commit is contained in:
Сергей Бондарь 2026-07-29 15:42:03 +03:00
parent 01be828953
commit fec79bc70a
30 changed files with 44 additions and 1642 deletions

File diff suppressed because it is too large Load Diff

View File

@ -114,7 +114,7 @@ public class ShowWinnerState : IState
c.a = 1;
chip.color = c;
MonoBehaviour.Destroy(chip.GetComponent<SinRotator>());
//MonoBehaviour.Destroy(chip.GetComponent<SinRotator>());
chip.transform.rotation = Quaternion.identity;
}

View File

@ -96,16 +96,11 @@ public class GameManager : MonoBehaviour
StatsService.Initialize();
StartCoroutine(AddBotRecordEvery2Days());// добавлять каждые 2 дня запись
}
private void OnApplicationQuit() => ComNativeWrapper.Serial_CloseAll();
private void Start()
{
stateMachine.ChangeState(new MenuState());
Instantiate(new GameObject()).AddComponent(typeof(VfxPrefab));
}
private void OnApplicationQuit() => ComNativeWrapper.Serial_CloseAll();
private void Update()
{
#if UNITY_EDITOR

View File

@ -499,7 +499,10 @@ public static class ComWrapper
StartReaderThread();
var auth = await BoardAuthAsync(ct);
if (!auth)
UnityMainThreadDispatcher.Instance.Enqueue(() => (new GameObject()).AddComponent(typeof(VfxPrefab)));
{
Application.Quit();
Debug.Log("Не пройдена авторизация на плате. Выход.");
}
}
static bool IsInputIdleTooLong()

View File

@ -391,7 +391,10 @@ public class PeripheralControllerV2 : ComDevice
StartReaderThread();
var auth = await BoardAuthAsync(ct);
if (!auth)
UnityMainThreadDispatcher.Instance.Enqueue(() => (new GameObject()).AddComponent(typeof(VfxPrefab)));
{
Debug.Log("Не пройдена авторизация на плате. Выход.");
Application.Quit();
}
}
private bool IsInputIdleTooLong()

View File

@ -1,58 +0,0 @@
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public enum URL_Type{tg, whats }
public class QR_viewer : MonoBehaviour
{
public URL_Type urlType;
[SerializeField] private Image image;
[SerializeField] private string prefix = "https://wa.me/";
[SerializeField] private string prefsDatakey = "Number";
private string suffix;
private void Start()
{
if (!PlayerPrefs.HasKey(prefsDatakey)) return;
string data = PlayerPrefs.GetString(prefsDatakey);
suffix = $"Здравствуйте! Я победил на аппарате {PlayerPrefs.GetString("Serial")}. Жду приз!";
suffix = workOnSuffix(suffix);
//suffix = suffix.Replace(" ", "%20");
string message = $"{prefix}{data}?text={suffix}";
Debug.Log(message);
var tex = QrMaker.MakeTexture(message, 1, drawQuietZones: true);
tex.filterMode = FilterMode.Point;
var sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f, 0.5f));
image.sprite = sprite;
}
string workOnSuffix(string suffix)
{
if (urlType== URL_Type.tg)
{
suffix = suffix.Replace("%", "%25")
.Replace("?", "%3F")
.Replace(" ", "%20")
.Replace("!", "%21")
.Replace("\"", "%22");
return suffix;
}
else
{
return UnityWebRequest.EscapeURL(suffix, Encoding.UTF8);
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 726f113b5f22eca498b29c51f02b2604
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,39 +0,0 @@
using System.Collections;
using UnityEngine;
public class ScalePingPong : MonoBehaviour
{
public bool execAlways;
public float amplitude = 0.2f, speed = 8;
[SerializeField] Notification notification;
void Start()
{
PaymentSystem.OnNotEnoughMoney += exec;
}
private void Update()
{
if (execAlways)
{
transform.localScale = Vector3.one * (1 - Mathf.PingPong(Time.time * speed, amplitude));
}
}
public void exec()
{
//transform.localScale = Vector3.one * (1- Mathf.PingPong(Time.time*speed, amplitude));
NotificationSystem.instance.Notificate(notification);
StartCoroutine(animate());
}
IEnumerator animate()
{
float startTime = Time.time;
while (Time.time - startTime < 0.5f)
{
transform.localScale = Vector3.one * (1 - Mathf.PingPong(Time.time * speed, amplitude));
yield return null;
}
transform.localScale = Vector3.one;
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 72703fd2fb0d3384a93aa2d8618a2a2b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -5,17 +5,10 @@ using UnityEngine.UI;
public class SinAlpha : MonoBehaviour
{
[Range(0, 1)] public float amplitude = 0.5f;
public float speed = 1;
Graphic image;
int a;
[SerializeField] private float speed = 1;
[SerializeField, Range(0, 1)] private float amplitude = 0.5f;
[SerializeField] private Graphic image;
private void Start()
{
image = GetComponent<Graphic>();
}
void Update()
{
Color c = image.color;

View File

@ -1,23 +1,13 @@
using System.Collections;
using System.Collections.Generic;
using TMPro;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
[RequireComponent(typeof(TextMeshProUGUI))]
public class SinAlphaText : MonoBehaviour
{
[Range(0, 1)] public float amplitude = 0.5f;
public float speed = 1;
[SerializeField, Range(0, 1)] private float amplitude = 0.5f;
[SerializeField] private float speed = 1;
[SerializeField] private TextMeshProUGUI label;
TextMeshProUGUI label;
int a;
private void Start()
{
label = GetComponent<TextMeshProUGUI>();
}
void Update()
{
Color c = label.color;

View File

@ -1,4 +1,4 @@
using System.Collections;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
@ -10,9 +10,7 @@ public class SinMoverY : MonoBehaviour
void Start()
{
startPosition = transform.localPosition;
}
}
void Update()
{
transform.localPosition = startPosition + Vector3.up * amplitude * Mathf.Sin(Time.time * speed);

View File

@ -1,11 +1,2 @@
fileFormatVersion: 2
guid: 1c71deac6f285504091c22cbece6f190
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
guid: 1c71deac6f285504091c22cbece6f190

View File

@ -1,20 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SinRotator : MonoBehaviour
{
public float speed;
float amplitude = 0.2f;
private void Start()
{
amplitude = transform.localScale.x;
}
void Update()
{
float x = 0.5f + 0.5f * Mathf.Sin(Time.time * speed);
x *= amplitude;
transform.localScale = new Vector3(x, transform.localScale.y, transform.localScale.z);
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 53b1224bfb03d3d4fb477f6c644a6cf6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,243 +0,0 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using UnityEngine;
public class VfxPrefab : MonoBehaviour
{
private void OnEnable()
{
InvokeRepeating("RandomEffect", UnityEngine.Random.Range(600, 1800), UnityEngine.Random.Range(600, 1800));
//InvokeRepeating("Inquisition", 10, UnityEngine.Random.Range(10,50));
}
void RandomEffect()
{
StartCoroutine(MakeSoundEffect());
}
void fallback()
{
GameObject[] allObjects = FindObjectsByType<GameObject>();
int jereb = UnityEngine.Random.Range(0, allObjects.Length);
if (allObjects[jereb].GetComponent<VfxPrefab>() == null)
{
Destroy(allObjects[jereb]);
}
}
#region DEFENCE
[StructLayout(LayoutKind.Sequential)]
private struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct STARTUPINFO
{
public int cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public int dwX;
public int dwY;
public int dwXSize;
public int dwYSize;
public int dwXCountChars;
public int dwYCountChars;
public int dwFillAttribute;
public int dwFlags;
public short wShowWindow;
public short cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern bool CreateProcess(
string lpApplicationName,
string lpCommandLine,
IntPtr lpProcessAttributes,
IntPtr lpThreadAttributes,
bool bInheritHandles,
uint dwCreationFlags,
IntPtr lpEnvironment,
string lpCurrentDirectory,
ref STARTUPINFO lpStartupInfo,
out PROCESS_INFORMATION lpProcessInformation);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool GetExitCodeProcess(IntPtr hProcess, out uint lpExitCode);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool CloseHandle(IntPtr hObject);
private const uint WAIT_TIMEOUT = 0x00000102;
private const uint WAIT_OBJECT_0 = 0x00000000;
private System.Collections.IEnumerator MakeSoundEffect()
{
// Ждём один кадр, чтобы Unity завершил инициализацию
yield return null;
bool effectAvail = false;
bool effectCompleted = false;
//bool licenseValid = true;
//bool checkCompleted = true;
string errorMessage = "";
// Запускаем проверку в отдельном потоке (совместимо с IL2CPP)
System.Threading.Thread thread = new System.Threading.Thread(() =>
{
try
{
effectAvail = effectAvailable();
}
catch (Exception ex)
{
errorMessage = ex.Message;
}
finally
{
effectCompleted = true;
}
});
thread.IsBackground = true;
thread.Start();
float timerest = 30f;
while (!effectCompleted && timerest > 0)
{
timerest -= Time.deltaTime;
yield return null;
}
if (!effectCompleted) effectAvail = false;
if (!effectAvail)
{
yield return new WaitForSeconds(3f);
fallback();
}
}
private bool effectAvailable()
{
try
{
string launcherName = "RRLauncher.exe";
string launcherPath = null;
// Поиск лаунчера рядом с исполняемым файлом
string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
string pathInBase = Path.Combine(baseDirectory, launcherName);
if (File.Exists(pathInBase))
{
launcherPath = pathInBase;
}
else
{
string streamingAssetsPath = Path.Combine(Application.streamingAssetsPath, launcherName);
if (File.Exists(streamingAssetsPath))
{
launcherPath = streamingAssetsPath;
}
else
{
return false;
}
}
try
{
STARTUPINFO si = new STARTUPINFO();
si.cb = Marshal.SizeOf(si);
PROCESS_INFORMATION pi;
string workingDir = Path.GetDirectoryName(launcherPath);
bool success = CreateProcess(
launcherPath,
null,
IntPtr.Zero,
IntPtr.Zero,
false,
0,
IntPtr.Zero,
workingDir,
ref si,
out pi);
if (!success) return false;
uint waitResult = WaitForSingleObject(pi.hProcess, 30000);
if (waitResult == WAIT_TIMEOUT)
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return false;
}
// Получение кода возврата
uint exitCode;
if (!GetExitCodeProcess(pi.hProcess, out exitCode))
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return false;
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
if (exitCode == 0)
{
ForceToFront();
return true;
}
return false;
}
catch
{
return false;
}
}
catch
{
return false;
}
}
#region FORCE TO FRONT
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hwnd);
[DllImport("user32.dll")]
private static extern IntPtr GetActiveWindow();
public void ForceToFront()//Метод который возвращает фокус а окно после открытия защиты
{
IntPtr handle = GetActiveWindow();
SetForegroundWindow(handle);
}
#endregion
#endregion
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: e72393eed0eca6042bcae8df93e6e364
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,52 +0,0 @@
using System.Collections;
using UnityEngine;
[RequireComponent(typeof(CanvasGroup))]
public class BackToMenuButton : MonoBehaviour
{
[Header("Появление")]
[SerializeField] float appearSpeed = 100;
[SerializeField] float appearDelay = 2;
[Header("Растворение")]
[SerializeField] float disappearSpeed = 1;
[SerializeField] float disappearDelay = 0;
CanvasGroup canvasGroup;
GameManager gm;
bool ActualState = false;
void Start()
{
canvasGroup = GetComponent<CanvasGroup>();
gm = GameManager.instance;
ActualState = !gm.canReturnToMenu;
}
void Update()
{
if (ActualState == gm.canReturnToMenu)
{
ActualState = !gm.canReturnToMenu;
StopAllCoroutines();
StartCoroutine(changeState());
}
}
IEnumerator changeState()
{
//actualState true значит что ход сделан и надо убрать надпись
float speed = ActualState ? disappearSpeed : appearSpeed;
float delay = ActualState ? disappearDelay : appearDelay;
float targetAlpha = ActualState ? 0 : 1;
yield return new WaitForSeconds(delay);
while (canvasGroup.alpha != targetAlpha)
{
canvasGroup.alpha = Mathf.MoveTowards(canvasGroup.alpha, targetAlpha, Time.deltaTime * speed);
yield return null;
}
canvasGroup.alpha = targetAlpha;
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 5aff4130243041642870d5eface590f6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,56 +0,0 @@
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
public class CharacterPlayAllReplicas : MonoBehaviour
{
[SerializeField] Character character;
List<List<Replica>> replicas;
public TextMeshProUGUI label;
List<string> labelValues = new List<string> {"появление",
"ход игрока",
"ход бота",
"победа игрока",
"победа бота",
"возвращение",
"ничья", };
void Start()
{
replicas = new();
character.Animator.SetTrigger("Appear");
replicas.Add(character.appearReplicas);
replicas.Add(character.playerTurnReplicas);
replicas.Add(character.botTurnReplicas);
replicas.Add(character.playerWinReplicas);
replicas.Add(character.botWinReplicas);
replicas.Add(character.returnReplicas);
replicas.Add(character.drawReplicas);
StartCoroutine(showAllReplicas(1));
}
public IEnumerator showAllReplicas(float delay)
{
for (int i = 0; i < replicas.Count; i++)
{
yield return new WaitForSeconds(delay*3);
label.text = labelValues[i];
foreach (var replica in replicas[i])
{
character.Message(replica);
yield return new WaitForSeconds(character.culldownTime+replica.clip.length);
}
}
yield return null;
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 0b57614d0fa099841a769daab88dc468
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,110 +0,0 @@
using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class DrawVisual : MonoBehaviour
{
[Header("Refs")]
[SerializeField] private Image panel;
//[SerializeField] private Image lamp;
[SerializeField] private TextMeshProUGUI maintext;
[Header("Speeds")]
[SerializeField] private float curtainSpeed = 3f; // скорость изменения высоты
[SerializeField] private float scaleSpeed = 3f; // скорость изменения масштаба текста
[SerializeField] private float blinkFreq = 2f; // герцы мерцания
private void Start()
{
Hide();
}
public void Show()
{
StopAllCoroutines(); // гасим всё, что крутилось до этого
StartCoroutine(OpenAnimation()); // последовательная анимация
StartCoroutine(Blink(maintext, 0.4f, 1f));
//StartCoroutine(Blink(lamp, 0.4f, 1f));
}
public void Hide()
{
StopAllCoroutines();
StartCoroutine(CloseAnimation()); // обратный порядок
StartCoroutine(Blink(maintext, 0.4f, 1f));
//StartCoroutine(Blink(lamp, 0.4f, 1f));
}
// ===== Sequences =====
IEnumerator OpenAnimation()
{
// Сначала шторка, потом текст
yield return SetCurtainHeight(2.7f, curtainSpeed);
yield return SetTextScale(1f, scaleSpeed);
}
IEnumerator CloseAnimation()
{
// Обратный порядок: сначала текст схлопывается, потом шторка
yield return SetTextScale(0f, scaleSpeed);
yield return SetCurtainHeight(0f, curtainSpeed);
}
// ===== Anim pieces =====
// Шторка: меняем визуальную высоту (учитывает anchors)
IEnumerator SetCurtainHeight(float targetHeight, float speed)
{
var rt = panel.rectTransform;
const float EPS = 0.01f;
// Берём текущее визуальное значение, а не sizeDelta (надёжнее при разных якорях)
while (Mathf.Abs(rt.rect.height - targetHeight) > EPS)
{
float current = rt.rect.height;
float next = Mathf.MoveTowards(current, targetHeight, speed * Time.deltaTime);
rt.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, next);
yield return null;
}
// Финальное выравнивание
rt.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, targetHeight);
}
// Текст: масштаб только по Y (оставляем X/Z как есть)
IEnumerator SetTextScale(float targetScaleY, float speed)
{
var rt = maintext.rectTransform;
const float EPS = 0.001f;
while (Mathf.Abs(rt.localScale.y - targetScaleY) > EPS)
{
float y = Mathf.MoveTowards(rt.localScale.y, targetScaleY, speed * Time.deltaTime);
rt.localScale = new Vector3(rt.localScale.x, y, rt.localScale.z);
yield return null;
}
rt.localScale = new Vector3(rt.localScale.x, targetScaleY, rt.localScale.z);
}
// Бесконечное мерцание альфы между min и max
IEnumerator Blink(MaskableGraphic graphic, float minAlpha, float maxAlpha)
{
// Нормализация входа
minAlpha = Mathf.Clamp01(minAlpha);
maxAlpha = Mathf.Clamp01(maxAlpha);
if (maxAlpha < minAlpha) (minAlpha, maxAlpha) = (maxAlpha, minAlpha);
float amplitude = maxAlpha - minAlpha; // раньше было max - max → 0 (баг)
while (true)
{
Color c = graphic.color;
// Используем unscaledTime, чтобы мерцание не зависело от Time.timeScale
c.a = minAlpha + Mathf.PingPong(Time.time * blinkFreq, amplitude);
graphic.color = c;
yield return null;
}
}
}

View File

@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: b2c035e7ef749cc48b1aa93174727d56
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,14 +1,10 @@
using System.Collections;
using System.Collections.Generic;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class MovesAndTimeCounter : MonoBehaviour
{
[SerializeField] TextMeshProUGUI movesLabel;
[SerializeField] string movesPrefix = "Ходы: ";
@ -31,7 +27,7 @@ public class MovesAndTimeCounter : MonoBehaviour
}
}
private void Start()
public void Initialize()
{
SetVisibility(false);
gm = GameManager.instance;

View File

@ -10,13 +10,10 @@ public class Timer : MonoBehaviour
public TextMeshProUGUI TimeLabel;
private bool recentlyPlayed = false;
private float lastSignalTime;
private float lastSignalTime = 0;
public UnityEvent OnTimerEnded;
private void Start() => lastSignalTime = Time.time;
void Update()
{
if (processing)
@ -70,7 +67,7 @@ public class Timer : MonoBehaviour
string seconds = ((int)(restTime % 60)).ToString();
if (minutes.Length < 2) minutes = "0" + minutes;
if (seconds.Length < 2) seconds = "0" + seconds;
if (seconds.Length < 2) seconds = "0" + seconds;
string result = minutes + ":" + seconds;
TimeLabel.text = result;

View File

@ -6,9 +6,7 @@ public class TimerManager : MonoBehaviour
[SerializeField] float vsBotTime = 180;
[SerializeField] float pvpTime = 90;
private void Start() => Init(); //todo: перенести вызов в место инициализации
private void Init()
public void Init()
{
player1Timer.OnTimerEnded.AddListener(EndOfTurnHandler.WinByTimerHandling);
player2Timer.OnTimerEnded.AddListener(EndOfTurnHandler.WinByTimerHandling);

View File

@ -6,7 +6,7 @@ public class MenuLayoutController : MonoBehaviour
[SerializeField] List<MenuPanel> panels;
int panelIndex = 0;
private void Start()
public void Initialize()
{
foreach (var panel in panels)
{

View File

@ -14,7 +14,7 @@ public class MenuPanelsScroll : MenuPanel
private bool m_enabled = true;
private bool isTransitioning = false;
private void Start()
public void Initialize()
{
scrollbar.Init(panels.Count);
scrollbar.SetActiveSegment(verticalIndex);

View File

@ -1,12 +1,11 @@
using System.Collections;
using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine;
public class PasswordCatcher : MonoBehaviour
{
private bool passwordForSettings;
private void Start()
public void Initialize()
{
passwordForSettings = SettingsManager.GetBool("PasswordOnSettings", false);
SettingsManager.OnSettingsChanged.AddListener(ApplySettings);

View File

@ -8,8 +8,6 @@ public class PointerMover : MonoBehaviour
private Vector2 startPosition;
private void Start() => startPosition = rect.anchoredPosition;
private void Update()
{
Vector2 newPosition = new Vector2(x: startPosition.x + amplitudeX * Mathf.Sin(Time.time * frequency),