Реализация новой призовой системы

This commit is contained in:
se_ga 2026-03-12 09:52:44 +03:00
parent 27204baca4
commit 40e46b0317
31 changed files with 1381 additions and 277 deletions

View File

@ -11349,7 +11349,7 @@ Material:
- _ClipRect: {r: -32767, g: -32767, b: 32767, a: 32767}
- _EnvMatrixRotation: {r: 0, g: 0, b: 0, a: 0}
- _FaceColor: {r: 1, g: 1, b: 1, a: 1}
- _GlowColor: {r: 1, g: 0.8115379, b: 0, a: 1}
- _GlowColor: {r: 0, g: 1, b: 0.14974451, a: 1}
- _MaskCoord: {r: 0, g: 0, b: 32767, a: 32767}
- _OutlineColor: {r: 0.554717, g: 0.554717, b: 0.554717, a: 1}
- _ReflectFaceColor: {r: 0, g: 0, b: 0, a: 1}

File diff suppressed because it is too large Load Diff

View File

@ -36,7 +36,8 @@ public class CoinCounter : MonoBehaviour
public void SetRevengePriceVisibility(bool visibility)
{
if(revengeSignGo != null) revengeSignGo.SetActive(visibility);
if(revengeSignGo != null)
revengeSignGo.SetActive(visibility);
int priceRevenge = PlayerPrefs.GetInt("PriceRevenge", 10);
int pricePve = PlayerPrefs.GetInt("PricePVE", 10);

View File

@ -150,6 +150,7 @@ public class EnterPasswordPanel : MonoBehaviour
"R2" => R2,
"A1" => D1,
"A2" => D2,
_ => L1
};
GameObject spawned = Instantiate(prefab, slots[enteredSymbols]);

View File

@ -9,7 +9,7 @@ public class ChipFallingState : IState
const float BOUNCE_SPEEDY_TRESHOLD = 5;
const float MAX_ANGULAR_SPEED = 500;
const bool USE_BOUNCE = false;
bool USE_BOUNCE = false;
int rowIndex;
int colIndex;

View File

@ -0,0 +1,75 @@
using PrizeSystem;
using UnityEngine;
public class PrizeState : IState
{
private GameManager gm;
private IState nextState;
private VitrinaPanel vitrina;
private QrPanel qr;
public PrizeState(IState nextState)
{
this.nextState = nextState;
}
public void enter()
{
Debug.Log("Çàøåë â ïðèç");
gm = GameManager.instance;
gm.timerManager.StopAllTimers();
if(PrizeSystemManager.HasVitrinaPrizeToGive)
{
if(gm.vitrinaPanel.TryGetComponent(out vitrina))
{
vitrina.OnComplete += OnComplete;
gm.vitrinaPanel.gameObject.SetActive(true);
VitrinaPrize prize = PrizeSystemManager.DequeueVitrinaPrize();
gm.vitrinaPanel.Initialize(prize.Boxes);
}
}
else if (PrizeSystemManager.HasQrPrizeToGive)
{
if (gm.qrPanel.TryGetComponent(out qr))
{
qr.OnComplete += OnComplete;
gm.qrPanel.gameObject.SetActive(true);
QrPrize prize = PrizeSystemManager.DequeueQrPrize();
gm.qrPanel.Initialize(prize);
}
}
//äîáàâèòü qr ïàíåëü-âûäàò÷èê.
else
{
gm.stateMachine.ChangeState(nextState);
}
}
private void OnComplete()
{
gm.stateMachine.ChangeState(nextState);
}
public void exit()
{
if (vitrina != null)
{
vitrina.OnComplete -= OnComplete;
vitrina = null;
}
}
public void update()
{
}
}

View File

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

View File

