Пароль на настройки готов. Супербот(гроза мобилок) готов

This commit is contained in:
_sega 2026-01-20 17:44:42 +03:00
parent 83c2f05a51
commit 34ca90431b
16 changed files with 2646 additions and 214 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.5024084, b: 0, a: 1}
- _GlowColor: {r: 0, g: 0.5683422, b: 1, 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

@ -13,7 +13,7 @@ MonoBehaviour:
m_Name: 5mistressM3_hard
m_EditorClassIdentifier:
Description: "\u0444\u0438\u0448\u043A\u0430_\u0441\u043B\u043E\u0436\u043D\u044B\u0439"
Depth: 8
Depth: 9
WinBonus: 1000000
RowOfTwoBonus: 0
RowOfThree: 0

View File

@ -0,0 +1,174 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class EnterPasswordPanel : MonoBehaviour
{
int enteredSymbols = 0;
int SymbolsCount = 6;
public AudioClip trueSound;
public AudioClip falseSound;
public AnimationCurve fillCurve;
float clearTimer = 0;
public Image ClearImage;
float exitTimer = 0;
public Image ExitImage;
public string symbols = "";
public List<RectTransform> slots;
public GameObject L1;
public GameObject L2;
public GameObject R1;
public GameObject R2;
public GameObject D1;
public GameObject D2;
private List<GameObject> spawnedObjs = new();
public bool truePassword = false;
private string password;
List<ButtonPinMapping> availableButtons = new List<ButtonPinMapping>
{
ButtonPinMapping.left1,
ButtonPinMapping.left2,
ButtonPinMapping.right1,
ButtonPinMapping.right2,
ButtonPinMapping.down1,
ButtonPinMapping.down2,
};
public void Initialize(string password)
{
truePassword = false;
this.password = password;
}
public void _Update()
{
//p2 очистить
ClearProcess();
ExitProcess();
//получить комбинацию по кнопке
ButtonsProcess();
}
void ClearProcess()
{
if (In.GetButton(ButtonPinMapping.startTwoPlayers)) clearTimer += Time.deltaTime;
else clearTimer -= Time.deltaTime;
clearTimer = Mathf.Clamp(clearTimer, 0.0f, 2.0f);
ProcessImageTimer(ClearImage, clearTimer, 2);
if (clearTimer == 2)
{
clearTimer = 0.0f;
Clear();
}
}
private void Clear()
{
clearTimer = 0;
exitTimer = 0;
enteredSymbols = 0;
symbols = string.Empty;
foreach (var go in spawnedObjs)
{
Destroy(go);
}
spawnedObjs.Clear();
}
private void ExitProcess()
{
if (In.GetButton(ButtonPinMapping.startOnePlayer)) exitTimer += Time.deltaTime;
else exitTimer -= Time.deltaTime;
exitTimer = Mathf.Clamp(exitTimer, 0.0f, 2.0f);
ProcessImageTimer(ExitImage, exitTimer, 2);
if (exitTimer == 2)
{
Clear();
GameManager.instance.stateMachine.ChangeState(new MenuState());
}
}
void ButtonsProcess()
{
if (enteredSymbols >= SymbolsCount) return;
foreach (ButtonPinMapping button in availableButtons)
{
if (In.GetButtonDown(button))
{
string combinationStr = GetStrCombination(button);
symbols+=combinationStr;
DisplaySymbol(combinationStr);
enteredSymbols++;
break;
}
}
if(enteredSymbols == SymbolsCount)
{
if(symbols == password)
{
truePassword = true;
SoundManager.instance.playClip(trueSound);
}
else
{
truePassword = false;
SoundManager.instance.playClip(falseSound);
}
Clear();
//введи все символы надо проверка
}
}
void DisplaySymbol(string symbol)
{
GameObject prefab = symbol switch
{
"L1" => L1,
"L2" => L2,
"R1" => R1,
"R2" => R2,
"A1" => D1,
"A2" => D2,
};
GameObject spawned = Instantiate(prefab, slots[enteredSymbols]);
spawnedObjs.Add(spawned);
}
string GetStrCombination(ButtonPinMapping button)
=> button switch
{
ButtonPinMapping.left1 => "L1",
ButtonPinMapping.left2 => "L2",
ButtonPinMapping.right1 => "R1",
ButtonPinMapping.right2 => "R2",
ButtonPinMapping.down1 => "A1",
ButtonPinMapping.down2 => "A2",
_ => null
};
void ProcessImageTimer(Image image, float time, float maxtime)
=> image.fillAmount = fillCurve.Evaluate(time / maxtime);
}

View File

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

View File

@ -67,11 +67,20 @@ public class BotThinkingState : IState
}
public bool displayed = false;
bool animationStarted = false;
float startAnimTime;
public void update()
{
//Алгоритм досчитал
//подсчет времени
if(calculatedColumn!= -1 && !displayed)
{
Debug.Log($"Думал: {Time.time - startTime}");
displayed = true;
}
if (calculatedColumn != -1 && Time.time - startTime > timeToThink)
{
if (!animationStarted)
@ -101,6 +110,30 @@ public class BotThinkingState : IState
}
void calc()
{
calculatedColumn = Solver.FindBestMove(GameManager.fieldModel.fieldArr, GameManager.instance.currentPlayer);
//calculatedColumn = Solver.FindBestMove(GameManager.fieldModel.fieldArr, GameManager.instance.currentPlayer);
GameManager gm = GameManager.instance;
//Судя по счету мы находимся на последнем боте.
bool OnBossByScore = gm.vsBotScore == gm.botsAmount - 1;
bool IsHardCommonDifficulty = SettingsManager.GetString("Difficulty", "Средняя") == "Сложная";
bool IsUpperCashDifficulty = SettingsManager.GetString("BaseBotDifficulty", "Повышенная") == "Повышенная";
bool NeedSuperPreset = OnBossByScore && (IsHardCommonDifficulty || IsUpperCashDifficulty);
Debug.Log($"Использовать суперсложность: {NeedSuperPreset}\nСейчас босс: {OnBossByScore}\nСложная сложность: {IsHardCommonDifficulty}\nВключен режим заработка: {IsUpperCashDifficulty}\n");
if (NeedSuperPreset)
{
calculatedColumn = SolverV2.FindBestMove(GameManager.fieldModel.fieldArr, GameManager.instance.currentPlayer);
}
else
{
calculatedColumn = Solver.FindBestMove(GameManager.fieldModel.fieldArr, GameManager.instance.currentPlayer);
}
}
}