@ -5,7 +5,6 @@ public class VictoryState : IState
{
VictoryScale scale;
GameManager gameManager;
bool givePrize;
TextMeshProUGUI ToMenuLabel;
TextMeshProUGUI TimerLabel;
@ -14,7 +13,6 @@ public class VictoryState : IState
IState nextState;
string timerTextCache;
public void enter()
{
@ -23,7 +21,6 @@ public class VictoryState : IState
gameManager.timerManager.StopAllTimers();
ToMenuLabel = gameManager.ToMenuLabel;
timerTextCache = ToMenuLabel.text;
//ToMenuLabel.text = "До перехода";
TimerLabel = gameManager.TimerLabel;
@ -34,7 +31,6 @@ public class VictoryState : IState
//определяем с какой шкалой мы имеем дело
if (gameManager.gameMode == GameMode.pvp)
{
givePrize = false;
nextState = new ShowWinnerState(gameManager.lastResult);
if (gameManager.currentPlayer == CellState.Player1)
{
@ -50,13 +46,9 @@ public class VictoryState : IState
else
{
//победили ботов
givePrize = true;
scale = gameManager.botScale;
gameManager.winPanel.ShowWin(CellState.Empty);
//это в меню переход. Надо в показ видео и лидерборд
//nextState = new ClearFieldState(true, CellState.Player1);
//А вот это переход в показ видео и заполнение в таблицу лидеров
nextState = new VictoryVideoState(new EnterNameState());
}
@ -70,7 +62,6 @@ public class VictoryState : IState
//выкл анимацию приза
scale.SetIdleState();
scale.winParticles.Stop();
//ToMenuLabel.text = timerTextCache; //не выводит \n почему то
gameManager.winPanel.CloseWin();
ToMenuLabel.gameObject.SetActive(false);
}
@ -80,11 +71,7 @@ public class VictoryState : IState
//полинг инпутов
if (In.GetButtonDownAnyPlayer(PlayerAction.down))
{
/*if (gameManager.gameMode == GameMode.pve)
gameManager.stateMachine.ChangeState(new VictoryVideoState(new EnterNameState()));
else*/
gameManager.stateMachine.ChangeState(nextState);
gameManager.stateMachine.ChangeState(nextState);
}
TimerProcessing();
}
@ -105,7 +92,7 @@ public class VictoryState : IState
TimerLabel.text = getTimeText();
}
string getTimeText()//в утилити бы это вынести
private string getTimeText()//в утилити бы это вынести
{
string minutes = ((int)(TimeRest / 60)).ToString();
string seconds = ((int)(TimeRest % 60)).ToString();

View File

@ -433,6 +433,7 @@ public class GameManager : MonoBehaviour
public SoundManager soundManager;
public VitrinaPanel vitrinaPanel;
public QrPanel qrPanel;
void Awake()
{
Cursor.lockState = CursorLockMode.Locked;

View File

@ -1,5 +1,4 @@
using PrizeSystem;
using Unity.VisualScripting;
using UnityEngine;
public static class EndOfTurnHandler
@ -12,7 +11,7 @@ public static class EndOfTurnHandler
gm = GameManager.instance;
gm.lastResult = result;
bool wrapToPrizeState = false;
IState nextState = new ShowWinnerState(result);//âðåìåííî
@ -29,14 +28,8 @@ public static class EndOfTurnHandler
PveEndroundHandler();
if (gm.currentPlayer == CellState.Player1)
{//àâòîïåðåõîä íà íåêñò áîòà.
//Òóò íóæíî ïåðåéòè â ïðèçîâîå ñîñòîÿíèå
//Ïîòîì èç íåãî èäòè äàëüøå.
ShowWinnerState showWinner = CreateAutoTransitionState(result, 4);
nextState = showWinner;
wrapToPrizeState = true;
nextState = CreateAutoTransitionState(result, 4);
}
}
@ -57,6 +50,9 @@ public static class EndOfTurnHandler
nextState = new StartTurnState();
}
if(wrapToPrizeState)
nextState = new PrizeState(nextState: nextState);
gm.stateMachine.ChangeState(nextState);
}

View File

@ -40,7 +40,7 @@ public static class ComWrapper
AvailablePorts = availablePorts;
if (_lifetimeCts != null) return;
_ = OpenPort(AvailablePorts);
_ = OpenPortAsync(AvailablePorts);
if (h <= 0)
{
Log("Порт не открылся при инициализации");
@ -269,7 +269,7 @@ public static class ComWrapper
_ = StartKeepAliveProcessAsync(ct);
}
private static async Task OpenPort(string[] availablePorts)
private static async Task OpenPortAsync(string[] availablePorts)
{
Log("Инициализация порта");
@ -494,7 +494,7 @@ public static class ComWrapper
CancelAllWaiters();
ClosePort();
OpenPort(AvailablePorts);
OpenPortAsync(AvailablePorts);
if (h <= 0)
{
Log($"Ошибка при переподключении.");

View File

@ -15,6 +15,7 @@ namespace PrizeSystem
[SerializeField] List<GameObject> controlPanels;
[SerializeField] private Color AccentColor;
[SerializeField] private AudioClip ClickClip;
int controlIndex = 0;
@ -116,6 +117,7 @@ namespace PrizeSystem
LightOnPanel(false);
controlIndex = (controlIndex + 1 + controlPanels.Count) % controlPanels.Count;
LightOnPanel(true);
if(ClickClip!= null) {SoundManager.instance.playClip(ClickClip); }
}
private void LightOnPanel(bool on)
@ -164,9 +166,6 @@ namespace PrizeSystem
{
GameManager.instance.stateMachine.ChangeState(new SettingsState());
}
IEnumerator BlinkAnimation(Graphic graphic)
{
while (true)

View File

@ -12,7 +12,7 @@ public class CharacterSelectionPanel : MonoBehaviour, IControl
[SerializeField] TextMeshProUGUI CharacterNameLabel;
[SerializeField] Image CharacterIcon;
[SerializeField] float ChangeCharacterInterval = 0.15f;
[SerializeField] AudioClip ClickSound;
private float LastSwipeTime = 0;
private Character[] characters;
@ -35,6 +35,7 @@ public class CharacterSelectionPanel : MonoBehaviour, IControl
{
if (CanSwipe)
{
if (ClickSound != null) { SoundManager.instance.playClip(ClickSound); }
BeforeCharacterChange?.Invoke(SelectedCharacter);
CharacterIndex = (CharacterIndex + direction + CharactersCount) % CharactersCount;

View File

@ -9,6 +9,7 @@ namespace PrizeSystem{
[SerializeField] TextMeshProUGUI TypeNameLabel;
[SerializeField] float ChangeTypeInterval = 0.15f;
[SerializeField] AudioClip ClickSound;
private int index = 0;
private float LastSwipeTime = 0;
@ -25,6 +26,7 @@ namespace PrizeSystem{
{
if (CanSwipe)
{
if(ClickSound!=null) { SoundManager.instance.playClip(ClickSound); }
index = (index + direction + PrizeTypes.Length) % PrizeTypes.Length;
RefresfUI();
OnTypeChanged?.Invoke(SelectedType);

View File

@ -48,11 +48,12 @@ namespace PrizeSystem
public override void Swipe(int direction)
{
if (CanSwipe)
{
if(Value+direction> Min && Value+direction< Max)
if (Value + direction >= Min && Value + direction <= Max)
{
if(SwitchClip != null) SoundManager.instance.playClip(SwitchClip);
if (SwitchClip != null) SoundManager.instance.playClip(SwitchClip);
}
Value += direction;
@ -67,16 +68,16 @@ namespace PrizeSystem
public override void Tick()
{
bool left = In.GetButtonAnyPlayer(PlayerAction.left);
bool right= In.GetButtonAnyPlayer(PlayerAction.right);
bool right = In.GetButtonAnyPlayer(PlayerAction.right);
if(!(left || right))
if (!(left || right))
{
Delay = MaxDelay;
LastSwipeTime = 0;
}
else
{
Delay = Mathf.Clamp(Delay - Acceleration*Time.deltaTime, MinDelay, MaxDelay);
Delay = Mathf.Clamp(Delay - Acceleration * Time.deltaTime, MinDelay, MaxDelay);
}
}

View File

@ -357,10 +357,9 @@ MonoBehaviour:
Min: 1
Max: 10
MinDelay: 0.15
MaxDelay: 0.5
Acceleration: 0
MaxDelay: 0.4
Acceleration: 0.2
SwitchClip: {fileID: 8300000, guid: 1c48900c9ab0aa8418920a8193050870, type: 3}
Delay: 0
--- !u!1 &8121963000491084903
GameObject:
m_ObjectHideFlags: 0

View File

@ -1479,6 +1479,8 @@ MonoBehaviour:
rankLabel: {fileID: 3175867621395834710}
textInput: {fileID: 1635635785162997950}
AccentColor: {r: 1, g: 0.4398854, b: 0, a: 1}
clickClip: {fileID: 8300000, guid: 1c48900c9ab0aa8418920a8193050870, type: 3}
SwipeInterval: 0.3
--- !u!1 &3113275906872636537
GameObject:
m_ObjectHideFlags: 0
@ -1647,6 +1649,7 @@ RectTransform:
- {fileID: 890072125137875243}
- {fileID: 5899164440865912696}
- {fileID: 5831607291207876570}
- {fileID: 5069836728228170916}
m_Father: {fileID: 5510025155540528801}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
@ -2211,7 +2214,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 100, y: -236}
m_AnchoredPosition: {x: 100, y: -245}
m_SizeDelta: {x: 800, y: 93.48999}
m_Pivot: {x: 0, y: 1}
--- !u!222 &6667019072543580359
@ -2305,6 +2308,11 @@ MonoBehaviour:
- {fileID: 102279635399659491}
frame: {fileID: 5548416305379766684}
alphabet: " \u0410\u0411\u0412\u0413\u0414\u0415\u0401\u0416\u0417\u0418\u0419\u041A\u041B\u041C\u041D\u041E\u041F\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042A\u042B\u042C\u042D\u042E\u042F\u0430\u0431\u0432\u0433\u0434\u0435\u0451\u0436\u0437\u0438\u0439\u043A\u043B\u043C\u043D\u043E\u043F\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044A\u044B\u044C\u044D\u044E\u044F0123456789_."
minInterval: 0.07
maxInterval: 0.3
acceleration: 3
interval: 0.3
ClickClip: {fileID: 8300000, guid: 1c48900c9ab0aa8418920a8193050870, type: 3}
--- !u!1 &4487900830859546338
GameObject:
m_ObjectHideFlags: 0
@ -2683,8 +2691,8 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 106, y: 20}
m_SizeDelta: {x: 200, y: 50}
m_AnchoredPosition: {x: 191.90503, y: 19.155212}
m_SizeDelta: {x: 371.8101, y: 38.3104}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &1166133467696736269
CanvasRenderer:
@ -2714,7 +2722,8 @@ MonoBehaviour:
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: "\u0422\u0435\u043A\u0441\u0442"
m_text: "\u041D\u0430\u0438\u043C\u0435\u043D\u043E\u0432\u0430\u043D\u0438\u0435
\u043F\u0440\u0438\u0437\u0430"
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 3f10bbcf486189d4f95b8de6dc2e2177, type: 2}
m_sharedMaterial: {fileID: 4262305343556741190, guid: 3f10bbcf486189d4f95b8de6dc2e2177, type: 2}
@ -2749,7 +2758,7 @@ MonoBehaviour:
m_fontSizeMax: 64
m_fontStyle: 0
m_HorizontalAlignment: 1
m_VerticalAlignment: 256
m_VerticalAlignment: 1024
m_textAlignment: 65535
m_characterSpacing: 0
m_wordSpacing: 0
@ -3611,7 +3620,7 @@ MonoBehaviour:
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: "\u0420\u0430\u043D\u0433"
m_text: "\u0426\u0435\u043D\u043D\u043E\u0441\u0442\u044C"
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 3f10bbcf486189d4f95b8de6dc2e2177, type: 2}
m_sharedMaterial: {fileID: 4262305343556741190, guid: 3f10bbcf486189d4f95b8de6dc2e2177, type: 2}
@ -3755,6 +3764,147 @@ MonoBehaviour:
m_FillOrigin: 0
m_UseSpriteMesh: 0
m_PixelsPerUnitMultiplier: 1
--- !u!1 &8561605351245038211
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 5069836728228170916}
- component: {fileID: 6237542341363723453}
- component: {fileID: 3701064555661367737}
m_Layer: 5
m_Name: Text (TMP)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &5069836728228170916
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8561605351245038211}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 396805755242335028}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 190.6, y: 50}
m_SizeDelta: {x: 506.4, y: 100}
m_Pivot: {x: 0, y: 1}
--- !u!222 &6237542341363723453
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8561605351245038211}
m_CullTransparentMesh: 1
--- !u!114 &3701064555661367737
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8561605351245038211}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_text: "\u0421\u0430\u043C\u044B\u0439 \u0446\u0435\u043D\u043D\u044B\u0439 \u043F\u0440\u0438\u0437
\u0431\u0443\u0434\u0435\u0442 \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0430\u0442\u044C\u0441\u044F
\u0432 \u043F\u0440\u0430\u0432\u0438\u043B\u0430\u0445 \u0441 \u0438\u043A\u043E\u043D\u043A\u043E\u0439
\u0437\u043E\u043B\u043E\u0442\u043E\u0439 \u043C\u0435\u0434\u0430\u043B\u0438\n\n\u0415\u0441\u043B\u0438
\u0435\u0441\u0442\u044C 2 qr-\u043A\u043E\u0434\u0430 \u0441 \u0437\u043E\u043B\u043E\u0442\u043E\u0439
\u043C\u0435\u0434\u0430\u043B\u044C\u044E,\n\u0442\u043E \u0446\u0435\u043D\u043D\u0435\u0435
\u0442\u043E\u0442, \u043A\u043E\u0442\u043E\u0440\u044B\u0439 \u0443 \u0431\u043E\u043B\u0435\u0435
\u0441\u0438\u043B\u044C\u043D\u043E\u0433\u043E \u0431\u043E\u0442\u0430"
m_isRightToLeft: 0
m_fontAsset: {fileID: 11400000, guid: 3f10bbcf486189d4f95b8de6dc2e2177, type: 2}
m_sharedMaterial: {fileID: 4262305343556741190, guid: 3f10bbcf486189d4f95b8de6dc2e2177, type: 2}
m_fontSharedMaterials: []
m_fontMaterial: {fileID: 0}
m_fontMaterials: []
m_fontColor32:
serializedVersion: 2
rgba: 4294967295
m_fontColor: {r: 1, g: 1, b: 1, a: 1}
m_enableVertexGradient: 0
m_colorMode: 3
m_fontColorGradient:
topLeft: {r: 1, g: 1, b: 1, a: 1}
topRight: {r: 1, g: 1, b: 1, a: 1}
bottomLeft: {r: 1, g: 1, b: 1, a: 1}
bottomRight: {r: 1, g: 1, b: 1, a: 1}
m_fontColorGradientPreset: {fileID: 0}
m_spriteAsset: {fileID: 0}
m_tintAllSprites: 0
m_StyleSheet: {fileID: 0}
m_TextStyleHashCode: -1183493901
m_overrideHtmlColors: 0
m_faceColor:
serializedVersion: 2
rgba: 4294967295
m_fontSize: 19.36
m_fontSizeBase: 19.36
m_fontWeight: 400
m_enableAutoSizing: 0
m_fontSizeMin: 16
m_fontSizeMax: 64
m_fontStyle: 0
m_HorizontalAlignment: 1
m_VerticalAlignment: 512
m_textAlignment: 65535
m_characterSpacing: 0
m_wordSpacing: 0
m_lineSpacing: -50
m_lineSpacingMax: 0
m_paragraphSpacing: -12.85
m_charWidthMaxAdj: 0
m_enableWordWrapping: 1
m_wordWrappingRatios: 0.4
m_overflowMode: 0
m_linkedTextComponent: {fileID: 0}
parentLinkedComponent: {fileID: 0}
m_enableKerning: 1
m_enableExtraPadding: 0
checkPaddingRequired: 0
m_isRichText: 1
m_parseCtrlCharacters: 1
m_isOrthographic: 1
m_isCullingEnabled: 0
m_horizontalMapping: 0
m_verticalMapping: 0
m_uvLineOffset: 0
m_geometrySortingOrder: 0
m_IsTextObjectScaleStatic: 0
m_VertexBufferAutoSizeReduction: 0
m_useMaxVisibleDescender: 1
m_pageToDisplay: 1
m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0
m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!1 &8632252750584089712
GameObject:
m_ObjectHideFlags: 0
@ -3792,7 +3942,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 100, y: -339.9}
m_AnchoredPosition: {x: 100, y: -348.9}
m_SizeDelta: {x: 800, y: 83.94061}
m_Pivot: {x: 0, y: 1}
--- !u!222 &8137459614657545606

View File

@ -13,21 +13,62 @@ public class QrTextInput : MonoBehaviour
private QrTextSlot CurrentSlot => slots[index];
private int index = 0;
private float LastSwipeLetter = 0;
[SerializeField] float minInterval = 0.07f;
[SerializeField] float maxInterval = 0.3f;
[SerializeField] float acceleration = 3f;
[SerializeField] private float interval;
[SerializeField] AudioClip ClickClip;
private bool CanSwipe => Time.time - LastSwipeLetter > interval;
private void OnEnable()
{
index = 0;
interval = maxInterval;
}
public void SwitchSlot(int direction)
{
if(direction == 0) {return;}
CurrentSlot.SetActive(false);
index = (index + direction + slots.Count) % slots.Count;
CurrentSlot.SetActive(true);
ClickSound();
}
public void DisableAllSlots()
{
foreach(QrTextSlot slot in slots) { slot.SetActive(false); }
}
public void EnableFirstSlot()
{
index = 0;
CurrentSlot.SetActive(true);
}
private void ClickSound()
{
if (ClickClip != null) SoundManager.instance.playClip(ClickClip);
}
public void SwitchLetter(int direction)
{
if (direction == 0) {return;}
if (!CanSwipe) { return; }
LastSwipeLetter = Time.time;
interval-= acceleration * Time.deltaTime;
interval = Mathf.Clamp(interval, minInterval, maxInterval);
ClickSound();
int currentLetterIndex = alphabet.IndexOf(CurrentSlot.GetText());
if (currentLetterIndex != -1)
{
@ -41,7 +82,17 @@ public class QrTextInput : MonoBehaviour
}
}
private void Update()
{
bool left = In.GetButton(ButtonPinMapping.left1);
bool right = In.GetButton(ButtonPinMapping.right1);
if (!(left || right))
{
interval = maxInterval;
LastSwipeLetter = 0;
}
}
public string GetText()
{
var sb = new StringBuilder();

View File

@ -323,10 +323,9 @@ MonoBehaviour:
Min: 1
Max: 100
MinDelay: 0
MaxDelay: 0.5
MaxDelay: 0.3
Acceleration: 0.2
SwitchClip: {fileID: 8300000, guid: 1c48900c9ab0aa8418920a8193050870, type: 3}
Delay: 0
--- !u!1 &5030279612583269179
GameObject:
m_ObjectHideFlags: 0

View File

@ -250,6 +250,7 @@ MonoBehaviour:
Content: {fileID: 905256846402403460}
TogglePrefab: {fileID: 1876997734204608492, guid: fe164a79739075f429d761ca69f8849e, type: 3}
Pointer: {fileID: 7754005565347381640}
NextToggleClip: {fileID: 8300000, guid: 1c48900c9ab0aa8418920a8193050870, type: 3}
--- !u!1 &3967834049323493430
GameObject:
m_ObjectHideFlags: 0

View File

@ -4,7 +4,6 @@ using UnityEngine.UI;
namespace PrizeSystem
{
//TODO ïðèêëàìïèòü ðàíã íà ñòàðòå
public class QrPrizeInput : AbstractPrizeConfigurator
{
@ -12,12 +11,14 @@ namespace PrizeSystem
[SerializeField] private TextMeshProUGUI rankLabel;
[SerializeField] private QrTextInput textInput;
[SerializeField] private Color AccentColor;
[SerializeField] private AudioClip clickClip;
[SerializeField] private float SwipeInterval = 0.3f;
private int rank = 1;
private SelectedOption currentOption = SelectedOption.Rank;
private float LastSwipe = 0;
private bool CanSwipe => Time.time - LastSwipe > SwipeInterval;
private void OnEnable()
{
@ -25,7 +26,7 @@ namespace PrizeSystem
textInput.Light(Color.black);
rankImage.color = AccentColor;
Display();
DisplayRank();
}
@ -35,7 +36,7 @@ namespace PrizeSystem
{
rank = qr.Rank;
textInput.SetText(qr.PrizeText);
Display();
DisplayRank();
}
}
@ -46,30 +47,40 @@ namespace PrizeSystem
if (currentOption == SelectedOption.Rank) currentOption = SelectedOption.Text;
else if ((currentOption == SelectedOption.Text)) currentOption = SelectedOption.Rank;
TryPlayClick();
if (currentOption == SelectedOption.Rank)
{
textInput.DisableAllSlots();
textInput.Light(Color.black);
rankImage.color = AccentColor;
}
else if (currentOption == SelectedOption.Text)
{
textInput.Light(AccentColor);
rankImage.color = Color.black;
}
}
public override void Swipe(int direction)
{
if (currentOption == SelectedOption.Rank)
{
rank = Mathf.Clamp(rank + direction, 1, GameManager.instance.botsAmount);
Display();
}
else if (currentOption == SelectedOption.Text)
{
textInput.Light(AccentColor);
textInput.EnableFirstSlot();
rankImage.color = Color.black;
}
}
public override void Swipe(int direction)
{
if (currentOption == SelectedOption.Rank)
{
if(direction == 0)
{
LastSwipe = 0;
return;
}
SwipeRank(direction);
}
else if (currentOption == SelectedOption.Text)
{
int leftDirection = 0;
if (In.GetButtonDown(ButtonPinMapping.left1)) leftDirection -= 1;
if (In.GetButtonDown(ButtonPinMapping.right1)) leftDirection += 1;
if (In.GetButton(ButtonPinMapping.left1)) leftDirection -= 1;
if (In.GetButton(ButtonPinMapping.right1)) leftDirection += 1;
int rightDirection = 0;
if (In.GetButtonDown(ButtonPinMapping.left2)) rightDirection -= 1;
@ -80,16 +91,34 @@ namespace PrizeSystem
textInput.SwitchSlot(rightDirection);
}
}
public override Prize GetPrize() => PrizeUtils.CreatePrize(rank, textInput.GetText());
public override void Tick() { }
private void Display()
private void DisplayRank()
{
rankLabel.text = rank.ToString();
//Òàê æå íóæíî äîï èíôó ïî ìåäàëÿì
}
private void SwipeRank(int direction)
{
if(!CanSwipe) return;
int resultRank = rank + direction;
if (resultRank >= 1 && resultRank <= GameManager.instance.botsAmount)
{
rank = resultRank;
TryPlayClick();
DisplayRank();
LastSwipe = Time.time;
}
}
private void TryPlayClick()
{
if (clickClip != null)
SoundManager.instance.playClip(clickClip);
}
enum SelectedOption { Rank, Text }
}