View File

@ -1,17 +1,98 @@
using UnityEngine;
using System.Collections.Generic;
using UnityEngine;
public class CheckSettingsPasswordState : IState
{
EnterPasswordPanel panel;
public void enter()
{
Debug.Log("[ЗДЕСЬ БУДЕТ ПРОВЕРКА ПАРОЛЯ]");
GameManager.instance.stateMachine.ChangeState(new SettingsState());
panel = GameManager.instance.enterPasswordPanel;
Debug.Log("[Проход в настройки]");
//Пароль не установлен.
bool Pwd = SettingsManager.GetBool("PasswordOnSettings", false);
if (!Pwd)
{
Debug.Log("[Пароля нет, заходим братья]");
GameManager.instance.stateMachine.ChangeState(new SettingsState());
return;
}
//Пароль есть.
//Получить пароль.
string password = ExternalFilesGetter.GetSettingsPassword();
//Если он не валидный, то сбросить настройку и пропустить.
if (password == null)
{
Debug.Log("[Файла пароля нет. Сброс пароля. Заход в настройки]");
disableCheck();
GameManager.instance.stateMachine.ChangeState(new SettingsState());
return;
}
if (PasswordValid(password))
{
// если валидный, то запускаем ввод пароля
panel.gameObject.SetActive(true);
panel.Initialize(password);
}
else
{
Debug.Log("[пароль невалидный. Сброс пароля. Заход в настройки]");
disableCheck();
ExternalFilesGetter.SetPassword("");
GameManager.instance.stateMachine.ChangeState(new SettingsState());
}
}
private static void disableCheck()
{
Setting setting = SettingsManager.Container.TryGetSetting("PasswordOnSettings");
setting.ChangeValue(-1);//ставим false
SettingsManager.OnSettingsChanged?.Invoke();
}
public void exit()
{
panel.gameObject.SetActive(false);
}
public void update()
{
panel._Update();
if (panel.truePassword)
{
GameManager.instance.stateMachine.ChangeState(new SettingsState());
}
}
}
private bool PasswordValid(string password)
{
if(password.Length!=12) return false;
List<string> combinations = SplitPasswordIntoPairs(password);
List<string> validCombinations = new List<string> { "L1", "L2", "R1", "R2", "A1", "A2", "P1", "P2" };
foreach (string combination in combinations)
{
if (!validCombinations.Contains(combination)) return false;
}
return true;
}
List<string> SplitPasswordIntoPairs(string password)
{
List<string> result = new List<string>();
for (int i = 0; i < password.Length; i += 2)
{
result.Add(password.Substring(i, 2));
}
return result;
}
}