View File

@ -11,6 +11,7 @@ namespace PrizeSystem
[SerializeField] private GameObject TogglePrefab;
[SerializeField] RectTransform Pointer;
[SerializeField] private AudioClip NextToggleClip;
private List<VitrinaToggle> toggles;
private int index = 0;
@ -19,8 +20,11 @@ namespace PrizeSystem
public override void ChangeOption(int direction)
{
//ňóň äîáŕâčňü çâóę
index = (index + 1 + BoxesCount) % BoxesCount;
SetPointerToCurrentToggle();
if(NextToggleClip != null)
SoundManager.instance.playClip(NextToggleClip);
}
public override void Configure(Prize prize)

View File

@ -1,4 +1,4 @@
using System.Collections;
using System;
using System.Collections.Generic;
using UnityEngine;
@ -6,6 +6,7 @@ public class VitrinaPanel : MonoBehaviour
{
private bool initialized = false;
//çàïðîñèòü êîðîáêè, ïðîâåðèòü êàêèå òðåáóåòñÿ, íàéòè ïåðåñå÷åíèå. Åñëè íåò, òî âîçâðàò.
public event Action OnComplete;
[SerializeField] private Transform BoxesRoot;
[SerializeField] private GameObject BoxViewPrefab;
@ -20,11 +21,7 @@ public class VitrinaPanel : MonoBehaviour
private void OnEnable()
{
initialized = false;
int[] boxes = { 1, 3, 5 };
Initialize(boxes);
initialized = false;
}
private void OnDisable()
{
@ -34,6 +31,7 @@ public class VitrinaPanel : MonoBehaviour
public void Initialize(int[] requiredBoxed)
{
if (initialized) return;
//òóò ïðîâåðêà ÷òî åñòü òàêèå êîðîáêè
pointerIndex = 0;
GenerateBoxes(requiredBoxed);
@ -67,7 +65,7 @@ public class VitrinaPanel : MonoBehaviour
private void ClearBoxes()
{
foreach (var box in generatedBoxes)
Destroy(box);
Destroy(box.gameObject);
generatedBoxes.Clear();
}
@ -75,14 +73,14 @@ public class VitrinaPanel : MonoBehaviour
{
if (!initialized) return;
var input = CollectInputs();
if(input.direction != 0)
if (input.direction != 0)
{
int count = generatedBoxes == null ? 0 : generatedBoxes.Count;
//îòîáðàçèòü èçìåíåíèÿ
CurrentBox.SetEnabled(false);
CurrentBox.shake =false;
CurrentBox.shake = false;
timer = 0;
pointerIndex = (pointerIndex + input.direction + count) % count;
@ -104,8 +102,11 @@ public class VitrinaPanel : MonoBehaviour
if (timer >= timeToAct)
{
Debug.Log("Äåéñòâèå");
_ = PrizeStandController.OpenBoxAsync(pointerIndex + 1);
timer = 0;
OnComplete?.Invoke();
gameObject.SetActive(false);
}
}

View File

@ -14,34 +14,36 @@ namespace PrizeSystem
static string FILE_PATH => Path.Combine(Application.persistentDataPath, CHARACTERS_PRIZES);
static int CharactersAmount => GameManager.instance.botsAmount;
private static List<Prize> cachedPrizes;
public static List<Prize> LoadPrizes()
{
if (cachedPrizes != null)
return cachedPrizes;
if (PrizeSystemManager.cachedPrizes != null)
return PrizeSystemManager.cachedPrizes;
List<Prize> prizes;
try
{
if (File.Exists(FILE_PATH))
{
string fileString = File.ReadAllText(FILE_PATH);
cachedPrizes = DeserializePrizes(fileString);
prizes = DeserializePrizes(fileString);
}
else
{
Debug.Log($"Файл {FILE_PATH} не найден, создаю с призами по умолчанию");
cachedPrizes = GetDefaultPrizes();
SavePrizes(cachedPrizes);
prizes = GetDefaultPrizes();
SavePrizes(prizes);
}
}
catch (Exception e)
{
Debug.LogError($"Ошибка загрузки призов: {e.Message}");
cachedPrizes = GetDefaultPrizes();
prizes = GetDefaultPrizes();
}
return cachedPrizes;
PrizeSystemManager.SetPrizesCache(prizes);
return prizes;
}
/// <summary>
@ -53,6 +55,7 @@ namespace PrizeSystem
string serialized = SerializePrizes(prizes);
Debug.Log($"serialized: {serialized}");
File.WriteAllText(FILE_PATH, serialized);
PrizeSystemManager.SetPrizesCache(prizes);
}
@ -76,7 +79,7 @@ namespace PrizeSystem
public static List<Prize> DeserializePrizes(string serialized)
{
List<Prize> prizes = new();
string[] lines = serialized.Split('\n');
if (lines.Length != CharactersAmount)
{
@ -99,11 +102,11 @@ namespace PrizeSystem
{
string stripped = line.Substring("Qr:".Length);
string[] entries = stripped.Split(',');
int rank = int.Parse(entries[0]);
string text = entries[1];
prizes.Add(PrizeUtils.CreatePrize(rank,text));
prizes.Add(PrizeUtils.CreatePrize(rank, text));
}
else
{//считаемый приз

View File

@ -1,4 +1,5 @@
using System.Collections;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
@ -32,13 +33,16 @@ namespace PrizeSystem
public static string SpecialPrizeCounter = "SpecialCounter";
public static event Action<List<Prize>> PrizesChanged;
private static PrizeSystemManager instance;
private static bool prizing = false;
public static List<Prize> cachedPrizes { get; private set; }
//Прописать тут очереди.
private static Queue<QrPrize> qrPrizes;
private static Queue<VitrinaPrize> vitrinaPrizes;
public static bool HasQrPrizeToGive => qrPrizes.Count > 0;
public static bool HasVitrinaPrizeToGive => vitrinaPrizes.Count > 0;
@ -59,6 +63,11 @@ namespace PrizeSystem
public static VitrinaPrize DequeueVitrinaPrize() => HasVitrinaPrizeToGive ? vitrinaPrizes.Dequeue() : null;
public static void SetPrizesCache(List<Prize> prizes)
{
cachedPrizes = prizes;
PrizesChanged?.Invoke(prizes);
}
public static void GivePrize(Prize prize)
{
if (prize == null)
@ -67,9 +76,9 @@ namespace PrizeSystem
}
//Если призы отключены в принципе, то не выдаем.
bool prizingEnabled = SettingsManager.GetBool("Prizing", false);
if (!prizingEnabled) return;
if (!prizingEnabled) return;
Debug.Log($"Поступил заказ приз: {prize.Body}");
@ -87,7 +96,7 @@ namespace PrizeSystem
{
vitrinaPrizes.Enqueue(vitrinaPrize);
}
else if(prize is QrPrize qrPrize)
else if (prize is QrPrize qrPrize)
{
qrPrizes.Enqueue(qrPrize);
}
@ -99,10 +108,10 @@ namespace PrizeSystem
private string StopHopperCommand => ComWrapper.BoardVersion switch { 1 => "302", 2 => "300", _ => "302" };
private IEnumerator PrizingProcess(int amount, CountablePrizeType Type)
{
if (prizing)
{
if (prizing)
{
Debug.LogError("Уже идет выдача приза. Повторная выдача отключена");
yield break;
yield break;
}
prizing = true;
@ -117,7 +126,7 @@ namespace PrizeSystem
float timeout = 10;
Debug.Log($"Включаю мотор хоппера: {StartHopperCommand}");
ComWrapper.Send(StartHopperCommand);//включаем мотор
@ -138,7 +147,7 @@ namespace PrizeSystem
}
//Выключаем мотор
Debug.Log($"Выключаю мотор: {StopHopperCommand}");
ComWrapper.Send(StopHopperCommand);
Debug.Log("Закончил. Успех: " + success);
@ -234,7 +243,7 @@ namespace PrizeSystem
if (!SoundNotification) return;
if (PrizeNotificationSounds == null || PrizeNotificationSounds.Count == 0) return;
int random = Random.Range(0, PrizeNotificationSounds.Count);
int random = UnityEngine.Random.Range(0, PrizeNotificationSounds.Count);
AudioClip notification = PrizeNotificationSounds[random];
SoundManager.instance.playClip(notification);
}

View File

@ -0,0 +1,99 @@
using PrizeSystem;
using System;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class QrPanel : MonoBehaviour
{
private bool initialized = false;
public event Action OnComplete;
[SerializeField] private Image QrImage;
[SerializeField] private TextMeshProUGUI Label;
[SerializeField] private float timer = 0;
private float timeToAct = 3;
private void OnEnable()
{
initialized = false;
}
private void OnDisable()
{
initialized = false;
Clear();
}
public void Initialize(Prize prize)
{
if (initialized) return;
if (prize is QrPrize qrPrize)
{
string message = $"Çäðàâñòâóéòå! ß ïîáåäèë íà àïïàðàòå {PlayerPrefs.GetString("Serial")}. Æäó ïðèç!" +
$" Äàòà âûèãðûøà: {DateTime.Now:dd.MM.yyyy HH:mm}. " +
$"Ïðèç: {qrPrize.PrizeText}";
message = workOnSuffix(message);
message = "https://t.me/+" + PlayerPrefs.GetString("Number")+"?text=" + 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));
QrImage.sprite = sprite;
Label.text = $"Âàø âûèãðûø: {qrPrize.PrizeText}";
}
else
{
OnComplete?.Invoke();
}
initialized = true;
}
private void Clear()
{
}
private void Update()
{
if (!initialized) return;
var input = CollectInputs();
if (input)
{
timer = Mathf.Clamp(timer + Time.deltaTime, 0, timeToAct);
}
else
{
timer = 0;
}
if (timer >= timeToAct)
{
OnComplete?.Invoke();
gameObject.SetActive(false);
}
}
bool CollectInputs()
{
bool action = In.GetButtonAnyPlayer(PlayerAction.left);
return action;
}
string workOnSuffix(string suffix)
{
suffix = suffix.Replace("%", "%25")
.Replace("?", "%3F")
.Replace(" ", "%20")
.Replace("!", "%21")
.Replace("\"", "%22");
return suffix;
}
}

View File

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

View File

@ -20,15 +20,5 @@ public static class QrMaker
tex.Apply(false, false);
return tex;
}
/*
// Сохранить как PNG-файл
public static string SavePng(string text, string filePath, int ppm = 8)
{
using var gen = new QRCodeGenerator();
using var data = gen.CreateQrCode(text, QRCodeGenerator.ECCLevel.M);
var png = new PngByteQRCode(data);
byte[] bytes = png.GetGraphic(ppm, "#000000", "#FFFFFF", true);
File.WriteAllBytes(filePath, bytes);
return filePath;
}*/
}

View File

@ -1,6 +1,7 @@
using PrizeSystem;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
@ -12,29 +13,66 @@ public class SpecialPrizeToggler : MonoBehaviour
[SerializeField] Color enabledColor;
[SerializeField] Color disabledColor;
private void OnEnable() => StartCoroutine(Check());
[SerializeField] private TextMeshProUGUI PrizeText;
private void OnDisable() => StopAllCoroutines();
private void OnEnable() => PrizeSystemManager.PrizesChanged += Refresh;
private void OnDisable() => PrizeSystemManager.PrizesChanged -= Refresh;
IEnumerator Check()
private void Refresh(List<Prize> prizes)
{
while (true)
var qrPrizes = CollectQrPrizes(prizes);
if (NeedToDisplay(qrPrizes))
{
SetVisibilityBySettings();
yield return new WaitForSeconds(5);
PrizeText.text = GetMostRankedPrize(qrPrizes).PrizeText;
SetColorToGraphics(enabledColor);
}
else
{
SetColorToGraphics(disabledColor);
}
}
void SetVisibilityBySettings()
List<QrPrize> CollectQrPrizes(List<Prize> prizes)
{
bool visibility = PrizeSerializer.LoadPrizes()[^1].PrizeType == PrizeType.Qr;
Color color = visibility ? enabledColor : disabledColor;
List<QrPrize> qrPrizes = new();
foreach (Prize prize in prizes)
if (prize is QrPrize qr)
qrPrizes.Add(qr);
return qrPrizes;
}
private bool NeedToDisplay(List<QrPrize> qrPrizes)
{
if(!SettingsManager.GetBool("Prizing", false)) return false;
if(qrPrizes.Count == 0) return false;
return true;
}
private void SetColorToGraphics(Color color)
{
foreach(var g in graphics)
{
g.color = color;
}
}
public QrPrize GetMostRankedPrize(List<QrPrize> qrPrizes)
{
if (qrPrizes == null || qrPrizes.Count == 0)
return null;
QrPrize maxPrize = qrPrizes[0];
for (int i = 1; i < qrPrizes.Count; i++)
{
if (qrPrizes[i].Rank >= maxPrize.Rank)
{
maxPrize = qrPrizes[i];
}
}
return maxPrize;
}
}