View File

@ -144,7 +144,7 @@ public class MenuState : IState
//Заход в настройки
if (ShouldGotosettings())
{
SoundManager.instance.playSwitch();
SoundManager.instance.playChoose();
//gm.stateMachine.ChangeState(new SettingsState());
gm.stateMachine.ChangeState(new CheckSettingsPasswordState());
return;

View File

@ -425,6 +425,7 @@ public class GameManager : MonoBehaviour
public MovesAndTimeCounter movesAndTimeCounter;
public GameObject setPasswordPanel;
public EnterPasswordPanel enterPasswordPanel;
void Awake()
{

486
Assets/Scripts/SolverV2.cs Normal file
View File

@ -0,0 +1,486 @@
using System;
using System.Collections.Generic;
using System.Numerics;
/// <summary>
/// Супер-сильный солвер 4-в-ряд на битбордах + Negamax(AlphaBeta) + TT + итеративное углубление.
/// Возвращает индекс колонки 0..6.
/// </summary>
public static class SolverV2
{
// Поле 6x7 (стандарт Connect4)
private const int WIDTH = 7;
private const int HEIGHT = 6;
private const int H1 = HEIGHT + 1; // 7: с "сентинел" битом на верх колонки
private const int MAX_MOVES = WIDTH * HEIGHT; // 42
/// <summary>
/// Можешь крутить глубину снаружи (чем выше — тем сильнее, но медленнее).
/// Реально "очень высокие" глубины становятся возможны за счёт TT и битбордов.
/// </summary>
public static int MaxDepth = 21;
/// <summary>
/// Ограничение на размер TT (чтобы не раздувать память). При переполнении — чистим.
/// </summary>
public static int TranspositionMaxEntries = 1_200_000;
// Порядок ходов: центр -> к краям (лучше и для игры, и для отсечений)
private static readonly int[] MoveOrder = { 3, 2, 4, 1, 5, 0, 6 };
// Битовые маски по колонкам
private static readonly ulong[] BottomMask = new ulong[WIDTH];
private static readonly ulong[] ColumnMask = new ulong[WIDTH];
private static readonly ulong[] TopPlayableMask = new ulong[WIDTH]; // верхняя игровая клетка (6-я строка)
// Все выигрышные "четвёрки" (для быстрой эвристики)
private static readonly ulong[] WinningLineMasks;
// TT
private enum Bound : byte { Exact, Lower, Upper }
private struct TTEntry
{
public short Value; // -21..21 + эвристика
public byte Depth; // глубина, на которой посчитано
public Bound Bound;
public byte BestCol; // лучший ход (для ordering)
}
private static readonly Dictionary<ulong, TTEntry> TT = new Dictionary<ulong, TTEntry>(1 << 20);
static SolverV2()
{
// Инициализация масок колонок
for (int c = 0; c < WIDTH; c++)
{
BottomMask[c] = 1UL << (c * H1);
ColumnMask[c] = ((1UL << HEIGHT) - 1UL) << (c * H1); // 6 бит игрового столбца
TopPlayableMask[c] = 1UL << (c * H1 + (HEIGHT - 1)); // верхняя игровая клетка (row=5)
}
// Генерация всех выигрышных линий (четвёрок)
WinningLineMasks = BuildWinningMasks();
}
/// <summary>
/// Главный метод: верни индекс колонки 0..6, куда бросать фишку.
/// </summary>
public static int FindBestMove(CellState[,] board, CellState currentPlayer)
{
if (board == null) throw new ArgumentNullException(nameof(board));
if (board.GetLength(0) != HEIGHT || board.GetLength(1) != WIDTH)
throw new ArgumentException($"Ожидается board размера [{HEIGHT},{WIDTH}]");
// Конвертируем в битборды
ulong p1 = 0, p2 = 0;
for (int r = 0; r < HEIGHT; r++)
{
for (int c = 0; c < WIDTH; c++)
{
var cs = board[r, c];
if (cs == CellState.Empty) continue;
// В битбордах row=0 снизу. В массиве чаще row=0 сверху => инвертируем
int br = (HEIGHT - 1) - r; // bottom=0
ulong bit = 1UL << (c * H1 + br);
if (cs == CellState.Player1) p1 |= bit;
else if (cs == CellState.Player2) p2 |= bit;
}
}
ulong mask = p1 | p2;
if (mask == 0)
{
// На пустом поле лучший ход — центр
return 3;
}
// Камень текущего игрока
ulong currentBits = (currentPlayer == CellState.Player1) ? p1 : p2;
var pos = new Position(currentBits, mask);
// Если TT распух — чистим (простая стратегия)
if (TT.Count > TranspositionMaxEntries) TT.Clear();
// На всякий: если центр забит и вообще нет ходов
if (pos.PossibleMovesMask() == 0) return FirstLegalColumn(pos);
// Итеративное углубление
int bestCol = FirstLegalColumn(pos);
int maxDepth = Math.Min(MaxDepth, pos.RemainingMoves());
// aspiration: можно добавить, но и так хорошо
for (int depth = 1; depth <= maxDepth; depth++)
{
int alpha = -INF;
int beta = INF;
int localBestCol = bestCol;
int localBestScore = -INF;
// ordering: если в TT есть лучший ход для корня — попробуем первым
int ttBest = TryGetTTBestMove(pos, out int ttCol) ? ttCol : -1;
// Ходы (сначала ttBest, потом центр-ориентированный порядок)
Span<int> cols = stackalloc int[WIDTH];
int n = BuildOrderedMoves(pos, cols, ttBest);
for (int i = 0; i < n; i++)
{
int col = cols[i];
ulong move = pos.MoveMask(col);
if (move == 0) continue;
var child = pos;
child.Play(move);
int score = -Negamax(child, depth - 1, -beta, -alpha);
if (score > localBestScore)
{
localBestScore = score;
localBestCol = col;
}
if (score > alpha) alpha = score;
if (alpha >= beta) break; // отсечение
}
bestCol = localBestCol;
// Если нашли гарантированный выигрыш — можно заканчивать раньше
if (localBestScore >= WinScore(pos))
break;
}
return bestCol;
}
// -------------------- Core search --------------------
private const int INF = 10_000;
// Оценка победы "чем быстрее — тем лучше"
private static int WinScore(Position p)
{
// Максимальный выигрыш в терминах "сколько ходов до конца"
// В классических решателях Connect4 используют диапазон [-21..21]
return (p.RemainingMoves() + 1) / 2;
}
private static int LossScore(Position p) => -WinScore(p);
private static int Negamax(Position p, int depth, int alpha, int beta)
{
// Если соперник уже выиграл предыдущим ходом, мы в проигрыше
if (HasFour(p.OpponentBits()))
return LossScore(p);
ulong possible = p.PossibleMovesMask();
if (possible == 0)
return 0; // ничья
// Быстрая проверка: есть ли выигрышный ход прямо сейчас
if (p.HasImmediateWinningMove())
return WinScore(p);
if (depth <= 0)
return Evaluate(p);
// TT probe
ulong key = p.Key();
if (TT.TryGetValue(key, out TTEntry entry) && entry.Depth >= depth)
{
int v = entry.Value;
switch (entry.Bound)
{
case Bound.Exact: return v;
case Bound.Lower: alpha = Math.Max(alpha, v); break;
case Bound.Upper: beta = Math.Min(beta, v); break;
}
if (alpha >= beta) return v;
}
int originalAlpha = alpha;
int bestCol = 255;
int bestValue = -INF;
// ordering: TT best first
int ttBest = (entry.BestCol <= 6) ? entry.BestCol : -1;
Span<int> cols = stackalloc int[WIDTH];
int n = BuildOrderedMoves(p, cols, ttBest);
for (int i = 0; i < n; i++)
{
int col = cols[i];
ulong move = p.MoveMask(col);
if (move == 0) continue;
var child = p;
child.Play(move);
int score = -Negamax(child, depth - 1, -beta, -alpha);
if (score > bestValue)
{
bestValue = score;
bestCol = col;
}
if (score > alpha) alpha = score;
if (alpha >= beta) break;
}
// Store TT
TTEntry store = new TTEntry
{
Value = (short)bestValue,
Depth = (byte)depth,
BestCol = (byte)(bestCol == 255 ? 3 : bestCol),
Bound = Bound.Exact
};
if (bestValue <= originalAlpha) store.Bound = Bound.Upper;
else if (bestValue >= beta) store.Bound = Bound.Lower;
TT[key] = store;
return bestValue;
}
// -------------------- Evaluation --------------------
private static int Evaluate(Position p)
{
// Быстрая эвристика: сколько "открытых" выигрышных линий у текущего игрока минус у оппонента,
// плюс небольшой приоритет центра (чтобы игра была сильнее на малой глубине).
ulong cur = p.CurrentBits;
ulong opp = p.OpponentBits();
int curOpen = 0;
int oppOpen = 0;
for (int i = 0; i < WinningLineMasks.Length; i++)
{
ulong m = WinningLineMasks[i];
// если в линии есть камни оппонента — линия не годится для текущего
if ((opp & m) == 0) curOpen++;
// если в линии есть камни текущего — линия не годится для оппонента
if ((cur & m) == 0) oppOpen++;
}
int centerBonus = CenterControlBonus(cur) - CenterControlBonus(opp);
// Масштабируем, чтобы не перебить "мат" значения (±21)
// 1) open-lines дают "стратегию", 2) центр слегка помогает
int score = (curOpen - oppOpen) + 2 * centerBonus;
// Сжимаем в разумный диапазон
return Math.Clamp(score / 4, -20, 20);
}
private static int CenterControlBonus(ulong bits)
{
// колонка 3 (центр)
int c = 3;
ulong col = ((1UL << HEIGHT) - 1UL) << (c * H1);
int count = PopCount(bits & col);
return count; // чем больше в центре, тем лучше
}
// -------------------- Bitboard Position --------------------
private struct Position
{
// Биты текущего игрока (того, кто ходит сейчас)
public ulong CurrentBits;
// Биты всех занятых клеток
public ulong Mask;
public Position(ulong current, ulong mask)
{
CurrentBits = current;
Mask = mask;
}
public int RemainingMoves() => MAX_MOVES - PopCount(Mask);
public ulong OpponentBits() => Mask ^ CurrentBits;
public ulong Key()
{
// Достаточно устойчивый ключ (не крипто), быстрый
return CurrentBits ^ (Mask << 1);
}
public ulong PossibleMovesMask()
{
// Все возможные ходы: для каждой колонки — бит "самого нижнего пустого слота"
ulong moves = 0;
for (int c = 0; c < WIDTH; c++)
moves |= MoveMask(c);
return moves;
}
public ulong MoveMask(int col)
{
// move = (mask + bottomMask) & columnMask
// даёт бит первой пустой ячейки в колонке, либо 0 если колонка полная
ulong m = (Mask + BottomMask[col]) & ColumnMask[col];
return m;
}
public void Play(ulong move)
{
// классическая схема:
// 1) после хода "текущий игрок" меняется => CurrentBits ^= Mask
// 2) добавляем камень => Mask |= move
CurrentBits ^= Mask;
Mask |= move;
}
public bool HasImmediateWinningMove()
{
// проверяем каждый ход: приводит ли к 4-в-ряд у текущего игрока
for (int i = 0; i < WIDTH; i++)
{
int c = MoveOrder[i];
ulong mv = MoveMask(c);
if (mv == 0) continue;
ulong after = CurrentBits | mv;
if (HasFour(after)) return true;
}
return false;
}
}
// -------------------- Helpers --------------------
private static int BuildOrderedMoves(Position p, Span<int> cols, int ttBest)
{
int n = 0;
// 1) TT best первым (если легален)
if (ttBest >= 0 && ttBest < WIDTH && p.MoveMask(ttBest) != 0)
cols[n++] = ttBest;
// 2) остальное — центр->края, без дубликатов
for (int i = 0; i < MoveOrder.Length; i++)
{
int c = MoveOrder[i];
if (c == ttBest) continue;
if (p.MoveMask(c) != 0)
cols[n++] = c;
}
return n;
}
private static bool TryGetTTBestMove(Position p, out int bestCol)
{
if (TT.TryGetValue(p.Key(), out var e) && e.BestCol <= 6)
{
bestCol = e.BestCol;
return true;
}
bestCol = -1;
return false;
}
private static int FirstLegalColumn(Position p)
{
for (int i = 0; i < MoveOrder.Length; i++)
{
int c = MoveOrder[i];
if (p.MoveMask(c) != 0) return c;
}
return 0;
}
private static bool HasFour(ulong b)
{
// Вертикаль (shift 1)
ulong m = b & (b >> 1);
if ((m & (m >> 2)) != 0) return true;
// Горизонталь (shift H1)
m = b & (b >> H1);
if ((m & (m >> (2 * H1))) != 0) return true;
// Диагональ /
m = b & (b >> (H1 - 1));
if ((m & (m >> (2 * (H1 - 1)))) != 0) return true;
// Диагональ \
m = b & (b >> (H1 + 1));
if ((m & (m >> (2 * (H1 + 1)))) != 0) return true;
return false;
}
private static int PopCount(ulong x)
{
#if NET5_0_OR_GREATER
return (int)BitOperations.PopCount(x);
#else
// fallback
int c = 0;
while (x != 0) { x &= (x - 1); c++; }
return c;
#endif
}
private static ulong[] BuildWinningMasks()
{
var list = new List<ulong>(100);
// Перебор всех 4-в-ряд масок в нашей бит-разметке
for (int c = 0; c < WIDTH; c++)
{
for (int r = 0; r < HEIGHT; r++)
{
// стартовая клетка: (c,r), где r=0 снизу
int idx = c * H1 + r;
ulong bit = 1UL << idx;
// вертикаль (r..r+3)
if (r + 3 < HEIGHT)
{
ulong m = bit | (bit << 1) | (bit << 2) | (bit << 3);
list.Add(m);
}
// горизонталь (c..c+3)
if (c + 3 < WIDTH)
{
ulong m = bit | (bit << H1) | (bit << (2 * H1)) | (bit << (3 * H1));
list.Add(m);
}
// диагональ \ (c..c+3, r..r+3)
if (c + 3 < WIDTH && r + 3 < HEIGHT)
{
int s = H1 + 1;
ulong m = bit | (bit << s) | (bit << (2 * s)) | (bit << (3 * s));
list.Add(m);
}
// диагональ / (c..c+3, r..r-3) => тут старт должен быть достаточно высоким
if (c + 3 < WIDTH && r - 3 >= 0)
{
int s = H1 - 1;
ulong m = bit | (bit << s) | (bit << (2 * s)) | (bit << (3 * s));
list.Add(m);
}
}
}
return list.ToArray();
}
}

View File

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

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -0,0 +1,23 @@
fileFormatVersion: 2
guid: 48c70e631c1936044be943e214a1a37f
AudioImporter:
externalObjects: {}
serializedVersion: 7
defaultSettings:
serializedVersion: 2
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
preloadAudioData: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@ -0,0 +1,23 @@
fileFormatVersion: 2
guid: 0a17192e2e481bd48bf553f772fdcdb4
AudioImporter:
externalObjects: {}
serializedVersion: 7
defaultSettings:
serializedVersion: 2
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
preloadAudioData: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant: