diff --git a/Assets/Scripts.meta b/Assets/Scripts.meta new file mode 100644 index 0000000..bad281c --- /dev/null +++ b/Assets/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5c194c683aa28491a8619be39f6eb721 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Game.meta b/Assets/Scripts/Game.meta new file mode 100644 index 0000000..7cb8ef5 --- /dev/null +++ b/Assets/Scripts/Game.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 83d33fbff670449c3946494137623be9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Game/DerivativePopAnimator.cs.meta b/Assets/Scripts/Game/DerivativePopAnimator.cs.meta new file mode 100644 index 0000000..1ab328a --- /dev/null +++ b/Assets/Scripts/Game/DerivativePopAnimator.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 1af5b27b1c8234106ab2bc0f7907f835 \ No newline at end of file diff --git a/First Principles/Assets/Resources/Localization/MathArticle/en.txt b/First Principles/Assets/Resources/Localization/MathArticle/en.txt index 2a46f31..54a23c9 100644 --- a/First Principles/Assets/Resources/Localization/MathArticle/en.txt +++ b/First Principles/Assets/Resources/Localization/MathArticle/en.txt @@ -1,7 +1,9 @@ +@@SECTION=intro Math concepts — in-game reader The game First Principles takes its name from public remarks by Elon Musk on a first-principles approach to business and to solving problems in life and work—then teaches calculus-first ideas on the graph as a matching metaphor. Use Math concepts while playing, or Math tips & snippets on Level select — same scrollable notes. Tap the dark backdrop or Close to dismiss. +@@SECTION=how_graph How this game teaches calculus (read the graph while you play) Main curve — the thick path on the Cartesian grid is \(y = f(x)\) for this stage. Your character tries to stand on platforms that follow that shape. The Equation label (when visible) names the rule being plotted. @@ -17,9 +19,11 @@ Everything below is a topic glossary you can skim between deaths or after finishing a graph — plus a First principles thinking (business) section before exam prep. +@@SECTION=s1 1. Derivatives = slope & rate The derivative \(f'(x)\) measures how steeply \(f(x)\) rises or falls. In physics it is often a rate: how fast position changes (velocity), how fast temperature changes along a bar, etc. In this game, the derivative helps decide where the ground exists. +@@SECTION=rules ──────── Differentiation rules — your skill tree ──────── These are the combo moves for turning \(f(x)\) into \(f'(x)\) without rebuilding from the limit every time. Read them like perks that change how your main curve and derivative HUD stay in sync. @@ -43,6 +47,7 @@ If \(y = f(g(x))\), then \(\displaystyle \frac{dy}{dx} = f'(g(x))\cdot g'(x)\). The game still draws \(f'\) with a numeric sampler on wild stages, but these identities explain why textbook curves snap into clean forms — and what AP / TMUA expects you to simplify before you sketch. Longer write-up: docs/derivative-rules.md. +@@SECTION=int_block ──────── Integrals: definite vs indefinite — score vs loadout ──────── Indefinite \(\displaystyle \int f(x)\,dx\) asks for an antiderivative — a whole family \(F(x)+C\) whose derivative is \(f\). Think loadout class: many valid builds differ by +\(C\) (same gameplay up to vertical shift in \(F\)). Definite \(\displaystyle \int_a^b f(x)\,dx\) is a single number (signed area from \(a\) to \(b\)) — like a run score for one fixed segment. No “+\(C\)” in the answer: endpoints pin it down. @@ -54,42 +59,55 @@ Rectangles (left / right / midpoint) estimate the definite score before y More detail: docs/definite-indefinite-integrals.md. (Graphing calculator / FTC proofs — see course notes; this is the game glossary.) +@@SECTION=s2 2. Parabola (power / quadratic) A quadratic \(y = a(x-h)^2+k\) is the shape of projectile motion in ideal textbook setups and many optimization problems (min/max). One smooth hump; the slope switches sign at the vertex. +@@SECTION=s3 3. Sine & cosine = waves & rotation Sines and cosines describe vibrations, AC signals, sound, and anything that repeats. Cosine is sine shifted: same wave, different starting phase. Complex numbers (below) make these waves easier to solve in circuits and vibrations. +@@SECTION=s4 4. Absolute value & kinks \(|x|\) bends the graph so there is a corner on the axis. The derivative jumps there in ideal math — in real programs we plot smooth samples, but the idea matters: nonsmooth points need special care in analysis and simulation. +@@SECTION=s5 5. Taylor & Maclaurin series Smooth functions can be approximated near a point by polynomials with matching derivatives. Maclaurin means “expand around \(0\).” More terms usually improve the fit nearby; the full infinite sum is the series (where it converges). +@@SECTION=s6 6. Geometric series Sums \(u^0+u^1+u^2+\cdots\) appear in probability, signal processing, and digital math. When \(|u|<1\) the tail shrinks and the infinite sum has a clean closed form; that is the same mood as stability and “things settle.” +@@SECTION=s7 7. Multivariable slices Surfaces \(z = f(x,y)\) can be cut by fixing \(y=y_0\) — you get a 1D curve in \(x\). That is how higher-dimensional calculus is often reasoned about in engineering: fix all but one variable, take partial derivatives, gradients, directional slopes. +@@SECTION=s8 8. Integrals & area (Riemann sums) The definite integral \(\displaystyle \int_a^b f(x)\,dx\) is the signed area under the curve. Riemann sums chop \([a,b]\) into thin rectangles: pick sample heights (left, right, midpoint), add \(f(x^\ast)\,\Delta x\). More rectangles → closer to the true integral. +@@SECTION=s9 9. Engineering math — modeling mindset Engineering math picks tools that match the world: linear algebra for structures and networks, complex numbers / phasors for steady AC, differential equations for motion and heat, transforms (Laplace/Fourier) for signals and control. The goal is a usable model, then check it against reality. +@@SECTION=s10 10. Damped oscillation Many systems lose energy while oscillating: \(e^{-\alpha t}\sin(\omega t)\) style decay is the cartoon of that idea — envelope shrinks, oscillation persists briefly. Mechanical damping, resistor–capacitor–inductor circuits, and control systems all share this language. +@@SECTION=s11 11. Catenary & cosh A hanging cable under its own weight forms a catenary; \(\cosh\) is the hyperbolic cosine that models that ideal shape (and shows up in hyperbolic PDEs and relativity too). Different from a parabola even if both look “like arches.” +@@SECTION=s12 12. Rectified sine \(|\sin|\) Full-wave rectification flips negative lobes upward — a first step in turning AC into something closer to DC for power supplies. Corners at zeros mean derivatives jump — a reminder that idealized circuits still start from calculus intuitions. +@@SECTION=s13 13. Circle \((x-h)^2 + (y-k)^2 = R^2\) A circle is usually written implicitly. Solving for \(y\) gives two branches (\(\pm\sqrt{\cdot}\)). The game’s circle stage uses the upper semicircle so the path stays a function \(y(x)\) over one sweep. Implicit differentiation yields \(\frac{dy}{dx} = -\frac{x-h}{y-k}\); at the ends of the diameter the tangent is vertical (slope blows up). +@@SECTION=aero ──────── Aerospace engineering & aerodynamics ──────── Levels prefixed Aerospace: turn textbook flight‑vehicle math into paths you run. They are toy models for pedagogy — not CFD, flight test, or ITAR‑grade simulations. @@ -101,6 +119,7 @@ A circle is usually written implicitly. Solving for \(y\) gives two branches (\( See docs/engineering-math.md § Aerospace for a longer map. +@@SECTION=biz ──────── First principles thinking (business) ──────── Startup culture often cites Elon Musk for reviving first principles at places like Tesla / SpaceX: stop trusting “the market always prices it this way,” and instead unpack assumptions until you hit bedrock facts (materials, energy, physics, true unit costs), then reason upward into a new design. The idea is older than any one founder — but the habit matches this game’s visuals. @@ -112,6 +131,7 @@ A circle is usually written implicitly. Solving for \(y\) gives two branches (\( This is not legal, tax, or investing advice — a thinking drill you can pair with real advisors and data. Full write-up: docs/first-principles-business.md on GitHub Pages. +@@SECTION=exam ──────── Exam prep (separate tracks) ──────── Competition mathematics (contest lens) diff --git a/First Principles/Assets/Resources/Localization/ar.txt b/First Principles/Assets/Resources/Localization/ar.txt index 8204374..0c85d4b 100644 --- a/First Principles/Assets/Resources/Localization/ar.txt +++ b/First Principles/Assets/Resources/Localization/ar.txt @@ -12,9 +12,6 @@ ui.jump=قفز ui.move=تحرك ui.keyboard_hint_mobile=(لوحة المفاتيح: الأسهم / المسافة) hud.stage=المرحلة -controls.mobile=تحرك ◀ ▶ · قفز مس (لوحة المفاتيح: الأسهم / المسافة) -controls.desktop=تحرك · قفز مسافة -controls.calculator=آلة رسومية اكتب f(u) · Trans · Scale · قرصة · رجوع graph.label_fu=f(u) = graph.placeholder=x^2 + sin(x) · ln(x) عندما x>0 · min(x,3)... graph.status_enter=Enter / اضغط خارج الحقل للرسم @@ -22,7 +19,7 @@ graph.status_graphed=تم الرسم graph.line1=وضع آلة الرسوم البيانية graph.line2=اكتب f(u) أدناه (المتغير x في المربع = u الداخلي). ثم: graph.line3=Trans ← {0} · نقرتان + · اضغط مطولًا · Scale تكبير باللمس / اضغط مطولًا للتصغير · قرصة بإصبعين -graph.line4=A={0}  k={1}  C={2}  D={3}   x في [{4},{5}] +graph.line4=A={0} k={1} C={2} D={3} x في [{4},{5}] graph.param_a=A (مقياس عمودي) graph.param_k=k (مقياس أفقي) graph.param_c=C (إزاحة عمودية) @@ -65,20 +62,28 @@ level.30=BC: طور وحركة توافقية بسيطة (طاقة) level.31=BC: تكعيب ونقطة انعطاف (رسم) level.32=BC: b^x و d/dx b^x level.33=دائرة: (x−h)² + (y−k)² = R² -level.34=طيران: رفع C_L(α) خطي + انفصال -level.35=طيران: قطب السحب (طفيلي، مُستحثّ، إجمالي) -level.36=طيران: جو متساوي الحرارة ρ(h) -level.37=طيران: حركة مجنحة / اهتزاز مُخمَّد -level.38=طيران: نيوتوني Cp ~ sin²α -level.39=طيران: Strouhal / نبرة انبعاث دوامات -level.40=طيران: غلاف دخول غلاف جوي (تسخين ρV) -level.41=اقتصاد: فقاعة الدوت كوم والانهيار (مؤشر توضيحي) -level.42=اقتصاد: أزمة 2008 والتعافي (مؤشر توضيحي) -level.43=الزعيم: شريحة هروب ماندلبروت (كسيري) -level.44=فيزياء C: الديناميكا الحرارية (P–V أديباتي، γ من N) -level.45=زعيم: لولب النسبة الذهبية (قطبي لوغاريتمي) -level.46=تحويلات: فورييه — طيف sinc -level.47=تحويلات: لابلاس — تضاؤل أسي -level.48=زعيم: ماندلبروت — الختام (شريحة هروب كسيرية) -level.49=زعيم: فراشة لورينز — الختام (جذاب غريب) +level.34=فيزياء C: الديناميكا الحرارية (P–V أديباتي، γ من N) +level.35=طيران: رفع C_L(α) خطي + انفصال +level.36=طيران: قطب السحب (طفيلي، مُستحثّ، إجمالي) +level.37=طيران: جو متساوي الحرارة ρ(h) +level.38=طيران: حركة مجنحة / اهتزاز مُخمَّد +level.39=طيران: نيوتوني Cp ~ sin²α +level.40=طيران: Strouhal / نبرة انبعاث دوامات +level.41=طيران: غلاف دخول غلاف جوي (تسخين ρV) +level.42=اقتصاد: فقاعة الدوت كوم والانهيار (مؤشر توضيحي) +level.43=اقتصاد: أزمة 2008 والتعافي (مؤشر توضيحي) +level.44=تحويلات: فورييه — طيف sinc +level.45=تحويلات: لابلاس — تضاؤل أسي +level.46=زعيم: لولب النسبة الذهبية (قطبي لوغاريتمي) +level.47=زعيم: ماندلبروت — الختام (شريحة هروب كسيرية) +level.48=زعيم: جاذب لورينز — نظرية الفوضى (جذاب غريب) +level.49=زعيم: ثقب أسود — بئر جاذبية (مقطع 1/r) level.50=فيزياء C: نابض–كتلة حركة توافقية (قانون هوك، بلا تخميد) +level.51=Big O: O(1) — constant time +level.52=Big O: O(log n) — logarithmic growth +level.53=Big O: O(√n) — sublinear root growth +level.54=Big O: O(n) — linear growth +level.55=Big O: O(n log n) — n log n growth +level.56=Big O: O(n²) — quadratic growth +level.57=Big O: O(n³) — cubic growth +level.58=Big O: O(2ⁿ) — exponential (base 2) diff --git a/First Principles/Assets/Resources/Localization/cs.txt b/First Principles/Assets/Resources/Localization/cs.txt index ec1eef5..d53fcac 100644 --- a/First Principles/Assets/Resources/Localization/cs.txt +++ b/First Principles/Assets/Resources/Localization/cs.txt @@ -7,10 +7,11 @@ level_select.cat.integration=Mult proměnné a integrály level_select.cat.engineering=Inženýrství level_select.cat.ap_bc=AP Calculus BC a fyzika C level_select.cat.aerospace=Letectví a kosmonautika -level_select.cat.finale=Pokročilé a boss +level_select.cat.economics=Ekonomie level_select.cat.transforms=Transformace level_select.cat.final_boss=Finální boss level_select.cat.spring_physics=Pružina a SHM +level_select.cat.big_o=Notace Big O ui.math_tips=Tipy k matematice ui.back_menu=Zpět do menu ui.graphing_calculator_mode=Grafická kalkulačka @@ -24,9 +25,6 @@ ui.jump=Skok ui.move=Pohyb ui.keyboard_hint_mobile=(klávesnice: šipky / Mezerník) hud.stage=FÁZE -controls.mobile=Pohyb ◀ ▶ · Skok klepnutí (klávesnice: šipky / Mezerník) -controls.desktop=Pohyb · Skok Mezerník -controls.calculator=Grafická kalkulačka Zadejte f(u) · Trans · Měřítko · Špetka · Zpět graph.label_fu=f(u) = graph.placeholder=x^2 + sin(x) · ln(x) pro x>0 · min(x,3)... graph.status_enter=Enter / klepněte mimo pro graf @@ -34,7 +32,7 @@ graph.status_graphed=Vykresleno graph.line1=Režim grafické kalkulačky graph.line2=Napište f(u) níže (proměnná x v poli = vnitřní u). Pak: graph.line3=Trans → {0} · dvojité klepnutí + · podržte · Měřítko přiblížení / podržte oddálení · špetka dvěma prsty -graph.line4=A={0}  k={1}  C={2}  D={3}   x v [{4},{5}] +graph.line4=A={0} k={1} C={2} D={3} x v [{4},{5}] graph.param_a=A (svislé měřítko) graph.param_k=k (vodorovné měřítko) graph.param_c=C (svislý posun) @@ -85,20 +83,28 @@ level.30=BC: fáze a SHM (výměna energie) level.31=BC: kubická a inflexe (náčrt) level.32=BC: b^x a d/dx b^x level.33=Kružnice: (x−h)² + (y−k)² = R² -level.34=Aerospace: vztlak C_L(α) lineární + vývrt -level.35=Aerospace: polára odporu (parazitní, indukovaná, celková) -level.36=Aerospace: isotermická atmosféra ρ(h) -level.37=Aerospace: fugoid / tlumený režim výška–klopení -level.38=Aerospace: Newtonovské Cp ~ sin²α -level.39=Aerospace: Strouhal / tón von Kármána -level.40=Aerospace: obal útlumu při vstupu (ρV teplo) -level.41=Ekonomika: bublina dot-com a pád (stylizovaný index) -level.42=Ekonomika: krize 2008 a oživení (stylizovaný index) -level.43=BOSS: řez úniku Mandelbrota (fraktálová nálada) -level.44=Fyzika C: termodynamika (adiabatické P–V, γ z N) -level.45=BOSS: zlatá spirála (logaritmická polární) -level.46=Transformace: Fourier — sinc (spektrum) -level.47=Transformace: Laplace — exponenciální pokles -level.48=BOSS: Mandelbrot — finále (fraktálový únikový řez) -level.49=BOSS: Lorenzův motýl — finále (podivný atraktor) -level.50=Fyzika C: pružina–hmota SHM (Hookeův zákon, bez tlumení) \ No newline at end of file +level.34=Fyzika C: termodynamika (adiabatické P–V, γ z N) +level.35=Aerospace: vztlak C_L(α) lineární + vývrt +level.36=Aerospace: polára odporu (parazitní, indukovaná, celková) +level.37=Aerospace: isotermická atmosféra ρ(h) +level.38=Aerospace: fugoid / tlumený režim výška–klopení +level.39=Aerospace: Newtonovské Cp ~ sin²α +level.40=Aerospace: Strouhal / tón von Kármána +level.41=Aerospace: obal útlumu při vstupu (ρV teplo) +level.42=Ekonomika: bublina dot-com a pád (stylizovaný index) +level.43=Ekonomika: krize 2008 a oživení (stylizovaný index) +level.44=Transformace: Fourier — sinc (spektrum) +level.45=Transformace: Laplace — exponenciální pokles +level.46=BOSS: zlatá spirála (logaritmická polární) +level.47=BOSS: Mandelbrot — finále (fraktálový únikový řez) +level.48=BOSS: Lorenzův atraktor — teorie chaosu (podivný atraktor) +level.49=BOSS: černá díra — gravitační jáma (řez ∝ 1/r) +level.50=Fyzika C: pružina–hmota SHM (Hookeův zákon, bez tlumení) +level.51=Big O: O(1) — constant time +level.52=Big O: O(log n) — logarithmic growth +level.53=Big O: O(√n) — sublinear root growth +level.54=Big O: O(n) — linear growth +level.55=Big O: O(n log n) — n log n growth +level.56=Big O: O(n²) — quadratic growth +level.57=Big O: O(n³) — cubic growth +level.58=Big O: O(2ⁿ) — exponential (base 2) \ No newline at end of file diff --git a/First Principles/Assets/Resources/Localization/de.txt b/First Principles/Assets/Resources/Localization/de.txt index c44dffe..3d5ec57 100644 --- a/First Principles/Assets/Resources/Localization/de.txt +++ b/First Principles/Assets/Resources/Localization/de.txt @@ -12,9 +12,6 @@ ui.jump=Sprung ui.move=Bewegen ui.keyboard_hint_mobile=(Tastatur: Pfeile / Leertaste) hud.stage=PHASE -controls.mobile=Bewegen ◀ ▶ · Sprung Tipp (Tastatur: Pfeile / Leertaste) -controls.desktop=Bewegen · Sprung Leertaste -controls.calculator=Grafikrechner f(u) eingeben · Trans · Maßstab · Pinch · Zurück graph.label_fu=f(u) = graph.placeholder=x^2 + sin(x) · ln(x) für x>0 · min(x,3)... graph.status_enter=Eingabe / außerhalb tippen zum Zeichnen @@ -22,7 +19,7 @@ graph.status_graphed=Gezeichnet graph.line1=Grafikrechner-Modus graph.line2=Geben Sie unten f(u) ein (Variable x im Feld = inneres u). Dann: graph.line3=Trans → {0} · Doppeltipp + · halten · Maßstab hereinzoomen / halten herauszoomen · Zweifinger-Pinch -graph.line4=A={0}  k={1}  C={2}  D={3}   x in [{4},{5}] +graph.line4=A={0} k={1} C={2} D={3} x in [{4},{5}] graph.param_a=A (vertikaler Maßstab) graph.param_k=k (horizontaler Maßstab) graph.param_c=C (vertikale Verschiebung) @@ -65,20 +62,28 @@ level.30=BC: Phase & SHM (Energie) level.31=BC: Kubik & Wendepunkt (Skizze) level.32=BC: b^x & d/dx b^x level.33=Kreis: (x−h)² + (y−k)² = R² -level.34=Luftfahrt: Auftrieb C_L(α) linear + Strömungsabriss -level.35=Luftfahrt: Widerstandspolare (profil-, induziert, gesamt) -level.36=Luftfahrt: isotherme Atmosphäre ρ(h) -level.37=Luftfahrt: Phugoid / gedämpfte Nick-Hubbewegung -level.38=Luftfahrt: newtonsch Cp ~ sin²α -level.39=Luftfahrt: Strouhal / Wirbelabwurf-Ton -level.40=Luftfahrt: Wiedereintritts-Hülle (ρV Erwärmung) -level.41=Wirtschaft: Dotcom-Blase & Crash (stilisierter Index) -level.42=Wirtschaft: Krise 2008 & Erholung (stilisierter Index) -level.43=BOSS: Mandelbrot-Escapeschnitt (Fraktal) -level.44=Physik C: Thermodynamik (adiabater P–V-Verlauf, γ aus N) -level.45=BOSS: Goldener-Spiralen-Logarithmus (Polar) -level.46=Transformationen: Fourier — sinc-Spektrum -level.47=Transformationen: Laplace — exponentieller Abfall -level.48=BOSS: Mandelbrot — Finale (Fraktal-Escape-Schnitt) -level.49=BOSS: Lorenz-Attraktor — Finale (seltsamer Attraktor) +level.34=Physik C: Thermodynamik (adiabater P–V-Verlauf, γ aus N) +level.35=Luftfahrt: Auftrieb C_L(α) linear + Strömungsabriss +level.36=Luftfahrt: Widerstandspolare (profil-, induziert, gesamt) +level.37=Luftfahrt: isotherme Atmosphäre ρ(h) +level.38=Luftfahrt: Phugoid / gedämpfte Nick-Hubbewegung +level.39=Luftfahrt: newtonsch Cp ~ sin²α +level.40=Luftfahrt: Strouhal / Wirbelabwurf-Ton +level.41=Luftfahrt: Wiedereintritts-Hülle (ρV Erwärmung) +level.42=Wirtschaft: Dotcom-Blase & Crash (stilisierter Index) +level.43=Wirtschaft: Krise 2008 & Erholung (stilisierter Index) +level.44=Transformationen: Fourier — sinc-Spektrum +level.45=Transformationen: Laplace — exponentieller Abfall +level.46=BOSS: Goldener-Spiralen-Logarithmus (Polar) +level.47=BOSS: Mandelbrot — Finale (Fraktal-Escape-Schnitt) +level.48=BOSS: Lorenz-Attraktor — Chaos-Theorie (seltsamer Attraktor) +level.49=BOSS: Schwarzes Loch — Gravitationsbrunnen (1/r-Schnitt) level.50=Physik C: Feder–Masse SHM (Hooke, ungedämpft) +level.51=Big O: O(1) — constant time +level.52=Big O: O(log n) — logarithmic growth +level.53=Big O: O(√n) — sublinear root growth +level.54=Big O: O(n) — linear growth +level.55=Big O: O(n log n) — n log n growth +level.56=Big O: O(n²) — quadratic growth +level.57=Big O: O(n³) — cubic growth +level.58=Big O: O(2ⁿ) — exponential (base 2) diff --git a/First Principles/Assets/Resources/Localization/en.txt b/First Principles/Assets/Resources/Localization/en.txt index 4313118..8eeddaa 100644 --- a/First Principles/Assets/Resources/Localization/en.txt +++ b/First Principles/Assets/Resources/Localization/en.txt @@ -8,10 +8,12 @@ level_select.cat.integration=Multivar & integration level_select.cat.engineering=Engineering level_select.cat.ap_bc=AP Calculus BC & Physics C level_select.cat.aerospace=Aerospace -level_select.cat.finale=Advanced & boss +level_select.cat.astrophysics=Astrophysics +level_select.cat.economics=Economics level_select.cat.transforms=Transforms level_select.cat.final_boss=Final boss level_select.cat.spring_physics=Spring & SHM +level_select.cat.big_o=Big O notation ui.math_tips=Math tips & snippets ui.back_menu=Back to Menu ui.graphing_calculator_mode=Graphing\ncalculator @@ -20,14 +22,14 @@ ui.language=Language ui.tap_change_language=Tap to change ui.stage_intro_hint=Tap anywhere to continue ui.close=Close +ui.coming_soon=Coming soon! +ui.coming_soon_tap=Tap anywhere to close ui.math_concepts=Math concepts ui.jump=Jump ui.move=Move ui.keyboard_hint_mobile=(keyboard: arrows / Space) hud.stage=STAGE -controls.mobile=Move ◀ ▶ · Jump tap (keyboard: arrows / Space) -controls.desktop=Move · Jump Space -controls.calculator=Graphing calculator Type f(u) · Deriv · · Trans · Scale · Pinch · Back +hud.points=PTS graph.calc_deriv=Deriv graph.calc_integral=∫ area graph.calc_primitive_prefix=Primitive (guess): @@ -39,7 +41,7 @@ graph.status_graphed=Graphed graph.line1=Graphing calculator mode graph.line2=Type f(u) below (variable x in the box = inner u). Then: graph.line3=Deriv adds f′ once (numeric) · ∫ area Riemann strips once + primitive guess · Trans → {0} · double-tap + · hold · Scale / pinch -graph.line4=A={0}  k={1}  C={2}  D={3}   x in [{4},{5}] +graph.line4=A={0} k={1} C={2} D={3} x in [{4},{5}] graph.param_a=A (vertical scale) graph.param_k=k (horizontal scale) graph.param_c=C (vertical shift) @@ -49,13 +51,13 @@ graph.polar.param_a=A (r scale) graph.polar.param_k=k (θ scale) graph.polar.param_c=C (r shift) graph.polar.param_d=D (θ phase / axis shift) -graph.polar.line4=A={0}  k={1}  C={2}  D={3}   θ∈[{4},{5}] -graph.calculator_intro=Graphing calculator mode\nType almost any f(u) in the field (variable x in your formula); Trans adjusts A, k, C, D; Scale & pinch zoom the window. -# Prepended to story text for every Aerospace stage (indices 34–40). +graph.polar.line4=A={0} k={1} C={2} D={3} θ∈[{4},{5}] +graph.calculator_intro=Graphing calculator mode\nType almost any f(u) in the field (variable x in your formula); Trans adjusts A, k, C, D; Scale · pinch zoom the window. +# Prepended to story text for every Aerospace stage (indices 35–41). aerospace.story_drag_polar_preamble=Drag polar refresher (every Aerospace stage)\nParasitic (zero-lift) drag — skin friction, form drag, interference lumped as CD0 in the parabolic model (roughly not the part that grows with lift).\nInduced drag — the cost of making lift: trailing vortices add ~ K CL² (higher CL / tighter turns → more induced).\nOverall drag polarCD = CD0 + K CL²: an upward-opening parabola in CL; min-drag CL sits between “too slow / high α” and “too fast / low α” for real missions. menu.tutorial_button=How to play menu.tutorial_title=How to play -menu.tutorial_body=Goal\nMove along the graph, use platforms (green), avoid red hazards, and reach the bright exit on the right.\n\nControls\n• Move — arrows / WASD, or on-screen buttons.\n• Jump — Space (or mobile jump). You jump from solid platforms.\n\nThe two curves\n• Main curve — the function you walk on.\n• Derivative f′ — slope information; it’s drawn as a second line.\n\nAir jump on the derivative\nWhile you are in the air, if your character overlaps the derivative curve, press Jump again for an extra hop.\n\nThe derivative line brightens when you touch it. You get one bonus jump each time you brush it until you leave the curve or land. On phones you may feel a short vibration when you touch f′; on PC a sound plays when vibration isn’t available.\n\nSelect level\nOn this screen, stages are grouped (Core, Engineering, AP Calculus, Aerospace …). Tap How to play at the bottom to reopen this help. Pick a group, then a level. +menu.tutorial_body=Goal\nMove along the graph, use platforms (green), avoid red hazards, and reach the bright exit on the right.\n\nControls\n• Move — arrows / WASD, or on a phone hold the left / right half of the screen.\n• Jump — Space, or on a phone tap with a second finger while holding left/right. You jump from solid platforms.\n\nThe two curves\n• Main curve — the function you walk on.\n• Derivative f′ — slope information; it’s drawn as a second line.\n\nAir jump on the derivative\nWhile you are in the air, if your character overlaps the derivative curve, press Jump again for an extra hop.\n\nThe derivative line brightens when you touch it. You get one bonus jump each time you brush it until you leave the curve or land. On phones you may feel a short vibration when you touch f′; on PC a sound plays when vibration isn’t available.\n\nSelect level\nOn this screen, stages are grouped (Core, Engineering, AP Calculus, Aerospace …). Tap How to play at the bottom to reopen this help. Pick a group, then a level. menu.player_icon_title=Player icon menu.player_icon_set=Player icon menu.player_icon_hint=Tap a symbol — it’s your avatar in levels. @@ -97,20 +99,29 @@ level.30=BC: phase & SHM (energy swaps) level.31=BC: cubic & inflection (sketching) level.32=BC: b^x & d/dx b^x level.33=Circle: (x−h)² + (y−k)² = R² -level.34=Aerospace: lift C_L(α) linear + stall -level.35=Aerospace: drag polar (parasitic, induced, total) -level.36=Aerospace: isothermal atmosphere ρ(h) -level.37=Aerospace: phugoid / damped pitch–heave mood -level.38=Aerospace: Newtonian Cp ~ sin²α -level.39=Aerospace: Strouhal / vortex shedding tone -level.40=Aerospace: re-entry decay envelope (ρV heating mood) -level.41=Economics: dot-com bubble & crash (stylized index) -level.42=Economics: 2008 crisis & recovery (stylized index) -level.43=BOSS: Mandelbrot escape slice (fractal boundary mood) -level.44=Physics C: thermodynamics (adiabatic P–V, γ from N) -level.45=BOSS: golden ratio spiral (logarithmic polar) -level.46=Transforms: Fourier — sinc spectrum (rect ↔ sinc) -level.47=Transforms: Laplace — causal exponential decay -level.48=BOSS: Mandelbrot — finale (fractal escape slice) -level.49=BOSS: Lorenz butterfly — finale (strange attractor) +level.34=Physics C: thermodynamics (adiabatic P–V, γ from N) +level.35=Aerospace: lift C_L(α) linear + stall +level.36=Aerospace: drag polar (parasitic, induced, total) +level.37=Aerospace: isothermal atmosphere ρ(h) +level.38=Aerospace: phugoid / damped pitch–heave mood +level.39=Aerospace: Newtonian Cp ~ sin²α +level.40=Aerospace: Strouhal / vortex shedding tone +level.41=Aerospace: re-entry decay envelope (ρV heating mood) +level.42=Economics: dot-com bubble & crash (stylized index) +level.43=Economics: 2008 crisis & recovery (stylized index) +level.44=Transforms: Fourier — sinc spectrum (rect ↔ sinc) +level.45=Transforms: Laplace — causal exponential decay +level.46=BOSS: golden ratio spiral (logarithmic polar) +level.47=BOSS: Mandelbrot — finale (fractal escape slice) +level.48=BOSS: Lorenz attractor — Chaos Theory (strange attractor) +level.49=BOSS: Black hole — gravity well (1/r slice) level.50=Physics C: spring–mass SHM (Hooke's law, undamped) +level.51=Big O: O(1) — constant time +level.52=Big O: O(log n) — logarithmic growth +level.53=Big O: O(√n) — sublinear root growth +level.54=Big O: O(n) — linear growth +level.55=Big O: O(n log n) — n log n growth +level.56=Big O: O(n²) — quadratic growth +level.57=Big O: O(n³) — cubic growth +level.58=Big O: O(2ⁿ) — exponential (base 2) +level.59=Astrophysics: Hohmann transfer diff --git a/First Principles/Assets/Resources/Localization/es.txt b/First Principles/Assets/Resources/Localization/es.txt index 3e5dd9b..cf2e452 100644 --- a/First Principles/Assets/Resources/Localization/es.txt +++ b/First Principles/Assets/Resources/Localization/es.txt @@ -12,9 +12,6 @@ ui.jump=Saltar ui.move=Mover ui.keyboard_hint_mobile=(teclado: flechas / Espacio) hud.stage=FASE -controls.mobile=Mover ◀ ▶ · Saltar tocar (teclado: flechas / Espacio) -controls.desktop=Mover · Saltar Espacio -controls.calculator=Calculadora gráfica Escribir f(u) · Trans · Escala · Pellizco · Atrás graph.label_fu=f(u) = graph.placeholder=x^2 + sin(x) · ln(x) para x>0 · min(x,3)... graph.status_enter=Intro / tocar fuera para graficar @@ -22,7 +19,7 @@ graph.status_graphed=Graficado graph.line1=Modo calculadora gráfica graph.line2=Escribe f(u) abajo (la variable x en el cuadro = u interior). Luego: graph.line3=Trans → {0} · doble toque + · mantén · Escala acercar / mantén alejar · pellizco con dos dedos -graph.line4=A={0}  k={1}  C={2}  D={3}   x en [{4},{5}] +graph.line4=A={0} k={1} C={2} D={3} x en [{4},{5}] graph.param_a=A (escala vertical) graph.param_k=k (escala horizontal) graph.param_c=C (desplazamiento vertical) @@ -65,20 +62,28 @@ level.30=BC: fase y MAS (energía) level.31=BC: cúbica e inflexión (boceto) level.32=BC: b^x y d/dx b^x level.33=Círculo: (x−h)² + (y−k)² = R² -level.34=Aero: sustentación C_L(α) lineal + pérdida -level.35=Aero: polar de arrastre (parásita, inducida, total) -level.36=Aero: atmósfera isoterma ρ(h) -level.37=Aero: fugoide / cabeceo–heave amortiguado -level.38=Aero: newtoniano Cp ~ sin²α -level.39=Aero: Strouhal / tono de vórtices -level.40=Aero: envolvente de reentrada (calor ρV) -level.41=Economía: burbuja dotcom y crash (índice estilizado) -level.42=Economía: crisis 2008 y recuperación (índice estilizado) -level.43=JEFE: corte de escape Mandelbrot (fractal) -level.44=Física C: termodinámica (P–V adiabático, γ desde N) -level.45=JEFE: espiral áurea (polar logarítmica) -level.46=Transformadas: Fourier — sinc (espectro) -level.47=Transformadas: Laplace — decaimiento exponencial -level.48=JEFE: Mandelbrot — final (corte de escape fractal) -level.49=JEFE: mariposa de Lorenz — final (atractor extraño) +level.34=Física C: termodinámica (P–V adiabático, γ desde N) +level.35=Aero: sustentación C_L(α) lineal + pérdida +level.36=Aero: polar de arrastre (parásita, inducida, total) +level.37=Aero: atmósfera isoterma ρ(h) +level.38=Aero: fugoide / cabeceo–heave amortiguado +level.39=Aero: newtoniano Cp ~ sin²α +level.40=Aero: Strouhal / tono de vórtices +level.41=Aero: envolvente de reentrada (calor ρV) +level.42=Economía: burbuja dotcom y crash (índice estilizado) +level.43=Economía: crisis 2008 y recuperación (índice estilizado) +level.44=Transformadas: Fourier — sinc (espectro) +level.45=Transformadas: Laplace — decaimiento exponencial +level.46=JEFE: espiral áurea (polar logarítmica) +level.47=JEFE: Mandelbrot — final (corte de escape fractal) +level.48=JEFE: atractor de Lorenz — teoría del caos (atractor extraño) +level.49=JEFE: agujero negro — pozo gravitatorio (corte 1/r) level.50=Física C: resorte–masa SHM (ley de Hooke, sin amortiguación) +level.51=Big O: O(1) — constant time +level.52=Big O: O(log n) — logarithmic growth +level.53=Big O: O(√n) — sublinear root growth +level.54=Big O: O(n) — linear growth +level.55=Big O: O(n log n) — n log n growth +level.56=Big O: O(n²) — quadratic growth +level.57=Big O: O(n³) — cubic growth +level.58=Big O: O(2ⁿ) — exponential (base 2) diff --git a/First Principles/Assets/Resources/Localization/fr.txt b/First Principles/Assets/Resources/Localization/fr.txt index 515a3d3..fbdcb0d 100644 --- a/First Principles/Assets/Resources/Localization/fr.txt +++ b/First Principles/Assets/Resources/Localization/fr.txt @@ -12,9 +12,6 @@ ui.jump=Saut ui.move=Déplacer ui.keyboard_hint_mobile=(clavier : flèches / Espace) hud.stage=NIVEAU -controls.mobile=Déplacer ◀ ▶ · Saut tapoter (clavier : flèches / Espace) -controls.desktop=Déplacer · Saut Espace -controls.calculator=Calculatrice graphique Saisir f(u) · Trans · Échelle · Pincer · Retour graph.label_fu=f(u) = graph.placeholder=x^2 + sin(x) · ln(x) si x>0 · min(x,3)... graph.status_enter=Entrée / toucher ailleurs pour tracer @@ -22,7 +19,7 @@ graph.status_graphed=Tracé graph.line1=Mode calculatrice graphique graph.line2=Saisissez f(u) ci-dessous (la variable x dans la zone = u interne). Ensuite : graph.line3=Trans → {0} · double appui + · maintenir · Échelle zoom avant / maintenir zoom arrière · pincer deux doigts -graph.line4=A={0}  k={1}  C={2}  D={3}   x ∈ [{4},{5}] +graph.line4=A={0} k={1} C={2} D={3} x ∈ [{4},{5}] graph.param_a=A (échelle verticale) graph.param_k=k (échelle horizontale) graph.param_c=C (translation verticale) @@ -65,20 +62,28 @@ level.30=BC : phase & MHS (échanges d’énergie) level.31=BC : cubique & inflexion (esquisse) level.32=BC : b^x & d/dx b^x level.33=Cercle : (x−h)² + (y−k)² = R² -level.34=Aéro : portance C_L(α) linéaire + décrochage -level.35=Aéro : polaire (traînée de profil, induite, totale) -level.36=Aéro : atmosphère isotherme ρ(h) -level.37=Aéro : phugoïde / oscillation amortie tangage–pilonnement -level.38=Aéro : newtonien Cp ~ sin²α -level.39=Aéro : Strouhal / tonalité tourbillonnaire -level.40=Aéro : enveloppe rentrée (échauffement ρV) -level.41=Éco : bulle internet & krach (indice stylisé) -level.42=Éco : crise 2008 & reprise (indice stylisé) -level.43=BOSS : tranche d’échappement Mandelbrot (fractale) -level.44=Physique C : thermodynamique (adiabatique P–V, γ depuis N) -level.45=BOSS : spirale d’or (polaire logarithmique) -level.46=Transformations : Fourier — sinc (spectre) -level.47=Transformations : Laplace — décroissance exponentielle -level.48=BOSS : Mandelbrot — finale (tranche d’échappement fractale) -level.49=BOSS : papillon de Lorenz — finale (attracteur étrange) +level.34=Physique C : thermodynamique (adiabatique P–V, γ depuis N) +level.35=Aéro : portance C_L(α) linéaire + décrochage +level.36=Aéro : polaire (traînée de profil, induite, totale) +level.37=Aéro : atmosphère isotherme ρ(h) +level.38=Aéro : phugoïde / oscillation amortie tangage–pilonnement +level.39=Aéro : newtonien Cp ~ sin²α +level.40=Aéro : Strouhal / tonalité tourbillonnaire +level.41=Aéro : enveloppe rentrée (échauffement ρV) +level.42=Éco : bulle internet & krach (indice stylisé) +level.43=Éco : crise 2008 & reprise (indice stylisé) +level.44=Transformations : Fourier — sinc (spectre) +level.45=Transformations : Laplace — décroissance exponentielle +level.46=BOSS : spirale d’or (polaire logarithmique) +level.47=BOSS : Mandelbrot — finale (tranche d’échappement fractale) +level.48=BOSS : attracteur de Lorenz — théorie du chaos (attracteur étrange) +level.49=BOSS : trou noir — puits de gravité (tranche 1/r) level.50=Physique C : ressort–masse SHM (loi de Hooke, non amorti) +level.51=Big O: O(1) — constant time +level.52=Big O: O(log n) — logarithmic growth +level.53=Big O: O(√n) — sublinear root growth +level.54=Big O: O(n) — linear growth +level.55=Big O: O(n log n) — n log n growth +level.56=Big O: O(n²) — quadratic growth +level.57=Big O: O(n³) — cubic growth +level.58=Big O: O(2ⁿ) — exponential (base 2) diff --git a/First Principles/Assets/Resources/Localization/hi.txt b/First Principles/Assets/Resources/Localization/hi.txt index aa2fc05..f729fbc 100644 --- a/First Principles/Assets/Resources/Localization/hi.txt +++ b/First Principles/Assets/Resources/Localization/hi.txt @@ -13,9 +13,6 @@ ui.jump=कूद ui.move=चलें ui.keyboard_hint_mobile=(कीबोर्ड: तीर / स्पेस) hud.stage=चरण -controls.mobile=चलें ◀ ▶ · कूद टैप (कीबोर्ड: तीर / स्पेस) -controls.desktop=चलें · कूद स्पेस -controls.calculator=ग्राफ़िंग कैलकुलेटर f(u) लिखें · Trans · Scale · पिंच · वापस graph.label_fu=f(u) = graph.placeholder=x^2 + sin(x) · ln(x) जब x>0 · min(x,3)... graph.status_enter=Enter / ग्राफ़ के लिए बाहर टैप करें @@ -23,7 +20,7 @@ graph.status_graphed=ग्राफ़ तैयार graph.line1=ग्राफ़िंग कैलकुलेटर मोड graph.line2=नीचे f(u) लिखें (बॉक्स में चर x = आंतरिक u)। फिर: graph.line3=Trans → {0} · + पर डबल-टैप · दबाकर रखें · Scale ज़ूम इन / आउट दबाकर रखें · दो उंगलियों से पिंच -graph.line4=A={0}  k={1}  C={2}  D={3}   x ∈ [{4},{5}] +graph.line4=A={0} k={1} C={2} D={3} x ∈ [{4},{5}] graph.param_a=A (लंबवत स्केल) graph.param_k=k (क्षैतिज स्केल) graph.param_c=C (लंबवत खिसकाव) @@ -67,20 +64,28 @@ level.30=BC: कला व सरल हार्मोनिक गति level.31=BC: घन व प्रगाढ़ता (रेखाचित्र) level.32=BC: b^x व d/dx b^x level.33=वृत्त: (x−h)² + (y−k)² = R² -level.34=एयरोस्पेस: लिफ़्ट C_L(α) रैखिक + स्टॉल -level.35=एयरोस्पेस: ड्रैग पोलर (पैरासिटिक, प्रेरित, कुल) -level.36=एयरोस्पेस: समतापमान वायुमंडल ρ(h) -level.37=एयरोस्पेस: फ्यूगॉइड / डैम्प्ड पिच-हीव -level.38=एयरोस्पेस: न्यूटोनियन Cp ~ sin²α -level.39=एयरोस्पेस: स्ट्रौहल / वॉर्टेक्स शेडिंग -level.40=एयरोस्पेस: पुनः प्रवेश क्षय लिफ़ाफ़ा (ρV ताप मूड) -level.41=अर्थव्यवस्था: डॉट-कॉम बुलबुला व पतन (नमूना सूचकांक) -level.42=अर्थव्यवस्था: 2008 संकट व रिकवरी (नमूना सूचकांक) -level.43=BOSS: मैंडेलब्रॉट एस्केप स्लाइस (फ्रैक्टल) -level.44=भौतिकी C: ऊष्मागतिकी (एडियाबैटिक P–V, γ का मान N से) -level.45=BOSS: स्वर्ण अनुपात सर्पिल (लघुगणकीय ध्रुवीय) -level.46=रूपांतरण: फूरियर — सिंक स्पेक्ट्रम -level.47=रूपांतरण: लाप्लास — घातांकी क्षय -level.48=BOSS: मैंडेलब्रॉट — अंतिम (फ्रैक्टल एस्केप स्लाइस) -level.49=BOSS: लोरेंज तितली — अंतिम (विलक्षण आकर्षक) +level.34=भौतिकी C: ऊष्मागतिकी (एडियाबैटिक P–V, γ का मान N से) +level.35=एयरोस्पेस: लिफ़्ट C_L(α) रैखिक + स्टॉल +level.36=एयरोस्पेस: ड्रैग पोलर (पैरासिटिक, प्रेरित, कुल) +level.37=एयरोस्पेस: समतापमान वायुमंडल ρ(h) +level.38=एयरोस्पेस: फ्यूगॉइड / डैम्प्ड पिच-हीव +level.39=एयरोस्पेस: न्यूटोनियन Cp ~ sin²α +level.40=एयरोस्पेस: स्ट्रौहल / वॉर्टेक्स शेडिंग +level.41=एयरोस्पेस: पुनः प्रवेश क्षय लिफ़ाफ़ा (ρV ताप मूड) +level.42=अर्थव्यवस्था: डॉट-कॉम बुलबुला व पतन (नमूना सूचकांक) +level.43=अर्थव्यवस्था: 2008 संकट व रिकवरी (नमूना सूचकांक) +level.44=रूपांतरण: फूरियर — सिंक स्पेक्ट्रम +level.45=रूपांतरण: लाप्लास — घातांकी क्षय +level.46=BOSS: स्वर्ण अनुपात सर्पिल (लघुगणकीय ध्रुवीय) +level.47=BOSS: मैंडेलब्रॉट — अंतिम (फ्रैक्टल एस्केप स्लाइस) +level.48=BOSS: लोरेंज आकर्षक — अराजकता सिद्धांत (विलक्षण आकर्षक) +level.49=BOSS: ब्लैक होल — गुरुत्वाकर्षण कुआँ (1/r स्लाइस) level.50=फिजिक्स C: स्प्रिंग–द्रव्यमान SHM (हूक का नियम, अवमंदन रहित) +level.51=Big O: O(1) — constant time +level.52=Big O: O(log n) — logarithmic growth +level.53=Big O: O(√n) — sublinear root growth +level.54=Big O: O(n) — linear growth +level.55=Big O: O(n log n) — n log n growth +level.56=Big O: O(n²) — quadratic growth +level.57=Big O: O(n³) — cubic growth +level.58=Big O: O(2ⁿ) — exponential (base 2) diff --git a/First Principles/Assets/Resources/Localization/it.txt b/First Principles/Assets/Resources/Localization/it.txt index e109b7e..243ddd4 100644 --- a/First Principles/Assets/Resources/Localization/it.txt +++ b/First Principles/Assets/Resources/Localization/it.txt @@ -7,10 +7,11 @@ level_select.cat.integration=Multivariabile e integrazione level_select.cat.engineering=Ingegneria level_select.cat.ap_bc=AP Calculus BC e Fisica C level_select.cat.aerospace=Aerospaziale -level_select.cat.finale=Avanzati e boss +level_select.cat.economics=Economia level_select.cat.transforms=Trasformate level_select.cat.final_boss=Boss finale level_select.cat.spring_physics=Molla e SHM +level_select.cat.big_o=Notazione Big O ui.math_tips=Suggerimenti di matematica ui.back_menu=Torna al menu ui.graphing_calculator_mode=Calcolatrice grafica @@ -24,9 +25,6 @@ ui.jump=Salta ui.move=Muoviti ui.keyboard_hint_mobile=(tastiera: frecce / Spazio) hud.stage=STADIO -controls.mobile=Muoviti ◀ ▶ · Salta tocco (tastiera: frecce / Spazio) -controls.desktop=Muoviti · Salta Spazio -controls.calculator=Calcolatrice grafica Digita f(u) · Trasf · Scala · Pizzica · Indietro graph.label_fu=f(u) = graph.placeholder=x^2 + sin(x) · ln(x) per x>0 · min(x,3)... graph.status_enter=Invio / tocca fuori per tracciare @@ -34,7 +32,7 @@ graph.status_graphed=Tracciato graph.line1=Modalità calcolatrice grafica graph.line2=Digita f(u) sotto (la variabile x nella casella = u interno). Poi: graph.line3=Trasf → {0} · doppio tocco + · tieni premuto · Scala zoom avanti / tieni zoom indietro · pizzica a due dita -graph.line4=A={0}  k={1}  C={2}  D={3}   x in [{4},{5}] +graph.line4=A={0} k={1} C={2} D={3} x in [{4},{5}] graph.param_a=A (scala verticale) graph.param_k=k (scala orizzontale) graph.param_c=C (traslazione verticale) @@ -85,20 +83,28 @@ level.30=BC: fase e moto armonico (scambio energia) level.31=BC: cubica e flesso (schizzo) level.32=BC: b^x e d/dx b^x level.33=Cerchio: (x−h)² + (y−k)² = R² -level.34=Aerospaziale: portanza C_L(α) lineare + stallo -level.35=Aerospaziale: polare di resistenza (parassita, indotta, totale) -level.36=Aerospaziale: atmosfera isoterma ρ(h) -level.37=Aerospaziale: fugoide / modo smorzato beccheggio‑altitudine -level.38=Aerospaziale: newtoniano Cp ~ sin²α -level.39=Aerospaziale: Strouhal / tono di scia vorticosa -level.40=Aerospaziale: inviluppo decadimento rientro (mood riscaldamento ρV) -level.41=Economia: bolla dot-com e crollo (indice stilizzato) -level.42=Economia: crisi 2008 e ripresa (indice stilizzato) -level.43=BOSS: sezione escape Mandelbrot (mood frattale) -level.44=Fisica C: termodinamica (P–V adiabatico, γ da N) -level.45=BOSS: spirale aurea (polare logaritmica) -level.46=Trasformate: Fourier — sinc (spettro) -level.47=Trasformate: Laplace — decadimento esponenziale -level.48=BOSS: Mandelbrot — finale (sezione escape frattale) -level.49=BOSS: farfalla di Lorenz — finale (attrattore strano) +level.34=Fisica C: termodinamica (P–V adiabatico, γ da N) +level.35=Aerospaziale: portanza C_L(α) lineare + stallo +level.36=Aerospaziale: polare di resistenza (parassita, indotta, totale) +level.37=Aerospaziale: atmosfera isoterma ρ(h) +level.38=Aerospaziale: fugoide / modo smorzato beccheggio‑altitudine +level.39=Aerospaziale: newtoniano Cp ~ sin²α +level.40=Aerospaziale: Strouhal / tono di scia vorticosa +level.41=Aerospaziale: inviluppo decadimento rientro (mood riscaldamento ρV) +level.42=Economia: bolla dot-com e crollo (indice stilizzato) +level.43=Economia: crisi 2008 e ripresa (indice stilizzato) +level.44=Trasformate: Fourier — sinc (spettro) +level.45=Trasformate: Laplace — decadimento esponenziale +level.46=BOSS: spirale aurea (polare logaritmica) +level.47=BOSS: Mandelbrot — finale (sezione escape frattale) +level.48=BOSS: attrattore di Lorenz — teoria del caos (attrattore strano) +level.49=BOSS: buco nero — pozzo gravitazionale (sezione 1/r) level.50=Fisica C: molla–massa SHM (legge di Hooke, non smorzato) +level.51=Big O: O(1) — constant time +level.52=Big O: O(log n) — logarithmic growth +level.53=Big O: O(√n) — sublinear root growth +level.54=Big O: O(n) — linear growth +level.55=Big O: O(n log n) — n log n growth +level.56=Big O: O(n²) — quadratic growth +level.57=Big O: O(n³) — cubic growth +level.58=Big O: O(2ⁿ) — exponential (base 2) diff --git a/First Principles/Assets/Resources/Localization/ja.txt b/First Principles/Assets/Resources/Localization/ja.txt index e2ba1ae..4a78070 100644 --- a/First Principles/Assets/Resources/Localization/ja.txt +++ b/First Principles/Assets/Resources/Localization/ja.txt @@ -12,9 +12,6 @@ ui.jump=ジャンプ ui.move=移動 ui.keyboard_hint_mobile=(キーボード:矢印/スペース) hud.stage=ステージ -controls.mobile=移動 ◀ ▶ · ジャンプ タップ (キーボード:矢印/スペース) -controls.desktop=移動 · ジャンプ スペース -controls.calculator=グラフ電卓 f(u) を入力 · Trans · Scale · ピンチ · 戻る graph.label_fu=f(u) = graph.placeholder=x^2 + sin(x) · ln(x) (x>0)· min(x,3)... graph.status_enter=Enter/外側タップでグラフ描画 @@ -22,7 +19,7 @@ graph.status_graphed=描画済み graph.line1=グラフ電卓モード graph.line2=下にf(u)を入力(欄内の変数xは内側の u)。次に: graph.line3=Trans → {0} · ダブルタップ + · 長押し · Scale はタップで拡大/長押しで縮小 · 2本指ピンチ -graph.line4=A={0}  k={1}  C={2}  D={3}   x は [{4},{5}] +graph.line4=A={0} k={1} C={2} D={3} x は [{4},{5}] graph.param_a=A(縦スケール) graph.param_k=k(横スケール) graph.param_c=C(縦シフト) @@ -65,20 +62,28 @@ level.30=BC:位相と単振動(エネルギー) level.31=BC:三次関数と変曲点(スケッチ) level.32=BC:b^x と d/dx b^x level.33=円:(x−h)² + (y−k)² = R² -level.34=航空:揚力C_L(α) 線形+失速 -level.35=航空:抗力極曲線(プロファイル·誘導·合計) -level.36=航空:等温大気 ρ(h) -level.37=航空:フゴイド/減衰ピッチ・上下動 -level.38=航空:ニュートン流 Cp ~ sin²α -level.39=航空:ストルーハル/渦放出音 -level.40=航空:再突入減衰包絡線(ρV加熱) -level.41=経済:ドットコムバブルと暴落(模式化インデックス) -level.42=経済:2008年危機と回復(模式化インデックス) -level.43=BOSS:マンデルブロ脱出断面(フラクタル) -level.44=物理C:熱力学(断熱P–V、γはNから) -level.45=BOSS:黄金螺旋(対数・極座標) -level.46=変換:フーリエ — sincスペクトラム -level.47=変換:ラプラス — 指数減衰 -level.48=BOSS:マンデルブロ — フィナーレ(フラクタル脱出断面) -level.49=BOSS:ローレンツの蝶 — フィナーレ(ストレンジアトラクター) +level.34=物理C:熱力学(断熱P–V、γはNから) +level.35=航空:揚力C_L(α) 線形+失速 +level.36=航空:抗力極曲線(プロファイル·誘導·合計) +level.37=航空:等温大気 ρ(h) +level.38=航空:フゴイド/減衰ピッチ・上下動 +level.39=航空:ニュートン流 Cp ~ sin²α +level.40=航空:ストルーハル/渦放出音 +level.41=航空:再突入減衰包絡線(ρV加熱) +level.42=経済:ドットコムバブルと暴落(模式化インデックス) +level.43=経済:2008年危機と回復(模式化インデックス) +level.44=変換:フーリエ — sincスペクトラム +level.45=変換:ラプラス — 指数減衰 +level.46=BOSS:黄金螺旋(対数・極座標) +level.47=BOSS:マンデルブロ — フィナーレ(フラクタル脱出断面) +level.48=BOSS:ローレンツアトラクター — カオス理論(ストレンジアトラクター) +level.49=BOSS:ブラックホール — 重力の井戸(1/r 断面) level.50=物理C:ばね–質点の単振動(フックの法則、減衰なし) +level.51=Big O: O(1) — constant time +level.52=Big O: O(log n) — logarithmic growth +level.53=Big O: O(√n) — sublinear root growth +level.54=Big O: O(n) — linear growth +level.55=Big O: O(n log n) — n log n growth +level.56=Big O: O(n²) — quadratic growth +level.57=Big O: O(n³) — cubic growth +level.58=Big O: O(2ⁿ) — exponential (base 2) diff --git a/First Principles/Assets/Resources/Localization/ko.txt b/First Principles/Assets/Resources/Localization/ko.txt index b703cd5..b931127 100644 --- a/First Principles/Assets/Resources/Localization/ko.txt +++ b/First Principles/Assets/Resources/Localization/ko.txt @@ -13,10 +13,11 @@ level_select.cat.integration=다변수 & 적분 level_select.cat.engineering=공학 level_select.cat.ap_bc=AP 미적분 BC · 물리 C level_select.cat.aerospace=항공우주 -level_select.cat.finale=심화 & 보스 +level_select.cat.economics=경제 level_select.cat.transforms=변환 level_select.cat.final_boss=최종 보스 level_select.cat.spring_physics=스프링·단진동 +level_select.cat.big_o=빅오 표기법 ui.math_tips=수학 팁 모음 ui.back_menu=메뉴로 ui.graphing_calculator_mode=그래프 계산기 @@ -29,9 +30,6 @@ ui.jump=점프 ui.move=이동 ui.keyboard_hint_mobile=(키보드: 방향키 / 스페이스) hud.stage=스테이지 -controls.mobile=이동 ◀ ▶ · 점프 (키보드: 방향키 / 스페이스) -controls.desktop=이동 · 점프 스페이스 -controls.calculator=그래프 계산기 f(u) 입력 · Trans · Scale · 핀치 · 뒤로 graph.label_fu=f(u) = graph.placeholder=x^2 + sin(x) · ln(x) (x>0) · min(x,3)... graph.status_enter=Enter / 바깥 탭으로 그래프 @@ -39,7 +37,7 @@ graph.status_graphed=그래프 완료 graph.line1=그래프 계산기 모드 graph.line2=아래에 f(u) 입력(상자 안 변수 x = 내부 u). 그다음: graph.line3=Trans → {0} · 더블탭 + · 길게 · Scale 탭 확대 / 길게 축소 · 두 손가락 핀치 -graph.line4=A={0}  k={1}  C={2}  D={3}   x ∈ [{4},{5}] +graph.line4=A={0} k={1} C={2} D={3} x ∈ [{4},{5}] graph.param_a=A (세로 스케일) graph.param_k=k (가로 스케일) graph.param_c=C (세로 이동) @@ -83,20 +81,28 @@ level.30=BC: 위상과 단진동 (에너지) level.31=BC: 삼차함수와 변곡점 (스케치) level.32=BC: b^x와 d/dx b^x level.33=원: (x−h)² + (y−k)² = R² -level.34=항공: 양력 C_L(α) 선형 및 실속 -level.35=항공: 항력 극곡선 (패러사이틱·유도·합) -level.36=항공: 등온 대기 ρ(h) -level.37=항공: 퓨고이드 / 감쇠 피치-헤이브 -level.38=항공: 뉴턴 Cp ~ sin²α -level.39=항공: 스트루할 / 와류 방출 음 -level.40=항공: 재진입 감쇠 포락선 (ρV 가열) -level.41=경제: 닷컴 버블·붕괴 (스타일화 지수) -level.42=경제: 2008 위기·회복 (스타일화 지수) -level.43=보스: 만델브로 탈출 단면 (프랙탈) -level.44=물리 C: 열역학 (단열 P–V, γ는 N에서) -level.45=보스: 황금비 나선 (로그 극좌표) -level.46=변환: 푸리에 — sinc 스펙트럼 -level.47=변환: 라플라스 — 지수 감쇠 -level.48=보스: 만델브로 — 피날레 (프랙탈 탈출 단면) -level.49=보스: 로렌츠 나비 — 피날레 (이상한 끌개) +level.34=물리 C: 열역학 (단열 P–V, γ는 N에서) +level.35=항공: 양력 C_L(α) 선형 및 실속 +level.36=항공: 항력 극곡선 (패러사이틱·유도·합) +level.37=항공: 등온 대기 ρ(h) +level.38=항공: 퓨고이드 / 감쇠 피치-헤이브 +level.39=항공: 뉴턴 Cp ~ sin²α +level.40=항공: 스트루할 / 와류 방출 음 +level.41=항공: 재진입 감쇠 포락선 (ρV 가열) +level.42=경제: 닷컴 버블·붕괴 (스타일화 지수) +level.43=경제: 2008 위기·회복 (스타일화 지수) +level.44=변환: 푸리에 — sinc 스펙트럼 +level.45=변환: 라플라스 — 지수 감쇠 +level.46=보스: 황금비 나선 (로그 극좌표) +level.47=보스: 만델브로 — 피날레 (프랙탈 탈출 단면) +level.48=보스: 로렌츠 어트랙터 — 카오스 이론 (이상한 끌개) +level.49=보스: 블랙홀 — 중력 우물 (1/r 단면) level.50=물리 C: 스프링–질점 SHM (훅의 법칙, 비감쇠) +level.51=Big O: O(1) — constant time +level.52=Big O: O(log n) — logarithmic growth +level.53=Big O: O(√n) — sublinear root growth +level.54=Big O: O(n) — linear growth +level.55=Big O: O(n log n) — n log n growth +level.56=Big O: O(n²) — quadratic growth +level.57=Big O: O(n³) — cubic growth +level.58=Big O: O(2ⁿ) — exponential (base 2) diff --git a/First Principles/Assets/Resources/Localization/pl.txt b/First Principles/Assets/Resources/Localization/pl.txt index fe27aa8..e16f0d3 100644 --- a/First Principles/Assets/Resources/Localization/pl.txt +++ b/First Principles/Assets/Resources/Localization/pl.txt @@ -7,10 +7,11 @@ level_select.cat.integration=Zmienne wielowymiarowe i całki level_select.cat.engineering=Inżynieria level_select.cat.ap_bc=AP Calculus BC i Fizyka C level_select.cat.aerospace=Lotnictwo i kosmonautyka -level_select.cat.finale=Zaawansowane i boss +level_select.cat.economics=Ekonomia level_select.cat.transforms=Transformaty level_select.cat.final_boss=Finałowy boss level_select.cat.spring_physics=Sprężyna i SHM +level_select.cat.big_o=Notacja dużego O ui.math_tips=Wskazówki matematyczne ui.back_menu=Powrót do menu ui.graphing_calculator_mode=Kalkulator graficzny @@ -24,9 +25,6 @@ ui.jump=Skok ui.move=Ruch ui.keyboard_hint_mobile=(klawiatura: strzałki / Spacja) hud.stage=ETAP -controls.mobile=Ruch ◀ ▶ · Skok dotknij (klawiatura: strzałki / Spacja) -controls.desktop=Ruch · Skok Spacja -controls.calculator=Kalkulator graficzny Wpisz f(u) · Trans · Skala · Szczyp · Wstecz graph.label_fu=f(u) = graph.placeholder=x^2 + sin(x) · ln(x) dla x>0 · min(x,3)... graph.status_enter=Enter / dotknij poza pole, aby narysować @@ -34,7 +32,7 @@ graph.status_graphed=Narysowano graph.line1=Tryb kalkulatora graficznego graph.line2=Wpisz f(u) poniżej (zmienna x w polu = wewnętrzne u). Potem: graph.line3=Trans → {0} · podwójne dotknięcie + · przytrzymaj · Skala przybliż / przytrzymaj oddal · szczyp dwoma palcami -graph.line4=A={0}  k={1}  C={2}  D={3}   x w [{4},{5}] +graph.line4=A={0} k={1} C={2} D={3} x w [{4},{5}] graph.param_a=A (skala pionowa) graph.param_k=k (skala pozioma) graph.param_c=C (przesunięcie pionowe) @@ -85,20 +83,28 @@ level.30=BC: faza i drgania harmoniczne (wymiana energii) level.31=BC: sześcienny i punkt przegięcia level.32=BC: b^x i d/dx b^x level.33=Okrąg: (x−h)² + (y−k)² = R² -level.34=Aerospace: siła nośna C_L(α) liniowa + przeciągnięcie -level.35=Aerospace: polara oporu (pasożytniczy, indukowany, całkowity) -level.36=Aerospace: atmosfera izotermiczna ρ(h) -level.37=Aerospace: fugoide / stłumiony tryb przechylenia -level.38=Aerospace: newtonowskie Cp ~ sin²α -level.39=Aerospace: Strouhal / ton wirów -level.40=Aerospace: obwiednia zaniku przy wejściu (ρV ciepło) -level.41=Ekonomia: bańka dot-com i krach (stylizowany indeks) -level.42=Ekonomia: kryzys 2008 i odbicie (stylizowany indeks) -level.43=BOSS: przekrój ucieczki Mandelbrota (nastrój fraktalny) -level.44=Fizyka C: termodynamika (adiabatyczny P–V, γ z N) -level.45=BOSS: spirala złotego podziału (logarytmiczna, biegunowa) -level.46=Transformaty: Fourier — sinc (widmo) -level.47=Transformaty: Laplace — wykładniczy zanik -level.48=BOSS: Mandelbrot — finał (fraktalny przekrój ucieczki) -level.49=BOSS: motyl Lorenza — finał (dziwny atraktor) +level.34=Fizyka C: termodynamika (adiabatyczny P–V, γ z N) +level.35=Aerospace: siła nośna C_L(α) liniowa + przeciągnięcie +level.36=Aerospace: polara oporu (pasożytniczy, indukowany, całkowity) +level.37=Aerospace: atmosfera izotermiczna ρ(h) +level.38=Aerospace: fugoide / stłumiony tryb przechylenia +level.39=Aerospace: newtonowskie Cp ~ sin²α +level.40=Aerospace: Strouhal / ton wirów +level.41=Aerospace: obwiednia zaniku przy wejściu (ρV ciepło) +level.42=Ekonomia: bańka dot-com i krach (stylizowany indeks) +level.43=Ekonomia: kryzys 2008 i odbicie (stylizowany indeks) +level.44=Transformaty: Fourier — sinc (widmo) +level.45=Transformaty: Laplace — wykładniczy zanik +level.46=BOSS: spirala złotego podziału (logarytmiczna, biegunowa) +level.47=BOSS: Mandelbrot — finał (fraktalny przekrój ucieczki) +level.48=BOSS: atraktor Lorenza — teoria chaosu (dziwny atraktor) +level.49=BOSS: czarna dziura — studnia grawitacji (przekrój 1/r) level.50=Fizyka C: sprężyna–masa SHM (prawo Hooka, nietłumione) +level.51=Big O: O(1) — constant time +level.52=Big O: O(log n) — logarithmic growth +level.53=Big O: O(√n) — sublinear root growth +level.54=Big O: O(n) — linear growth +level.55=Big O: O(n log n) — n log n growth +level.56=Big O: O(n²) — quadratic growth +level.57=Big O: O(n³) — cubic growth +level.58=Big O: O(2ⁿ) — exponential (base 2) diff --git a/First Principles/Assets/Resources/Localization/ru.txt b/First Principles/Assets/Resources/Localization/ru.txt index 38e7881..595cc09 100644 --- a/First Principles/Assets/Resources/Localization/ru.txt +++ b/First Principles/Assets/Resources/Localization/ru.txt @@ -7,10 +7,11 @@ level_select.cat.integration=Многие переменные и интегра level_select.cat.engineering=Инженерия level_select.cat.ap_bc=AP Calculus BC и физика C level_select.cat.aerospace=Аэрокосмос -level_select.cat.finale=Сложные и босс +level_select.cat.economics=Экономика level_select.cat.transforms=Преобразования level_select.cat.final_boss=Финальный босс level_select.cat.spring_physics=Пружина и ГС +level_select.cat.big_o=О-нотация ui.math_tips=Советы по математике ui.back_menu=В меню ui.graphing_calculator_mode=Графический калькулятор @@ -24,9 +25,6 @@ ui.jump=Прыжок ui.move=Движение ui.keyboard_hint_mobile=(клавиатура: стрелки / Пробел) hud.stage=ЭТАП -controls.mobile=Движение ◀ ▶ · Прыжок тап (клавиатура: стрелки / Пробел) -controls.desktop=Движение · Прыжок Пробел -controls.calculator=Граф. калькулятор Ввод f(u) · Транс · Масштаб · Щипок · Назад graph.label_fu=f(u) = graph.placeholder=x^2 + sin(x) · ln(x) при x>0 · min(x,3)... graph.status_enter=Enter / тап вне поля для графика @@ -34,7 +32,7 @@ graph.status_graphed=Построено graph.line1=Режим графического калькулятора graph.line2=Введите f(u) ниже (переменная x в поле = внутреннее u). Затем: graph.line3=Транс → {0} · двойной тап + · удерживайте · Масштаб увеличить / удерживайте уменьшить · щипок двумя пальцами -graph.line4=A={0}  k={1}  C={2}  D={3}   x ∈ [{4},{5}] +graph.line4=A={0} k={1} C={2} D={3} x ∈ [{4},{5}] graph.param_a=A (вертикальный масштаб) graph.param_k=k (горизонтальный масштаб) graph.param_c=C (вертикальный сдвиг) @@ -85,20 +83,28 @@ level.30=BC: фаза и гармонические колебания level.31=BC: кубическая и точка перегиба level.32=BC: b^x и d/dx b^x level.33=Окружность: (x−h)² + (y−k)² = R² -level.34=Aerospace: подъёмная сила C_L(α) линейно + срыв -level.35=Aerospace: поляра сопротивления (паразит., индукт., суммарн.) -level.36=Aerospace: изотерм. атмосфера ρ(h) -level.37=Aerospace: фюгоид / затух. тангаж-высота -level.38=Aerospace: ньютоновское Cp ~ sin²α -level.39=Aerospace: Струхал / тон вихревой дорожки -level.40=Aerospace: оболочка затухания при входе (ρV тепло) -level.41=Экономика: пузырь dot-com и крах (стилиз. индекс) -level.42=Экономика: кризис 2008 и восстановление (стилиз. индекс) -level.43=БОСС: сечение убегания Мандельброта (фрактал) -level.44=Физика C: термодинамика (адиабата P–V, γ из N) -level.45=БОСС: золотая спираль (логарифмическая, полярная) -level.46=Преобразования: Фурье — sinc-спектр -level.47=Преобразования: Лаплас — затухание -level.48=БОСС: Мандельброт — финал (фрактальный срез побега) -level.49=БОСС: эффект бабочки Лоренца — финал (странный аттрактор) +level.34=Физика C: термодинамика (адиабата P–V, γ из N) +level.35=Aerospace: подъёмная сила C_L(α) линейно + срыв +level.36=Aerospace: поляра сопротивления (паразит., индукт., суммарн.) +level.37=Aerospace: изотерм. атмосфера ρ(h) +level.38=Aerospace: фюгоид / затух. тангаж-высота +level.39=Aerospace: ньютоновское Cp ~ sin²α +level.40=Aerospace: Струхал / тон вихревой дорожки +level.41=Aerospace: оболочка затухания при входе (ρV тепло) +level.42=Экономика: пузырь dot-com и крах (стилиз. индекс) +level.43=Экономика: кризис 2008 и восстановление (стилиз. индекс) +level.44=Преобразования: Фурье — sinc-спектр +level.45=Преобразования: Лаплас — затухание +level.46=БОСС: золотая спираль (логарифмическая, полярная) +level.47=БОСС: Мандельброт — финал (фрактальный срез побега) +level.48=БОСС: аттрактор Лоренца — теория хаоса (странный аттрактор) +level.49=БОСС: чёрная дыра — гравитационная яма (сечение 1/r) level.50=Физика C: пружина–масса ГС (закон Гука, без затухания) +level.51=Big O: O(1) — constant time +level.52=Big O: O(log n) — logarithmic growth +level.53=Big O: O(√n) — sublinear root growth +level.54=Big O: O(n) — linear growth +level.55=Big O: O(n log n) — n log n growth +level.56=Big O: O(n²) — quadratic growth +level.57=Big O: O(n³) — cubic growth +level.58=Big O: O(2ⁿ) — exponential (base 2) diff --git a/First Principles/Assets/Resources/Localization/ur.txt b/First Principles/Assets/Resources/Localization/ur.txt index e9c290f..982201c 100644 --- a/First Principles/Assets/Resources/Localization/ur.txt +++ b/First Principles/Assets/Resources/Localization/ur.txt @@ -13,9 +13,6 @@ ui.jump=چھلانگ ui.move=حرکت ui.keyboard_hint_mobile=(کی بورڈ: تیر / اسپیس) hud.stage=اسٹیج -controls.mobile=حرکت ◀ ▶ · چھلانگ تھپتھی (کی بورڈ: تیر / اسپیس) -controls.desktop=حرکت · چھلانگ اسپیس -controls.calculator=گرافنگ کیلکولیٹر f(u) لکھیں · Trans · Scale · پنچ · واپس graph.label_fu=f(u) = graph.placeholder=x^2 + sin(x) · ln(x) جب x>0 · min(x,3)... graph.status_enter=Enter / گراف کے لیے باہر تھپتھپائیں @@ -23,7 +20,7 @@ graph.status_graphed=گراف مکمل graph.line1=گرافنگ کیلکولیٹر موڈ graph.line2=f(u) نیچے لکھیں (باکس میں متغیر x = اندرونی u)۔ پھر: graph.line3=Trans → {0} · + پر ڈبل-تھپتھی · دبائے رکھیں · Scale زوم اندر / باہر دبائے رکھیں · دو انگلیوں سے پنچ -graph.line4=A={0}  k={1}  C={2}  D={3}   x ∈ [{4},{5}] +graph.line4=A={0} k={1} C={2} D={3} x ∈ [{4},{5}] graph.param_a=A (عمودی پیمانہ) graph.param_k=k (افقی پیمانہ) graph.param_c=C (عمودی بِدائل) @@ -67,20 +64,28 @@ level.30=BC: مرحلہ اور SHM level.31=BC: مکعب اور انفلیکشن level.32=BC: b^x و d/dx b^x level.33=دائرہ: (x−h)² + (y−k)² = R² -level.34=ایرواسپیس: لفٹ C_L(α) + اسٹال -level.35=ایرواسپیس: ڈریگ پولر (پیراسٹک، انڈیوسڈ، کل) -level.36=ایرواسپیس: ہمحرارتی فضا ρ(h) -level.37=ایرواسپیس: فیگوئڈ / ڈیمپڈ موڈ -level.38=ایرواسپیس: نیوٹنی Cp ~ sin²α -level.39=ایرواسپیس: اسٹروہل / وورٹیکس شیڈنگ -level.40=ایرواسپیس: دوبارہ دخول زوال -level.41=معیشت: ڈاٹ کام ببل اور حادثہ (اسٹائل شدہ انڈیکس) -level.42=معیشت: 2008 بحران اور بحالی (اسٹائل شدہ انڈیکس) -level.43=بوس: مینڈلبرو فرکٹل سلائس -level.44=فزکس C: تھرموڈائنانمکس (ایڈیابیٹک P–V، γ از N) -level.45=بوس: سنہری تناسب سنئلی (لوگ قطبی) -level.46=تبدیل: فوریے — سینک سپیکٹرم -level.47=تبدیل: لاپلاس — نماتی زوال -level.48=بوس: مینڈلبرو — اختتام (فرکٹل فرار سلائس) -level.49=بوس: لورینز تیتلی — اختتام (عجیب اٹریکٹر) +level.34=فزکس C: تھرموڈائنانمکس (ایڈیابیٹک P–V، γ از N) +level.35=ایرواسپیس: لفٹ C_L(α) + اسٹال +level.36=ایرواسپیس: ڈریگ پولر (پیراسٹک، انڈیوسڈ، کل) +level.37=ایرواسپیس: ہمحرارتی فضا ρ(h) +level.38=ایرواسپیس: فیگوئڈ / ڈیمپڈ موڈ +level.39=ایرواسپیس: نیوٹنی Cp ~ sin²α +level.40=ایرواسپیس: اسٹروہل / وورٹیکس شیڈنگ +level.41=ایرواسپیس: دوبارہ دخول زوال +level.42=معیشت: ڈاٹ کام ببل اور حادثہ (اسٹائل شدہ انڈیکس) +level.43=معیشت: 2008 بحران اور بحالی (اسٹائل شدہ انڈیکس) +level.44=تبدیل: فوریے — سینک سپیکٹرم +level.45=تبدیل: لاپلاس — نماتی زوال +level.46=بوس: سنہری تناسب سنئلی (لوگ قطبی) +level.47=بوس: مینڈلبرو — اختتام (فرکٹل فرار سلائس) +level.48=بوس: لورینز اٹریکٹر — کیس تھیوری (عجیب اٹریکٹر) +level.49=باس: بلیک ہول — کشش ثقل کنواں (1/r سلائس) level.50=فزکس C: سپرنگ–عنصر جرم SHM (ہوک کا قانون، ڈیمپنگ کے بغیر) +level.51=Big O: O(1) — constant time +level.52=Big O: O(log n) — logarithmic growth +level.53=Big O: O(√n) — sublinear root growth +level.54=Big O: O(n) — linear growth +level.55=Big O: O(n log n) — n log n growth +level.56=Big O: O(n²) — quadratic growth +level.57=Big O: O(n³) — cubic growth +level.58=Big O: O(2ⁿ) — exponential (base 2) diff --git a/First Principles/Assets/Resources/Localization/zh.txt b/First Principles/Assets/Resources/Localization/zh.txt index 6f990e4..83dcc99 100644 --- a/First Principles/Assets/Resources/Localization/zh.txt +++ b/First Principles/Assets/Resources/Localization/zh.txt @@ -12,9 +12,6 @@ ui.jump=跳跃 ui.move=移动 ui.keyboard_hint_mobile=(键盘:方向键 / 空格) hud.stage=阶段 -controls.mobile=移动 ◀ ▶ · 跳跃 点按 (键盘:方向键 / 空格) -controls.desktop=移动 · 跳跃 空格 -controls.calculator=图形计算器 输入 f(u) · Trans · Scale · 双指缩放 · 返回 graph.label_fu=f(u) = graph.placeholder=x^2 + sin(x) · ln(x)(x>0)· min(x,3)... graph.status_enter=回车 / 点击外部绘制图象 @@ -22,7 +19,7 @@ graph.status_graphed=已绘制 graph.line1=图形计算器模式 graph.line2=在下方输入 f(u)(框内变量 x 为内层 u)。然后: graph.line3=Trans → {0} · 双击 + · 长按 · Scale 点按放大 / 长按缩小 · 双指 捏合 -graph.line4=A={0}  k={1}  C={2}  D={3}   x 在 [{4},{5}] 内 +graph.line4=A={0} k={1} C={2} D={3} x 在 [{4},{5}] 内 graph.param_a=A(纵向缩放) graph.param_k=k(横向缩放) graph.param_c=C(纵向平移) @@ -65,20 +62,28 @@ level.30=BC:相位与简谐振动(能量) level.31=BC:三次与拐点(作图) level.32=BC:b^x 与 d/dx b^x level.33=圆:(x−h)² + (y−k)² = R² -level.34=航空:升力 C_L(α) 线性+失速 -level.35=航空:阻力极曲线(型阻·诱导·总阻) -level.36=航空:等温大气 ρ(h) -level.37=航空:起伏运动 / 阻尼俯仰-沉浮 -level.38=航空:牛顿流 Cp ~ sin²α -level.39=航空:斯特劳哈尔 / 涡脱落音 -level.40=航空:再入衰减包络(ρV 加热) -level.41=经济:互联网泡沫与崩盘(示意指数曲线) -level.42=经济:2008 危机与复苏(示意指数曲线) -level.43=BOSS:曼德博逃逸截面(分形) -level.44=物理C:热力学(绝热P–V,γ由N给出) -level.45=BOSS:黄金比例螺旋(对数极坐标) -level.46=变换:傅里叶 — sinc 频谱 -level.47=变换:拉普拉斯 — 指数衰减 -level.48=BOSS:曼德博 — 终章(分形逃逸截面) -level.49=BOSS:洛伦兹蝴蝶 — 终章(奇异吸引子) +level.34=物理C:热力学(绝热P–V,γ由N给出) +level.35=航空:升力 C_L(α) 线性+失速 +level.36=航空:阻力极曲线(型阻·诱导·总阻) +level.37=航空:等温大气 ρ(h) +level.38=航空:起伏运动 / 阻尼俯仰-沉浮 +level.39=航空:牛顿流 Cp ~ sin²α +level.40=航空:斯特劳哈尔 / 涡脱落音 +level.41=航空:再入衰减包络(ρV 加热) +level.42=经济:互联网泡沫与崩盘(示意指数曲线) +level.43=经济:2008 危机与复苏(示意指数曲线) +level.44=变换:傅里叶 — sinc 频谱 +level.45=变换:拉普拉斯 — 指数衰减 +level.46=BOSS:黄金比例螺旋(对数极坐标) +level.47=BOSS:曼德博 — 终章(分形逃逸截面) +level.48=BOSS:洛伦兹吸引子 — 混沌理论(奇异吸引子) +level.49=BOSS:黑洞 — 引力势阱(1/r 切片) level.50=物理C:弹簧–质点简谐振动(胡克定律,无阻尼) +level.51=Big O: O(1) — constant time +level.52=Big O: O(log n) — logarithmic growth +level.53=Big O: O(√n) — sublinear root growth +level.54=Big O: O(n) — linear growth +level.55=Big O: O(n log n) — n log n growth +level.56=Big O: O(n²) — quadratic growth +level.57=Big O: O(n³) — cubic growth +level.58=Big O: O(2ⁿ) — exponential (base 2) diff --git a/First Principles/Assets/Resources/UI_BlackHoleGargantuaBackdrop.shader b/First Principles/Assets/Resources/UI_BlackHoleGargantuaBackdrop.shader new file mode 100644 index 0000000..0a6dbbc --- /dev/null +++ b/First Principles/Assets/Resources/UI_BlackHoleGargantuaBackdrop.shader @@ -0,0 +1,208 @@ +// GPU backdrop for the gravity-well boss: Schwarzschild equatorial null geodesics. +// Math: photon Binet equation d²u/dφ² + u = 3 M u² with u = 1/r (G = c = 1). +// First integral (conserved b = L/E): (du/dφ)² = (1−2Mu)²/b² − u² + 2M u³. +// Ray is stepped in φ; emission samples a thin equatorial accretion disk (multiple passes = lensed images). +// Not full Kerr (Gargantua is rotating); Schwarzschild is the documented GR core here. +Shader "UI/BlackHoleGargantuaBackdrop" +{ + Properties + { + [PerRendererData] _MainTex ("Dummy", 2D) = "white" {} + _Color ("Multiply", Color) = (1, 1, 1, 0.78) + _Mass ("M (geometric units, Rs=2M)", Float) = 1 + _CamDist ("Observer Schwarzschild r", Float) = 16 + _BMin ("Impact param b min", Float) = 3.3 + _BMax ("Impact param b max", Float) = 14 + _DiskIn ("Disk inner r / M", Float) = 3.35 + _DiskOut ("Disk outer r / M", Float) = 9 + _DiskSpin ("Disk phase speed", Float) = 0.35 + _DiskBright ("Disk emissivity", Float) = 2.4 + _PhotonRing ("Photon ring boost", Float) = 1.15 + _Dphi ("φ step (radians)", Float) = 0.045 + _Steps ("Integration steps", Int) = 88 + _Aspect ("UV width / height", Float) = 1.7 + _TimeLive ("Time (set from C#)", Float) = 0 + _StarField ("Star field strength", Float) = 0.085 + } + + SubShader + { + Tags + { + "Queue" = "Transparent" + "IgnoreProjector" = "True" + "RenderType" = "Transparent" + "PreviewType" = "Plane" + "CanUseSpriteAtlas" = "True" + } + + ZWrite Off + ZTest Always + Blend SrcAlpha OneMinusSrcAlpha + Cull Off + + Pass + { + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #pragma target 3.0 + #include "UnityCG.cginc" + + sampler2D _MainTex; + float4 _MainTex_ST; + float4 _Color; + float _Mass; + float _CamDist; + float _BMin; + float _BMax; + float _DiskIn; + float _DiskOut; + float _DiskSpin; + float _DiskBright; + float _PhotonRing; + float _Dphi; + int _Steps; + float _Aspect; + float _TimeLive; + float _StarField; + + struct appdata + { + float4 vertex : POSITION; + float4 color : COLOR; + float2 texcoord : TEXCOORD0; + }; + + struct v2f + { + float4 vertex : SV_POSITION; + float4 color : COLOR; + float2 uv : TEXCOORD0; + }; + + v2f vert(appdata v) + { + v2f o; + o.vertex = UnityObjectToClipPos(v.vertex); + o.color = v.color; + o.uv = v.texcoord; + return o; + } + + // Cheap hash for star speckle (not physical, background only). + float n2(float2 p) + { + return frac(sin(dot(p, float2(127.1, 311.7))) * 43758.5453); + } + + void rk4Step(inout float u, inout float v, inout float phi, float M, float h) + { + float h2 = h * 0.5; + float k1u = v; + float k1v = 3.0 * M * u * u - u; + float u2 = u + h2 * k1u; + float v2 = v + h2 * k1v; + float k2u = v2; + float k2v = 3.0 * M * u2 * u2 - u2; + u2 = u + h2 * k2u; + v2 = v + h2 * k2v; + float k3u = v2; + float k3v = 3.0 * M * u2 * u2 - u2; + u2 = u + h * k3u; + v2 = v + h * k3v; + float k4u = v2; + float k4v = 3.0 * M * u2 * u2 - u2; + u += h * (k1u + 2.0 * k2u + 2.0 * k3u + k4u) / 6.0; + v += h * (k1v + 2.0 * k2v + 2.0 * k3v + k4v) / 6.0; + phi += h; + } + + fixed4 frag(v2f i) : SV_Target + { + float2 uv = i.uv; + float M = max(_Mass, 0.05); + float Rs = 2.0 * M; + float rObs = max(_CamDist, Rs * 1.5); + float u = 1.0 / rObs; + float b = lerp(_BMin, _BMax, uv.x); + b = max(b, Rs * 1.01); + float fMu = 1.0 - 2.0 * M * u; + if (fMu <= 0.001) + return fixed4(0, 0, 0, _Color.a * i.color.a); + + float disc = (1.0 / (b * b)) * fMu * fMu - u * u + 2.0 * M * u * u * u; + if (disc < 0.0) + disc = 0.0; + float v = sqrt(disc); + float vy = (uv.y - 0.5) * 2.2; + v *= 1.0 + vy * 0.18; + + float phi = 0.0; + int steps = clamp(_Steps, 24, 128); + float h = max(_Dphi, 0.012); + + float3 acc = float3(0, 0, 0); + float dIn = _DiskIn * M; + float dOut = _DiskOut * M; + float rPhIn = 2.95 * M; + float rPhOut = 3.15 * M; + + for (int k = 0; k < 128; k++) + { + if (k >= steps) + break; + + float r = 1.0 / max(u, 1e-5); + if (r < Rs + 0.015) + { + acc += float3(0, 0, 0.015); + break; + } + + float x = r * cos(phi); + float z = r * sin(phi); + float rho = sqrt(x * x + z * z); + + if (rho > dIn && rho < dOut) + { + float t = saturate((rho - dIn) / max(dOut - dIn, 1e-3)); + float band = smoothstep(0.0, 0.08, t) * smoothstep(1.0, 0.92, t); + float spin = phi + _TimeLive * _DiskSpin; + float dop = 1.0 + 0.42 * sin(spin + uv.x * 6.28318); + dop *= 1.0 - 0.22 * sin(spin * 0.5 + vy * 3.14); + float3 hot = lerp(float3(1.0, 0.18, 0.02), float3(1.0, 0.55, 0.2), t); + hot = lerp(hot, float3(1.0, 0.85, 0.55), pow(t, 2.2)); + acc += hot * band * dop * _DiskBright * h * 2.8; + } + + if (rho > rPhIn && rho < rPhOut) + { + float pr = smoothstep(rPhIn, rPhIn + 0.04 * M, rho) * smoothstep(rPhOut, rPhOut - 0.04 * M, rho); + acc += float3(1.0, 0.95, 0.78) * pr * _PhotonRing * h * 0.45; + } + + rk4Step(u, v, phi, M, h); + + if (u < 0.0 || u > 200.0) + break; + + if (u > 1.0 / max(Rs * 0.98, 1e-4)) + break; + } + + float2 suv = uv * float2(_Aspect * 120.0, 120.0); + float stars = pow(n2(floor(suv)), 12.0) * _StarField; + acc += float3(0.55, 0.62, 1.0) * stars; + + float lum = max(max(acc.x, acc.y), acc.z); + acc = acc / (lum + 0.85); + fixed4 outc = fixed4(acc, _Color.a * i.color.a); + outc.rgb *= _Color.rgb * i.color.rgb; + return outc; + } + ENDCG + } + } + FallBack Off +} diff --git a/First Principles/Assets/Resources/UI_BlackHoleGargantuaBackdrop.shader.meta b/First Principles/Assets/Resources/UI_BlackHoleGargantuaBackdrop.shader.meta new file mode 100644 index 0000000..10331f2 --- /dev/null +++ b/First Principles/Assets/Resources/UI_BlackHoleGargantuaBackdrop.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 6fa2973b396514f74aff0c0946fabcf4 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/First Principles/Assets/Resources/UI_GoldenSpiralBackdrop.shader b/First Principles/Assets/Resources/UI_GoldenSpiralBackdrop.shader new file mode 100644 index 0000000..0639d9f --- /dev/null +++ b/First Principles/Assets/Resources/UI_GoldenSpiralBackdrop.shader @@ -0,0 +1,121 @@ +// Procedural logarithmic spiral mood (golden ratio boss): φ-growth arms in polar view, +// warm gold on deep field — matches r ∝ φ^{kθ} teaching language on the stage. +Shader "UI/GoldenSpiralBackdrop" +{ + Properties + { + [PerRendererData] _MainTex ("Dummy", 2D) = "white" {} + _Color ("Tint & alpha", Color) = (1, 0.85, 0.45, 0.48) + _Aspect ("UV width / height", Float) = 1.7 + _TimeLive ("Time", Float) = 0 + } + + SubShader + { + Tags + { + "Queue" = "Transparent" + "IgnoreProjector" = "True" + "RenderType" = "Transparent" + "PreviewType" = "Plane" + "CanUseSpriteAtlas" = "True" + } + + ZWrite Off + ZTest Always + Blend SrcAlpha OneMinusSrcAlpha + Cull Off + + Pass + { + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #include "UnityCG.cginc" + + sampler2D _MainTex; + float4 _MainTex_ST; + float4 _Color; + float _Aspect; + float _TimeLive; + + struct appdata + { + float4 vertex : POSITION; + float4 color : COLOR; + float2 texcoord : TEXCOORD0; + }; + + struct v2f + { + float4 vertex : SV_POSITION; + float4 color : COLOR; + float2 uv : TEXCOORD0; + }; + + v2f vert(appdata v) + { + v2f o; + o.vertex = UnityObjectToClipPos(v.vertex); + o.color = v.color; + o.uv = v.texcoord; + return o; + } + + fixed4 frag(v2f i) : SV_Target + { + float2 uv = i.uv; + float asp = max(_Aspect, 0.25); + float2 p = (uv - 0.5) * 2.0; + p.x *= asp; + + float r = length(p); + float ang = atan2(p.y, p.x); + + // Golden ratio φ; log-spiral with one arm per 2π matches r ∝ φ^{θ/(2π)}. + float phi = 1.618033988749; + float twoPi = 6.28318530718; + float b = log(phi) / twoPi; + + float t = _TimeLive * 0.22; + + float phase1 = log(r + 0.07) - b * ang; + float spiral1 = abs(frac(phase1 * 2.15 + t * 0.045) - 0.5); + + float phase2 = log(r + 0.09) - b * (ang + 2.399963); // ~ golden angle + float spiral2 = abs(frac(phase2 * 2.15 - t * 0.032) - 0.5); + + float phase3 = log(r + 0.05) - b * (-ang + 0.73); + float spiral3 = abs(frac(phase3 * 1.85 + t * 0.028) - 0.5); + + float arms = + smoothstep(0.13, 0.0, spiral1) + + smoothstep(0.13, 0.0, spiral2) * 0.72 + + smoothstep(0.11, 0.0, spiral3) * 0.45; + + float radPhase = log(r + 0.04) / log(phi) * 2.8 + t * 0.06; + float rings = smoothstep(0.09, 0.0, abs(frac(radPhase) - 0.5)) * 0.35; + + float vign = smoothstep(1.55, 0.28, r); + float core = smoothstep(0.02, 0.14, r); + + float3 bgDeep = float3(0.05, 0.04, 0.1); + float3 bgWarm = float3(0.12, 0.07, 0.04); + float3 baseCol = lerp(bgDeep, bgWarm, saturate(r * 0.35 + uv.y * 0.25)); + + float3 goldHi = float3(1.0, 0.9, 0.42); + float3 goldMid = float3(0.92, 0.62, 0.22); + float3 glow = lerp(goldMid, goldHi, arms * 0.65 + rings * 0.4); + + float intensity = (arms * 0.62 + rings * 0.28) * vign * (0.35 + 0.65 * core); + float3 col = baseCol + glow * intensity; + + col = saturate(col); + float a = _Color.a * i.color.a; + return fixed4(col * _Color.rgb * i.color.rgb, a); + } + ENDCG + } + } + FallBack Off +} diff --git a/First Principles/Assets/Resources/UI_GoldenSpiralBackdrop.shader.meta b/First Principles/Assets/Resources/UI_GoldenSpiralBackdrop.shader.meta new file mode 100644 index 0000000..b39048b --- /dev/null +++ b/First Principles/Assets/Resources/UI_GoldenSpiralBackdrop.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: a8e3c91d4f2b4069b7c5d8e1f3a2940b +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/First Principles/Assets/Resources/UI_WindTunnelBackdrop.shader b/First Principles/Assets/Resources/UI_WindTunnelBackdrop.shader new file mode 100644 index 0000000..70dd08c --- /dev/null +++ b/First Principles/Assets/Resources/UI_WindTunnelBackdrop.shader @@ -0,0 +1,156 @@ +// Procedural wind-tunnel mood (aerospace stages): left→right freestream, +// smoke/schlieren streaks, faint test-section grid, subtle symmetric airfoil silhouette. +Shader "UI/WindTunnelBackdrop" +{ + Properties + { + [PerRendererData] _MainTex ("Dummy", 2D) = "white" {} + _Color ("Tint & alpha", Color) = (0.9, 0.96, 1, 0.54) + _FlowSpeed ("Flow speed", Float) = 0.55 + _StreakScale ("Streak scale", Float) = 9 + _Aspect ("UV width / height", Float) = 1.7 + } + + SubShader + { + Tags + { + "Queue" = "Transparent" + "IgnoreProjector" = "True" + "RenderType" = "Transparent" + "PreviewType" = "Plane" + "CanUseSpriteAtlas" = "True" + } + + ZWrite Off + ZTest Always + Blend SrcAlpha OneMinusSrcAlpha + Cull Off + + Pass + { + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #include "UnityCG.cginc" + + sampler2D _MainTex; + float4 _MainTex_ST; + float4 _Color; + float _FlowSpeed; + float _StreakScale; + float _Aspect; + + struct appdata + { + float4 vertex : POSITION; + float4 color : COLOR; + float2 texcoord : TEXCOORD0; + }; + + struct v2f + { + float4 vertex : SV_POSITION; + float4 color : COLOR; + float2 uv : TEXCOORD0; + }; + + v2f vert(appdata v) + { + v2f o; + o.vertex = UnityObjectToClipPos(v.vertex); + o.color = v.color; + o.uv = v.texcoord; + return o; + } + + float hash21(float2 p) + { + float h = dot(p, float2(127.1, 311.7)); + return frac(sin(h) * 43758.5453123); + } + + float noise2(float2 p) + { + float2 i = floor(p); + float2 f = frac(p); + f = f * f * (3.0 - 2.0 * f); + float a = hash21(i); + float b = hash21(i + float2(1, 0)); + float c = hash21(i + float2(0, 1)); + float d = hash21(i + float2(1, 1)); + return lerp(lerp(a, b, f.x), lerp(c, d, f.x), f.y); + } + + float fbm(float2 p) + { + float s = 0.0; + float a = 0.5; + for (int k = 0; k < 5; k++) + { + s += a * noise2(p); + p *= 2.02; + a *= 0.5; + } + return s; + } + + // Thin symmetric airfoil thickness (teaching shape): y_t(x) ~ semi-ellipse chord. + float airfoilThickness(float xNorm) + { + xNorm = abs(xNorm); + if (xNorm >= 1.0) + return 0.0; + return 0.18 * sqrt(1.0 - xNorm * xNorm); + } + + fixed4 frag(v2f i) : SV_Target + { + float2 uv = i.uv; + float t = _Time.y * _FlowSpeed; + float asp = max(_Aspect, 0.25); + + float2 p = (uv - 0.5) * 2.0; + p.x *= asp; + + // Freestream along +x (wind enters from left of screen). + float2 flow = float2(uv.x * asp * _StreakScale * 0.35 + t * 0.9, uv.y * _StreakScale * 0.55); + float sm = fbm(flow); + float sm2 = fbm(flow * 1.6 + float2(3.1, -t * 0.4)); + + // Streaks: elongated along x. + float streak = pow(sm * sm2, 1.4); + streak *= smoothstep(0.15, 0.55, streak); + + // Wake wobble behind nominal chord (x in p space ~ -0.2 to 0.5). + float chordX = p.x / 0.62; + float yt = airfoilThickness(chordX); + float distWing = abs(p.y) - yt; + float wingMask = 1.0 - smoothstep(-0.02, 0.06, distWing); + float wake = smoothstep(0.05, 0.45, p.x) * exp(-abs(p.y) * 2.2) * (1.0 - smoothstep(-0.35, 0.55, p.x)); + + float turbWake = fbm(float2(p.x * 4.0 - t * 1.2, p.y * 8.0 + sin(p.x * 6.0 + t))) * wake * 0.55; + + // Test-section vertical rails (window frames). + float rail = smoothstep(0.02, 0.0, abs(uv.x - 0.08)) + smoothstep(0.02, 0.0, abs(uv.x - 0.92)); + rail *= 0.15; + + // Cool tunnel base gradient (floor darker) — slightly lifted for readability. + float3 baseCol = lerp(float3(0.06, 0.1, 0.15), float3(0.13, 0.18, 0.26), uv.y); + baseCol += float3(0.08, 0.12, 0.17) * (1.0 - uv.y) * rail; + + float3 mist = float3(0.58, 0.76, 0.98) * streak * 0.72; + mist += float3(0.5, 0.66, 0.92) * turbWake * 1.12; + mist += float3(0.32, 0.42, 0.58) * wingMask * 0.16; + + float3 col = baseCol + mist; + col = saturate(col); + + float a = _Color.a * i.color.a; + return fixed4(col * _Color.rgb * i.color.rgb, a); + } + ENDCG + } + } + FallBack Off +} diff --git a/First Principles/Assets/Resources/UI_WindTunnelBackdrop.shader.meta b/First Principles/Assets/Resources/UI_WindTunnelBackdrop.shader.meta new file mode 100644 index 0000000..2fb8240 --- /dev/null +++ b/First Principles/Assets/Resources/UI_WindTunnelBackdrop.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 6426e7063d26b4ffbb3950a79360b1cc +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/First Principles/Assets/Scenes/Game.unity b/First Principles/Assets/Scenes/Game.unity index 24e72d6..333a2c6 100644 --- a/First Principles/Assets/Scenes/Game.unity +++ b/First Principles/Assets/Scenes/Game.unity @@ -2871,7 +2871,7 @@ MonoBehaviour: m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 0.122641504, g: 0.122641504, b: 0.122641504, a: 1} - m_RaycastTarget: 1 + m_RaycastTarget: 0 m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 m_OnCullStateChanged: diff --git a/First Principles/Assets/Scenes/Menu.unity b/First Principles/Assets/Scenes/Menu.unity index d03d1c7..91d53c6 100644 --- a/First Principles/Assets/Scenes/Menu.unity +++ b/First Principles/Assets/Scenes/Menu.unity @@ -436,8 +436,8 @@ RectTransform: 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: 0, y: -380} - m_SizeDelta: {x: 964.3611, y: 110} + m_AnchoredPosition: {x: 0, y: -452} + m_SizeDelta: {x: 964.3611, y: 132} m_Pivot: {x: 0.5, y: 0.5} --- !u!114 &1004057114 MonoBehaviour: diff --git a/First Principles/Assets/Scripts/Functions/FunctionPlotter.cs b/First Principles/Assets/Scripts/Functions/FunctionPlotter.cs index e253d30..d4ebbb0 100644 --- a/First Principles/Assets/Scripts/Functions/FunctionPlotter.cs +++ b/First Principles/Assets/Scripts/Functions/FunctionPlotter.cs @@ -47,6 +47,9 @@ public class FunctionPlotter : MonoBehaviour public bool differentiate = false; + [Tooltip("Level mode: wind-tunnel GPU backdrop (set from LevelDefinition for aerospace stages).")] + public bool showWindTunnelBackdrop = false; + [Tooltip("Level mode: vertically scale f and f′ so the band fits the grid (flat curves read clearly).")] public bool autoScaleVertical = true; @@ -57,6 +60,9 @@ public class FunctionPlotter : MonoBehaviour [Tooltip("Level mode: horizontally scale the domain window [xStart,xEnd] so it fills most of the grid.")] public bool autoScaleHorizontal = true; + [Tooltip("Graphing calculator: match vertical scale to horizontal zoom so one grid column and one row span the same plotter x/y units (pinch/Scale zoom x and y together). Ignored for polar plot styles.")] + public bool lockVerticalPlotScaleToHorizontalWindow = false; + [Tooltip("Fraction of half the grid width (from center) used by the fitted x-window.")] [Range(0.38f, 0.92f)] public float horizontalFillFraction = 0.74f; @@ -131,7 +137,12 @@ void UpdateGraphRevealAnimation() } float dur = Mathf.Max(0.05f, graphRevealDurationSeconds); - _graphRevealT01 = Mathf.MoveTowards(_graphRevealT01, 1f, Time.deltaTime / dur); + // Lorenz / chaos-theory stage already animates via _lorenzPhaseScroll; horizontal alpha reveal uses grid-x and + // can zero the whole polyline when revealX sits on gx0 (progress 0 → all vertices faded). + if (functionType == FunctionType.ChaosLorenzButterflyX) + _graphRevealT01 = 1f; + else + _graphRevealT01 = Mathf.MoveTowards(_graphRevealT01, 1f, Time.deltaTime / dur); if (functionType == FunctionType.ChaosLorenzButterflyX) { @@ -145,7 +156,8 @@ int ComputeGraphRevealParamsHash() { int a = HashCode.Combine(functionType, xStart, xEnd, step, transA, transK); int b = HashCode.Combine(transC, transD, power, baseN, customExpression ?? ""); - int c = HashCode.Combine(autoScaleVertical, autoScaleHorizontal, verticalFillFraction, horizontalFillFraction); + int c = HashCode.Combine(autoScaleVertical, autoScaleHorizontal, lockVerticalPlotScaleToHorizontalWindow, + verticalFillFraction, horizontalFillFraction); return HashCode.Combine(a, b, c); } @@ -158,16 +170,17 @@ void PushGraphRevealToRenderers() float gx0 = MapDisplayX(xStart) + go.x; float gx1 = MapDisplayX(xEnd) + go.x; - lineRenderer.SetGraphRevealFade(_graphRevealT01, gx0, gx1); + float revealT = functionType == FunctionType.ChaosLorenzButterflyX ? 1f : _graphRevealT01; + lineRenderer.SetGraphRevealFade(revealT, gx0, gx1); if (derivRenderer != null) - derivRenderer.SetGraphRevealFade(_graphRevealT01, gx0, gx1); + derivRenderer.SetGraphRevealFade(revealT, gx0, gx1); if (functionType == FunctionType.AeroDragPolarTriple) { if (overlayParasitic != null) - overlayParasitic.SetGraphRevealFade(_graphRevealT01, gx0, gx1); + overlayParasitic.SetGraphRevealFade(revealT, gx0, gx1); if (overlayInduced != null) - overlayInduced.SetGraphRevealFade(_graphRevealT01, gx0, gx1); + overlayInduced.SetGraphRevealFade(revealT, gx0, gx1); } } @@ -177,7 +190,8 @@ public void ApplyGraphRevealToLineRenderer(LineRendererUI lr) if (lr == null || lineRenderer == null) return; Vector2Int go = lineRenderer.gridSize / 2; - lr.SetGraphRevealFade(_graphRevealT01, MapDisplayX(xStart) + go.x, MapDisplayX(xEnd) + go.x); + float revealT = functionType == FunctionType.ChaosLorenzButterflyX ? 1f : _graphRevealT01; + lr.SetGraphRevealFade(revealT, MapDisplayX(xStart) + go.x, MapDisplayX(xEnd) + go.x); } public void InitPlotFunction() @@ -194,6 +208,8 @@ public void RefreshLine() public void RefreshDeriv() { + if (derivRenderer == null) + return; derivRenderer.enabled = false; derivRenderer.enabled = true; } @@ -331,6 +347,13 @@ private void PlotFunction(FunctionType type) lineRenderer = LineRendererUI.FindPrimaryCurve(); derivRenderer = FindAnyObjectByType(); + // Lorenz: disable per-vertex horizontal fade (see UpdateGraphRevealAnimation); derivative uses same flag. + bool lorenzButterfly = type == FunctionType.ChaosLorenzButterflyX; + if (lineRenderer != null) + lineRenderer.enableHorizontalGraphReveal = !lorenzButterfly; + if (derivRenderer != null) + derivRenderer.enableHorizontalGraphReveal = !lorenzButterfly; + if (lineRenderer != null) { points.Clear(); @@ -368,16 +391,23 @@ private void PlotFunction(FunctionType type) else if (differentiate == false) { dPoints.Clear(); - - // Refresh ONLY the derivative graph & hide on the UI - RefreshDeriv(); + // Do not call RefreshDeriv() here — it re-enabled the Graphic every frame while stale + // points could remain on DerivRendererUI (list is only aliased to dPoints when differentiate is true). + if (derivRenderer != null) + { + derivRenderer.points.Clear(); + derivRenderer.enabled = false; + } } - // Boss: show classic Mandelbrot set in c-plane behind the grid (1D slice curve on top). + // Stage backdrops: Mandelbrot; black hole; golden φ-spiral; wind tunnel (aerospace). if (lineRenderer != null) { var gridRt = lineRenderer.transform.parent as RectTransform; MandelbrotFractalBackdrop.Sync(gridRt, this); + BlackHoleGargantuaBackdrop.Sync(gridRt, this); + GoldenSpiralBackdrop.Sync(gridRt, this); + WindTunnelBackdrop.Sync(gridRt, this); PushGraphRevealToRenderers(); } } @@ -402,6 +432,12 @@ public void ComputeGraph(FunctionType functionType, float transA, float transK, ComputeVerticalAutoFit(lineRenderer.gridSize.y, fLo, fHi); ComputeHorizontalAutoFit(lineRenderer.gridSize.x, xStart, xEnd); + if (lockVerticalPlotScaleToHorizontalWindow && !IsPolarPlotStyle(functionType)) + { + _autoMid = 0f; + _autoScale = _autoScaleX; + } + // --- Pass 2: build polylines with display mapping --- for (float i = xStart; i <= xEnd; i += step) { @@ -577,9 +613,15 @@ private float EvaluateFunctionY(FunctionType type, float transA, float transK, f FunctionType.TransformFourierSinc => TransformFourierSincY(u, transA, transC), FunctionType.TransformLaplaceCausalDecay => TransformLaplaceCausalDecayY(u, transA, transC, baseN), - // Final boss: Lorenz x(t) slice (normalized), “butterfly” chaotic sensitivity. + // Final boss: Lorenz x(t) slice (normalized); chaos theory / sensitive dependence. FunctionType.ChaosLorenzButterflyX => ChaosLorenzButterflyYEval(u, transA, transC), + // Boss: Newtonian-style potential slice Φ ∝ −1/√(r²+ε²) (softened 1/r “gravity well”). + FunctionType.PhysicsGravityWellInverseSqrt => GravityWellInverseSqrtY(u, transA, transC, transD), + + // CS / algorithms: growth shape n ln n for n>0 (u plays the role of n on the horizontal axis). + FunctionType.BigONLogN => BigONLogNY(u, transA, transC), + _ => 0f }; } @@ -729,6 +771,19 @@ float ChaosLorenzButterflyYEval(float u, float a, float c) return a * LorenzAttractorSamples.SampleNormalizedX(t) + c; } + static float GravityWellInverseSqrtY(float u, float a, float c, float softFromD) + { + float eps = Mathf.Max(0.08f, Mathf.Abs(softFromD)); + float r2 = u * u + eps * eps; + return a * (-1f / Mathf.Sqrt(r2)) + c; + } + + static float BigONLogNY(float u, float a, float c) + { + float n = Mathf.Max(u, 0.02f); + return a * (n * Mathf.Log(n)) + c; + } + /// y = k + √(R² − u²) for |u|≤R; outside domain uses k so samples stay finite (flat shoulder). private static float CircleUpperY(float u, float radiusSigned, float k) { @@ -1012,9 +1067,19 @@ private void UpdateEquationText(FunctionType type, float transA, float transK, f } case FunctionType.ChaosLorenzButterflyX: equationText.text = - $@"\(\text{{Butterfly effect}}\) — Lorenz \(x(t)\), \(\sigma=10,\rho=28,\beta=8/3\), \(u={k}(x-{d})\approx t\)\n" + + $@"\(\text{{Chaos theory}}\) — Lorenz \(x(t)\), \(\sigma=10,\rho=28,\beta=8/3\), \(u={k}(x-{d})\approx t\)\n" + $@"Tiny initial changes diverge on the attractor — this curve is a time slice of that chaos, normalized to read on the grid."; break; + case FunctionType.PhysicsGravityWellInverseSqrt: + equationText.text = + $@"\(\text{{Gravity well}}\) slice \(f \propto -1/\sqrt{{u^{2}+\varepsilon^{2}}}+C,\; u={k}(x-{d}),\; \varepsilon\sim |{d}|\)\n" + + $@"Softened \(1/r\) potential — steep near the center, flattens away; a readable stand-in for “falling into” a deep well."; + break; + case FunctionType.BigONLogN: + equationText.text = + $@"\(O(n\log n)\) growth mood: \(f \propto u\ln u + C,\; u=\max({k}(x-{d}),\text{{small}})\)\n" + + $@"Classic merge-sort / balanced-tree flavor: work grows a bit faster than linear, slower than quadratic."; + break; case FunctionType.CustomExpression: { string esc = EscapeTmpRichText(customExpression); @@ -1188,8 +1253,14 @@ public enum FunctionType /// Causal \(H(t)\,e^{-st}\) — Laplace-table exponential decay for \(t\ge 0\); \(s\sim \texttt{baseN}/100\). TransformLaplaceCausalDecay, - /// Final boss: Lorenz attractor \(x(t)\) (normalized), butterfly / sensitive dependence visualization. - ChaosLorenzButterflyX + /// Final boss: Lorenz attractor \(x(t)\) (normalized); chaos theory / sensitive dependence visualization. + ChaosLorenzButterflyX, + + /// Boss: softened \(1/r\) gravitational potential slice (deep well at \(u=0\)). + PhysicsGravityWellInverseSqrt, + + /// CS: \(O(n\log n)\) growth shape via \(u\ln u\) (positive branch). + BigONLogN } /* diff --git a/First Principles/Assets/Scripts/Game/DerivativePopAnimator.cs b/First Principles/Assets/Scripts/Game/DerivativePopAnimator.cs index e42e80e..705b8c6 100644 --- a/First Principles/Assets/Scripts/Game/DerivativePopAnimator.cs +++ b/First Principles/Assets/Scripts/Game/DerivativePopAnimator.cs @@ -14,17 +14,23 @@ public class DerivativePopAnimator : MonoBehaviour [SerializeField] private float thicknessMultiplier = 1.8f; [SerializeField] private float popDurationSeconds = 0.25f; - private float baseThickness; - private Color baseColor; + /// + /// Baseline stroke width for f′ (not the momentary boosted value). Stopping a pop mid-animation used to leave + /// elevated; the next pop then multiplied that again — runaway “thick line”. + /// + private float _restThickness = DerivRendererUI.DefaultThicknessPixels; public void SetTarget(DerivRendererUI target) { this.target = target; - if (this.target != null) - { - baseThickness = this.target.thickness; - baseColor = this.target.color; - } + SyncRestThicknessFromTarget(); + } + + /// Call after resetting on level load / theme apply. + public void SyncRestThicknessFromTarget() + { + if (target != null) + _restThickness = Mathf.Max(0.25f, target.thickness); } public void Pop(Color popColor) @@ -33,7 +39,12 @@ public void Pop(Color popColor) return; if (popRoutine != null) + { StopCoroutine(popRoutine); + popRoutine = null; + // Interrupted mid-pulse — snap back so the next pop does not compound thickness. + target.thickness = _restThickness; + } popRoutine = StartCoroutine(PopRoutine(popColor)); } @@ -42,16 +53,16 @@ private IEnumerator PopRoutine(Color popColor) { float elapsed = 0f; - baseThickness = target.thickness; - baseColor = target.color; + Color colorBeforePop = target.color; Color c = popColor; if (c.a <= 0f) c.a = 1f; target.color = c; - float startThickness = baseThickness; - float endThickness = baseThickness * thicknessMultiplier; + float restT = _restThickness; + float startThickness = restT; + float endThickness = restT * thicknessMultiplier; while (elapsed < popDurationSeconds * 0.5f) { @@ -67,12 +78,16 @@ private IEnumerator PopRoutine(Color popColor) { settleT += Time.deltaTime; float t = Mathf.Clamp01(settleT / (popDurationSeconds * 0.5f)); - target.thickness = Mathf.Lerp(fromThickness, startThickness, t); + target.thickness = Mathf.Lerp(fromThickness, restT, t); yield return null; } + target.thickness = restT; + var restored = target.color; - restored.a = baseColor.a; + restored.a = colorBeforePop.a; target.color = restored; + + popRoutine = null; } } diff --git a/First Principles/Assets/Scripts/Game/GameLevelCatalog.cs b/First Principles/Assets/Scripts/Game/GameLevelCatalog.cs index 0c01328..d856e7c 100644 --- a/First Principles/Assets/Scripts/Game/GameLevelCatalog.cs +++ b/First Principles/Assets/Scripts/Game/GameLevelCatalog.cs @@ -69,6 +69,7 @@ public static class GameLevelCatalog "BC: cubic & inflection (sketching)", "BC: b^x & d/dx b^x", "Circle: (x−h)² + (y−k)² = R²", + "Physics C: thermodynamics (adiabatic P–V, γ from N)", // --- Aerospace engineering & aerodynamics (order must match LevelManager.BuildSampleLevels) --- "Aerospace: lift C_L(α) linear + stall", "Aerospace: drag polar (parasitic, induced, total)", @@ -79,18 +80,33 @@ public static class GameLevelCatalog "Aerospace: re-entry decay envelope (ρV heating mood)", "Economics: dot-com bubble & crash (stylized index)", "Economics: 2008 crisis & recovery (stylized index)", - "BOSS: Mandelbrot escape slice (fractal boundary mood)", - "Physics C: thermodynamics (adiabatic P–V, γ from N)", - "BOSS: golden ratio spiral (logarithmic polar)", "Transforms: Fourier — sinc spectrum (rect ↔ sinc)", "Transforms: Laplace — causal exponential decay", + "BOSS: golden ratio spiral (logarithmic polar)", "BOSS: Mandelbrot — finale (fractal escape slice)", - "BOSS: Lorenz butterfly — finale (strange attractor)", - "Physics C: spring–mass SHM (Hooke's law, undamped)" + "BOSS: Lorenz attractor — Chaos Theory (strange attractor)", + "BOSS: Black hole — gravity well (1/r slice)", + "Physics C: spring–mass SHM (Hooke's law, undamped)", + "Big O: O(1) — constant time", + "Big O: O(log n) — logarithmic growth", + "Big O: O(√n) — sublinear root growth", + "Big O: O(n) — linear growth", + "Big O: O(n log n) — n log n growth", + "Big O: O(n²) — quadratic growth", + "Big O: O(n³) — cubic growth", + "Big O: O(2ⁿ) — exponential (base 2)", + // Placeholder: listed in Level Select but not built in LevelManager yet (see IsComingSoonLevel). + "Astrophysics: Hohmann transfer" }; public static int LevelCount => DisplayNames.Length; + /// Level index reserved for a future stage; shows “coming soon” instead of loading Game. + public const int HohmannTransferComingSoonLevelIndex = 59; + + public static bool IsComingSoonLevel(int index) => + index == HohmannTransferComingSoonLevelIndex; + /// /// Grouped picker on the Level Select scene (indices must match / ). /// @@ -99,19 +115,21 @@ public static class GameLevelCatalog new LevelSelectCategory("level_select.cat.core", "Core & series", 0, 8), new LevelSelectCategory("level_select.cat.integration", "Multivar & integration", 9, 13), new LevelSelectCategory("level_select.cat.engineering", "Engineering", 14, 16), - new LevelSelectCategory("level_select.cat.ap_bc", "AP Calculus BC & Physics C", 17, 33), - new LevelSelectCategory("level_select.cat.aerospace", "Aerospace", 34, 40), - new LevelSelectCategory("level_select.cat.finale", "Advanced & boss", 41, 45), - new LevelSelectCategory("level_select.cat.transforms", "Transforms", 46, 47), - new LevelSelectCategory("level_select.cat.final_boss", "Final boss", 48, 49), + new LevelSelectCategory("level_select.cat.ap_bc", "AP Calculus BC & Physics C", 17, 34), + new LevelSelectCategory("level_select.cat.aerospace", "Aerospace", 35, 41), + new LevelSelectCategory("level_select.cat.astrophysics", "Astrophysics", 59, 59), + new LevelSelectCategory("level_select.cat.economics", "Economics", 42, 43), + new LevelSelectCategory("level_select.cat.transforms", "Transforms", 44, 45), new LevelSelectCategory("level_select.cat.spring_physics", "Spring & SHM", 50, 50), + new LevelSelectCategory("level_select.cat.big_o", "Big O notation", 51, 58), + new LevelSelectCategory("level_select.cat.final_boss", "Final boss", 46, 49), }; /// First index of the contiguous Aerospace: block (must match sample levels). - public const int AerospaceLevelsBeginIndex = 34; + public const int AerospaceLevelsBeginIndex = 35; /// Inclusive last index of the Aerospace block (re-entry stage). - public const int AerospaceLevelsEndIndex = 40; + public const int AerospaceLevelsEndIndex = 41; /// True for levels whose titles start with Aerospace: in the catalog. public static bool IsAerospaceLevel(int index) => diff --git a/First Principles/Assets/Scripts/Game/GameplayViewportBounds.cs b/First Principles/Assets/Scripts/Game/GameplayViewportBounds.cs index 4a88c1b..36c59c0 100644 --- a/First Principles/Assets/Scripts/Game/GameplayViewportBounds.cs +++ b/First Principles/Assets/Scripts/Game/GameplayViewportBounds.cs @@ -42,11 +42,21 @@ public static GameplayPlayBounds Compute(RectTransform cartesianPlane, Vector2In ? Mathf.Max(16f, w * 0.022f) : Mathf.Max(10f, w * 0.018f); + // Narrow portrait: reserve a bit more side margin so the playfield matches the visibly inset graph. + float aspectTall = h / Mathf.Max(1f, w); + if (!DeviceLayout.IsTabletLike() && aspectTall > 1.45f) + hPad = Mathf.Max(hPad, w * 0.026f); + float topPad = Mathf.Max(44f, h * 0.065f); float bottomPad = Mathf.Max(12f, h * 0.022f); if (DeviceLayout.PreferOnScreenGameControls) - bottomPad = Mathf.Max(bottomPad, DeviceLayout.TouchControlBarHeight + 36f); + { + if (DeviceLayout.GameplayUsesFullScreenTouchZones) + bottomPad = Mathf.Max(bottomPad, 28f); + else + bottomPad = Mathf.Max(bottomPad, DeviceLayout.TouchControlBarHeight + 36f); + } float xMin = hPad / unitX; float xMax = gridSize.x - hPad / unitX; diff --git a/First Principles/Assets/Scripts/Game/GraphCalculatorAnalysisControls.cs b/First Principles/Assets/Scripts/Game/GraphCalculatorAnalysisControls.cs index 19d4463..4b3afae 100644 --- a/First Principles/Assets/Scripts/Game/GraphCalculatorAnalysisControls.cs +++ b/First Principles/Assets/Scripts/Game/GraphCalculatorAnalysisControls.cs @@ -107,7 +107,7 @@ void LateUpdate() && (!Mathf.Approximately(integralCachedXStart, plotter.xStart) || !Mathf.Approximately(integralCachedXEnd, plotter.xEnd))) { - riemann.RebuildForGraphingCalculator(plotter, RiemannRectCount, RiemannRule.Midpoint, CalculatorRiemannFill); + riemann.RebuildForGraphingCalculator(plotter, primaryCurve, RiemannRectCount, RiemannRule.Midpoint, CalculatorRiemannFill); integralCachedXStart = plotter.xStart; integralCachedXEnd = plotter.xEnd; if (primaryCurve.transform.parent != null) @@ -168,7 +168,7 @@ void OnIntegralPressed() integralBarsActive = true; RefreshButtonInteractable(); - riemann.RebuildForGraphingCalculator(plotter, RiemannRectCount, RiemannRule.Midpoint, CalculatorRiemannFill); + riemann.RebuildForGraphingCalculator(plotter, primaryCurve, RiemannRectCount, RiemannRule.Midpoint, CalculatorRiemannFill); integralCachedXStart = plotter.xStart; integralCachedXEnd = plotter.xEnd; if (primaryCurve != null && primaryCurve.transform.parent != null) @@ -340,4 +340,15 @@ void DestroyUiButtons() derivButton = null; integralButton = null; } + + /// + /// Top edge of the Deriv / ∫ row in the same bottom‑anchored space as + /// (anchoredPosition.y + button height). + /// + public static float DerivativeIntegralRowTopFromBottom(float transRowBottomY, bool tablet) + { + float h = tablet ? 108f : 100f; + float row2Bottom = transRowBottomY + h + 10f; + return row2Bottom + h * 0.92f; + } } diff --git a/First Principles/Assets/Scripts/Game/GraphCalculatorEquationPanel.cs b/First Principles/Assets/Scripts/Game/GraphCalculatorEquationPanel.cs index 2e4c23b..56e4c36 100644 --- a/First Principles/Assets/Scripts/Game/GraphCalculatorEquationPanel.cs +++ b/First Principles/Assets/Scripts/Game/GraphCalculatorEquationPanel.cs @@ -8,14 +8,18 @@ /// public static class GraphCalculatorEquationPanel { - private const string RootName = "GraphicCalculatorEquationRoot"; + public const string EquationRootObjectName = "GraphicCalculatorEquationRoot"; + private const string RootName = EquationRootObjectName; private const string LegacyRootName = "FaxasEquationInputRoot"; private static TextMeshProUGUI labelTmp; private static TextMeshProUGUI placeholderTmp; private static TextMeshProUGUI statusTmp; - public static void Ensure(RectTransform parent, FunctionPlotter plotter, TextMeshProUGUI typographyReference, float bottomY, float panelHeight) + /// When is null: anchored Y from bottom of parent (legacy placement). + /// When set: panel is top-anchored directly under this banner (graphing calculator). + public static void Ensure(RectTransform parent, FunctionPlotter plotter, TextMeshProUGUI typographyReference, float bottomY, float panelHeight, + RectTransform layoutBelowStory = null, float gapBelowStory = 10f) { if (parent == null || plotter == null) return; @@ -24,6 +28,11 @@ public static void Ensure(RectTransform parent, FunctionPlotter plotter, TextMes if (existing != null) { ApplyEquationPanelFontAndWeight(existing, typographyReference, plotter); + var ert = existing.GetComponent(); + if (layoutBelowStory != null) + ApplyEquationPanelLayoutBelowStory(ert, layoutBelowStory, gapBelowStory, panelHeight); + else + ApplyEquationPanelBottomLayout(ert, parent, bottomY, panelHeight); return; } @@ -32,6 +41,11 @@ public static void Ensure(RectTransform parent, FunctionPlotter plotter, TextMes { legacyRoot.name = RootName; ApplyEquationPanelFontAndWeight(legacyRoot, typographyReference, plotter); + var legacyRt = legacyRoot.GetComponent(); + if (layoutBelowStory != null) + ApplyEquationPanelLayoutBelowStory(legacyRt, layoutBelowStory, gapBelowStory, panelHeight); + else + ApplyEquationPanelBottomLayout(legacyRt, parent, bottomY, panelHeight); return; } @@ -40,12 +54,17 @@ public static void Ensure(RectTransform parent, FunctionPlotter plotter, TextMes var root = new GameObject(RootName); var rt = root.AddComponent(); - rt.SetParent(parent, false); - rt.anchorMin = new Vector2(0.5f, 0f); - rt.anchorMax = new Vector2(0.5f, 0f); - rt.pivot = new Vector2(0.5f, 0f); - rt.anchoredPosition = new Vector2(0f, bottomY); - rt.sizeDelta = new Vector2(w, panelHeight); + rt.SetParent(layoutBelowStory != null ? layoutBelowStory.parent : parent, false); + if (layoutBelowStory != null) + ApplyEquationPanelLayoutBelowStory(rt, layoutBelowStory, gapBelowStory, panelHeight); + else + { + rt.anchorMin = new Vector2(0.5f, 0f); + rt.anchorMax = new Vector2(0.5f, 0f); + rt.pivot = new Vector2(0.5f, 0f); + rt.anchoredPosition = new Vector2(0f, bottomY); + rt.sizeDelta = new Vector2(w, panelHeight); + } var bg = root.AddComponent(); RuntimeUiPolish.UseRoundedSliced(bg); @@ -53,13 +72,13 @@ public static void Ensure(RectTransform parent, FunctionPlotter plotter, TextMes bg.raycastTarget = true; var labelGo = new GameObject("Label"); - var lrt = labelGo.AddComponent(); - lrt.SetParent(rt, false); - lrt.anchorMin = new Vector2(0f, 1f); - lrt.anchorMax = new Vector2(0f, 1f); - lrt.pivot = new Vector2(0f, 1f); - lrt.anchoredPosition = new Vector2(tablet ? 16f : 12f, -6f); - lrt.sizeDelta = new Vector2(220f, 28f); + var labelRt = labelGo.AddComponent(); + labelRt.SetParent(rt, false); + labelRt.anchorMin = new Vector2(0f, 1f); + labelRt.anchorMax = new Vector2(0f, 1f); + labelRt.pivot = new Vector2(0f, 1f); + labelRt.anchoredPosition = new Vector2(tablet ? 16f : 12f, -6f); + labelRt.sizeDelta = new Vector2(220f, 28f); var label = labelGo.AddComponent(); label.text = LocalizationManager.Get("graph.label_fu", "f(u) ="); label.fontSize = UiTypography.Scale(tablet ? 26 : 24); @@ -266,4 +285,34 @@ static void ApplyStatusHintLayoutAndSize(TextMeshProUGUI status, RectTransform s srt.sizeDelta = new Vector2(-24f, 28f); } } + + /// Top-anchored panel flush under the intro banner (same horizontal stretch as ). + static void ApplyEquationPanelLayoutBelowStory(RectTransform eqRt, RectTransform storyRt, float gap, float panelHeight) + { + if (eqRt == null || storyRt == null) + return; + + eqRt.SetParent(storyRt.parent, false); + eqRt.anchorMin = storyRt.anchorMin; + eqRt.anchorMax = storyRt.anchorMax; + eqRt.pivot = new Vector2(0.5f, 1f); + eqRt.sizeDelta = new Vector2(0f, panelHeight); + float storyH = storyRt.sizeDelta.y; + eqRt.anchoredPosition = new Vector2(storyRt.anchoredPosition.x, storyRt.anchoredPosition.y - storyH - gap); + } + + static void ApplyEquationPanelBottomLayout(RectTransform eqRt, RectTransform parent, float bottomY, float panelHeight) + { + if (eqRt == null || parent == null) + return; + + bool tablet = DeviceLayout.IsTabletLike(); + float w = tablet ? 980f : 900f; + eqRt.SetParent(parent, false); + eqRt.anchorMin = new Vector2(0.5f, 0f); + eqRt.anchorMax = new Vector2(0.5f, 0f); + eqRt.pivot = new Vector2(0.5f, 0f); + eqRt.anchoredPosition = new Vector2(0f, bottomY); + eqRt.sizeDelta = new Vector2(w, panelHeight); + } } diff --git a/First Principles/Assets/Scripts/Game/GraphCalculatorToolbar.cs b/First Principles/Assets/Scripts/Game/GraphCalculatorToolbar.cs index b7d2402..8fdf9d2 100644 --- a/First Principles/Assets/Scripts/Game/GraphCalculatorToolbar.cs +++ b/First Principles/Assets/Scripts/Game/GraphCalculatorToolbar.cs @@ -128,6 +128,10 @@ private void ApplyZoomWindow(float halfWidthMultiplier) plot.xStart = mid - half; plot.xEnd = mid + half; plot.step = Mathf.Clamp((plot.xEnd - plot.xStart) / 480f, 0.004f, 0.42f); + plot.InitPlotFunction(); + var lm = FindAnyObjectByType(); + if (lm != null) + lm.RefreshAllTickLabels(); } private void RefreshHint() @@ -164,9 +168,9 @@ private void RefreshHint() float th1 = plot.transK * (plot.xEnd - plot.transD); string line4Fmt = polar ? LocalizationManager.Get("graph.polar.line4", - "A={0}  k={1}  C={2}  D={3}   θ∈[{4},{5}]") + "A={0} k={1} C={2} D={3} θ∈[{4},{5}]") : LocalizationManager.Get("graph.line4", - "A={0}  k={1}  C={2}  D={3}   x∈[{4},{5}]"); + "A={0} k={1} C={2} D={3} x∈[{4},{5}]"); string line4 = polar ? string.Format(line4Fmt, plot.transA.ToString("0.##"), diff --git a/First Principles/Assets/Scripts/Game/GraphObstacleGenerator.cs b/First Principles/Assets/Scripts/Game/GraphObstacleGenerator.cs index 3312a34..3a89be4 100644 --- a/First Principles/Assets/Scripts/Game/GraphObstacleGenerator.cs +++ b/First Principles/Assets/Scripts/Game/GraphObstacleGenerator.cs @@ -43,6 +43,36 @@ public class GraphWorld /// When true, keeps the avatar inside horizontally and uses them for fall death. public bool hasPlayBounds; public GameplayPlayBounds playBounds; + + /// Call after is recomputed (e.g. rotation) so the exit band stays in the padded region. + public void RefreshFinishFromPlayBounds() + { + if (!hasPlayBounds) + return; + const float finishWidth = 1f; + var b = playBounds; + finish = new GridRect(Mathf.Max(b.XMax - finishWidth, b.XMin), b.XMax, b.YMin, b.YMax); + } +} + +/// Caches grid-space AABB for a platform/hazard/finish visual; reapplies pixel rect when the plane size changes. +public sealed class GraphObstacleUILayout : MonoBehaviour +{ + public GridRect gridRect; + + public void ApplyPixelLayout(float unitWidth, float unitHeight) + { + var rt = transform as RectTransform; + if (rt == null) + return; + + float pxX = gridRect.xMin * unitWidth; + float pxY = gridRect.yMin * unitHeight; + float pxW = (gridRect.xMax - gridRect.xMin) * unitWidth; + float pxH = (gridRect.yMax - gridRect.yMin) * unitHeight; + rt.anchoredPosition = new Vector2(pxX, pxY); + rt.sizeDelta = new Vector2(pxW, pxH); + } } /// @@ -67,6 +97,16 @@ public void SetLayout(RectTransform obstaclesRoot, Vector2Int gridSize, float un obstacleSprite = RuntimeUiPolish.Rounded9Slice != null ? RuntimeUiPolish.Rounded9Slice : TryGetSquareSprite(); } + /// Repositions platform/hazard/finish quads after the Cartesian plane is scaled (rotation, safe area). + public void RefreshObstaclePixelLayout() + { + if (obstaclesRoot == null) + return; + var layouts = obstaclesRoot.GetComponentsInChildren(true); + for (int i = 0; i < layouts.Length; i++) + layouts[i].ApplyPixelLayout(unitWidth, unitHeight); + } + /// Required for Riemann stair mode; used to evaluate exact f at sample x. /// Inset AABB in grid units; null = full grid, no player hard clamp. public GraphWorld GenerateWorld( @@ -433,6 +473,9 @@ private void CreateFinishExitGradient(GridRect finishBand) rt.anchoredPosition = new Vector2(pxX, pxY); rt.sizeDelta = new Vector2(pxW, pxH); + var finishLayout = go.AddComponent(); + finishLayout.gridRect = rect; + var grad = go.AddComponent(); grad.raycastTarget = false; grad.SetGradientColors( @@ -463,6 +506,9 @@ private void CreateRectVisual(string name, GridRect rect, Color color) rt.anchoredPosition = new Vector2(pxX, pxY); rt.sizeDelta = new Vector2(pxW, pxH); + var layout = go.AddComponent(); + layout.gridRect = rect; + var img = go.AddComponent(); img.sprite = obstacleSprite; bool isHazard = name.StartsWith("Hazard", System.StringComparison.OrdinalIgnoreCase); diff --git a/First Principles/Assets/Scripts/Game/GraphPinchZoom.cs b/First Principles/Assets/Scripts/Game/GraphPinchZoom.cs index 7d54d90..c850611 100644 --- a/First Principles/Assets/Scripts/Game/GraphPinchZoom.cs +++ b/First Principles/Assets/Scripts/Game/GraphPinchZoom.cs @@ -52,5 +52,9 @@ private void ApplyHalfWidthScale(float ratio) plot.xStart = mid - half; plot.xEnd = mid + half; plot.step = Mathf.Clamp((plot.xEnd - plot.xStart) / 520f, 0.004f, 0.42f); + plot.InitPlotFunction(); + var lm = FindAnyObjectByType(); + if (lm != null) + lm.RefreshAllTickLabels(); } } diff --git a/First Principles/Assets/Scripts/Game/LearningArticleLibrary.cs b/First Principles/Assets/Scripts/Game/LearningArticleLibrary.cs index 90b79d4..5ec1d85 100644 --- a/First Principles/Assets/Scripts/Game/LearningArticleLibrary.cs +++ b/First Principles/Assets/Scripts/Game/LearningArticleLibrary.cs @@ -1,26 +1,118 @@ +using System; +using System.Collections.Generic; +using System.Text; using UnityEngine; /// /// Plain-language math snippets for the in-game reader (TextMesh Pro rich text). /// Mathematical parts use LaTeX delimiters \( … \) / \[ … \]; converts them at load time. /// Body text loads from Resources/Localization/MathArticle/{language}.txt (fallback: en.txt) so every locale can ship a translation. -/// Mirror ideas in docs (MathJax on GitHub Pages). +/// Optional lines @@SECTION=id split the article; in-game can request a subset by level. /// public static class LearningArticleLibrary { private const string MathArticleResourcePrefix = "Localization/MathArticle/"; + private const string SectionDirectivePrefix = "@@SECTION="; - /// Large TMP block; per-locale file is UTF-8 with meaningful newlines. - public static string GetLevelSelectArticleRichText() + /// Full glossary (level select, or locales without section markers). + public static string GetLevelSelectArticleRichText() => GetArticleRichTextForOverlay(forLevelIndex: null); + + /// = entire article (section directive lines stripped). Otherwise sections from . + public static string GetArticleRichTextForOverlay(int? forLevelIndex) { string raw = LoadRawArticleForCurrentLanguage(); - return TmpLatex.Process(raw); + string selected = SelectRawForOverlay(raw, forLevelIndex); + return ProcessArticleBody(selected); + } + + private static string ProcessArticleBody(string raw) + { + string processed = TmpLatex.Process(raw); + return processed.Replace("&", "&"); + } + + private static string SelectRawForOverlay(string raw, int? forLevelIndex) + { + if (string.IsNullOrEmpty(raw) || raw.IndexOf(SectionDirectivePrefix, StringComparison.Ordinal) < 0) + return raw; + + if (forLevelIndex == null) + return StripSectionDirectiveLines(raw); + + Dictionary sections = ParseSectionDictionary(raw); + if (sections.Count == 0) + return StripSectionDirectiveLines(raw); + + IReadOnlyList keys = MathArticleLevelSectionMap.GetSectionKeysForLevel(forLevelIndex.Value); + var sb = new StringBuilder(); + foreach (string key in keys) + { + if (!sections.TryGetValue(key, out string chunk) || string.IsNullOrWhiteSpace(chunk)) + continue; + if (sb.Length > 0) + sb.Append("\n\n"); + sb.Append(chunk.Trim()); + } + + if (sb.Length == 0) + return StripSectionDirectiveLines(raw); + + return sb.ToString(); + } + + private static string StripSectionDirectiveLines(string raw) + { + string[] lines = raw.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None); + var sb = new StringBuilder(); + foreach (string line in lines) + { + if (line.TrimStart().StartsWith(SectionDirectivePrefix, StringComparison.Ordinal)) + continue; + if (sb.Length > 0) + sb.Append('\n'); + sb.Append(line); + } + + return sb.ToString(); + } + + private static Dictionary ParseSectionDictionary(string raw) + { + var d = new Dictionary(StringComparer.Ordinal); + string[] lines = raw.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None); + string currentKey = null; + var chunk = new StringBuilder(); + + void Flush() + { + if (currentKey != null) + d[currentKey] = chunk.ToString().TrimEnd(); + chunk.Clear(); + } + + foreach (string line in lines) + { + string t = line.Trim(); + if (t.StartsWith(SectionDirectivePrefix, StringComparison.Ordinal) && t.Length > SectionDirectivePrefix.Length) + { + Flush(); + currentKey = t.Substring(SectionDirectivePrefix.Length).Trim(); + continue; + } + + if (chunk.Length > 0) + chunk.Append('\n'); + chunk.Append(line); + } + + Flush(); + return d; } private static string LoadRawArticleForCurrentLanguage() { string code = LocalizationManager.CurrentLanguage; - var ta = Resources.Load($"{MathArticleResourcePrefix}{code}"); + TextAsset ta = Resources.Load($"{MathArticleResourcePrefix}{code}"); if (ta == null || string.IsNullOrWhiteSpace(ta.text)) ta = Resources.Load($"{MathArticleResourcePrefix}en"); diff --git a/First Principles/Assets/Scripts/Game/LevelDefinition.cs b/First Principles/Assets/Scripts/Game/LevelDefinition.cs index aeef65f..398c104 100644 --- a/First Principles/Assets/Scripts/Game/LevelDefinition.cs +++ b/First Principles/Assets/Scripts/Game/LevelDefinition.cs @@ -88,6 +88,9 @@ public class LevelDefinition : ScriptableObject [Tooltip("Tint the background grid to match this level’s mood.")] public bool applyGridTheming = false; + [Tooltip("GPU wind-tunnel / schlieren backdrop (aerospace category).")] + public bool showWindTunnelBackdrop = false; + public Color gridCenterLineTheming = new Color(1f, 1f, 1f, 0.39f); public Color gridOutsideLineTheming = new Color(1f, 1f, 1f, 0.14f); diff --git a/First Principles/Assets/Scripts/Game/LevelManager.cs b/First Principles/Assets/Scripts/Game/LevelManager.cs index af7be04..4f84d71 100644 --- a/First Principles/Assets/Scripts/Game/LevelManager.cs +++ b/First Principles/Assets/Scripts/Game/LevelManager.cs @@ -41,6 +41,9 @@ public class LevelManager : MonoBehaviour private DerivRendererUI derivRenderer; private GridRendererUI gridRenderer; private RectTransform cartesianPlaneRect; + /// Scene-authored Cartesian plane size (fallback 1820×980); used to scale down on narrow portrait screens. + private Vector2 _cartesianGameplayDesignSize = new Vector2(1820f, 980f); + private Vector2 _lastSyncedCartesianRectSize = new Vector2(-1f, -1f); private GraphObstacleGenerator obstacleGenerator; private PlayerControllerUI2D playerController; @@ -51,7 +54,7 @@ public class LevelManager : MonoBehaviour private TextMeshProUGUI storyText; private TextMeshProUGUI stageHudText; - private TextMeshProUGUI controlsHintText; + private TextMeshProUGUI scoreHudText; private int lastStageHudKey = int.MinValue; private Sprite cachedHudPanelSprite; private float storyMiddlePauseSeconds = 1.65f; @@ -64,6 +67,12 @@ public class LevelManager : MonoBehaviour private readonly List levels = new List(); private int currentLevelIndex; + private const int GameplayStartingScore = 100; + private const int DerivativeTouchPenaltyPoints = 5; + + /// Touch f′ penalty score (starts at each level). + private int gameplayScore = GameplayStartingScore; + /// How many stage boundary thresholds the player has already crossed (derivative pops). private int nextStageIndex; private List stageTriggerXGrid; @@ -121,38 +130,29 @@ private void OnDisable() private void OnLocalizationChanged() { - RefreshControlsHintLocalized(); RefreshMathConceptsLabelLocalized(); RefreshStageHudLocalizedForce(); if (graphCalculatorMode) + { RefreshStoryBannerForCurrentMode(null); + TightenGraphCalculatorStoryBanner(); + var canvas = FindAnyObjectByType(); + var safe = canvas != null ? MobileUiRoots.GetSafeContentParent(canvas.transform) as RectTransform : null; + var calcParent = safe != null ? safe : canvas?.transform as RectTransform; + float bridge = DeviceLayout.PreferOnScreenGameControls ? DeviceLayout.TouchHintVerticalOffset : 22f; + float transRow = bridge + 74f; + float eqBottom = GraphCalculatorEquationPanelBottomY(transRow); + if (functionPlotter != null && calcParent != null) + GraphCalculatorEquationPanel.Ensure(calcParent, functionPlotter, FindPrimaryEquationTmp(), eqBottom, 108f); + var paramTmp = GameObject.Find("GraphicCalculatorParamHint")?.GetComponent(); + LayoutGraphCalculatorParamHintBelowStory(paramTmp, storyText != null ? storyText.rectTransform : null, + DeviceLayout.IsTabletLike() ? 144f : 132f, 10f); + } else if (levels.Count > 0 && currentLevelIndex >= 0 && currentLevelIndex < levels.Count) RefreshStoryBannerForCurrentMode(levels[currentLevelIndex]); - } - - private void RefreshControlsHintLocalized() - { - if (controlsHintText == null) - return; - if (graphCalculatorMode) - { - controlsHintText.text = LocalizationManager.Get("controls.calculator", - "Graphing calculator Type f(u) · Deriv · · Trans · Scale · Pinch · Back"); - } - else if (DeviceLayout.PreferOnScreenGameControls) - { - controlsHintText.text = LocalizationManager.Get("controls.mobile", - "Move \u25C0 \u25B6 \u00b7 Jump tap (keyboard: arrows / Space)"); - } - else - { - controlsHintText.text = LocalizationManager.Get("controls.desktop", - "Move \u2190 \u2192 \u00b7 Jump Space"); - } - - LocalizationManager.ApplyTextDirection(controlsHintText); + RefreshScoreHud(); } private void RefreshMathConceptsLabelLocalized() @@ -171,6 +171,7 @@ private void RefreshStageHudLocalizedForce() { lastStageHudKey = int.MinValue; RefreshStageHud(); + RefreshScoreHud(); } private void RefreshStoryBannerForCurrentMode(LevelDefinition def) @@ -182,7 +183,7 @@ private void RefreshStoryBannerForCurrentMode(LevelDefinition def) { storyText.text = TmpLatex.Process(LocalizationManager.Get("graph.calculator_intro", "Graphing calculator mode\n" + - "Type almost any f(u) in the field (variable x in your formula); Trans adjusts A, k, C, D; Scale & pinch zoom the window.")); + "Type almost any f(u) in the field (variable x in your formula); Trans adjusts A, k, C, D; Scale · pinch zoom the window.")); LocalizationManager.ApplyTextDirection(storyText); return; } @@ -241,6 +242,13 @@ private void SetupReferences() if (cartesianPlaneRect == null) cartesianPlaneRect = curveRenderer.GetComponent(); + if (cartesianPlaneRect != null) + { + Vector2 sd = cartesianPlaneRect.sizeDelta; + if (sd.sqrMagnitude > 10_000f) + _cartesianGameplayDesignSize = sd; + } + obstacleGenerator = GetComponent(); if (obstacleGenerator == null) obstacleGenerator = gameObject.AddComponent(); @@ -258,15 +266,159 @@ private void SetupReferences() HideLegacyGraphTuningButtons(); EnsureRiemannRenderer(); var mainCanvas = FindAnyObjectByType(); - if (mainCanvas != null && !graphCalculatorMode) - MobileTouchControls.EnsureForGameCanvas(mainCanvas.transform); + // Always create the layer on phones/tablets; disable in graphing calculator so a later level load + // (or any code that re-runs Ensure) does not depend on "first scene entry was platformer". + if (mainCanvas != null && DeviceLayout.PreferOnScreenGameControls) + { + GameplayScreenTouchZones.EnsureForGameCanvas(mainCanvas.transform); + GameplayScreenTouchZones.SetActiveForGameplayMode(!graphCalculatorMode); + } // Wire callbacks. playerController.SetDeathCallback(RestartCurrentLevel); playerController.SetFinishCallback(AdvanceLevel); + playerController.SetDerivativeLineGrazeScoringCallback(OnDerivativeLineGrazePenalty); if (derivRenderer != null) playerController.BindDerivativeRenderer(derivRenderer); ConfigureGameBackButtonDestination(); + + if (!graphCalculatorMode) + { + FitCartesianPlaneForGameplay(); + SyncGameplayLayoutToCartesianPlane(); + EnsurePlatformerHudPresentation(); + } + } + + /// + /// Scales the fixed-design Cartesian plane to fit the grid background (portrait phones, notches, touch HUD). + /// + private void FitCartesianPlaneForGameplay() + { + if (graphCalculatorMode || cartesianPlaneRect == null) + return; + + var parent = cartesianPlaneRect.parent as RectTransform; + if (parent == null) + return; + + float pw = parent.rect.width; + float ph = parent.rect.height; + if (pw < 2f || ph < 2f) + return; + + bool mobile = DeviceLayout.PreferOnScreenGameControls; + float hPad = mobile ? 8f : 14f; + float aspectTall = ph / Mathf.Max(1f, pw); + float topReserve; + float bottomReserve; + if (mobile) + { + // Portrait height fraction so graph + axes scale together on tall phones (not only TMP labels). + float tallBlend = Mathf.Clamp01((aspectTall - 1.35f) / 0.82f); + topReserve = Mathf.Clamp(ph * Mathf.Lerp(0.102f, 0.086f, tallBlend), 120f, 205f); + float hintFloor = DeviceLayout.TouchHintVerticalOffset + 26f; + bottomReserve = Mathf.Clamp(ph * Mathf.Lerp(0.128f, 0.112f, tallBlend), hintFloor, 255f); + } + else + { + topReserve = 138f; + bottomReserve = 70f; + } + + float maxW = Mathf.Max(64f, pw - hPad * 2f); + float maxH = Mathf.Max(64f, ph - topReserve - bottomReserve); + + float baseW = Mathf.Max(1f, _cartesianGameplayDesignSize.x); + float baseH = Mathf.Max(1f, _cartesianGameplayDesignSize.y); + float s = Mathf.Min(1f, maxW / baseW, maxH / baseH); + + Vector2 newSize = new Vector2(baseW * s, baseH * s); + float yNudge = mobile ? (bottomReserve - topReserve) * 0.18f : 0f; + + cartesianPlaneRect.anchorMin = new Vector2(0.5f, 0.5f); + cartesianPlaneRect.anchorMax = new Vector2(0.5f, 0.5f); + cartesianPlaneRect.pivot = new Vector2(0.5f, 0.5f); + + if ((cartesianPlaneRect.sizeDelta - newSize).sqrMagnitude < 0.25f && + Mathf.Abs(cartesianPlaneRect.anchoredPosition.y - yNudge) < 0.5f) + return; + + cartesianPlaneRect.sizeDelta = newSize; + cartesianPlaneRect.anchoredPosition = new Vector2(0f, yNudge); + } + + /// + /// Authoring used a fixed 1820×980 grid rect; after the Cartesian plane + /// shrinks on phones — stretch grid + curve renderers to fill it so axes, graphs, and obstacle math line up. + /// + private void StretchGameplayGridStackToCartesianPlane() + { + if (gridRenderer == null || cartesianPlaneRect == null) + return; + + var gridRt = gridRenderer.rectTransform; + gridRt.anchorMin = Vector2.zero; + gridRt.anchorMax = Vector2.one; + gridRt.pivot = new Vector2(0.5f, 0.5f); + gridRt.offsetMin = Vector2.zero; + gridRt.offsetMax = Vector2.zero; + gridRt.anchoredPosition = Vector2.zero; + + for (int i = 0; i < gridRt.childCount; i++) + { + var lineRt = gridRt.GetChild(i) as RectTransform; + if (lineRt == null) + continue; + lineRt.anchorMin = Vector2.zero; + lineRt.anchorMax = Vector2.one; + lineRt.pivot = new Vector2(0f, 0f); + lineRt.offsetMin = Vector2.zero; + lineRt.offsetMax = Vector2.zero; + lineRt.anchoredPosition = Vector2.zero; + } + + gridRenderer.SetVerticesDirty(); + } + + private void SyncGameplayLayoutToCartesianPlane() + { + if (graphCalculatorMode || cartesianPlaneRect == null || gridRenderer == null || + obstacleGenerator == null || playerController == null) + return; + + StretchGameplayGridStackToCartesianPlane(); + + Vector2 sz = cartesianPlaneRect.rect.size; + var gridSize = gridRenderer.gridSize; + + if (obstaclesRoot != null) + { + obstaclesRoot.sizeDelta = sz; + float uw = sz.x / gridSize.x; + float uh = sz.y / gridSize.y; + obstacleGenerator.SetLayout(obstaclesRoot, gridSize, uw, uh); + obstacleGenerator.RefreshObstaclePixelLayout(); + } + + playerController.ApplyResponsivePlaneLayout(cartesianPlaneRect, gridSize); + } + + private void LateUpdate() + { + if (graphCalculatorMode) + return; + if (cartesianPlaneRect == null || gridRenderer == null || obstacleGenerator == null || playerController == null) + return; + + FitCartesianPlaneForGameplay(); + + Vector2 sz = cartesianPlaneRect.rect.size; + if ((sz - _lastSyncedCartesianRectSize).sqrMagnitude < 0.01f) + return; + + _lastSyncedCartesianRectSize = sz; + SyncGameplayLayoutToCartesianPlane(); } /// @@ -351,10 +503,19 @@ private void EnterGraphCalculatorMode() RefreshStoryBannerForCurrentMode(null); storyText.color = new Color(1f, 1f, 1f, 0.94f); storyText.fontStyle = FontStyles.Bold; + TightenGraphCalculatorStoryBanner(); } + // No STAGE / PTS HUD in calculator — hide the whole panel (not platformer scoring). if (stageHudText != null && stageHudText.transform.parent != null) stageHudText.transform.parent.gameObject.SetActive(false); + else + { + if (stageHudText != null) + stageHudText.gameObject.SetActive(false); + if (scoreHudText != null) + scoreHudText.gameObject.SetActive(false); + } functionPlotter.transA = 1f; functionPlotter.transK = 1f; @@ -369,7 +530,11 @@ private void EnterGraphCalculatorMode() functionPlotter.SetEquationExtraSuffix(""); functionPlotter.SetCustomExpression("x^2"); functionPlotter.autoScaleVertical = false; - functionPlotter.autoScaleHorizontal = false; + // Stretch [xStart,xEnd] across the grid so pinch / Scale update _autoMidX/_autoScaleX; axis ticks track (LabelManager). + functionPlotter.autoScaleHorizontal = true; + // Pinch / Scale: same plotter units per grid row as per column (square math window). + functionPlotter.lockVerticalPlotScaleToHorizontalWindow = true; + functionPlotter.showWindTunnelBackdrop = false; if (curveRenderer != null) { @@ -393,12 +558,13 @@ private void EnterGraphCalculatorMode() var hintParent = safe != null ? safe : canvas?.transform as RectTransform; float bridgeControls = DeviceLayout.PreferOnScreenGameControls ? DeviceLayout.TouchHintVerticalOffset : 22f; float transRowBottom = bridgeControls + 74f; + float equationPanelBottomY = GraphCalculatorEquationPanelBottomY(transRowBottom); var equationStyleRef = FindPrimaryEquationTmp(); if (equationStyleRef != null) equationStyleRef.fontStyle = FontStyles.Bold; - GraphCalculatorEquationPanel.Ensure(hintParent, functionPlotter, equationStyleRef, transRowBottom + 110f, 108f); + GraphCalculatorEquationPanel.Ensure(hintParent, functionPlotter, equationStyleRef, equationPanelBottomY, 108f); var transGo = GameObject.Find("TransButton"); var scaleGo = GameObject.Find("ScaleButton"); @@ -409,24 +575,18 @@ private void EnterGraphCalculatorMode() if (legacyHint != null) legacyHint.name = "GraphicCalculatorParamHint"; + bool tabletHint = DeviceLayout.IsTabletLike(); if (hintParent != null && GameObject.Find("GraphicCalculatorParamHint") == null) { var hintGo = new GameObject("GraphicCalculatorParamHint"); var hrt = hintGo.AddComponent(); hrt.SetParent(hintParent, false); - hrt.anchorMin = new Vector2(0.5f, 0f); - hrt.anchorMax = new Vector2(0.5f, 0f); - hrt.pivot = new Vector2(0.5f, 0f); - bool tablet = DeviceLayout.IsTabletLike(); - float up = DeviceLayout.PreferOnScreenGameControls ? DeviceLayout.TouchHintVerticalOffset + 312f : 318f; - hrt.anchoredPosition = new Vector2(0f, up); - hrt.sizeDelta = new Vector2(tablet ? 1040f : 960f, tablet ? 144f : 132f); paramHint = hintGo.AddComponent(); paramHint.richText = true; paramHint.textWrappingMode = TextWrappingModes.Normal; paramHint.overflowMode = TextOverflowModes.Overflow; - paramHint.fontSize = UiTypography.Scale(tablet ? 31 : 27); + paramHint.fontSize = UiTypography.Scale(tabletHint ? 31 : 27); paramHint.alignment = TextAlignmentOptions.Top; paramHint.color = new Color(0.9f, 0.93f, 0.98f, 0.96f); ApplyPrimaryUiTypography(paramHint, FindPrimaryEquationTmp(), outlineWidth: 0.12f, outlineAlpha: 0.45f); @@ -450,6 +610,9 @@ private void EnterGraphCalculatorMode() } } + LayoutGraphCalculatorParamHintBelowStory(paramHint, storyText != null ? storyText.rectTransform : null, + tabletHint ? 144f : 132f, 10f); + ApplyGraphCalculatorControlButtonTypography(transGo); ApplyGraphCalculatorControlButtonTypography(scaleGo); @@ -471,8 +634,6 @@ private void EnterGraphCalculatorMode() if (calcAnalysis == null) calcAnalysis = gameObject.AddComponent(); calcAnalysis.Configure(functionPlotter, riemannRenderer, curveRenderer, equationStyleRef, transRowBottom); - - RefreshControlsHintLocalized(); } /// Trans / Scale labels use the project TMP default font and bold weight in calculator mode. @@ -495,6 +656,46 @@ private static void ApplyGraphCalculatorControlButtonTypography(GameObject butto } } + /// Shrink the tall story placeholder so the intro sits at the top; height follows TMP preferred size. + void TightenGraphCalculatorStoryBanner() + { + if (storyText == null) + return; + + storyText.alignment = TextAlignmentOptions.Top; + Canvas.ForceUpdateCanvases(); + storyText.ForceMeshUpdate(); + float w = storyText.rectTransform.rect.width; + if (w < 48f) + w = Mathf.Max(320f, Screen.safeArea.width * 0.88f); + Vector2 pv = storyText.GetPreferredValues(storyText.text, w, 0f); + float h = Mathf.Clamp(pv.y + 14f, 52f, 280f); + storyText.rectTransform.sizeDelta = new Vector2(0f, h); + } + + /// Bottom Y for the f(u) panel so it sits just above the Deriv / ∫ row (matches ). + float GraphCalculatorEquationPanelBottomY(float transRowBottomY) + { + bool tablet = DeviceLayout.IsTabletLike(); + return GraphCalculatorAnalysisControls.DerivativeIntegralRowTopFromBottom(transRowBottomY, tablet) + 12f; + } + + /// Places the Trans / Scale hint under the intro banner (calculator mode). + static void LayoutGraphCalculatorParamHintBelowStory(TextMeshProUGUI hint, RectTransform storyRt, float blockHeight, float gap) + { + if (hint == null || storyRt == null) + return; + + RectTransform hrt = hint.rectTransform; + hrt.SetParent(storyRt.parent, false); + hrt.anchorMin = storyRt.anchorMin; + hrt.anchorMax = storyRt.anchorMax; + hrt.pivot = new Vector2(0.5f, 1f); + hrt.sizeDelta = new Vector2(0f, blockHeight); + hrt.anchoredPosition = new Vector2(storyRt.anchoredPosition.x, + storyRt.anchoredPosition.y - storyRt.sizeDelta.y - gap); + } + private static void LayoutCalculatorToolButtons(GameObject transGo, GameObject scaleGo, float anchoredBottomY) { var canvas = UnityEngine.Object.FindAnyObjectByType(); @@ -674,7 +875,8 @@ private void CreateGameplayHudIfNeeded() panelRt.pivot = new Vector2(0f, 1f); float topPad = DeviceLayout.PreferOnScreenGameControls ? 12f : 20f; panelRt.anchoredPosition = new Vector2(18f, -topPad); - panelRt.sizeDelta = new Vector2(440f, 88f); + bool wideHud = DeviceLayout.IsTabletLike(); + panelRt.sizeDelta = new Vector2(wideHud ? 620f : 560f, wideHud ? 92f : 88f); RuntimeUiPolish.ApplyDropShadow(panelRt, new Vector2(2f, -3f), 0.26f); var panelBg = panelGo.AddComponent(); @@ -702,10 +904,10 @@ private void CreateGameplayHudIfNeeded() var textGo = new GameObject("StageHud"); var textRt = textGo.AddComponent(); textRt.SetParent(panelGo.transform, false); - textRt.anchorMin = Vector2.zero; - textRt.anchorMax = Vector2.one; + textRt.anchorMin = new Vector2(0f, 0f); + textRt.anchorMax = new Vector2(0.54f, 1f); textRt.offsetMin = new Vector2(18f, 12f); - textRt.offsetMax = new Vector2(-16f, -14f); + textRt.offsetMax = new Vector2(-6f, -14f); var tmp = textGo.AddComponent(); tmp.richText = true; @@ -723,57 +925,34 @@ private void CreateGameplayHudIfNeeded() tmp.text = FormatStageHudLine(1, 1); stageHudText = tmp; + + var scoreGo = new GameObject("ScoreHud"); + var scoreRt = scoreGo.AddComponent(); + scoreRt.SetParent(panelGo.transform, false); + scoreRt.anchorMin = new Vector2(0.52f, 0f); + scoreRt.anchorMax = new Vector2(1f, 1f); + scoreRt.offsetMin = new Vector2(4f, 12f); + scoreRt.offsetMax = new Vector2(-18f, -14f); + var scoreTmp = scoreGo.AddComponent(); + scoreTmp.richText = true; + scoreTmp.textWrappingMode = TextWrappingModes.Normal; + scoreTmp.overflowMode = TextOverflowModes.Overflow; + scoreTmp.fontSize = UiTypography.Scale(28); + scoreTmp.enableAutoSizing = true; + scoreTmp.fontSizeMin = UiTypography.Scale(16); + scoreTmp.fontSizeMax = UiTypography.Scale(30); + scoreTmp.alignment = TextAlignmentOptions.MidlineRight; + scoreTmp.color = new Color(0.94f, 0.95f, 0.98f, 1f); + scoreTmp.lineSpacing = -4f; + ApplyPrimaryUiTypography(scoreTmp, equationStyle, outlineWidth: 0.16f, outlineAlpha: 0.55f); + scoreHudText = scoreTmp; + RefreshScoreHud(); } CreateMathConceptsButtonIfNeeded(canvas, equationStyle); - - if (!graphCalculatorMode) - { - if (controlsHintText == null) - { - bool tabletUi = DeviceLayout.IsTabletLike(); - var barGo = new GameObject("ControlsHintPanel"); - var barRt = barGo.AddComponent(); - var safe = MobileUiRoots.GetSafeContentParent(canvas.transform); - barRt.SetParent(safe != null ? safe : canvas.transform, false); - barRt.anchorMin = new Vector2(0.5f, 0f); - barRt.anchorMax = new Vector2(0.5f, 0f); - barRt.pivot = new Vector2(0.5f, 0f); - float up = DeviceLayout.PreferOnScreenGameControls ? DeviceLayout.TouchHintVerticalOffset : 22f; - barRt.anchoredPosition = new Vector2(0f, up); - barRt.sizeDelta = new Vector2(tabletUi ? 900f : 760f, tabletUi ? 60f : 56f); - - var barBg = barGo.AddComponent(); - barBg.sprite = panelSprite; - barBg.color = new Color(0.08f, 0.09f, 0.13f, 0.85f); - barBg.raycastTarget = false; - barBg.type = panelSprite != null && panelSprite.border.sqrMagnitude > 0.001f ? Image.Type.Sliced : Image.Type.Simple; - - var textGo = new GameObject("ControlsHint"); - var textRt = textGo.AddComponent(); - textRt.SetParent(barGo.transform, false); - textRt.anchorMin = Vector2.zero; - textRt.anchorMax = Vector2.one; - textRt.offsetMin = new Vector2(20f, 8f); - textRt.offsetMax = new Vector2(-20f, -8f); - - var tmp = textGo.AddComponent(); - tmp.richText = true; - tmp.textWrappingMode = TextWrappingModes.Normal; - tmp.overflowMode = TextOverflowModes.Overflow; - tmp.fontSize = UiTypography.Scale(24); - tmp.alignment = TextAlignmentOptions.Midline; - tmp.color = new Color(0.82f, 0.85f, 0.92f, 0.92f); - tmp.characterSpacing = 0.25f; - ApplyPrimaryUiTypography(tmp, equationStyle, outlineWidth: 0.14f, outlineAlpha: 0.5f); - controlsHintText = tmp; - } - - RefreshControlsHintLocalized(); - } } - /// Top-right control: opens (same body as level-select math tips). + /// Top-right control: opens with math sections scoped to the current level (full glossary in graphing-calculator mode). private void CreateMathConceptsButtonIfNeeded(Canvas canvas, TextMeshProUGUI equationStyle) { if (canvas == null || GameObject.Find("MathConceptsButton") != null) @@ -802,7 +981,8 @@ private void CreateMathConceptsButtonIfNeeded(Canvas canvas, TextMeshProUGUI equ RuntimeUiPolish.ApplyButtonTransitions(btn, RuntimeUiPolish.AccentTeal, Color.Lerp(RuntimeUiPolish.AccentTeal, Color.white, 0.18f), Color.Lerp(RuntimeUiPolish.AccentTeal, Color.black, 0.25f)); - btn.onClick.AddListener(() => MathArticlesOverlay.Open(canvas.transform)); + btn.onClick.AddListener(() => MathArticlesOverlay.Open(canvas.transform, + graphCalculatorMode ? (int?)null : currentLevelIndex)); RuntimeUiPolish.ApplyDropShadow(rt, new Vector2(2f, -3f), 0.3f); var textGo = new GameObject("Text"); @@ -816,6 +996,11 @@ private void CreateMathConceptsButtonIfNeeded(Canvas canvas, TextMeshProUGUI equ var tmp = textGo.AddComponent(); tmp.text = LocalizationManager.Get("ui.math_concepts", "Math concepts"); tmp.fontSize = UiTypography.Scale(tablet ? 30 : 27); + tmp.enableAutoSizing = true; + tmp.fontSizeMin = UiTypography.Scale(17); + tmp.fontSizeMax = UiTypography.Scale(tablet ? 30 : 27); + tmp.textWrappingMode = TextWrappingModes.Normal; + tmp.overflowMode = TextOverflowModes.Truncate; tmp.fontStyle = FontStyles.Bold; tmp.alignment = TextAlignmentOptions.Center; tmp.color = new Color(0.92f, 0.97f, 1f, 1f); @@ -884,6 +1069,54 @@ private void RefreshStageHud() LocalizationManager.ApplyTextDirection(stageHudText); } + void ResetGameplayScoreForNewLevel() + { + gameplayScore = GameplayStartingScore; + RefreshScoreHud(); + } + + void OnDerivativeLineGrazePenalty() + { + if (graphCalculatorMode) + return; + gameplayScore = Mathf.Max(0, gameplayScore - DerivativeTouchPenaltyPoints); + RefreshScoreHud(); + } + + void RefreshScoreHud() + { + if (scoreHudText == null) + return; + string label = LocalizationManager.Get("hud.points", "PTS"); + scoreHudText.text = + $"{label}\n{gameplayScore}"; + LocalizationManager.ApplyTextDirection(scoreHudText); + } + + /// + /// Stage + score share StageHudPanel. Graphing calculator hides the whole panel; platformer needs + /// both lines visible. Other UI can reparent later — re-activate panel + children and bring HUD forward. + /// + private void EnsurePlatformerHudPresentation() + { + if (graphCalculatorMode) + return; + + if (stageHudText != null && stageHudText.transform.parent != null) + { + var stagePanel = stageHudText.transform.parent.gameObject; + stagePanel.SetActive(true); + stageHudText.gameObject.SetActive(true); + if (scoreHudText != null) + { + scoreHudText.gameObject.SetActive(true); + RefreshScoreHud(); + } + + stagePanel.transform.SetAsLastSibling(); + } + } + /// Square / UI sprite for flat panels (falls back to a tiny white sprite so Image always draws). private Sprite GetHudPanelSprite() { @@ -947,9 +1180,10 @@ private void EnsureRiemannRenderer() { var curveLineRt = curveRenderer.GetComponent(); Transform lineParent = curveLineRt != null ? curveLineRt.parent : null; - if (lineParent != null && riemannRenderer.transform.parent != lineParent) + if (lineParent != null) { - riemannRenderer.transform.SetParent(lineParent, false); + if (riemannRenderer.transform.parent != lineParent) + riemannRenderer.transform.SetParent(lineParent, false); var riemannRt = riemannRenderer.GetComponent(); if (curveLineRt != null && riemannRt != null) { @@ -960,6 +1194,9 @@ private void EnsureRiemannRenderer() riemannRt.sizeDelta = curveLineRt.sizeDelta; riemannRt.localScale = curveLineRt.localScale; } + + riemannRenderer.gameObject.SetActive(true); + riemannRenderer.enabled = true; riemannRenderer.transform.SetSiblingIndex(0); } } @@ -1811,10 +2048,35 @@ private void BuildSampleLevels() storyPauseSecondsOverride: 2.65f )); - // ---- Aerospace engineering & aerodynamics (indices 34–40) ----------------------------- - levels.Add(MakeLevel( GameLevelCatalog.DisplayNames[34], + FunctionType.ThermoAdiabaticPV, + curveColor: new Color(0.98f, 0.52f, 0.28f, 1f), + derivativeColor: new Color(0.45f, 0.82f, 0.98f, 1f), + transA: 9.5f, + transK: 0.38f, + transC: -2.35f, + transD: -16f, + power: 2, + baseN: 140, + story: + "Thermodynamics — reversible adiabatic path — for an ideal gas, quasi-static adiabats obey PVγ = constant (no heat exchange, work comes only from internal energy bookkeeping).\n\n" + + "Here the horizontal walk is a scaled “volume-like” coordinate; height tracks pressure mood as P ∝ V−γ. We set N = 140 so γ ≈ 1.40 — a familiar air/diatomic story problem vibe, not a lab instrument.\n\n" + + "Teaching sketch only: real pistons have losses, gradients, and non-equilibrium corners — but the slope story you feel underfoot is still γ.", + derivativePopTriggerCountOverride: 4, + applyGridTheming: true, + gridCenter: new Color(0.38f, 0.18f, 0.1f, 0.36f), + gridOutside: new Color(0.22f, 0.1f, 0.06f, 0.1f), + storyPauseSecondsOverride: 2.85f, + graphStep: 0.11f, + levelXStart: -14f, + levelXEnd: 14f + )); + + // ---- Aerospace engineering & aerodynamics (indices 35–41) ----------------------------- + + levels.Add(MakeLevel( + GameLevelCatalog.DisplayNames[35], FunctionType.AeroLiftVsAlpha, curveColor: new Color(0.35f, 0.72f, 1f, 1f), derivativeColor: new Color(1f, 0.58f, 0.3f, 1f), @@ -1832,7 +2094,8 @@ private void BuildSampleLevels() applyGridTheming: true, gridCenter: new Color(0.16f, 0.32f, 0.48f, 0.37f), gridOutside: new Color(0.12f, 0.22f, 0.34f, 0.11f), - storyPauseSecondsOverride: 2.65f + storyPauseSecondsOverride: 2.65f, + showWindTunnelBackdrop: true )); var dragPolarOverlays = new[] @@ -1842,7 +2105,7 @@ private void BuildSampleLevels() }; levels.Add(MakeLevel( - GameLevelCatalog.DisplayNames[35], + GameLevelCatalog.DisplayNames[36], FunctionType.AeroDragPolarTriple, curveColor: new Color(0.75f, 0.55f, 1f, 1f), derivativeColor: new Color(1f, 0.72f, 0.35f, 1f), @@ -1861,11 +2124,12 @@ private void BuildSampleLevels() gridCenter: new Color(0.35f, 0.25f, 0.5f, 0.36f), gridOutside: new Color(0.25f, 0.18f, 0.36f, 0.1f), storyPauseSecondsOverride: 2.65f, - dragPolarOverlayColors: dragPolarOverlays + dragPolarOverlayColors: dragPolarOverlays, + showWindTunnelBackdrop: true )); levels.Add(MakeLevel( - GameLevelCatalog.DisplayNames[36], + GameLevelCatalog.DisplayNames[37], FunctionType.AeroIsothermalDensity, curveColor: new Color(0.45f, 0.88f, 0.72f, 1f), derivativeColor: new Color(0.95f, 0.45f, 0.5f, 1f), @@ -1883,7 +2147,8 @@ private void BuildSampleLevels() applyGridTheming: true, gridCenter: new Color(0.18f, 0.42f, 0.34f, 0.36f), gridOutside: new Color(0.13f, 0.3f, 0.24f, 0.1f), - storyPauseSecondsOverride: 2.6f + storyPauseSecondsOverride: 2.6f, + showWindTunnelBackdrop: true )); var aeroPhugColors = new[] @@ -1894,7 +2159,7 @@ private void BuildSampleLevels() }; levels.Add(MakeLevel( - GameLevelCatalog.DisplayNames[37], + GameLevelCatalog.DisplayNames[38], FunctionType.DampedOscillator, curveColor: new Color(0.4f, 0.85f, 0.95f, 1f), derivativeColor: new Color(1f, 0.52f, 0.28f, 1f), @@ -1913,11 +2178,12 @@ private void BuildSampleLevels() gridCenter: new Color(0.14f, 0.35f, 0.48f, 0.36f), gridOutside: new Color(0.1f, 0.25f, 0.34f, 0.1f), levelStageColors: aeroPhugColors, - storyPauseSecondsOverride: 2.75f + storyPauseSecondsOverride: 2.75f, + showWindTunnelBackdrop: true )); levels.Add(MakeLevel( - GameLevelCatalog.DisplayNames[38], + GameLevelCatalog.DisplayNames[39], FunctionType.AeroNewtonianSinSquared, curveColor: new Color(1f, 0.45f, 0.42f, 1f), derivativeColor: new Color(0.5f, 0.82f, 1f, 1f), @@ -1935,11 +2201,12 @@ private void BuildSampleLevels() applyGridTheming: true, gridCenter: new Color(0.48f, 0.22f, 0.2f, 0.35f), gridOutside: new Color(0.34f, 0.15f, 0.14f, 0.1f), - storyPauseSecondsOverride: 2.55f + storyPauseSecondsOverride: 2.55f, + showWindTunnelBackdrop: true )); levels.Add(MakeLevel( - GameLevelCatalog.DisplayNames[39], + GameLevelCatalog.DisplayNames[40], FunctionType.Sine, curveColor: new Color(0.55f, 0.65f, 1f, 1f), derivativeColor: new Color(1f, 0.48f, 0.72f, 1f), @@ -1957,11 +2224,12 @@ private void BuildSampleLevels() applyGridTheming: true, gridCenter: new Color(0.22f, 0.28f, 0.52f, 0.36f), gridOutside: new Color(0.16f, 0.2f, 0.38f, 0.1f), - storyPauseSecondsOverride: 2.45f + storyPauseSecondsOverride: 2.45f, + showWindTunnelBackdrop: true )); levels.Add(MakeLevel( - GameLevelCatalog.DisplayNames[40], + GameLevelCatalog.DisplayNames[41], FunctionType.ExponentialDecay, curveColor: new Color(1f, 0.72f, 0.38f, 1f), derivativeColor: new Color(0.45f, 0.78f, 1f, 1f), @@ -1979,12 +2247,13 @@ private void BuildSampleLevels() applyGridTheming: true, gridCenter: new Color(0.42f, 0.3f, 0.18f, 0.35f), gridOutside: new Color(0.3f, 0.22f, 0.12f, 0.1f), - storyPauseSecondsOverride: 2.65f + storyPauseSecondsOverride: 2.65f, + showWindTunnelBackdrop: true )); - // Economics (41–42) + Mandelbrot (43) + thermo (44) + golden spiral (45); Transforms (46–47); Mandelbrot encore finale (48). + // Economics (42–43); Transforms (44–45); boss block (46–49); spring (50); Big O (51–58). levels.Add(MakeLevel( - GameLevelCatalog.DisplayNames[41], + GameLevelCatalog.DisplayNames[42], FunctionType.EconomyDotcomBubbleStylized, curveColor: new Color(0.14f, 0.58f, 0.34f, 1f), derivativeColor: new Color(0.98f, 0.72f, 0.28f, 1f), @@ -2007,7 +2276,7 @@ private void BuildSampleLevels() )); levels.Add(MakeLevel( - GameLevelCatalog.DisplayNames[42], + GameLevelCatalog.DisplayNames[43], FunctionType.EconomySubprime2008Stylized, curveColor: new Color(0.72f, 0.22f, 0.2f, 1f), derivativeColor: new Color(0.52f, 0.78f, 0.95f, 1f), @@ -2029,83 +2298,8 @@ private void BuildSampleLevels() graphStep: 0.09f )); - levels.Add(MakeLevel( - GameLevelCatalog.DisplayNames[43], - FunctionType.MandelbrotEscapeImSlice, - curveColor: new Color(0.25f, 0.98f, 0.62f, 1f), - derivativeColor: new Color(0.98f, 0.38f, 0.82f, 1f), - transA: -0.743643887f, - transK: 0.088f, - transC: -2.18f, - transD: 0f, - power: 80, - baseN: 26, - story: - "Final stage — Mandelbrot set — the backdrop is the classic c-plane (Re horizontal, Im vertical) colored by smooth escape time; the bright line marks your fixed Re(c). The green curve is the same slice as before: height vs Im(c).\n\n" + - "The cardioid and bulbs are the boundary where Julia sets disconnect; zooming that coastline reveals endless filaments (true deep zoom needs a different engine, but the map is real Mandelbrot math).\n\n" + - "Slice iteration uses |Im(c)| (conjugate symmetry). Curve uses fractional escape counts so steps look less “flat” than raw integers.", - derivativePopTriggerCountOverride: 4, - applyGridTheming: true, - gridCenter: new Color(0.12f, 0.32f, 0.48f, 0.4f), - gridOutside: new Color(0.08f, 0.18f, 0.28f, 0.12f), - storyPauseSecondsOverride: 2.9f, - graphStep: 0.14f, - levelXStart: -16f, - levelXEnd: 16f - )); - levels.Add(MakeLevel( GameLevelCatalog.DisplayNames[44], - FunctionType.ThermoAdiabaticPV, - curveColor: new Color(0.98f, 0.52f, 0.28f, 1f), - derivativeColor: new Color(0.45f, 0.82f, 0.98f, 1f), - transA: 9.5f, - transK: 0.38f, - transC: -2.35f, - transD: -16f, - power: 2, - baseN: 140, - story: - "Thermodynamics — reversible adiabatic path — for an ideal gas, quasi-static adiabats obey PVγ = constant (no heat exchange, work comes only from internal energy bookkeeping).\n\n" + - "Here the horizontal walk is a scaled “volume-like” coordinate; height tracks pressure mood as P ∝ V−γ. We set N = 140 so γ ≈ 1.40 — a familiar air/diatomic story problem vibe, not a lab instrument.\n\n" + - "Teaching sketch only: real pistons have losses, gradients, and non-equilibrium corners — but the slope story you feel underfoot is still γ.", - derivativePopTriggerCountOverride: 4, - applyGridTheming: true, - gridCenter: new Color(0.38f, 0.18f, 0.1f, 0.36f), - gridOutside: new Color(0.22f, 0.1f, 0.06f, 0.1f), - storyPauseSecondsOverride: 2.85f, - graphStep: 0.11f, - levelXStart: -14f, - levelXEnd: 14f - )); - - levels.Add(MakeLevel( - GameLevelCatalog.DisplayNames[45], - FunctionType.PolarGoldenLogSpiral, - curveColor: new Color(0.99f, 0.86f, 0.38f, 1f), - derivativeColor: new Color(0.62f, 0.42f, 0.98f, 1f), - transA: 2.15f, - transK: 1f, - transC: -3.08f, - transD: 0f, - power: 1, - baseN: 105, - story: - "Secret boss — golden spiral — nature’s favorite growth curve is a logarithmic spiral: each time angle θ advances steadily, radius scales by a fixed factor tied to the golden ratio φ = (1+√5)/2.\n\n" + - "Fibonacci rectangles, nautilus moods, and phyllotaxis in sunflowers all whisper the same proportion — here you walk the graph as r(θ) ∝ φ^{kθ} on a polar-style readout (horizontal = θ, vertical = r).\n\n" + - "Exact classical spirals use arc-length subtleties; this stage is the clean calculus headline: exponential growth in φ as you turn.", - derivativePopTriggerCountOverride: 4, - applyGridTheming: true, - gridCenter: new Color(0.42f, 0.34f, 0.14f, 0.38f), - gridOutside: new Color(0.22f, 0.17f, 0.08f, 0.12f), - storyPauseSecondsOverride: 2.95f, - graphStep: 0.075f, - levelXStart: -11.5f, - levelXEnd: 13.5f - )); - - levels.Add(MakeLevel( - GameLevelCatalog.DisplayNames[46], FunctionType.TransformFourierSinc, curveColor: new Color(0.42f, 0.78f, 1f, 1f), derivativeColor: new Color(1f, 0.55f, 0.85f, 1f), @@ -2130,7 +2324,7 @@ private void BuildSampleLevels() )); levels.Add(MakeLevel( - GameLevelCatalog.DisplayNames[47], + GameLevelCatalog.DisplayNames[45], FunctionType.TransformLaplaceCausalDecay, curveColor: new Color(0.55f, 0.95f, 0.65f, 1f), derivativeColor: new Color(0.98f, 0.72f, 0.38f, 1f), @@ -2155,7 +2349,32 @@ private void BuildSampleLevels() )); levels.Add(MakeLevel( - GameLevelCatalog.DisplayNames[48], + GameLevelCatalog.DisplayNames[46], + FunctionType.PolarGoldenLogSpiral, + curveColor: new Color(0.99f, 0.86f, 0.38f, 1f), + derivativeColor: new Color(0.62f, 0.42f, 0.98f, 1f), + transA: 2.15f, + transK: 1f, + transC: -3.08f, + transD: 0f, + power: 1, + baseN: 105, + story: + "Secret boss — golden spiral — nature’s favorite growth curve is a logarithmic spiral: each time angle θ advances steadily, radius scales by a fixed factor tied to the golden ratio φ = (1+√5)/2.\n\n" + + "Fibonacci rectangles, nautilus moods, and phyllotaxis in sunflowers all whisper the same proportion — here you walk the graph as r(θ) ∝ φ^{kθ} on a polar-style readout (horizontal = θ, vertical = r).\n\n" + + "Exact classical spirals use arc-length subtleties; this stage is the clean calculus headline: exponential growth in φ as you turn.", + derivativePopTriggerCountOverride: 4, + applyGridTheming: true, + gridCenter: new Color(0.42f, 0.34f, 0.14f, 0.38f), + gridOutside: new Color(0.22f, 0.17f, 0.08f, 0.12f), + storyPauseSecondsOverride: 2.95f, + graphStep: 0.075f, + levelXStart: -11.5f, + levelXEnd: 13.5f + )); + + levels.Add(MakeLevel( + GameLevelCatalog.DisplayNames[47], FunctionType.MandelbrotEscapeImSlice, curveColor: new Color(0.25f, 0.98f, 0.62f, 1f), derivativeColor: new Color(0.98f, 0.38f, 0.82f, 1f), @@ -2168,7 +2387,7 @@ private void BuildSampleLevels() story: "True finale — Mandelbrot encore — the backdrop is again the classic c-plane (Re horizontal, Im vertical) colored by smooth escape time; your path follows the same slice: height vs Im(c) at fixed Re(c).\n\n" + "This is the final boss gate: every step still reads Julia–Mandelbrot folklore — bulbs, filaments, and the cardioid where behavior flips.\n\n" + - "Same slice recipe as the mid-finale: fractional escape counts + |Im| symmetry. Welcome back to the boundary.", + "Fractional escape counts + |Im| symmetry on this slice — the Mandelbrot coastline in one graph.", derivativePopTriggerCountOverride: 4, applyGridTheming: true, gridCenter: new Color(0.12f, 0.32f, 0.48f, 0.4f), @@ -2184,7 +2403,7 @@ private void BuildSampleLevels() float lorenzBossK = LorenzAttractorSamples.TimeMax / Mathf.Max(lorenzBossX1 - lorenzBossX0, 0.01f); levels.Add(MakeLevel( - GameLevelCatalog.DisplayNames[49], + GameLevelCatalog.DisplayNames[48], FunctionType.ChaosLorenzButterflyX, curveColor: new Color(0.42f, 0.86f, 1f, 1f), derivativeColor: new Color(1f, 0.52f, 0.88f, 1f), @@ -2195,8 +2414,8 @@ private void BuildSampleLevels() power: 1, baseN: 2, story: - "True finale — Lorenz butterfly — the horizontal axis is a long stretch of simulation time; height tracks the classic Lorenz x(t) with σ=10, ρ=28, β=8/3.\n\n" + - "Watch how the attractor keeps retuning: the same law, sensitive dependence, a path that never quite repeats — the butterfly effect made legible as motion.\n\n" + + "True finale — Chaos Theory — the horizontal axis is a long stretch of simulation time; height tracks the classic Lorenz x(t) with σ=10, ρ=28, β=8/3.\n\n" + + "Watch how the attractor keeps retuning: the same law, sensitive dependence, a path that never quite repeats — chaos theory made legible as motion.\n\n" + "Normalized after burn-in so the wings fill your grid; the curve scrolls through phase so the stage feels alive.", derivativePopTriggerCountOverride: 4, applyGridTheming: true, @@ -2208,6 +2427,31 @@ private void BuildSampleLevels() levelXEnd: lorenzBossX1 )); + levels.Add(MakeLevel( + GameLevelCatalog.DisplayNames[49], + FunctionType.PhysicsGravityWellInverseSqrt, + curveColor: new Color(0.55f, 0.72f, 1f, 1f), + derivativeColor: new Color(1f, 0.45f, 0.35f, 1f), + transA: 4.2f, + transK: 0.82f, + transC: 1.35f, + transD: 0.38f, + power: 1, + baseN: 2, + story: + "BOSS: Black hole — gravity well — the curve is a softened 1/r slice: depth spikes toward the center, then relaxes into a gentle far-field shoulder.\n\n" + + "It is a teaching stand-in for how gravitational potential tightens near mass — not a full GR embedding, but the right “falling in” intuition on a 1D graph.\n\n" + + "ε from D keeps the well finite so the derivative game stays fair; ride the rim, respect the steep core.", + derivativePopTriggerCountOverride: 4, + applyGridTheming: true, + gridCenter: new Color(0.06f, 0.08f, 0.22f, 0.48f), + gridOutside: new Color(0.04f, 0.06f, 0.14f, 0.14f), + storyPauseSecondsOverride: 3f, + graphStep: 0.1f, + levelXStart: -12f, + levelXEnd: 12f + )); + var springMassColors = new[] { new Color(0.42f, 0.95f, 0.68f, 1f), @@ -2240,6 +2484,167 @@ private void BuildSampleLevels() levelXStart: -14f, levelXEnd: 14f )); + + // --- Big O notation (algorithms): u = k(x−D) plays the role of input size n on the graph --- + levels.Add(MakeLevel( + GameLevelCatalog.DisplayNames[51], + FunctionType.Power, + curveColor: new Color(0.65f, 0.85f, 1f, 1f), + derivativeColor: new Color(1f, 0.78f, 0.45f, 1f), + transA: 1.85f, + transK: 0.12f, + transC: -0.35f, + transD: 0f, + power: 0, + baseN: 2, + story: + "Big O: O(1) — constant time: the work doesn’t grow with input size. Here u⁰ = 1, so height stays flat as u (our stand-in for n) marches.\n\n" + + "Hash lookups and array indexing are classic O(1) when the model fits — the graph is the calm horizontal proof.", + derivativePopTriggerCountOverride: 3, + graphStep: 0.11f, + levelXStart: -12f, + levelXEnd: 12f + )); + + levels.Add(MakeLevel( + GameLevelCatalog.DisplayNames[52], + FunctionType.NaturalLog, + curveColor: new Color(0.5f, 0.92f, 0.78f, 1f), + derivativeColor: new Color(0.98f, 0.55f, 0.82f, 1f), + transA: 1.05f, + transK: 0.38f, + transC: -2.35f, + transD: 0f, + power: 1, + baseN: 2, + story: + "Big O: O(log n) — each step shrinks the problem by a constant factor (binary search, balanced trees). ln u climbs gently forever.\n\n" + + "Domain needs u > 0 — we sample away from zero so the law stays finite on the grid.", + derivativePopTriggerCountOverride: 3, + graphStep: 0.1f, + levelXStart: 0.45f, + levelXEnd: 16f + )); + + levels.Add(MakeLevel( + GameLevelCatalog.DisplayNames[53], + FunctionType.SquareRoot, + curveColor: new Color(0.72f, 0.78f, 1f, 1f), + derivativeColor: new Color(1f, 0.62f, 0.48f, 1f), + transA: 1.15f, + transK: 0.36f, + transC: -2.05f, + transD: 0f, + power: 1, + baseN: 2, + story: + "Big O: O(√n) — sublinear growth: think nested loops that only walk up to √n, or some number-theory sieves. √u bends upward but bows to log in the long run.\n\n" + + "We keep u ≥ 0 so the square root stays real.", + derivativePopTriggerCountOverride: 3, + graphStep: 0.095f, + levelXStart: 0f, + levelXEnd: 15f + )); + + levels.Add(MakeLevel( + GameLevelCatalog.DisplayNames[54], + FunctionType.Power, + curveColor: new Color(0.55f, 0.9f, 1f, 1f), + derivativeColor: new Color(1f, 0.5f, 0.65f, 1f), + transA: 0.34f, + transK: 0.5f, + transC: -2.12f, + transD: 0f, + power: 1, + baseN: 2, + story: + "Big O: O(n) — scan the input once: summing a list, finding a max, a single loop. u¹ is the straight-ahead ramp.\n\n" + + "Slope (derivative) stays in the same growth class — still linear in this stylized picture.", + derivativePopTriggerCountOverride: 3, + graphStep: 0.1f, + levelXStart: -9f, + levelXEnd: 9f + )); + + levels.Add(MakeLevel( + GameLevelCatalog.DisplayNames[55], + FunctionType.BigONLogN, + curveColor: new Color(0.48f, 0.82f, 1f, 1f), + derivativeColor: new Color(1f, 0.58f, 0.78f, 1f), + transA: 0.22f, + transK: 0.48f, + transC: -2.45f, + transD: 0f, + power: 1, + baseN: 2, + story: + "Big O: O(n log n) — the sweet spot for sorting lower bounds (comparison sorts) and many divide steps. u ln u pulls away from linear but loses to n².\n\n" + + "We clamp the small‑u end so ln doesn’t sing on zero — same idea as “n big enough” in proofs.", + derivativePopTriggerCountOverride: 3, + graphStep: 0.095f, + levelXStart: 0.5f, + levelXEnd: 14f + )); + + levels.Add(MakeLevel( + GameLevelCatalog.DisplayNames[56], + FunctionType.Power, + curveColor: new Color(0.6f, 0.72f, 1f, 1f), + derivativeColor: new Color(1f, 0.52f, 0.42f, 1f), + transA: 0.042f, + transK: 0.46f, + transC: -2f, + transD: 0f, + power: 2, + baseN: 2, + story: + "Big O: O(n²) — nested loops, many pairwise checks, naive matrix setups. u² accelerates — the derivative warns you early.\n\n" + + "When you see the parabola in complexity class, look for a double walk over data.", + derivativePopTriggerCountOverride: 3, + graphStep: 0.09f, + levelXStart: -7.5f, + levelXEnd: 7.5f + )); + + levels.Add(MakeLevel( + GameLevelCatalog.DisplayNames[57], + FunctionType.Power, + curveColor: new Color(0.52f, 0.68f, 0.98f, 1f), + derivativeColor: new Color(1f, 0.48f, 0.55f, 1f), + transA: 0.0055f, + transK: 0.34f, + transC: -1.55f, + transD: 0f, + power: 3, + baseN: 2, + story: + "Big O: O(n³) — triple loops, naive Floyd–Warshall mood, dense cubic work. u³ rockets faster than n² — small constants don’t save you forever.\n\n" + + "Good algorithms often avoid this exponent; the graph shows why.", + derivativePopTriggerCountOverride: 3, + graphStep: 0.085f, + levelXStart: -6f, + levelXEnd: 6f + )); + + levels.Add(MakeLevel( + GameLevelCatalog.DisplayNames[58], + FunctionType.Exponential, + curveColor: new Color(0.58f, 0.95f, 0.72f, 1f), + derivativeColor: new Color(1f, 0.45f, 0.88f, 1f), + transA: 0.075f, + transK: 0.42f, + transC: -1.15f, + transD: 0f, + power: 1, + baseN: 2, + story: + "Big O: O(2ⁿ) — exhaustive subsets, brute-force SAT-ish nightmares. 2ᵘ explodes; we keep the window modest so the grid survives.\n\n" + + "Memoization, pruning, and smarter structure exist precisely because this curve leaves polite bounds.", + derivativePopTriggerCountOverride: 3, + graphStep: 0.11f, + levelXStart: -5.5f, + levelXEnd: 3.5f + )); } /// @@ -2273,7 +2678,8 @@ private LevelDefinition MakeLevel( float? levelXStart = null, float? levelXEnd = null, Color[] dragPolarOverlayColors = null, - float? riemannPlatformCoverage = null) + float? riemannPlatformCoverage = null, + bool showWindTunnelBackdrop = false) { var def = ScriptableObject.CreateInstance(); def.levelName = name; @@ -2345,6 +2751,8 @@ private LevelDefinition MakeLevel( }; } + def.showWindTunnelBackdrop = showWindTunnelBackdrop; + return def; } @@ -2354,6 +2762,9 @@ private void LoadLevel(int index) if (levels.Count == 0 || functionPlotter == null) return; + if (!graphCalculatorMode) + ResetGameplayScoreForNewLevel(); + currentLevelIndex = Mathf.Clamp(index, 0, levels.Count - 1); nextStageIndex = 0; lastStageHudKey = int.MinValue; @@ -2382,6 +2793,7 @@ private void ApplyLevelTheme(LevelDefinition def) functionPlotter.verticalFillFraction = def.graphVerticalFillFraction; functionPlotter.autoScaleHorizontal = def.autoFitGraphHorizontal; functionPlotter.horizontalFillFraction = def.graphHorizontalFillFraction; + functionPlotter.lockVerticalPlotScaleToHorizontalWindow = false; functionPlotter.transA = def.transA; functionPlotter.transK = def.transK; @@ -2391,6 +2803,7 @@ private void ApplyLevelTheme(LevelDefinition def) functionPlotter.power = def.power; functionPlotter.baseN = def.baseN; functionPlotter.differentiate = true; + functionPlotter.showWindTunnelBackdrop = def.showWindTunnelBackdrop; if (def.showRiemannVisualization) { @@ -2406,6 +2819,9 @@ private void ApplyLevelTheme(LevelDefinition def) curveRenderer.color = def.curveColor; derivRenderer.color = def.derivativeColor; + derivRenderer.thickness = DerivRendererUI.DefaultThicknessPixels; + if (popAnimator != null) + popAnimator.SyncRestThicknessFromTarget(); if (def.functionType == FunctionType.AeroDragPolarTriple) { @@ -2470,11 +2886,59 @@ private void ApplyLevelTheme(LevelDefinition def) // Story + roleplay intro run from after the world is built. } + /// + /// Stops full-screen overlays that can survive (same scene) and block touch raycasts. + /// + private void TearDownInterruptedLevelFlowUi() + { + if (stageIntroRoot != null) + { + if (stageIntroCanvasGroup != null) + { + stageIntroCanvasGroup.blocksRaycasts = false; + stageIntroCanvasGroup.interactable = false; + } + + stageIntroRoot.SetActive(false); + } + + var canvas = FindAnyObjectByType(); + if (canvas == null) + return; + + var safe = MobileUiRoots.GetSafeContentParent(canvas.transform); + Transform parent = safe != null ? safe : canvas.transform; + for (int i = parent.childCount - 1; i >= 0; i--) + { + var c = parent.GetChild(i); + if (c.name == "MobileControlGuideOverlay") + Destroy(c.gameObject); + } + } + + /// + /// Re-creates / re-parents the full-screen touch catcher after layout so it stays above the graph stack. + /// + private void EnsureGameplayTouchZonesAfterLevelReady() + { + if (graphCalculatorMode || !DeviceLayout.PreferOnScreenGameControls) + return; + + var canvas = FindAnyObjectByType(); + if (canvas == null) + return; + + GameplayScreenTouchZones.EnsureForGameCanvas(canvas.transform); + GameplayScreenTouchZones.SetActiveForGameplayMode(true); + } + /// /// Builds platforms after plot refresh; then optional roleplay “page”, then the ordinary story banner fade. /// private IEnumerator LoadLevelFullRoutine(LevelDefinition def) { + TearDownInterruptedLevelFlowUi(); + if (playerController != null) playerController.SetInputLocked(true); @@ -2499,7 +2963,13 @@ private IEnumerator LoadLevelFullRoutine(LevelDefinition def) // Match original behaviour: player can move while the top story banner fades. if (playerController != null) + { + MobileInputBridge.ClearTouchRouting(); playerController.SetInputLocked(false); + } + + EnsureGameplayTouchZonesAfterLevelReady(); + EnsurePlatformerHudPresentation(); if (storyText != null) { @@ -2836,6 +3306,8 @@ private IEnumerator LoadWorldAfterThemeChange(LevelDefinition def, bool grantStr if (obstacleGenerator == null || playerController == null) yield break; + FitCartesianPlaneForGameplay(); + var gridSize = gridRenderer.gridSize; var unitWidth = cartesianPlaneRect.rect.width / (float)gridSize.x; @@ -2863,8 +3335,11 @@ private IEnumerator LoadWorldAfterThemeChange(LevelDefinition def, bool grantStr else playerController.SetDeathMinYGrid(deathMinYGrid); + playerController.SetGridToPixelUnits(unitWidth, unitHeight); playerController.SetWorld(world); playerController.ResetToSpawn(world, grantStrongFirstGroundJump); + + _lastSyncedCartesianRectSize = cartesianPlaneRect.rect.size; } private IEnumerator FadeStoryTextRoutine() diff --git a/First Principles/Assets/Scripts/Game/LevelSelectController.cs b/First Principles/Assets/Scripts/Game/LevelSelectController.cs index 2d229e1..9b70ecf 100644 --- a/First Principles/Assets/Scripts/Game/LevelSelectController.cs +++ b/First Principles/Assets/Scripts/Game/LevelSelectController.cs @@ -637,7 +637,100 @@ private void BuildLevelViewForCategory(int categoryIndex, int firstLevel, int la private void StartGameAt(int index) { + if (GameLevelCatalog.IsComingSoonLevel(index)) + { + ShowComingSoonOverlay(); + return; + } + LevelSelection.SetSelectedLevel(index); SceneTransitionHost.LoadSingleScene("Game"); } + + private const string ComingSoonOverlayName = "ComingSoonOverlayRoot"; + + /// Full-screen message for catalog levels not yet playable (e.g. Hohmann transfer). + private void ShowComingSoonOverlay() + { + var canvas = FindAnyObjectByType(); + if (canvas == null) + return; + + var existing = canvas.transform.Find(ComingSoonOverlayName); + if (existing != null) + Destroy(existing.gameObject); + + var root = new GameObject(ComingSoonOverlayName); + var rootRt = root.AddComponent(); + rootRt.SetParent(canvas.transform, false); + rootRt.anchorMin = Vector2.zero; + rootRt.anchorMax = Vector2.one; + rootRt.offsetMin = Vector2.zero; + rootRt.offsetMax = Vector2.zero; + rootRt.SetAsLastSibling(); + + var dim = root.AddComponent(); + dim.color = new Color(0.04f, 0.05f, 0.1f, 0.88f); + dim.raycastTarget = true; + + var dimBtn = root.AddComponent public class DerivRendererUI : Graphic { + /// Scene / level default stroke width (reset on theme load and after derivative pop animation). + public const float DefaultThicknessPixels = 10f; + public Vector2Int gridSize; public List points = new List(); - public float thickness = 10f; + public float thickness = DefaultThicknessPixels; [Tooltip("When < 1, the polyline fades in left→right (set by FunctionPlotter).")] [Range(0f, 1f)] diff --git a/First Principles/Assets/Scripts/UI/DeviceLayout.cs b/First Principles/Assets/Scripts/UI/DeviceLayout.cs index 91768da..85fa059 100644 --- a/First Principles/Assets/Scripts/UI/DeviceLayout.cs +++ b/First Principles/Assets/Scripts/UI/DeviceLayout.cs @@ -6,7 +6,7 @@ /// /// Central place for **screen-dependent layout policy** used by HUD, level select, touch bar, CanvasScaler tuning. /// -/// — show touch gameplay chrome. +/// — use full-screen touch zones + guide (no virtual button strip). /// — dp-based; avoids treating phones as tablets. /// — normalized → RectTransform anchors. /// @@ -75,7 +75,16 @@ public static float RecommendedCanvasMatchWidthOrHeight() public static float TouchControlBarHeight => IsTabletLike() ? 188f : 168f; - public static float TouchHintVerticalOffset => IsTabletLike() ? 212f : 188f; + /// True in Game when we use left/right screen halves + second-finger jump (no ◀ ▶ Jump strip). + public static bool GameplayUsesFullScreenTouchZones => PreferOnScreenGameControls; + + /// Bottom inset for game UI anchored above the safe area (no on-screen controls strip). + public static float TouchHintVerticalOffset => + !PreferOnScreenGameControls + ? 22f + : GameplayUsesFullScreenTouchZones + ? (IsTabletLike() ? 28f : 18f) + : (IsTabletLike() ? 212f : 188f); // Leave vertical room for bottom “Math tips” / “How to play” band + back chip. public static Vector2 LevelSelectScrollAnchorMin => diff --git a/First Principles/Assets/Scripts/UI/GameplayScreenTouchZones.cs b/First Principles/Assets/Scripts/UI/GameplayScreenTouchZones.cs new file mode 100644 index 0000000..d85b353 --- /dev/null +++ b/First Principles/Assets/Scripts/UI/GameplayScreenTouchZones.cs @@ -0,0 +1,255 @@ +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.EventSystems; +using UnityEngine.UI; + +/// +/// Game scene: invisible full-screen touch layer. Hold left half → move left, hold right half → move right. +/// While holding movement, put down a second finger anywhere → jump (one shot per touch-down). +/// +public class GameplayScreenTouchZones : MonoBehaviour, + IPointerDownHandler, IPointerUpHandler, IPointerExitHandler +{ + public const string RootObjectName = "GameplayScreenTouchZonesRoot"; + + private static GameplayScreenTouchZones _instance; + + private readonly Dictionary _pointerSide = new Dictionary(); + private readonly HashSet _jumpOnlyPointerIds = new HashSet(); + + public static void EnsureForGameCanvas(Transform canvasTransform) + { + if (canvasTransform == null || !DeviceLayout.PreferOnScreenGameControls) + return; + + DestroyLegacyButtonBar(canvasTransform); + + // Deep find: after ReparentTouchLayerAboveGraph the root lives under GraphContainer, not a direct canvas child. + Transform existing = FindDeepChildByName(canvasTransform, RootObjectName); + + RectTransform rt; + if (existing != null) + { + rt = existing as RectTransform; + _instance = existing.GetComponent(); + if (_instance == null) + _instance = existing.gameObject.AddComponent(); + } + else + { + var parentRt = MobileUiRoots.GetSafeContentParent(canvasTransform) ?? canvasTransform as RectTransform; + if (parentRt == null) + return; + + var go = new GameObject(RootObjectName, typeof(RectTransform)); + rt = go.GetComponent(); + rt.SetParent(parentRt, false); + rt.anchorMin = Vector2.zero; + rt.anchorMax = Vector2.one; + rt.offsetMin = Vector2.zero; + rt.offsetMax = Vector2.zero; + + var img = go.AddComponent(); + img.color = new Color(0f, 0f, 0f, 0f); + img.raycastTarget = true; + + _instance = go.AddComponent(); + } + + _instance.EnsureRaycastGraphic(); + + // Must sit above the full-screen graph stack (GraphicRaycaster hits top-first). Under _SafeContent + // as first sibling put this layer *behind* GraphContainer — touches never reached gameplay. + ReparentTouchLayerAboveGraph(canvasTransform, rt); + } + + /// + /// Full-screen touch layer is created whenever mobile gameplay prefers it, but disabled in graphing calculator + /// so the same scene path always has the object (avoids missing controls after Menu → calculator → level). + /// + public static void SetActiveForGameplayMode(bool gameplayMovementEnabled) + { + if (_instance != null) + { + if (_instance.gameObject.activeSelf != gameplayMovementEnabled) + _instance.gameObject.SetActive(gameplayMovementEnabled); + return; + } + + var canvas = Object.FindAnyObjectByType(); + if (canvas == null) + return; + var t = FindDeepChildByName(canvas.transform, RootObjectName); + if (t != null && t.gameObject.activeSelf != gameplayMovementEnabled) + t.gameObject.SetActive(gameplayMovementEnabled); + } + + /// + /// Inserts the touch catcher just above Graph inside GraphContainer so Footer/HUD stays on top. + /// + static void ReparentTouchLayerAboveGraph(Transform canvasTransform, RectTransform touchRt) + { + if (touchRt == null || canvasTransform == null) + return; + + var graphContainer = FindDeepChildByName(canvasTransform, "GraphContainer") as RectTransform; + if (graphContainer == null) + { + var fallback = MobileUiRoots.GetSafeContentParent(canvasTransform) ?? canvasTransform as RectTransform; + if (fallback == null) + return; + touchRt.SetParent(fallback, false); + touchRt.anchorMin = Vector2.zero; + touchRt.anchorMax = Vector2.one; + touchRt.offsetMin = Vector2.zero; + touchRt.offsetMax = Vector2.zero; + int gc = -1; + for (int i = 0; i < fallback.childCount; i++) + { + if (fallback.GetChild(i).name == "GraphContainer") + { + gc = i; + break; + } + } + + if (gc >= 0) + { + int fallbackMaxSibling = Mathf.Max(0, fallback.childCount - 1); + touchRt.SetSiblingIndex(Mathf.Clamp(gc + 1, 0, fallbackMaxSibling)); + } + else + touchRt.SetAsLastSibling(); + return; + } + + touchRt.SetParent(graphContainer, false); + touchRt.anchorMin = Vector2.zero; + touchRt.anchorMax = Vector2.one; + touchRt.offsetMin = Vector2.zero; + touchRt.offsetMax = Vector2.zero; + + int graphIdx = 0; + for (int i = 0; i < graphContainer.childCount; i++) + { + if (graphContainer.GetChild(i).name == "Graph") + { + graphIdx = i; + break; + } + } + + int graphMaxSibling = Mathf.Max(0, graphContainer.childCount - 1); + touchRt.SetSiblingIndex(Mathf.Clamp(graphIdx + 1, 0, graphMaxSibling)); + } + + static Transform FindDeepChildByName(Transform root, string name) + { + if (root == null) + return null; + if (root.name == name) + return root; + for (int i = 0; i < root.childCount; i++) + { + var c = FindDeepChildByName(root.GetChild(i), name); + if (c != null) + return c; + } + + return null; + } + + private static void DestroyLegacyButtonBar(Transform canvasTransform) + { + Transform t = canvasTransform.Find("MobileTouchControlsRoot"); + if (t == null) + { + var safe = canvasTransform.Find(MobileUiRoots.SafeContentName); + if (safe != null) + t = safe.Find("MobileTouchControlsRoot"); + } + + if (t != null) + UnityEngine.Object.Destroy(t.gameObject); + } + + private void Awake() + { + EnsureRaycastGraphic(); + } + + private void EnsureRaycastGraphic() + { + var img = GetComponent(); + if (img == null) + { + img = gameObject.AddComponent(); + img.color = new Color(0f, 0f, 0f, 0f); + } + + img.raycastTarget = true; + } + + private void OnDestroy() + { + if (_instance == this) + _instance = null; + MobileInputBridge.ClearTouchRouting(); + } + + public void OnPointerDown(PointerEventData eventData) + { + int id = eventData.pointerId; + + // Second finger while already steering: jump (do not stack another left/right hold). + if (_pointerSide.Count >= 1) + { + MobileInputBridge.QueueJump(); + _jumpOnlyPointerIds.Add(id); + return; + } + + Vector2 pos = eventData.position; + float mid = Screen.width * 0.5f; + int side = pos.x < mid ? -1 : 1; + _pointerSide[id] = side; + if (side < 0) + MobileHoldAxis.PressLeft(); + else + MobileHoldAxis.PressRight(); + } + + public void OnPointerUp(PointerEventData eventData) => + EndPointer(eventData.pointerId); + + public void OnPointerExit(PointerEventData eventData) => + EndPointer(eventData.pointerId); + + private void EndPointer(int pointerId) + { + if (_jumpOnlyPointerIds.Remove(pointerId)) + return; + + if (!_pointerSide.TryGetValue(pointerId, out int side)) + return; + + if (side < 0) + MobileHoldAxis.ReleaseLeft(); + else + MobileHoldAxis.ReleaseRight(); + _pointerSide.Remove(pointerId); + } + + /// + /// Clears pointer bookkeeping when runs. + /// Must match — otherwise _pointerSide.Count >= 1 stays true while axis is 0 + /// and every new touch is misclassified as a second-finger jump (movement appears dead). + /// + internal static void ClearAuxiliaryPointerState() + { + if (_instance == null) + return; + _instance._jumpOnlyPointerIds.Clear(); + _instance._pointerSide.Clear(); + } +} diff --git a/First Principles/Assets/Scripts/UI/GameplayScreenTouchZones.cs.meta b/First Principles/Assets/Scripts/UI/GameplayScreenTouchZones.cs.meta new file mode 100644 index 0000000..236fcde --- /dev/null +++ b/First Principles/Assets/Scripts/UI/GameplayScreenTouchZones.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 537a369e35cbd4f37a39d1c8f9787937 \ No newline at end of file diff --git a/First Principles/Assets/Scripts/UI/GoldenSpiralBackdrop.cs b/First Principles/Assets/Scripts/UI/GoldenSpiralBackdrop.cs new file mode 100644 index 0000000..dbe8a53 --- /dev/null +++ b/First Principles/Assets/Scripts/UI/GoldenSpiralBackdrop.cs @@ -0,0 +1,122 @@ +using UnityEngine; +using UnityEngine.UI; + +// ----------------------------------------------------------------------------- +// GoldenSpiralBackdrop — logarithmic φ-spiral field behind the graph (boss stage) +// ----------------------------------------------------------------------------- +// Shown when FunctionType is PolarGoldenLogSpiral; GPU-only, matches stage theme. +// ----------------------------------------------------------------------------- + +[DisallowMultipleComponent] +[RequireComponent(typeof(RawImage))] +public sealed class GoldenSpiralBackdrop : MonoBehaviour +{ + public const string ChildName = "_GoldenSpiralBackdrop"; + + static readonly int IdTimeLive = Shader.PropertyToID("_TimeLive"); + static readonly int IdAspect = Shader.PropertyToID("_Aspect"); + static readonly int IdColor = Shader.PropertyToID("_Color"); + + static readonly Color GoldenTint = new Color(1f, 0.88f, 0.52f, 0.5f); + + RawImage _raw; + Material _mat; + + void Awake() + { + _raw = GetComponent(); + _raw.raycastTarget = false; + } + + void OnDestroy() + { + if (_mat != null) + Destroy(_mat); + } + + void Update() + { + if (_mat == null || !_raw.gameObject.activeInHierarchy) + return; + _mat.SetFloat(IdTimeLive, Time.time); + } + + public static void Sync(RectTransform gridPanel, FunctionPlotter fp) + { + if (gridPanel == null || fp == null) + return; + + Transform existing = gridPanel.Find(ChildName); + if (fp.functionType != FunctionType.PolarGoldenLogSpiral) + { + if (existing != null) + existing.gameObject.SetActive(false); + return; + } + + GameObject go; + if (existing == null) + { + go = new GameObject(ChildName, typeof(RectTransform), typeof(CanvasRenderer), typeof(RawImage), typeof(GoldenSpiralBackdrop)); + go.transform.SetParent(gridPanel, false); + var rt = go.GetComponent(); + rt.anchorMin = Vector2.zero; + rt.anchorMax = Vector2.one; + rt.offsetMin = Vector2.zero; + rt.offsetMax = Vector2.zero; + var raw = go.GetComponent(); + raw.raycastTarget = false; + raw.texture = Texture2D.whiteTexture; + raw.color = Color.white; + } + else + go = existing.gameObject; + + go.SetActive(true); + go.transform.SetAsFirstSibling(); + + var backdrop = go.GetComponent(); + if (backdrop == null) + backdrop = go.AddComponent(); + backdrop.Drive(fp); + } + + void EnsureMaterial() + { + if (_mat != null) + return; + + Shader sh = Resources.Load("UI_GoldenSpiralBackdrop"); + if (sh == null) + sh = Shader.Find("UI/GoldenSpiralBackdrop"); + if (sh == null) + { + Debug.LogWarning("GoldenSpiralBackdrop: shader UI_GoldenSpiralBackdrop not found (place under Resources)."); + return; + } + + _mat = new Material(sh); + _raw.material = _mat; + } + + public void Drive(FunctionPlotter fp) + { + EnsureMaterial(); + if (_mat == null) + return; + + var rtDrive = (RectTransform)transform; + if (rtDrive.anchorMin != Vector2.zero || rtDrive.anchorMax != Vector2.one) + { + rtDrive.anchorMin = Vector2.zero; + rtDrive.anchorMax = Vector2.one; + rtDrive.offsetMin = Vector2.zero; + rtDrive.offsetMax = Vector2.zero; + } + + float aspect = rtDrive.rect.height > 1e-3f ? Mathf.Max(0.2f, rtDrive.rect.width / rtDrive.rect.height) : 1.7f; + _mat.SetFloat(IdAspect, aspect); + _mat.SetFloat(IdTimeLive, Time.time); + _mat.SetColor(IdColor, GoldenTint); + } +} diff --git a/First Principles/Assets/Scripts/UI/GoldenSpiralBackdrop.cs.meta b/First Principles/Assets/Scripts/UI/GoldenSpiralBackdrop.cs.meta new file mode 100644 index 0000000..590279e --- /dev/null +++ b/First Principles/Assets/Scripts/UI/GoldenSpiralBackdrop.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b9f4d02e5a3c4170c8d6e9f2a4b3051c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/First Principles/Assets/Scripts/UI/GridRendererUI.cs b/First Principles/Assets/Scripts/UI/GridRendererUI.cs index 3037ca6..586a656 100644 --- a/First Principles/Assets/Scripts/UI/GridRendererUI.cs +++ b/First Principles/Assets/Scripts/UI/GridRendererUI.cs @@ -20,6 +20,8 @@ public class GridRendererUI : Graphic private float height; private float cellWidth; private float cellHeight; + private float _meshXMin; + private float _meshYMin; private LabelManager labelManager; @@ -50,8 +52,12 @@ protected override void OnPopulateMesh(VertexHelper vh) { vh.Clear(); - width = rectTransform.rect.width; - height = rectTransform.rect.height; + Rect r = rectTransform.rect; + width = r.width; + height = r.height; + // Vertices were authored for bottom-left origin; centered/stretched pivots shift rect.xMin/yMin — offset so grid matches curve/labels. + _meshXMin = r.xMin; + _meshYMin = r.yMin; cellWidth = width / (float)gridSize.x; cellHeight = height / (float)gridSize.y; @@ -78,32 +84,34 @@ private void DrawCell(int x, int y, int index, VertexHelper vh) UIVertex vertex = UIVertex.simpleVert; vertex.color = outsideLine; - vertex.position = new Vector3(xPos, yPos); + float bx = _meshXMin + xPos; + float by = _meshYMin + yPos; + vertex.position = new Vector3(bx, by); vh.AddVert(vertex); - vertex.position = new Vector3(xPos, yPos + cellHeight); + vertex.position = new Vector3(bx, by + cellHeight); vh.AddVert(vertex); - vertex.position = new Vector3(xPos + cellWidth, yPos + cellHeight); + vertex.position = new Vector3(bx + cellWidth, by + cellHeight); vh.AddVert(vertex); - vertex.position = new Vector3(xPos + cellWidth, yPos); + vertex.position = new Vector3(bx + cellWidth, by); vh.AddVert(vertex); float widthSqr = Mathf.Pow(thickness, 2); float distanceSqr = widthSqr / 2; float distance = Mathf.Sqrt(distanceSqr); - vertex.position = new Vector3(xPos + distance, yPos + distance); + vertex.position = new Vector3(bx + distance, by + distance); vh.AddVert(vertex); - vertex.position = new Vector3(xPos + distance, yPos + (cellHeight - distance)); + vertex.position = new Vector3(bx + distance, by + (cellHeight - distance)); vh.AddVert(vertex); - vertex.position = new Vector3(xPos + (cellWidth - distance), yPos + (cellHeight - distance)); + vertex.position = new Vector3(bx + (cellWidth - distance), by + (cellHeight - distance)); vh.AddVert(vertex); - vertex.position = new Vector3(xPos + (cellWidth - distance), yPos + distance); + vertex.position = new Vector3(bx + (cellWidth - distance), by + distance); vh.AddVert(vertex); int offset = index * 8; @@ -127,25 +135,26 @@ private void DrawCell(int x, int y, int index, VertexHelper vh) private void DrawCenterLine(int index, VertexHelper vh) { - float width = rectTransform.rect.width; - float height = rectTransform.rect.height; + float cx = _meshXMin; + float cy = _meshYMin; float centerLineOffset = centerLineThickness / 2; UIVertex vertex = UIVertex.simpleVert; vertex.color = centerLine; + float midY = cy + height * 0.5f; //Horizontal Line - vertex.position = new Vector3(0, (height / 2) - centerLineOffset); + vertex.position = new Vector3(cx, midY - centerLineOffset); vh.AddVert(vertex); - vertex.position = new Vector3(0, (height / 2) + centerLineOffset); + vertex.position = new Vector3(cx, midY + centerLineOffset); vh.AddVert(vertex); - vertex.position = new Vector3(width, (height / 2) + centerLineOffset); + vertex.position = new Vector3(cx + width, midY + centerLineOffset); vh.AddVert(vertex); - vertex.position = new Vector3(width, (height / 2) - centerLineOffset); + vertex.position = new Vector3(cx + width, midY - centerLineOffset); vh.AddVert(vertex); int offset = index * 8; @@ -153,17 +162,18 @@ private void DrawCenterLine(int index, VertexHelper vh) vh.AddTriangle(offset + 0, offset + 1, offset + 2); vh.AddTriangle(offset + 2, offset + 3, offset + 0); + float midX = cx + width * 0.5f; //Vertical Line - vertex.position = new Vector3((width / 2) - centerLineOffset, 0); + vertex.position = new Vector3(midX - centerLineOffset, cy); vh.AddVert(vertex); - vertex.position = new Vector3((width / 2) - centerLineOffset, height); + vertex.position = new Vector3(midX - centerLineOffset, cy + height); vh.AddVert(vertex); - vertex.position = new Vector3((width / 2) + centerLineOffset, height); + vertex.position = new Vector3(midX + centerLineOffset, cy + height); vh.AddVert(vertex); - vertex.position = new Vector3((width / 2) + centerLineOffset, 0); + vertex.position = new Vector3(midX + centerLineOffset, cy); vh.AddVert(vertex); vh.AddTriangle(offset + 4, offset + 5, offset + 6); diff --git a/First Principles/Assets/Scripts/UI/LabelManager.cs b/First Principles/Assets/Scripts/UI/LabelManager.cs index a64533d..a8619f6 100644 --- a/First Principles/Assets/Scripts/UI/LabelManager.cs +++ b/First Principles/Assets/Scripts/UI/LabelManager.cs @@ -6,7 +6,7 @@ /// Spawns TMP axis labels from extents. /// Y-axis numbers track when vertical auto-fit is on. /// X-axis numbers track and refresh when the plot window -/// (zoom / pinch), Trans (k, D), or mode changes — calculator ticks show inner u. +/// (zoom / pinch), horizontal auto-fit pivots, Trans (k, D), or mode changes — calculator ticks show inner u. /// public class LabelManager : MonoBehaviour { @@ -40,6 +40,8 @@ public class LabelManager : MonoBehaviour private float _lastTransD = float.NaN; private FunctionType _lastFunctionTypeForXAxis = (FunctionType)(-1); + private Vector2 _lastGridPixelSize = Vector2.zero; + private void Awake() { gridRenderer = FindAnyObjectByType(); @@ -48,6 +50,16 @@ private void Awake() private void Start() { GenerateLabels(); + if (gridRenderer != null) + _lastGridPixelSize = RectSize(gridRenderer.rectTransform); + } + + private static Vector2 RectSize(RectTransform rt) + { + if (rt == null) + return Vector2.zero; + var r = rt.rect; + return new Vector2(r.width, r.height); } private void LateUpdate() @@ -56,6 +68,17 @@ private void LateUpdate() if (plotter == null) return; + if (gridRenderer != null) + { + Vector2 gridPx = RectSize(gridRenderer.rectTransform); + if (gridPx.x > 16f && gridPx.y > 16f && + (gridPx - _lastGridPixelSize).sqrMagnitude > 36f) + { + _lastGridPixelSize = gridPx; + GenerateLabels(); + } + } + float mid = plotter.VerticalAxisLabelPivot; float sc = plotter.VerticalAxisLabelScale; @@ -212,6 +235,26 @@ void RefreshXAxisLabelText() } } + /// + /// Re-read tick strings from the current mapping (e.g. after pinch / Scale in graphing calculator). + /// Syncs cached pivots so does not lag one frame. + /// + public void RefreshAllTickLabels() + { + var plotter = FindAnyObjectByType(); + if (plotter != null) + { + _lastAutoMid = plotter.VerticalAxisLabelPivot; + _lastAutoScale = plotter.VerticalAxisLabelScale; + _lastAutoMidX = plotter.HorizontalAxisLabelPivot; + _lastAutoScaleX = plotter.HorizontalAxisLabelScale; + CacheHorizontalAxisState(plotter); + } + + RefreshXAxisLabelText(); + RefreshYAxisLabelText(); + } + static string FormatXTick(FunctionPlotter plotter, float tickOffsetFromCenter) { float v = plotter != null ? plotter.AxisTickOffsetToMathX(tickOffsetFromCenter) : tickOffsetFromCenter; diff --git a/First Principles/Assets/Scripts/UI/LineRendererUI.cs b/First Principles/Assets/Scripts/UI/LineRendererUI.cs index 33ffefa..bcdb053 100644 --- a/First Principles/Assets/Scripts/UI/LineRendererUI.cs +++ b/First Principles/Assets/Scripts/UI/LineRendererUI.cs @@ -16,7 +16,9 @@ public class LineRendererUI : Graphic /// public static LineRendererUI FindPrimaryCurve() { - var all = UnityEngine.Object.FindObjectsByType(FindObjectsInactive.Include); + // Active hierarchy only: inactive clones / hidden UI must not steal grid sizing from the visible graph + // (breaks Riemann strips & anything sampling f(x) with a mismatched grid origin). + var all = UnityEngine.Object.FindObjectsByType(FindObjectsInactive.Exclude, FindObjectsSortMode.None); foreach (var lr in all) { if (lr == null || lr.gameObject == null) @@ -29,7 +31,7 @@ public static LineRendererUI FindPrimaryCurve() return lr; } - return all != null && all.Length > 0 ? all[0] : null; + return null; } public Vector2Int gridSize; diff --git a/First Principles/Assets/Scripts/UI/MathArticlesOverlay.cs b/First Principles/Assets/Scripts/UI/MathArticlesOverlay.cs index 0feb489..1a993e8 100644 --- a/First Principles/Assets/Scripts/UI/MathArticlesOverlay.cs +++ b/First Principles/Assets/Scripts/UI/MathArticlesOverlay.cs @@ -4,7 +4,7 @@ /// /// Full-screen scroll overlay for — opened from Level select -/// (Math tips & snippets) or from the Game scene (Math concepts). +/// (Math tips & snippets, full glossary) or from the Game scene (Math concepts, sections for the current level when the locale article uses @@SECTION= markers). /// public static class MathArticlesOverlay { @@ -12,13 +12,18 @@ public static class MathArticlesOverlay private static TextMeshProUGUI closeButtonTmp; private static TextMeshProUGUI articleBodyTmp; + /// Preserves level filter when the article reloads after a language change. + private static int? _articleLevelFilter; /// Usually the scene Canvas; overlay becomes its last sibling. - public static void Open(Transform canvasTransform) + /// = full glossary (level select). Otherwise filtered sections for that level. + public static void Open(Transform canvasTransform, int? forGameLevelIndex = null) { if (canvasTransform == null) return; + _articleLevelFilter = forGameLevelIndex; + var existing = canvasTransform.Find(OverlayName); if (existing != null) { @@ -45,6 +50,7 @@ public static void Open(Transform canvasTransform) void Close() { + _articleLevelFilter = null; LocalizationManager.LanguageChanged -= RefreshArticleBodyGlobal; articleBodyTmp = null; UnityEngine.Object.Destroy(root); @@ -116,8 +122,9 @@ void Close() var scroll = scrollGo.AddComponent(); scroll.horizontal = false; scroll.vertical = true; - scroll.movementType = ScrollRect.MovementType.Clamped; - scroll.scrollSensitivity = tablet ? 40f : 25f; + scroll.movementType = ScrollRect.MovementType.Elastic; + scroll.elasticity = 0.12f; + scroll.scrollSensitivity = DeviceLayout.LevelSelectScrollSensitivity; var viewportGo = new GameObject("Viewport"); var viewportRt = viewportGo.AddComponent(); @@ -144,10 +151,6 @@ void Close() scroll.content = contentRt; - var contentSize = contentGo.AddComponent(); - contentSize.horizontalFit = ContentSizeFitter.FitMode.Unconstrained; - contentSize.verticalFit = ContentSizeFitter.FitMode.PreferredSize; - var tmpGo = new GameObject("ArticleText"); var tmpRt = tmpGo.AddComponent(); tmpRt.SetParent(contentRt, false); @@ -165,22 +168,17 @@ void Close() body.alignment = TextAlignmentOptions.TopLeft; body.color = new Color(0.92f, 0.93f, 0.96f, 1f); body.textWrappingMode = TextWrappingModes.Normal; + body.overflowMode = TextOverflowModes.Overflow; body.richText = true; body.margin = new Vector4(12f, 12f, 12f, 12f); CopyFont(body); ApplyArticleReadingLayout(body); - var fitter = tmpGo.AddComponent(); - fitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained; - fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; - var le = tmpGo.AddComponent(); le.minWidth = 1f; - body.ForceMeshUpdate(true); - LayoutRebuilder.ForceRebuildLayoutImmediate(contentRt); Canvas.ForceUpdateCanvases(); - scroll.verticalNormalizedPosition = 1f; + SyncArticleScrollLayout(body, scroll); root.transform.SetAsLastSibling(); } @@ -208,12 +206,11 @@ private static void RefreshArticleBodyText() { if (articleBodyTmp == null) return; - articleBodyTmp.text = LearningArticleLibrary.GetLevelSelectArticleRichText(); + articleBodyTmp.text = LearningArticleLibrary.GetArticleRichTextForOverlay(_articleLevelFilter); + ApplyArticleReadingLayout(articleBodyTmp); LocalizationManager.ApplyTextDirection(articleBodyTmp); - articleBodyTmp.ForceMeshUpdate(true); - var contentRt = articleBodyTmp.rectTransform.parent as RectTransform; - if (contentRt != null) - LayoutRebuilder.ForceRebuildLayoutImmediate(contentRt); + var scroll = articleBodyTmp.GetComponentInParent(); + SyncArticleScrollLayout(articleBodyTmp, scroll); } private static void RefreshArticleBodyAndLayout(Transform overlayRoot) @@ -231,6 +228,50 @@ private static void RefreshArticleBodyAndLayout(Transform overlayRoot) scroll.verticalNormalizedPosition = 1f; } + /// + /// TMP + layout groups often under-report height; drive content height from so the can scroll long articles. + /// + private static void SyncArticleScrollLayout(TextMeshProUGUI body, ScrollRect scroll) + { + if (body == null) + return; + + body.overflowMode = TextOverflowModes.Overflow; + body.enableWordWrapping = true; + + var tmpRt = body.rectTransform; + var contentRt = tmpRt.parent as RectTransform; + var viewportRt = contentRt != null ? contentRt.parent as RectTransform : null; + if (contentRt == null || viewportRt == null) + return; + + Canvas.ForceUpdateCanvases(); + LayoutRebuilder.ForceRebuildLayoutImmediate(viewportRt); + + // Content must be at least viewport-tall so width is valid on first layout pass. + float viewportW = Mathf.Max(1f, viewportRt.rect.width); + float viewportH = Mathf.Max(1f, viewportRt.rect.height); + if (contentRt.sizeDelta.y < viewportH) + contentRt.sizeDelta = new Vector2(0f, viewportH); + + Canvas.ForceUpdateCanvases(); + float innerW = Mathf.Max(48f, contentRt.rect.width - 48f); + body.ForceMeshUpdate(true); + Vector2 pref = body.GetPreferredValues(innerW, 0f); + float textH = Mathf.Max(pref.y, 1f); + const float verticalPad = 20f; + tmpRt.sizeDelta = new Vector2(-40f, textH); + contentRt.sizeDelta = new Vector2(0f, Mathf.Max(viewportH, textH + verticalPad)); + + LayoutRebuilder.ForceRebuildLayoutImmediate(contentRt); + LayoutRebuilder.ForceRebuildLayoutImmediate(viewportRt); + if (scroll != null) + { + Canvas.ForceUpdateCanvases(); + scroll.verticalNormalizedPosition = 1f; + } + } + private static void RefreshCloseLabel() { if (closeButtonTmp == null) diff --git a/First Principles/Assets/Scripts/UI/MenuTutorialOverlay.cs b/First Principles/Assets/Scripts/UI/MenuTutorialOverlay.cs index dc6310b..3103dbb 100644 --- a/First Principles/Assets/Scripts/UI/MenuTutorialOverlay.cs +++ b/First Principles/Assets/Scripts/UI/MenuTutorialOverlay.cs @@ -207,8 +207,8 @@ private static string DefaultBodyEnglish() "Goal\n" + "Move along the graph, use platforms (green), avoid red hazards, and reach the bright exit on the right.\n\n" + "Controls\n" + - "• Move — arrows / WASD, or on-screen buttons.\n" + - "• Jump — Space (or mobile jump). You jump from solid platforms.\n\n" + + "• Move — arrows / WASD, or on a phone hold the left / right half of the screen.\n" + + "• Jump — Space, or on a phone tap with a second finger while holding left/right. You jump from solid platforms.\n\n" + "The two curves\n" + "• Main curve — the function you walk on.\n" + "• Derivative \\(f'\\) — slope information; it’s drawn as a second line.\n\n" + diff --git a/First Principles/Assets/Scripts/UI/MobileInputBridge.cs b/First Principles/Assets/Scripts/UI/MobileInputBridge.cs index 059cb00..68f5eb5 100644 --- a/First Principles/Assets/Scripts/UI/MobileInputBridge.cs +++ b/First Principles/Assets/Scripts/UI/MobileInputBridge.cs @@ -1,7 +1,7 @@ using UnityEngine; /// -/// Tiny IPC between (UI events) and . +/// IPC between (full-screen touch) and . /// Horizontal motion uses counts; jump uses a one-shot queue consumed each Update. /// public static class MobileInputBridge @@ -19,4 +19,49 @@ public static bool ConsumeJump() JumpQueued = false; return true; } + + /// Clears jump queue, axis holds, and auxiliary touch ids after overlays or before unlocking control. + public static void ClearTouchRouting() + { + JumpQueued = false; + MobileHoldAxis.Clear(); + GameplayScreenTouchZones.ClearAuxiliaryPointerState(); + } +} + +/// +/// Ref-count style axis: multiple pointers can press left/right; release decrements. Player reads aggregated -1/0/+1. +/// +public static class MobileHoldAxis +{ + private static int _left; + private static int _right; + + public static void PressLeft() => _left++; + + public static void ReleaseLeft() => _left = Mathf.Max(0, _left - 1); + + public static void PressRight() => _right++; + + public static void ReleaseRight() => _right = Mathf.Max(0, _right - 1); + + public static float Axis + { + get + { + if (_left > 0 && _right > 0) + return 0f; + if (_left > 0) + return -1f; + if (_right > 0) + return 1f; + return 0f; + } + } + + public static void Clear() + { + _left = 0; + _right = 0; + } } diff --git a/First Principles/Assets/Scripts/UI/MobileTouchControls.cs b/First Principles/Assets/Scripts/UI/MobileTouchControls.cs deleted file mode 100644 index 3afca98..0000000 --- a/First Principles/Assets/Scripts/UI/MobileTouchControls.cs +++ /dev/null @@ -1,310 +0,0 @@ -using TMPro; -using UnityEngine; -using UnityEngine.EventSystems; -using UnityEngine.UI; - -/// -/// Builds a bottom **◀ / ▶ / Jump** row parented under . -/// Phones: buttons expand to fill width. Tablets: fixed widths + flex spacers so landscape iPad -/// does not create kilometer-wide hit targets. Uses for responsive hold-to-run. -/// -/// Visuals aim for a **Minecraft PE–style** translucent strip: low-alpha panels so the graph stays readable; -/// only the three buttons use raycastTarget — the bar backdrop is non-blocking so -/// taps in any gaps/spacers pass through to content behind (HUD is laid out above ). -/// -public class MobileTouchControls : MonoBehaviour -{ - private static MobileTouchControls _instance; - - private TextMeshProUGUI jumpLabelTmp; - - // --- Minecraft-style translucency (tweak alphas here) ---------------------------------- - private static readonly Color TouchBarBackdrop = new Color(0.06f, 0.07f, 0.09f, 0.34f); - private static readonly Color MoveButtonFace = new Color(0.18f, 0.2f, 0.24f, 0.52f); - private static readonly Color JumpButtonFace = new Color(0.14f, 0.38f, 0.32f, 0.55f); - private const float TouchButtonShadowAlpha = 0.14f; - - public static void EnsureForGameCanvas(Transform canvasTransform) - { - if (canvasTransform == null || !ShouldShow()) - return; - - if (_instance != null) - return; - - Transform existing = canvasTransform.Find("MobileTouchControlsRoot"); - if (existing == null) - { - var safe = canvasTransform.Find(MobileUiRoots.SafeContentName); - if (safe != null) - existing = safe.Find("MobileTouchControlsRoot"); - } - - if (existing != null) - { - _instance = existing.GetComponent(); - return; - } - - var go = new GameObject("MobileTouchControlsRoot", typeof(RectTransform)); - var rt = go.GetComponent(); - var parent = MobileUiRoots.GetSafeContentParent(canvasTransform) ?? canvasTransform as RectTransform; - rt.SetParent(parent, false); - rt.SetAsLastSibling(); - rt.anchorMin = new Vector2(0f, 0f); - rt.anchorMax = new Vector2(1f, 0f); - rt.pivot = new Vector2(0.5f, 0f); - rt.anchoredPosition = new Vector2(0f, 10f); - rt.sizeDelta = new Vector2(0f, DeviceLayout.TouchControlBarHeight); - - _instance = go.AddComponent(); - _instance.Build(rt); - } - - private static bool ShouldShow() => DeviceLayout.PreferOnScreenGameControls; - - private void OnEnable() - { - LocalizationManager.LanguageChanged += RefreshJumpLabel; - } - - private void OnDisable() - { - LocalizationManager.LanguageChanged -= RefreshJumpLabel; - } - - private void RefreshJumpLabel() - { - if (jumpLabelTmp == null) - return; - jumpLabelTmp.text = LocalizationManager.Get("ui.jump", "Jump"); - LocalizationManager.ApplyTextDirection(jumpLabelTmp); - } - - private void OnDestroy() - { - if (_instance == this) - _instance = null; - MobileHoldAxis.Clear(); - } - - private void Build(RectTransform root) - { - bool tablet = DeviceLayout.IsTabletLike(); - float gap = tablet ? 20f : 16f; - - // Full-bar tint only; raycasts off so this never steals input from UI above or gaps between controls. - var backdropGo = new GameObject("TouchBarBackdrop", typeof(RectTransform)); - var bdRt = backdropGo.GetComponent(); - bdRt.SetParent(root, false); - bdRt.SetAsFirstSibling(); - bdRt.anchorMin = Vector2.zero; - bdRt.anchorMax = Vector2.one; - bdRt.offsetMin = Vector2.zero; - bdRt.offsetMax = Vector2.zero; - var bdImg = backdropGo.AddComponent(); - RuntimeUiPolish.UseRoundedSliced(bdImg); - bdImg.color = TouchBarBackdrop; - bdImg.raycastTarget = false; - - var row = new GameObject("Row", typeof(RectTransform)); - var rowRt = row.GetComponent(); - rowRt.SetParent(root, false); - rowRt.anchorMin = Vector2.zero; - rowRt.anchorMax = Vector2.one; - rowRt.offsetMin = new Vector2(tablet ? 20f : 12f, 10f); - rowRt.offsetMax = new Vector2(tablet ? -20f : -12f, -10f); - - var hlg = row.AddComponent(); - hlg.spacing = gap; - hlg.childAlignment = TextAnchor.MiddleCenter; - hlg.childControlHeight = true; - hlg.childControlWidth = true; - hlg.childForceExpandHeight = true; - // Phones: stretch buttons across width. Tablets: fixed widths + side spacers so bars are not huge in landscape. - hlg.childForceExpandWidth = !tablet; - - if (tablet) - AddLayoutSpacer(rowRt, flexibleWidth: 1f); - - CreateHoldButton(rowRt, "Left", -1f, tablet); - CreateHoldButton(rowRt, "Right", 1f, tablet); - CreateJumpButtonInstance(rowRt, tablet); - - if (tablet) - AddLayoutSpacer(rowRt, flexibleWidth: 1f); - } - - private static void AddLayoutSpacer(Transform parent, float flexibleWidth) - { - var go = new GameObject("Spacer", typeof(RectTransform)); - go.transform.SetParent(parent, false); - var le = go.AddComponent(); - le.flexibleWidth = flexibleWidth; - le.minWidth = 0f; - le.preferredWidth = 0f; - } - - private static void CreateHoldButton(Transform parent, string label, float dir, bool tablet) - { - var go = new GameObject($"Btn_{label}", typeof(RectTransform)); - var rt = go.GetComponent(); - rt.SetParent(parent, false); - - var le = go.AddComponent(); - le.preferredWidth = tablet ? 252f : 200f; - le.flexibleWidth = tablet ? 0f : 1f; - le.minHeight = tablet ? 132f : 120f; - if (tablet) - le.preferredHeight = 132f; - - var img = go.AddComponent(); - RuntimeUiPolish.UseRoundedSliced(img); - img.color = MoveButtonFace; - - var h = go.AddComponent(); - h.Init(dir); - RuntimeUiPolish.ApplyDropShadow(rt, new Vector2(1f, -2f), TouchButtonShadowAlpha); - - var tr = new GameObject("Text"); - var trt = tr.AddComponent(); - trt.SetParent(go.transform, false); - trt.anchorMin = Vector2.zero; - trt.anchorMax = Vector2.one; - trt.offsetMin = Vector2.zero; - trt.offsetMax = Vector2.zero; - var tmp = tr.AddComponent(); - tmp.text = label == "Left" ? "\u25C0" : "\u25B6"; - tmp.fontSize = UiTypography.Scale(tablet ? 54f : 48f); - tmp.alignment = TextAlignmentOptions.Center; - tmp.color = new Color(1f, 0.9f, 0.55f, 0.92f); - CopyTmpFont(tmp); - } - - private void CreateJumpButtonInstance(Transform parent, bool tablet) - { - var go = new GameObject("Btn_Jump", typeof(RectTransform)); - var rt = go.GetComponent(); - rt.SetParent(parent, false); - - var le = go.AddComponent(); - le.preferredWidth = tablet ? 268f : 220f; - le.flexibleWidth = tablet ? 0f : 1.2f; - le.minHeight = tablet ? 132f : 120f; - if (tablet) - le.preferredHeight = 132f; - - var img = go.AddComponent(); - RuntimeUiPolish.UseRoundedSliced(img); - img.color = JumpButtonFace; - RuntimeUiPolish.ApplyDropShadow(rt, new Vector2(1.5f, -2.5f), TouchButtonShadowAlpha); - - var tr = new GameObject("Text"); - var trt = tr.AddComponent(); - trt.SetParent(go.transform, false); - trt.anchorMin = Vector2.zero; - trt.anchorMax = Vector2.one; - trt.offsetMin = Vector2.zero; - trt.offsetMax = Vector2.zero; - jumpLabelTmp = tr.AddComponent(); - jumpLabelTmp.text = LocalizationManager.Get("ui.jump", "Jump"); - jumpLabelTmp.fontSize = UiTypography.Scale(tablet ? 34f : 30f); - jumpLabelTmp.fontStyle = FontStyles.Bold; - jumpLabelTmp.alignment = TextAlignmentOptions.Center; - jumpLabelTmp.color = new Color(0.98f, 1f, 1f, 0.94f); - CopyTmpFont(jumpLabelTmp); - LocalizationManager.ApplyTextDirection(jumpLabelTmp); - - var ev = go.AddComponent(); - } - - private static void CopyTmpFont(TextMeshProUGUI tmp) - { - var any = FindAnyObjectByType(); - if (any != null && any.font != null) - tmp.font = any.font; - else if (TMP_Settings.defaultFontAsset != null) - tmp.font = TMP_Settings.defaultFontAsset; - } - - private class MobileHoldButton : MonoBehaviour, IPointerDownHandler, IPointerUpHandler - { - private float _dir; - private bool _held; - - public void Init(float dir) => _dir = dir; - - public void OnPointerDown(PointerEventData eventData) - { - _held = true; - if (_dir < 0f) - MobileHoldAxis.PressLeft(); - else - MobileHoldAxis.PressRight(); - } - - public void OnPointerUp(PointerEventData eventData) - { - if (!_held) - return; - _held = false; - if (_dir < 0f) - MobileHoldAxis.ReleaseLeft(); - else - MobileHoldAxis.ReleaseRight(); - } - - private void OnDisable() - { - if (_held) - { - _held = false; - if (_dir < 0f) - MobileHoldAxis.ReleaseLeft(); - else - MobileHoldAxis.ReleaseRight(); - } - } - } - - /// Fires jump on pointer down (not only click) for better touch response. - private class MobileJumpTouch : MonoBehaviour, IPointerDownHandler - { - public void OnPointerDown(PointerEventData eventData) => MobileInputBridge.QueueJump(); - } -} - -/// -/// Ref-count style axis: multiple pointers could press Left; release decrements. Player reads aggregated -1/0/+1. -/// -public static class MobileHoldAxis -{ - private static int _left; - private static int _right; - - public static void PressLeft() => _left++; - public static void ReleaseLeft() => _left = Mathf.Max(0, _left - 1); - - public static void PressRight() => _right++; - public static void ReleaseRight() => _right = Mathf.Max(0, _right - 1); - - public static float Axis - { - get - { - if (_left > 0 && _right > 0) - return 0f; - if (_left > 0) - return -1f; - if (_right > 0) - return 1f; - return 0f; - } - } - - public static void Clear() - { - _left = 0; - _right = 0; - } -} diff --git a/First Principles/Assets/Scripts/UI/RiemannStripRendererUI.cs b/First Principles/Assets/Scripts/UI/RiemannStripRendererUI.cs index aff750a..c11b479 100644 --- a/First Principles/Assets/Scripts/UI/RiemannStripRendererUI.cs +++ b/First Principles/Assets/Scripts/UI/RiemannStripRendererUI.cs @@ -144,7 +144,8 @@ public void Rebuild(LevelDefinition def, FunctionPlotter plotter) } /// Riemann rectangles over the graphing calculator window (no ). - public void RebuildForGraphingCalculator(FunctionPlotter plotter, int rectCount, RiemannRule rule, Color fillColor) + /// Main for this graph (same as calculator); avoids wrong grid if multiple curves exist. + public void RebuildForGraphingCalculator(FunctionPlotter plotter, LineRendererUI primaryCurve, int rectCount, RiemannRule rule, Color fillColor) { strips.Clear(); color = fillColor; @@ -155,7 +156,10 @@ public void RebuildForGraphingCalculator(FunctionPlotter plotter, int rectCount, return; } - SyncGridSizeFromPrimaryCurve(); + if (primaryCurve != null && primaryCurve.gridSize.x >= 1 && primaryCurve.gridSize.y >= 1) + gridSize = primaryCurve.gridSize; + else + SyncGridSizeFromPrimaryCurve(); if (grid == null) grid = GetComponentInParent(); if (grid != null && (gridSize.x < 1 || gridSize.y < 1)) diff --git a/First Principles/Assets/Scripts/UI/WindTunnelBackdrop.cs b/First Principles/Assets/Scripts/UI/WindTunnelBackdrop.cs new file mode 100644 index 0000000..ae4b8fb --- /dev/null +++ b/First Principles/Assets/Scripts/UI/WindTunnelBackdrop.cs @@ -0,0 +1,119 @@ +using UnityEngine; +using UnityEngine.UI; + +// ----------------------------------------------------------------------------- +// WindTunnelBackdrop — procedural wind-tunnel / schlieren mood behind the graph +// ----------------------------------------------------------------------------- +// Shown on all aerospace category stages via FunctionPlotter.showWindTunnelBackdrop. +// GPU-only; no CPU texture. +// ----------------------------------------------------------------------------- + +[DisallowMultipleComponent] +[RequireComponent(typeof(RawImage))] +public sealed class WindTunnelBackdrop : MonoBehaviour +{ + public const string ChildName = "_WindTunnelBackdrop"; + + static readonly int IdAspect = Shader.PropertyToID("_Aspect"); + static readonly int IdFlowSpeed = Shader.PropertyToID("_FlowSpeed"); + static readonly int IdStreakScale = Shader.PropertyToID("_StreakScale"); + static readonly int IdColor = Shader.PropertyToID("_Color"); + + static readonly Color WindTint = new Color(0.9f, 0.96f, 1f, 0.54f); + + RawImage _raw; + Material _mat; + + void Awake() + { + _raw = GetComponent(); + _raw.raycastTarget = false; + } + + void OnDestroy() + { + if (_mat != null) + Destroy(_mat); + } + + public static void Sync(RectTransform gridPanel, FunctionPlotter fp) + { + if (gridPanel == null || fp == null) + return; + + Transform existing = gridPanel.Find(ChildName); + if (!fp.showWindTunnelBackdrop) + { + if (existing != null) + existing.gameObject.SetActive(false); + return; + } + + GameObject go; + if (existing == null) + { + go = new GameObject(ChildName, typeof(RectTransform), typeof(CanvasRenderer), typeof(RawImage), typeof(WindTunnelBackdrop)); + go.transform.SetParent(gridPanel, false); + var rt = go.GetComponent(); + rt.anchorMin = Vector2.zero; + rt.anchorMax = Vector2.one; + rt.offsetMin = Vector2.zero; + rt.offsetMax = Vector2.zero; + var raw = go.GetComponent(); + raw.raycastTarget = false; + raw.texture = Texture2D.whiteTexture; + raw.color = Color.white; + } + else + go = existing.gameObject; + + go.SetActive(true); + go.transform.SetAsFirstSibling(); + + var backdrop = go.GetComponent(); + if (backdrop == null) + backdrop = go.AddComponent(); + backdrop.Drive(fp); + } + + void EnsureMaterial() + { + if (_mat != null) + return; + + Shader sh = Resources.Load("UI_WindTunnelBackdrop"); + if (sh == null) + sh = Shader.Find("UI/WindTunnelBackdrop"); + if (sh == null) + { + Debug.LogWarning("WindTunnelBackdrop: shader UI_WindTunnelBackdrop not found (place under Resources)."); + return; + } + + _mat = new Material(sh); + _mat.SetColor(IdColor, WindTint); + _raw.material = _mat; + } + + public void Drive(FunctionPlotter fp) + { + EnsureMaterial(); + if (_mat == null) + return; + + var rt = (RectTransform)transform; + if (rt.anchorMin != Vector2.zero || rt.anchorMax != Vector2.one) + { + rt.anchorMin = Vector2.zero; + rt.anchorMax = Vector2.one; + rt.offsetMin = Vector2.zero; + rt.offsetMax = Vector2.zero; + } + + float aspect = rt.rect.height > 1e-3f ? Mathf.Max(0.2f, rt.rect.width / rt.rect.height) : 1.7f; + _mat.SetFloat(IdAspect, aspect); + _mat.SetFloat(IdFlowSpeed, 0.42f + Mathf.Clamp01(fp.transK) * 0.35f); + _mat.SetFloat(IdStreakScale, 7.5f + Mathf.Abs(fp.transA) * 1.2f); + _mat.SetColor(IdColor, WindTint); + } +} diff --git a/First Principles/Assets/Scripts/UI/WindTunnelBackdrop.cs.meta b/First Principles/Assets/Scripts/UI/WindTunnelBackdrop.cs.meta new file mode 100644 index 0000000..c15f9a1 --- /dev/null +++ b/First Principles/Assets/Scripts/UI/WindTunnelBackdrop.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 5426f749a56a94bcdaafe25f3a3a4711 \ No newline at end of file diff --git a/First Principles/Assets/TextMesh Pro/Resources/Fonts & Materials/LiberationSans SDF - Fallback.asset b/First Principles/Assets/TextMesh Pro/Resources/Fonts & Materials/LiberationSans SDF - Fallback.asset index 6a24e10..8897c1f 100644 --- a/First Principles/Assets/TextMesh Pro/Resources/Fonts & Materials/LiberationSans SDF - Fallback.asset +++ b/First Principles/Assets/TextMesh Pro/Resources/Fonts & Materials/LiberationSans SDF - Fallback.asset @@ -687,10 +687,661 @@ MonoBehaviour: m_XAdvance: 0 m_YAdvance: 0 m_FeatureLookupFlags: 0 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 882 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -1.2177734 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 862 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 89159760 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 882 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -1.2177734 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 872 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 0 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 882 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -1.2177734 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 881 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 1146060800 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 882 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -1.2177734 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 884 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 95103336 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 882 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -1.2177734 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 885 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 1 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 882 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -1.2177734 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 888 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 95072720 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 882 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -1.2177734 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 891 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 1 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 882 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -1.2177734 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 896 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 836 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 839 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -4.745117 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 3 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 0 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 839 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -1.8056641 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 843 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 1969516365 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 839 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -1.8056641 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 850 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 83 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 839 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -4.9970703 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 854 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 0 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 839 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -6.3828125 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 855 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 1289 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 839 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -6.3828125 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 861 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 1109393408 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 55 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -4.745117 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 16 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 0 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 57 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -4.745117 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 16 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 0 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 58 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -1.5537109 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 16 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 0 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 60 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -7.8945312 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 16 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 0 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 855 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -7.810547 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 16 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 0 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 854 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -9.448242 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 871 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 0 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 827 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -1.5537109 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 869 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 0 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 836 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -1.5537109 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 869 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 0 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 854 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -7.4746094 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 869 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 0 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 855 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -4.1152344 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 869 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 0 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 872 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -3.6113281 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 869 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 0 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 888 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -1.6376953 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 877 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 0 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 888 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -1.2177734 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 882 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 65966 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 888 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -1.2177734 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 886 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 0 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 888 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -2.3095703 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 889 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 1133903872 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 856 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -2.477539 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 836 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 2003134806 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 856 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -2.7714844 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 855 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 1141604352 + - m_FirstAdjustmentRecord: + m_GlyphIndex: 856 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: -2.7714844 + m_YAdvance: 0 + m_SecondAdjustmentRecord: + m_GlyphIndex: 861 + m_GlyphValueRecord: + m_XPlacement: 0 + m_YPlacement: 0 + m_XAdvance: 0 + m_YAdvance: 0 + m_FeatureLookupFlags: 67 m_MarkToBaseAdjustmentRecords: [] m_MarkToMarkAdjustmentRecords: [] m_ShouldReimportFontFeatures: 0 - m_FallbackFontAssetTable: [] + m_FallbackFontAssetTable: + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} + - {fileID: 0} m_FontWeightTable: - regularTypeface: {fileID: 0} italicTypeface: {fileID: 0} diff --git a/First Principles/ProjectSettings/ProjectSettings.asset b/First Principles/ProjectSettings/ProjectSettings.asset index 65193d6..006f5e1 100644 --- a/First Principles/ProjectSettings/ProjectSettings.asset +++ b/First Principles/ProjectSettings/ProjectSettings.asset @@ -8,7 +8,7 @@ PlayerSettings: AndroidProfiler: 0 AndroidFilterTouchesWhenObscured: 0 AndroidEnableSustainedPerformanceMode: 0 - defaultScreenOrientation: 4 + defaultScreenOrientation: 1 targetDevice: 2 useOnDemandResources: 0 accelerometerFrequency: 60 @@ -59,10 +59,10 @@ PlayerSettings: androidShowActivityIndicatorOnLoading: -1 iosUseCustomAppBackgroundBehavior: 0 allowedAutorotateToPortrait: 1 - allowedAutorotateToPortraitUpsideDown: 1 - allowedAutorotateToLandscapeRight: 1 - allowedAutorotateToLandscapeLeft: 1 - useOSAutorotation: 1 + allowedAutorotateToPortraitUpsideDown: 0 + allowedAutorotateToLandscapeRight: 0 + allowedAutorotateToLandscapeLeft: 0 + useOSAutorotation: 0 use32BitDisplayBuffer: 1 preserveFramebufferAlpha: 0 disableDepthAndStencilBuffers: 0 diff --git a/First Principles/UserSettings/Layouts/default-6000.dwlt b/First Principles/UserSettings/Layouts/default-6000.dwlt index 72ca1a4..2b0068b 100644 --- a/First Principles/UserSettings/Layouts/default-6000.dwlt +++ b/First Principles/UserSettings/Layouts/default-6000.dwlt @@ -20,11 +20,86 @@ MonoBehaviour: height: 995 m_ShowMode: 4 m_Title: Console - m_RootView: {fileID: 2} + m_RootView: {fileID: 5} m_MinSize: {x: 875, y: 300} m_MaxSize: {x: 10000, y: 10000} m_Maximized: 1 --- !u!114 &2 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 12004, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: UnityEditor.dll::UnityEditor.ContainerWindow + m_PixelRect: + serializedVersion: 2 + x: 163 + y: 307 + width: 725 + height: 578 + m_ShowMode: 0 + m_Title: Build Profiles + m_RootView: {fileID: 4} + m_MinSize: {x: 725, y: 426} + m_MaxSize: {x: 4000, y: 4026} + m_Maximized: 0 +--- !u!114 &3 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} + m_Name: BuildProfileWindow + m_EditorClassIdentifier: UnityEditor.dll::UnityEditor.DockArea + m_Children: [] + m_Position: + serializedVersion: 2 + x: 0 + y: 0 + width: 725 + height: 578 + m_MinSize: {x: 725, y: 426} + m_MaxSize: {x: 4000, y: 4026} + m_ActualView: {fileID: 15} + m_Panes: + - {fileID: 15} + m_Selected: 0 + m_LastSelected: 0 +--- !u!114 &4 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: UnityEditor.dll::UnityEditor.SplitView + m_Children: + - {fileID: 3} + m_Position: + serializedVersion: 2 + x: 0 + y: 0 + width: 725 + height: 578 + m_MinSize: {x: 725, y: 426} + m_MaxSize: {x: 4000, y: 4026} + vertical: 0 + controlID: 508 + draggingID: 0 +--- !u!114 &5 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -37,9 +112,9 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_Children: - - {fileID: 3} - - {fileID: 5} - - {fileID: 4} + - {fileID: 6} + - {fileID: 8} + - {fileID: 7} m_Position: serializedVersion: 2 x: 0 @@ -52,7 +127,7 @@ MonoBehaviour: m_TopViewHeight: 36 m_UseBottomView: 1 m_BottomViewHeight: 20 ---- !u!114 &3 +--- !u!114 &6 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -73,8 +148,8 @@ MonoBehaviour: height: 36 m_MinSize: {x: 50, y: 50} m_MaxSize: {x: 4000, y: 4000} - m_ActualView: {fileID: 12} ---- !u!114 &4 + m_ActualView: {fileID: 16} +--- !u!114 &7 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -95,7 +170,7 @@ MonoBehaviour: height: 20 m_MinSize: {x: 0, y: 0} m_MaxSize: {x: 0, y: 0} ---- !u!114 &5 +--- !u!114 &8 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -108,8 +183,8 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_Children: - - {fileID: 6} - - {fileID: 11} + - {fileID: 9} + - {fileID: 14} m_Position: serializedVersion: 2 x: 0 @@ -119,9 +194,9 @@ MonoBehaviour: m_MinSize: {x: 300, y: 112} m_MaxSize: {x: 24288, y: 16192} vertical: 0 - controlID: 63 + controlID: 52 draggingID: 0 ---- !u!114 &6 +--- !u!114 &9 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -134,8 +209,8 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_Children: - - {fileID: 7} - {fileID: 10} + - {fileID: 13} m_Position: serializedVersion: 2 x: 0 @@ -145,9 +220,9 @@ MonoBehaviour: m_MinSize: {x: 200, y: 112} m_MaxSize: {x: 16192, y: 16192} vertical: 1 - controlID: 64 + controlID: 53 draggingID: 0 ---- !u!114 &7 +--- !u!114 &10 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -160,20 +235,20 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_Children: - - {fileID: 8} - - {fileID: 9} + - {fileID: 11} + - {fileID: 12} m_Position: serializedVersion: 2 x: 0 y: 0 width: 962 - height: 604 + height: 605 m_MinSize: {x: 200, y: 56} m_MaxSize: {x: 16192, y: 8096} vertical: 0 - controlID: 65 + controlID: 54 draggingID: 0 ---- !u!114 &8 +--- !u!114 &11 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -191,15 +266,15 @@ MonoBehaviour: x: 0 y: 0 width: 226 - height: 604 + height: 605 m_MinSize: {x: 201, y: 226} m_MaxSize: {x: 4001, y: 4026} - m_ActualView: {fileID: 13} + m_ActualView: {fileID: 17} m_Panes: - - {fileID: 13} + - {fileID: 17} m_Selected: 0 m_LastSelected: 0 ---- !u!114 &9 +--- !u!114 &12 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -217,17 +292,17 @@ MonoBehaviour: x: 226 y: 0 width: 736 - height: 604 + height: 605 m_MinSize: {x: 202, y: 226} m_MaxSize: {x: 4002, y: 4026} - m_ActualView: {fileID: 14} + m_ActualView: {fileID: 18} m_Panes: - - {fileID: 14} - - {fileID: 15} - - {fileID: 16} + - {fileID: 18} + - {fileID: 19} + - {fileID: 20} m_Selected: 0 m_LastSelected: 1 ---- !u!114 &10 +--- !u!114 &13 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -243,18 +318,18 @@ MonoBehaviour: m_Position: serializedVersion: 2 x: 0 - y: 604 + y: 605 width: 962 - height: 335 + height: 334 m_MinSize: {x: 101, y: 126} m_MaxSize: {x: 4001, y: 4026} - m_ActualView: {fileID: 18} + m_ActualView: {fileID: 22} m_Panes: - - {fileID: 17} - - {fileID: 18} + - {fileID: 21} + - {fileID: 22} m_Selected: 1 m_LastSelected: 0 ---- !u!114 &11 +--- !u!114 &14 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -275,12 +350,50 @@ MonoBehaviour: height: 939 m_MinSize: {x: 276, y: 76} m_MaxSize: {x: 4001, y: 4026} - m_ActualView: {fileID: 19} + m_ActualView: {fileID: 23} m_Panes: - - {fileID: 19} + - {fileID: 23} m_Selected: 0 m_LastSelected: 0 ---- !u!114 &12 +--- !u!114 &15 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 15004, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: UnityEditor.BuildProfileModule.dll::UnityEditor.Build.Profile.BuildProfileWindow + m_MinSize: {x: 725, y: 400} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Build Profiles + m_Image: {fileID: 0} + m_Tooltip: + m_TextWithWhitespace: "Build Profiles\u200B" + m_Pos: + serializedVersion: 2 + x: 0 + y: 26 + width: 725 + height: 552 + m_SerializedDataModeController: + m_DataMode: 0 + m_PreferredDataMode: 0 + m_SupportedDataModes: + isAutomatic: 1 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_ContainerData: [] + m_DynamicPanelContainerData: [] + m_OverlaysVisible: 1 + m_DynamicPanelBehavior: 0 +--- !u!114 &16 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -546,7 +659,7 @@ MonoBehaviour: m_DynamicPanelContainerData: [] m_OverlaysVisible: 1 m_DynamicPanelBehavior: 0 ---- !u!114 &13 +--- !u!114 &17 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -570,7 +683,7 @@ MonoBehaviour: x: 0 y: 24 width: 225 - height: 578 + height: 579 m_SerializedDataModeController: m_DataMode: 0 m_PreferredDataMode: 0 @@ -591,21 +704,14 @@ MonoBehaviour: m_LastClickedID: m_Data: 0 m_ExpandedIDs: - - m_Data: -9474 - - m_Data: -9052 - - m_Data: -8046 - - m_Data: -7476 - - m_Data: -7464 - - m_Data: -7456 - - m_Data: -7380 - - m_Data: -7346 - - m_Data: -7224 - - m_Data: -7128 - - m_Data: -5988 - - m_Data: -5926 - - m_Data: -5440 - - m_Data: -1344 - - m_Data: 36266 + - m_Data: -62118 + - m_Data: -60778 + - m_Data: -60660 + - m_Data: -60636 + - m_Data: -60622 + - m_Data: -60586 + - m_Data: -35118 + - m_Data: -34368 m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: @@ -632,7 +738,7 @@ MonoBehaviour: m_IsLocked: 0 m_CurrentSortingName: TransformSorting m_WindowGUID: 46b7a0fefa812c44ca6fda42b4d7b176 ---- !u!114 &14 +--- !u!114 &18 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -656,7 +762,7 @@ MonoBehaviour: x: 227 y: 24 width: 734 - height: 578 + height: 579 m_SerializedDataModeController: m_DataMode: 0 m_PreferredDataMode: 0 @@ -1303,7 +1409,7 @@ MonoBehaviour: m_LastSceneViewRotation: {x: 0.31118897, y: 0.09269961, z: -0.030600414, w: 0.9453927} m_LastSceneViewOrtho: 1 m_Viewpoint: - m_SceneView: {fileID: 14} + m_SceneView: {fileID: 18} m_CameraOverscanSettings: m_Opacity: 50 m_Scale: 1 @@ -1316,7 +1422,7 @@ MonoBehaviour: name: Contributors / Receivers section: Lighting m_ViewIsLockedToObject: 0 ---- !u!114 &15 +--- !u!114 &19 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -1340,7 +1446,7 @@ MonoBehaviour: x: 226 y: 97 width: 734 - height: 578 + height: 579 m_SerializedDataModeController: m_DataMode: 0 m_PreferredDataMode: 0 @@ -1360,7 +1466,7 @@ MonoBehaviour: m_ShowGizmos: 0 m_TargetDisplay: 0 m_ClearColor: {r: 0, g: 0, b: 0, a: 0} - m_TargetSize: {x: 2560, y: 1440} + m_TargetSize: {x: 1468, y: 1116} m_TextureFilterMode: 0 m_TextureHideFlags: 61 m_RenderIMGUI: 1 @@ -1375,10 +1481,10 @@ MonoBehaviour: m_VRangeLocked: 0 hZoomLockedByDefault: 0 vZoomLockedByDefault: 0 - m_HBaseRangeMin: -640 - m_HBaseRangeMax: 640 - m_VBaseRangeMin: -360 - m_VBaseRangeMax: 360 + m_HBaseRangeMin: -367 + m_HBaseRangeMax: 367 + m_VBaseRangeMin: -279 + m_VBaseRangeMax: 279 m_HAllowExceedBaseRangeMin: 1 m_HAllowExceedBaseRangeMax: 1 m_VAllowExceedBaseRangeMin: 1 @@ -1397,29 +1503,29 @@ MonoBehaviour: x: 0 y: 21 width: 734 - height: 557 - m_Scale: {x: 0.5734375, y: 0.5734375} - m_Translation: {x: 367, y: 278.5} + height: 558 + m_Scale: {x: 1, y: 1} + m_Translation: {x: 367, y: 279} m_MarginLeft: 0 m_MarginRight: 0 m_MarginTop: 0 m_MarginBottom: 0 m_LastShownAreaInsideMargins: serializedVersion: 2 - x: -640 - y: -485.66757 - width: 1280 - height: 971.33514 + x: -367 + y: -279 + width: 734 + height: 558 m_MinimalGUI: 1 - m_defaultScale: 0.5734375 - m_LastWindowPixelSize: {x: 1468, y: 1156} + m_defaultScale: 1 + m_LastWindowPixelSize: {x: 1468, y: 1158} m_ClearInEditMode: 1 m_NoCameraWarning: 1 m_LowResolutionForAspectRatios: 01000000000100000100 m_XRRenderMode: 0 m_RenderTexture: {fileID: 0} m_showToolbar: 1 ---- !u!114 &16 +--- !u!114 &20 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -1457,7 +1563,7 @@ MonoBehaviour: m_DynamicPanelContainerData: [] m_OverlaysVisible: 1 m_DynamicPanelBehavior: 0 ---- !u!114 &17 +--- !u!114 &21 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -1479,9 +1585,9 @@ MonoBehaviour: m_Pos: serializedVersion: 2 x: 0 - y: 701 + y: 702 width: 961 - height: 309 + height: 308 m_SerializedDataModeController: m_DataMode: 0 m_PreferredDataMode: 0 @@ -1506,7 +1612,7 @@ MonoBehaviour: m_SkipHidden: 0 m_SearchArea: 1 m_Folders: - - Assets/Scenes + - Assets/Scripts/Game m_Globs: [] m_ProductIds: m_AnyWithAssetOrigin: 0 @@ -1516,21 +1622,23 @@ MonoBehaviour: m_ViewMode: 1 m_StartGridSize: 16 m_LastFolders: - - Assets/Scenes + - Assets/Scripts/Game m_LastFoldersGridSize: 16 - m_LastProjectPath: /Users/johnseong/Documents/GitHub/First-Principles/First Principles + m_LastProjectPath: /Users/johnseong/Documents/GitHub2/First-Principles/First Principles m_LockTracker: m_IsLocked: 0 m_LastLocalAssetsSearchArea: 1 m_FolderTreeState: - scrollPos: {x: 0, y: 12.000122} + scrollPos: {x: 0, y: 80.00061} m_SelectedIDs: - - m_Data: 35280 + - m_Data: 40708 m_LastClickedID: - m_Data: 35280 + m_Data: 40708 m_ExpandedIDs: - m_Data: 0 - - m_Data: 34846 + - m_Data: 34560 + - m_Data: 1000000000 + - m_Data: 2147483647 m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: @@ -1548,7 +1656,7 @@ MonoBehaviour: m_OriginalEventType: 11 m_IsRenamingFilename: 1 m_TrimLeadingAndTrailingWhitespace: 0 - m_ClientGUIView: {fileID: 10} + m_ClientGUIView: {fileID: 13} m_SearchString: m_CreateAssetUtility: m_EndAction: {fileID: 0} @@ -1564,7 +1672,9 @@ MonoBehaviour: m_Data: 0 m_ExpandedIDs: - m_Data: 0 - - m_Data: 34846 + - m_Data: 34560 + - m_Data: 1000000000 + - m_Data: 2147483647 m_RenameOverlay: m_UserAcceptedRename: 0 m_Name: @@ -1582,7 +1692,7 @@ MonoBehaviour: m_OriginalEventType: 11 m_IsRenamingFilename: 1 m_TrimLeadingAndTrailingWhitespace: 0 - m_ClientGUIView: {fileID: 10} + m_ClientGUIView: {fileID: 13} m_SearchString: m_CreateAssetUtility: m_EndAction: {fileID: 0} @@ -1592,10 +1702,9 @@ MonoBehaviour: m_Icon: {fileID: 0} m_ResourceFile: m_ListAreaState: - m_SelectedInstanceIDs: - - m_Data: 35348 + m_SelectedInstanceIDs: [] m_LastClickedEntityId: - m_Data: 35348 + m_Data: 0 m_HadKeyboardFocusLastEvent: 1 m_ExpandedInstanceIDs: [] m_RenameOverlay: @@ -1615,7 +1724,7 @@ MonoBehaviour: m_OriginalEventType: 11 m_IsRenamingFilename: 1 m_TrimLeadingAndTrailingWhitespace: 0 - m_ClientGUIView: {fileID: 10} + m_ClientGUIView: {fileID: 13} m_CreateAssetUtility: m_EndAction: {fileID: 0} m_EntityId: @@ -1624,11 +1733,11 @@ MonoBehaviour: m_Icon: {fileID: 0} m_ResourceFile: m_NewAssetIndexInList: -1 - m_ScrollPosition: {x: 0, y: 0} + m_ScrollPosition: {x: 0, y: 77.5} m_GridSize: 16 m_SkipHiddenPackages: 0 m_DirectoriesAreaWidth: 199 ---- !u!114 &18 +--- !u!114 &22 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} @@ -1650,9 +1759,9 @@ MonoBehaviour: m_Pos: serializedVersion: 2 x: 0 - y: 628 + y: 629 width: 961 - height: 309 + height: 308 m_SerializedDataModeController: m_DataMode: 0 m_PreferredDataMode: 0 @@ -1666,7 +1775,7 @@ MonoBehaviour: m_DynamicPanelContainerData: [] m_OverlaysVisible: 1 m_DynamicPanelBehavior: 0 ---- !u!114 &19 +--- !u!114 &23 MonoBehaviour: m_ObjectHideFlags: 52 m_CorrespondingSourceObject: {fileID: 0} diff --git a/Packages/manifest.json b/Packages/manifest.json new file mode 100644 index 0000000..be6ce35 --- /dev/null +++ b/Packages/manifest.json @@ -0,0 +1,39 @@ +{ + "dependencies": { + "com.unity.multiplayer.center": "1.0.1", + "com.unity.modules.accessibility": "1.0.0", + "com.unity.modules.adaptiveperformance": "1.0.0", + "com.unity.modules.ai": "1.0.0", + "com.unity.modules.androidjni": "1.0.0", + "com.unity.modules.animation": "1.0.0", + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.cloth": "1.0.0", + "com.unity.modules.director": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.particlesystem": "1.0.0", + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.physics2d": "1.0.0", + "com.unity.modules.screencapture": "1.0.0", + "com.unity.modules.terrain": "1.0.0", + "com.unity.modules.terrainphysics": "1.0.0", + "com.unity.modules.tilemap": "1.0.0", + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.uielements": "1.0.0", + "com.unity.modules.umbra": "1.0.0", + "com.unity.modules.unityanalytics": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.unitywebrequestassetbundle": "1.0.0", + "com.unity.modules.unitywebrequestaudio": "1.0.0", + "com.unity.modules.unitywebrequesttexture": "1.0.0", + "com.unity.modules.unitywebrequestwww": "1.0.0", + "com.unity.modules.vectorgraphics": "1.0.0", + "com.unity.modules.vehicles": "1.0.0", + "com.unity.modules.video": "1.0.0", + "com.unity.modules.vr": "1.0.0", + "com.unity.modules.wind": "1.0.0", + "com.unity.modules.xr": "1.0.0" + } +} diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json new file mode 100644 index 0000000..6aaea1b --- /dev/null +++ b/Packages/packages-lock.json @@ -0,0 +1,287 @@ +{ + "dependencies": { + "com.unity.multiplayer.center": { + "version": "1.0.1", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.uielements": "1.0.0" + } + }, + "com.unity.modules.accessibility": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.adaptiveperformance": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.subsystems": "1.0.0" + } + }, + "com.unity.modules.ai": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.androidjni": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.animation": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.assetbundle": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.audio": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.cloth": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0" + } + }, + "com.unity.modules.director": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.animation": "1.0.0" + } + }, + "com.unity.modules.hierarchycore": { + "version": "1.0.0", + "depth": 1, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.imageconversion": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.imgui": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.jsonserialize": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.particlesystem": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.physics": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.physics2d": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.screencapture": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.imageconversion": "1.0.0" + } + }, + "com.unity.modules.subsystems": { + "version": "1.0.0", + "depth": 1, + "source": "builtin", + "dependencies": { + "com.unity.modules.jsonserialize": "1.0.0" + } + }, + "com.unity.modules.terrain": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.terrainphysics": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.terrain": "1.0.0" + } + }, + "com.unity.modules.tilemap": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics2d": "1.0.0" + } + }, + "com.unity.modules.ui": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.uielements": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.hierarchycore": "1.0.0", + "com.unity.modules.physics": "1.0.0" + } + }, + "com.unity.modules.umbra": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.unityanalytics": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0" + } + }, + "com.unity.modules.unitywebrequest": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.unitywebrequestassetbundle": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0" + } + }, + "com.unity.modules.unitywebrequestaudio": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.audio": "1.0.0" + } + }, + "com.unity.modules.unitywebrequesttexture": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0" + } + }, + "com.unity.modules.unitywebrequestwww": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.unitywebrequestassetbundle": "1.0.0", + "com.unity.modules.unitywebrequestaudio": "1.0.0", + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0" + } + }, + "com.unity.modules.vectorgraphics": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.uielements": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0", + "com.unity.modules.imgui": "1.0.0" + } + }, + "com.unity.modules.vehicles": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0" + } + }, + "com.unity.modules.video": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0" + } + }, + "com.unity.modules.vr": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.xr": "1.0.0" + } + }, + "com.unity.modules.wind": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.xr": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.subsystems": "1.0.0" + } + } + } +} diff --git a/ProjectSettings/AudioManager.asset b/ProjectSettings/AudioManager.asset new file mode 100644 index 0000000..50b4625 --- /dev/null +++ b/ProjectSettings/AudioManager.asset @@ -0,0 +1,23 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!11 &1 +AudioManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Volume: 1 + Rolloff Scale: 1 + Doppler Factor: 1 + Default Speaker Mode: 2 + m_SampleRate: 0 + m_DSPBufferSize: 1024 + m_VirtualVoiceCount: 512 + m_RealVoiceCount: 32 + m_EnableOutputSuspension: 1 + m_SpatializerPlugin: + m_AmbisonicDecoderPlugin: + m_DisableAudio: 0 + m_VirtualizeEffects: 1 + m_RequestedDSPBufferSize: 0 + m_AudioFoundation: 0 + m_OutputChannelLayout: 2 + m_OutputSamplingRate: 48000 diff --git a/ProjectSettings/ClusterInputManager.asset b/ProjectSettings/ClusterInputManager.asset new file mode 100644 index 0000000..e7886b2 --- /dev/null +++ b/ProjectSettings/ClusterInputManager.asset @@ -0,0 +1,6 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!236 &1 +ClusterInputManager: + m_ObjectHideFlags: 0 + m_Inputs: [] diff --git a/ProjectSettings/DynamicsManager.asset b/ProjectSettings/DynamicsManager.asset new file mode 100644 index 0000000..af0927b --- /dev/null +++ b/ProjectSettings/DynamicsManager.asset @@ -0,0 +1,45 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!55 &1 +PhysicsManager: + m_ObjectHideFlags: 0 + serializedVersion: 23 + m_Gravity: {x: 0, y: -9.81, z: 0} + m_DefaultMaterial: {fileID: 0} + m_BounceThreshold: 2 + m_DefaultMaxDepenetrationVelocity: 10 + m_SleepThreshold: 0.005 + m_DefaultContactOffset: 0.01 + m_DefaultSolverIterations: 6 + m_DefaultSolverVelocityIterations: 1 + m_QueriesHitBackfaces: 0 + m_QueriesHitTriggers: 1 + m_EnableAdaptiveForce: 0 + m_ClothInterCollisionDistance: 0.1 + m_ClothInterCollisionStiffness: 0.2 + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + m_SimulationMode: 0 + m_AutoSyncTransforms: 0 + m_ReuseCollisionCallbacks: 1 + m_InvokeCollisionCallbacks: 1 + m_ClothInterCollisionSettingsToggle: 0 + m_ClothGravity: {x: 0, y: -9.81, z: 0} + m_ContactPairsMode: 0 + m_BroadphaseType: 0 + m_WorldBounds: + m_Center: {x: 0, y: 0, z: 0} + m_Extent: {x: 256, y: 256, z: 256} + m_WorldSubdivisions: 8 + m_FrictionType: 0 + m_EnableEnhancedDeterminism: 0 + m_ImprovedPatchFriction: 0 + m_GenerateOnTriggerStayEvents: 1 + m_SolverType: 0 + m_DefaultMaxAngularSpeed: 50 + m_ScratchBufferChunkCount: 4 + m_CurrentBackendId: 4072204805 + m_FastMotionThreshold: 3.4028235e+38 + m_SceneBuffersReleaseInterval: 0 + m_ReleaseSceneBuffers: 0 + m_LogVerbosity: 3 + m_IncrementalStaticBroadphase: 1 diff --git a/ProjectSettings/EditorBuildSettings.asset b/ProjectSettings/EditorBuildSettings.asset new file mode 100644 index 0000000..0147887 --- /dev/null +++ b/ProjectSettings/EditorBuildSettings.asset @@ -0,0 +1,8 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1045 &1 +EditorBuildSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Scenes: [] + m_configObjects: {} diff --git a/ProjectSettings/EditorSettings.asset b/ProjectSettings/EditorSettings.asset new file mode 100644 index 0000000..092d90f --- /dev/null +++ b/ProjectSettings/EditorSettings.asset @@ -0,0 +1,52 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!159 &1 +EditorSettings: + m_ObjectHideFlags: 0 + serializedVersion: 15 + m_SerializationMode: 2 + m_LineEndingsForNewScripts: 1 + m_DefaultBehaviorMode: 0 + m_PrefabRegularEnvironment: {fileID: 0} + m_PrefabUIEnvironment: {fileID: 0} + m_SpritePackerMode: 0 + m_SpritePackerCacheSize: 10 + m_SpritePackerPaddingPower: 1 + m_Bc7TextureCompressor: 0 + m_EtcTextureCompressorBehavior: 1 + m_EtcTextureFastCompressor: 1 + m_EtcTextureNormalCompressor: 2 + m_EtcTextureBestCompressor: 4 + m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;asmref;rsp;java;cpp;c;mm;m;h + m_ProjectGenerationRootNamespace: + m_EnableTextureStreamingInEditMode: 1 + m_EnableTextureStreamingInPlayMode: 1 + m_EnableEditorAsyncCPUTextureLoading: 0 + m_AsyncShaderCompilation: 1 + m_BlockShaders: 0 + m_UnlockBlockShaders: 0 + m_PrefabModeAllowAutoSave: 1 + m_EnterPlayModeOptionsEnabled: 1 + m_EnterPlayModeOptions: 0 + m_GameObjectNamingDigits: 1 + m_GameObjectNamingScheme: 0 + m_AssetNamingUsesSpace: 1 + m_InspectorUseIMGUIDefaultInspector: 0 + m_UseLegacyProbeSampleCount: 0 + m_SerializeInlineMappingsOnOneLine: 1 + m_DisableCookiesInLightmapper: 0 + m_ShadowmaskStitching: 1 + m_AssetPipelineMode: 1 + m_RefreshImportMode: 0 + m_CacheServerMode: 0 + m_CacheServerEndpoint: + m_CacheServerNamespacePrefix: default + m_CacheServerEnableDownload: 1 + m_CacheServerEnableUpload: 1 + m_CacheServerEnableTls: 0 + m_CacheServerValidationMode: 2 + m_CacheServerDownloadBatchSize: 128 + m_EnableEnlightenBakedGI: 0 + m_ReferencedClipsExactNaming: 1 + m_ForceAssetUnloadAndGCOnSceneLoad: 1 + m_HideBuildProfileClassicPlatforms: 0 diff --git a/ProjectSettings/GraphicsSettings.asset b/ProjectSettings/GraphicsSettings.asset new file mode 100644 index 0000000..4b152c0 --- /dev/null +++ b/ProjectSettings/GraphicsSettings.asset @@ -0,0 +1,68 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!30 &1 +GraphicsSettings: + m_ObjectHideFlags: 0 + serializedVersion: 16 + m_Deferred: + m_Mode: 1 + m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} + m_DeferredReflections: + m_Mode: 1 + m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} + m_ScreenSpaceShadows: + m_Mode: 1 + m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} + m_DepthNormals: + m_Mode: 1 + m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} + m_MotionVectors: + m_Mode: 1 + m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} + m_LightHalo: + m_Mode: 1 + m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} + m_LensFlare: + m_Mode: 1 + m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} + m_VideoShadersIncludeMode: 2 + m_AlwaysIncludedShaders: + - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10783, guid: 0000000000000000f000000000000000, type: 0} + m_PreloadedShaders: [] + m_PreloadShadersBatchTimeLimit: -1 + m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0} + m_CustomRenderPipeline: {fileID: 0} + m_TransparencySortMode: 0 + m_TransparencySortAxis: {x: 0, y: 0, z: 1} + m_DefaultRenderingPath: 1 + m_DefaultMobileRenderingPath: 1 + m_TierSettings: [] + m_LightmapStripping: 0 + m_FogStripping: 0 + m_InstancingStripping: 0 + m_BrgStripping: 0 + m_LightmapKeepPlain: 1 + m_LightmapKeepDirCombined: 1 + m_LightmapKeepDynamicPlain: 1 + m_LightmapKeepDynamicDirCombined: 1 + m_LightmapKeepShadowMask: 1 + m_LightmapKeepSubtractive: 1 + m_FogKeepLinear: 1 + m_FogKeepExp: 1 + m_FogKeepExp2: 1 + m_AlbedoSwatchInfos: [] + m_RenderPipelineGlobalSettingsMap: {} + m_ShaderBuildSettings: + keywordDeclarationOverrides: [] + m_LightsUseLinearIntensity: 0 + m_LightsUseColorTemperature: 0 + m_LogWhenShaderIsCompiled: 0 + m_LightProbeOutsideHullStrategy: 1 + m_CameraRelativeLightCulling: 0 + m_CameraRelativeShadowCulling: 0 diff --git a/ProjectSettings/InputManager.asset b/ProjectSettings/InputManager.asset new file mode 100644 index 0000000..8068b20 --- /dev/null +++ b/ProjectSettings/InputManager.asset @@ -0,0 +1,296 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!13 &1 +InputManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Axes: + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: left + positiveButton: right + altNegativeButton: a + altPositiveButton: d + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: down + positiveButton: up + altNegativeButton: s + altPositiveButton: w + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left ctrl + altNegativeButton: + altPositiveButton: mouse 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left alt + altNegativeButton: + altPositiveButton: mouse 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left shift + altNegativeButton: + altPositiveButton: mouse 2 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: space + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse X + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse Y + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse ScrollWheel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 2 + joyNum: 0 + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 0 + type: 2 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 1 + type: 2 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 0 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 1 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 2 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 3 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: return + altNegativeButton: + altPositiveButton: joystick button 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: enter + altNegativeButton: + altPositiveButton: space + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Cancel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: escape + altNegativeButton: + altPositiveButton: joystick button 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + m_UsePhysicalKeys: 1 diff --git a/ProjectSettings/MemorySettings.asset b/ProjectSettings/MemorySettings.asset new file mode 100644 index 0000000..517e60e --- /dev/null +++ b/ProjectSettings/MemorySettings.asset @@ -0,0 +1,35 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!387306366 &1 +MemorySettings: + m_ObjectHideFlags: 0 + m_EditorMemorySettings: + m_MainAllocatorBlockSize: -1 + m_ThreadAllocatorBlockSize: -1 + m_MainGfxBlockSize: -1 + m_ThreadGfxBlockSize: -1 + m_CacheBlockSize: -1 + m_TypetreeBlockSize: -1 + m_ProfilerBlockSize: -1 + m_ProfilerEditorBlockSize: -1 + m_BucketAllocatorGranularity: -1 + m_BucketAllocatorBucketsCount: -1 + m_BucketAllocatorBlockSize: -1 + m_BucketAllocatorBlockCount: -1 + m_ProfilerBucketAllocatorGranularity: -1 + m_ProfilerBucketAllocatorBucketsCount: -1 + m_ProfilerBucketAllocatorBlockSize: -1 + m_ProfilerBucketAllocatorBlockCount: -1 + m_TempAllocatorSizeMain: -1 + m_JobTempAllocatorBlockSize: -1 + m_BackgroundJobTempAllocatorBlockSize: -1 + m_JobTempAllocatorReducedBlockSize: -1 + m_TempAllocatorSizeGIBakingWorker: -1 + m_TempAllocatorSizeNavMeshWorker: -1 + m_TempAllocatorSizeAudioWorker: -1 + m_TempAllocatorSizeCloudWorker: -1 + m_TempAllocatorSizeGfx: -1 + m_TempAllocatorSizeJobWorker: -1 + m_TempAllocatorSizeBackgroundWorker: -1 + m_TempAllocatorSizePreloadManager: -1 + m_PlatformMemorySettings: [] diff --git a/ProjectSettings/MultiplayerManager.asset b/ProjectSettings/MultiplayerManager.asset new file mode 100644 index 0000000..c19bcd7 --- /dev/null +++ b/ProjectSettings/MultiplayerManager.asset @@ -0,0 +1,9 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!655991488 &1 +MultiplayerManager: + m_ObjectHideFlags: 0 + m_EnableMultiplayerRoles: 0 + m_EnablePlayModeLocalDeployment: 0 + m_EnablePlayModeRemoteDeployment: 0 + m_StrippingTypes: {} diff --git a/ProjectSettings/NavMeshAreas.asset b/ProjectSettings/NavMeshAreas.asset new file mode 100644 index 0000000..2e2e369 --- /dev/null +++ b/ProjectSettings/NavMeshAreas.asset @@ -0,0 +1,93 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!126 &1 +NavMeshProjectSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + areas: + - name: Walkable + cost: 1 + - name: Not Walkable + cost: 1 + - name: Jump + cost: 2 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + m_LastAgentTypeID: -887442657 + m_Settings: + - serializedVersion: 3 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.75 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + buildHeightMesh: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 + m_SettingNames: + - Humanoid diff --git a/ProjectSettings/PackageManagerSettings.asset b/ProjectSettings/PackageManagerSettings.asset new file mode 100644 index 0000000..944120c --- /dev/null +++ b/ProjectSettings/PackageManagerSettings.asset @@ -0,0 +1,42 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &1 +MonoBehaviour: + m_ObjectHideFlags: 53 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: UnityEditor.dll::UnityEditor.PackageManager.UI.Internal.PackageManagerProjectSettings + m_EnablePreReleasePackages: 0 + m_AdvancedSettingsExpanded: 1 + m_ScopedRegistriesSettingsExpanded: 1 + m_SeeAllPackageVersions: 0 + m_DismissPreviewPackagesInUse: 0 + oneTimeWarningShown: 0 + oneTimePackageErrorsPopUpShown: 0 + m_Registries: + - m_Id: main + m_Name: + m_Url: https://packages.unity.com + m_Scopes: [] + m_IsDefault: 1 + m_Capabilities: 7 + m_ConfigSource: 0 + m_Compliance: + m_Status: 0 + m_Violations: [] + m_UserSelectedRegistryName: + m_UserAddingNewScopedRegistry: 0 + m_RegistryInfoDraft: + m_Modified: 0 + m_ErrorMessage: + m_UserModificationsEntityId: + m_Data: -982 + m_OriginalEntityId: + m_Data: -984 + m_LoadAssets: 0 diff --git a/ProjectSettings/Physics2DSettings.asset b/ProjectSettings/Physics2DSettings.asset new file mode 100644 index 0000000..14f419f --- /dev/null +++ b/ProjectSettings/Physics2DSettings.asset @@ -0,0 +1,57 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!19 &1 +Physics2DSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_Gravity: {x: 0, y: -9.81} + m_DefaultMaterial: {fileID: 0} + m_VelocityIterations: 8 + m_PositionIterations: 3 + m_BounceThreshold: 1 + m_MaxLinearCorrection: 0.2 + m_MaxAngularCorrection: 8 + m_MaxTranslationSpeed: 100 + m_MaxRotationSpeed: 360 + m_BaumgarteScale: 0.2 + m_BaumgarteTimeOfImpactScale: 0.75 + m_TimeToSleep: 0.5 + m_LinearSleepTolerance: 0.01 + m_AngularSleepTolerance: 2 + m_DefaultContactOffset: 0.01 + m_ContactThreshold: 0 + m_JobOptions: + serializedVersion: 2 + useMultithreading: 0 + useConsistencySorting: 0 + m_InterpolationPosesPerJob: 100 + m_NewContactsPerJob: 30 + m_CollideContactsPerJob: 100 + m_ClearFlagsPerJob: 200 + m_ClearBodyForcesPerJob: 200 + m_SyncDiscreteFixturesPerJob: 50 + m_SyncContinuousFixturesPerJob: 50 + m_FindNearestContactsPerJob: 100 + m_UpdateTriggerContactsPerJob: 100 + m_IslandSolverCostThreshold: 100 + m_IslandSolverBodyCostScale: 1 + m_IslandSolverContactCostScale: 10 + m_IslandSolverJointCostScale: 10 + m_IslandSolverBodiesPerJob: 50 + m_IslandSolverContactsPerJob: 50 + m_SimulationMode: 0 + m_SimulationLayers: + serializedVersion: 2 + m_Bits: 4294967295 + m_MaxSubStepCount: 4 + m_MinSubStepFPS: 30 + m_UseSubStepping: 0 + m_UseSubStepContacts: 0 + m_QueriesHitTriggers: 1 + m_QueriesStartInColliders: 1 + m_CallbacksOnDisable: 1 + m_ReuseCollisionCallbacks: 1 + m_AutoSyncTransforms: 0 + m_GizmoOptions: 10 + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + m_PhysicsLowLevelSettings: {fileID: 0} diff --git a/ProjectSettings/PresetManager.asset b/ProjectSettings/PresetManager.asset new file mode 100644 index 0000000..67a94da --- /dev/null +++ b/ProjectSettings/PresetManager.asset @@ -0,0 +1,7 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1386491679 &1 +PresetManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_DefaultPresets: {} diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset new file mode 100644 index 0000000..f5fc046 --- /dev/null +++ b/ProjectSettings/ProjectSettings.asset @@ -0,0 +1,893 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!129 &1 +PlayerSettings: + m_ObjectHideFlags: 0 + serializedVersion: 28 + productGUID: cb17d67df55ec447ebac830ac522c475 + AndroidProfiler: 0 + AndroidFilterTouchesWhenObscured: 0 + AndroidEnableSustainedPerformanceMode: 0 + defaultScreenOrientation: 4 + targetDevice: 2 + useOnDemandResources: 0 + accelerometerFrequency: 60 + companyName: DefaultCompany + productName: First-Principles + defaultCursor: {fileID: 0} + cursorHotspot: {x: 0, y: 0} + m_SplashScreenBackgroundColor: {r: 0.12156863, g: 0.12156863, b: 0.1254902, a: 1} + m_ShowUnitySplashScreen: 1 + m_ShowUnitySplashLogo: 1 + m_SplashScreenOverlayOpacity: 1 + m_SplashScreenAnimation: 1 + m_SplashScreenLogoStyle: 1 + m_SplashScreenDrawMode: 0 + m_SplashScreenBackgroundAnimationZoom: 1 + m_SplashScreenLogoAnimationZoom: 1 + m_SplashScreenBackgroundLandscapeAspect: 1 + m_SplashScreenBackgroundPortraitAspect: 1 + m_SplashScreenBackgroundLandscapeUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenBackgroundPortraitUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenLogos: [] + m_VirtualRealitySplashScreen: {fileID: 0} + defaultScreenWidth: 1920 + defaultScreenHeight: 1080 + defaultScreenWidthWeb: 960 + defaultScreenHeightWeb: 600 + m_StereoRenderingPath: 0 + m_ActiveColorSpace: 0 + unsupportedMSAAFallback: 0 + m_SpriteBatchMaxVertexCount: 65535 + m_SpriteBatchVertexThreshold: 300 + m_MTRendering: 1 + mipStripping: 0 + numberOfMipsStripped: 0 + numberOfMipsStrippedPerMipmapLimitGroup: {} + m_StackTraceTypes: 010000000100000001000000010000000100000001000000 + iosShowActivityIndicatorOnLoading: -1 + androidShowActivityIndicatorOnLoading: -1 + iosUseCustomAppBackgroundBehavior: 0 + allowedAutorotateToPortrait: 1 + allowedAutorotateToPortraitUpsideDown: 1 + allowedAutorotateToLandscapeRight: 1 + allowedAutorotateToLandscapeLeft: 1 + useOSAutorotation: 1 + use32BitDisplayBuffer: 1 + preserveFramebufferAlpha: 0 + disableDepthAndStencilBuffers: 0 + androidStartInFullscreen: 1 + androidRenderOutsideSafeArea: 1 + androidUseSwappy: 1 + androidDisplayOptions: 1 + androidBlitType: 0 + androidResizeableActivity: 1 + androidDefaultWindowWidth: 1920 + androidDefaultWindowHeight: 1080 + androidMinimumWindowWidth: 400 + androidMinimumWindowHeight: 300 + androidFullscreenMode: 1 + androidAutoRotationBehavior: 1 + androidPredictiveBackSupport: 1 + androidApplicationEntry: 2 + defaultIsNativeResolution: 1 + macRetinaSupport: 1 + runInBackground: 0 + muteOtherAudioSources: 0 + Prepare IOS For Recording: 0 + Force IOS Speakers When Recording: 0 + audioSpatialExperience: 0 + deferSystemGesturesMode: 0 + hideHomeButton: 0 + submitAnalytics: 1 + usePlayerLog: 1 + dedicatedServerOptimizations: 1 + bakeCollisionMeshes: 0 + forceSingleInstance: 0 + useFlipModelSwapchain: 1 + resizableWindow: 0 + useMacAppStoreValidation: 0 + macAppStoreCategory: public.app-category.games + gpuSkinning: 0 + meshDeformation: 0 + xboxPIXTextureCapture: 0 + xboxEnableAvatar: 0 + xboxEnableKinect: 0 + xboxEnableKinectAutoTracking: 0 + xboxEnableFitness: 0 + visibleInBackground: 1 + allowFullscreenSwitch: 1 + fullscreenMode: 1 + xboxSpeechDB: 0 + xboxEnableHeadOrientation: 0 + xboxEnableGuest: 0 + xboxEnablePIXSampling: 0 + metalFramebufferOnly: 0 + metalUseMetalDisplayLink: 0 + xboxOneResolution: 0 + xboxOneSResolution: 0 + xboxOneXResolution: 3 + xboxOneMonoLoggingLevel: 0 + xboxOneLoggingLevel: 1 + xboxOneDisableEsram: 0 + xboxOneEnableTypeOptimization: 0 + xboxOnePresentImmediateThreshold: 0 + switchQueueCommandMemory: 1048576 + switchQueueControlMemory: 16384 + switchQueueComputeMemory: 262144 + switchNVNShaderPoolsGranularity: 33554432 + switchNVNDefaultPoolsGranularity: 16777216 + switchNVNOtherPoolsGranularity: 16777216 + switchGpuScratchPoolGranularity: 2097152 + switchAllowGpuScratchShrinking: 0 + switchNVNMaxPublicTextureIDCount: 0 + switchNVNMaxPublicSamplerIDCount: 0 + switchMaxWorkerMultiple: 8 + switchNVNGraphicsFirmwareMemory: 32 + switchGraphicsJobsSyncAfterKick: 1 + vulkanNumSwapchainBuffers: 3 + vulkanEnableSetSRGBWrite: 0 + vulkanEnablePreTransform: 0 + vulkanEnableLateAcquireNextImage: 0 + vulkanEnableCommandBufferRecycling: 1 + loadStoreDebugModeEnabled: 0 + visionOSBundleVersion: 1.0 + tvOSBundleVersion: 1.0 + bundleVersion: 1.0 + preloadedAssets: [] + metroInputSource: 0 + wsaTransparentSwapchain: 0 + xboxOneDisableKinectGpuReservation: 1 + xboxOneEnable7thCore: 1 + vrSettings: + enable360StereoCapture: 0 + enableFrameTimingStats: 0 + enableOpenGLProfilerGPURecorders: 1 + allowHDRDisplaySupport: 0 + useHDRDisplay: 0 + hdrBitDepth: 0 + m_ColorGamuts: 00000000 + targetPixelDensity: 30 + resolutionScalingMode: 0 + resetResolutionOnWindowResize: 0 + androidSupportedAspectRatio: 1 + androidMaxAspectRatio: 2.4 + androidMinAspectRatio: 1 + applicationIdentifier: {} + buildNumber: + Standalone: 0 + VisionOS: 0 + iPhone: 0 + tvOS: 0 + overrideDefaultApplicationIdentifier: 0 + AndroidBundleVersionCode: 1 + AndroidMinSdkVersion: 25 + AndroidTargetSdkVersion: 0 + AndroidPreferredInstallLocation: 1 + AndroidPreferredDataLocation: 1 + aotOptions: + stripEngineCode: 1 + iPhoneStrippingLevel: 0 + iPhoneScriptCallOptimization: 0 + ForceInternetPermission: 0 + ForceSDCardPermission: 0 + CreateWallpaper: 0 + androidSplitApplicationBinary: 0 + keepLoadedShadersAlive: 0 + StripUnusedMeshComponents: 0 + strictShaderVariantMatching: 0 + VertexChannelCompressionMask: 4054 + iPhoneSdkVersion: 988 + iOSSimulatorArchitecture: 0 + iOSTargetOSVersionString: 15.0 + tvOSSdkVersion: 0 + tvOSSimulatorArchitecture: 0 + tvOSRequireExtendedGameController: 0 + tvOSTargetOSVersionString: 15.0 + VisionOSSdkVersion: 0 + VisionOSTargetOSVersionString: 1.0 + uIPrerenderedIcon: 0 + uIRequiresPersistentWiFi: 0 + uIRequiresFullScreen: 1 + uIStatusBarHidden: 1 + uIExitOnSuspend: 0 + uIStatusBarStyle: 0 + appleTVSplashScreen: {fileID: 0} + appleTVSplashScreen2x: {fileID: 0} + tvOSSmallIconLayers: [] + tvOSSmallIconLayers2x: [] + tvOSLargeIconLayers: [] + tvOSLargeIconLayers2x: [] + tvOSTopShelfImageLayers: [] + tvOSTopShelfImageLayers2x: [] + tvOSTopShelfImageWideLayers: [] + tvOSTopShelfImageWideLayers2x: [] + iOSLaunchScreenType: 0 + iOSLaunchScreenPortrait: {fileID: 0} + iOSLaunchScreenLandscape: {fileID: 0} + iOSLaunchScreenBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreenFillPct: 100 + iOSLaunchScreenSize: 100 + iOSLaunchScreeniPadType: 0 + iOSLaunchScreeniPadImage: {fileID: 0} + iOSLaunchScreeniPadBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreeniPadFillPct: 100 + iOSLaunchScreeniPadSize: 100 + iOSLaunchScreenCustomStoryboardPath: + iOSLaunchScreeniPadCustomStoryboardPath: + iOSDeviceRequirements: [] + iOSURLSchemes: [] + macOSURLSchemes: [] + iOSBackgroundModes: 0 + iOSMetalForceHardShadows: 0 + metalEditorSupport: 1 + metalAPIValidation: 1 + metalCompileShaderBinary: 0 + iOSRenderExtraFrameOnPause: 0 + iosCopyPluginsCodeInsteadOfSymlink: 0 + appleDeveloperTeamID: + iOSManualSigningProvisioningProfileID: + tvOSManualSigningProvisioningProfileID: + VisionOSManualSigningProvisioningProfileID: + iOSManualSigningProvisioningProfileType: 0 + tvOSManualSigningProvisioningProfileType: 0 + VisionOSManualSigningProvisioningProfileType: 0 + appleEnableAutomaticSigning: 0 + iOSRequireARKit: 0 + iOSAutomaticallyDetectAndAddCapabilities: 1 + appleEnableProMotion: 0 + shaderPrecisionModel: 0 + clonedFromGUID: 00000000000000000000000000000000 + templatePackageId: + templateDefaultScene: + useCustomMainManifest: 0 + useCustomLauncherManifest: 0 + useCustomMainGradleTemplate: 0 + useCustomLauncherGradleManifest: 0 + useCustomBaseGradleTemplate: 0 + useCustomGradlePropertiesTemplate: 0 + useCustomGradleSettingsTemplate: 0 + useCustomProguardFile: 0 + AndroidTargetArchitectures: 2 + AndroidAllowedArchitectures: -1 + AndroidSplashScreenScale: 0 + androidSplashScreen: {fileID: 0} + AndroidKeystoreName: + AndroidKeyaliasName: + AndroidEnableArmv9SecurityFeatures: 0 + AndroidEnableArm64MTE: 0 + AndroidBuildApkPerCpuArchitecture: 0 + AndroidTVCompatibility: 0 + AndroidIsGame: 1 + androidAppCategory: 3 + useAndroidAppCategory: 1 + androidAppCategoryOther: + AndroidEnableTango: 0 + androidEnableBanner: 1 + androidUseLowAccuracyLocation: 0 + androidUseCustomKeystore: 0 + m_AndroidBanners: + - width: 320 + height: 180 + banner: {fileID: 0} + androidGamepadSupportLevel: 0 + AndroidMinifyRelease: 0 + AndroidMinifyDebug: 0 + AndroidValidateAppBundleSize: 1 + AndroidAppBundleSizeToValidate: 200 + AndroidReportGooglePlayAppDependencies: 1 + androidSymbolsSizeThreshold: 800 + m_BuildTargetIcons: [] + m_BuildTargetPlatformIcons: + - m_BuildTarget: iPhone + m_Icons: + - m_Textures: [] + m_Width: 180 + m_Height: 180 + m_Kind: 0 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 120 + m_Height: 120 + m_Kind: 0 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 167 + m_Height: 167 + m_Kind: 0 + m_SubKind: iPad + - m_Textures: [] + m_Width: 152 + m_Height: 152 + m_Kind: 0 + m_SubKind: iPad + - m_Textures: [] + m_Width: 76 + m_Height: 76 + m_Kind: 0 + m_SubKind: iPad + - m_Textures: [] + m_Width: 120 + m_Height: 120 + m_Kind: 3 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 80 + m_Height: 80 + m_Kind: 3 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 80 + m_Height: 80 + m_Kind: 3 + m_SubKind: iPad + - m_Textures: [] + m_Width: 40 + m_Height: 40 + m_Kind: 3 + m_SubKind: iPad + - m_Textures: [] + m_Width: 87 + m_Height: 87 + m_Kind: 1 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 58 + m_Height: 58 + m_Kind: 1 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 29 + m_Height: 29 + m_Kind: 1 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 58 + m_Height: 58 + m_Kind: 1 + m_SubKind: iPad + - m_Textures: [] + m_Width: 29 + m_Height: 29 + m_Kind: 1 + m_SubKind: iPad + - m_Textures: [] + m_Width: 60 + m_Height: 60 + m_Kind: 2 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 40 + m_Height: 40 + m_Kind: 2 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 40 + m_Height: 40 + m_Kind: 2 + m_SubKind: iPad + - m_Textures: [] + m_Width: 20 + m_Height: 20 + m_Kind: 2 + m_SubKind: iPad + - m_Textures: [] + m_Width: 1024 + m_Height: 1024 + m_Kind: 4 + m_SubKind: App Store + - m_BuildTarget: Android + m_Icons: + - m_Textures: [] + m_Width: 432 + m_Height: 432 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 324 + m_Height: 324 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 216 + m_Height: 216 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 162 + m_Height: 162 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 108 + m_Height: 108 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 81 + m_Height: 81 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 192 + m_Height: 192 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 144 + m_Height: 144 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 96 + m_Height: 96 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 72 + m_Height: 72 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 48 + m_Height: 48 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 36 + m_Height: 36 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 192 + m_Height: 192 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 144 + m_Height: 144 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 96 + m_Height: 96 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 72 + m_Height: 72 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 48 + m_Height: 48 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 36 + m_Height: 36 + m_Kind: 0 + m_SubKind: + - m_BuildTarget: VisionOS + m_Icons: + - m_Textures: [] + m_Width: 1024 + m_Height: 1024 + m_Kind: 0 + m_SubKind: + m_BuildTargetBatching: [] + m_BuildTargetShaderSettings: [] + m_BuildTargetGraphicsJobs: [] + m_BuildTargetGraphicsJobMode: [] + m_BuildTargetGraphicsAPIs: [] + m_BuildTargetVRSettings: [] + m_DefaultShaderChunkSizeInMB: 16 + m_DefaultShaderChunkCount: 0 + openGLRequireES31: 0 + openGLRequireES31AEP: 0 + openGLRequireES32: 0 + m_TemplateCustomTags: {} + mobileMTRendering: + Android: 1 + VisionOS: 1 + iPhone: 1 + tvOS: 1 + m_BuildTargetGroupLightmapEncodingQuality: [] + m_BuildTargetGroupHDRCubemapEncodingQuality: [] + m_BuildTargetGroupLightmapSettings: [] + m_BuildTargetGroupLoadStoreDebugModeSettings: [] + m_BuildTargetNormalMapEncoding: [] + m_BuildTargetDefaultTextureCompressionFormat: [] + playModeTestRunnerEnabled: 0 + runPlayModeTestAsEditModeTest: 0 + actionOnDotNetUnhandledException: 1 + editorGfxJobOverride: 1 + enableInternalProfiler: 0 + logObjCUncaughtExceptions: 1 + enableCrashReportAPI: 0 + cameraUsageDescription: + locationUsageDescription: + microphoneUsageDescription: + bluetoothUsageDescription: + macOSTargetOSVersion: 12.0 + switchNMETAOverride: + switchNetLibKey: + switchSocketMemoryPoolSize: 6144 + switchSocketAllocatorPoolSize: 128 + switchSocketConcurrencyLimit: 14 + switchScreenResolutionBehavior: 2 + switchUseCPUProfiler: 0 + switchEnableFileSystemTrace: 0 + switchLTOSetting: 0 + switchApplicationID: 0x01004b9000490000 + switchNSODependencies: + switchCompilerFlags: + switchTitleNames_0: + switchTitleNames_1: + switchTitleNames_2: + switchTitleNames_3: + switchTitleNames_4: + switchTitleNames_5: + switchTitleNames_6: + switchTitleNames_7: + switchTitleNames_8: + switchTitleNames_9: + switchTitleNames_10: + switchTitleNames_11: + switchTitleNames_12: + switchTitleNames_13: + switchTitleNames_14: + switchTitleNames_15: + switchPublisherNames_0: + switchPublisherNames_1: + switchPublisherNames_2: + switchPublisherNames_3: + switchPublisherNames_4: + switchPublisherNames_5: + switchPublisherNames_6: + switchPublisherNames_7: + switchPublisherNames_8: + switchPublisherNames_9: + switchPublisherNames_10: + switchPublisherNames_11: + switchPublisherNames_12: + switchPublisherNames_13: + switchPublisherNames_14: + switchPublisherNames_15: + switchIcons_0: {fileID: 0} + switchIcons_1: {fileID: 0} + switchIcons_2: {fileID: 0} + switchIcons_3: {fileID: 0} + switchIcons_4: {fileID: 0} + switchIcons_5: {fileID: 0} + switchIcons_6: {fileID: 0} + switchIcons_7: {fileID: 0} + switchIcons_8: {fileID: 0} + switchIcons_9: {fileID: 0} + switchIcons_10: {fileID: 0} + switchIcons_11: {fileID: 0} + switchIcons_12: {fileID: 0} + switchIcons_13: {fileID: 0} + switchIcons_14: {fileID: 0} + switchIcons_15: {fileID: 0} + switchSmallIcons_0: {fileID: 0} + switchSmallIcons_1: {fileID: 0} + switchSmallIcons_2: {fileID: 0} + switchSmallIcons_3: {fileID: 0} + switchSmallIcons_4: {fileID: 0} + switchSmallIcons_5: {fileID: 0} + switchSmallIcons_6: {fileID: 0} + switchSmallIcons_7: {fileID: 0} + switchSmallIcons_8: {fileID: 0} + switchSmallIcons_9: {fileID: 0} + switchSmallIcons_10: {fileID: 0} + switchSmallIcons_11: {fileID: 0} + switchSmallIcons_12: {fileID: 0} + switchSmallIcons_13: {fileID: 0} + switchSmallIcons_14: {fileID: 0} + switchSmallIcons_15: {fileID: 0} + switchManualHTML: + switchAccessibleURLs: + switchLegalInformation: + switchMainThreadStackSize: 1048576 + switchPresenceGroupId: + switchLogoHandling: 0 + switchReleaseVersion: 0 + switchDisplayVersion: 1.0.0 + switchStartupUserAccount: 0 + switchSupportedLanguagesMask: 0 + switchLogoType: 0 + switchApplicationErrorCodeCategory: + switchUserAccountSaveDataSize: 0 + switchUserAccountSaveDataJournalSize: 0 + switchApplicationAttribute: 0 + switchCardSpecSize: -1 + switchCardSpecClock: -1 + switchRatingsMask: 0 + switchRatingsInt_0: 0 + switchRatingsInt_1: 0 + switchRatingsInt_2: 0 + switchRatingsInt_3: 0 + switchRatingsInt_4: 0 + switchRatingsInt_5: 0 + switchRatingsInt_6: 0 + switchRatingsInt_7: 0 + switchRatingsInt_8: 0 + switchRatingsInt_9: 0 + switchRatingsInt_10: 0 + switchRatingsInt_11: 0 + switchRatingsInt_12: 0 + switchLocalCommunicationIds_0: + switchLocalCommunicationIds_1: + switchLocalCommunicationIds_2: + switchLocalCommunicationIds_3: + switchLocalCommunicationIds_4: + switchLocalCommunicationIds_5: + switchLocalCommunicationIds_6: + switchLocalCommunicationIds_7: + switchParentalControl: 0 + switchAllowsScreenshot: 1 + switchAllowsVideoCapturing: 1 + switchAllowsRuntimeAddOnContentInstall: 0 + switchDataLossConfirmation: 0 + switchUserAccountLockEnabled: 0 + switchSystemResourceMemory: 16777216 + switchSupportedNpadStyles: 22 + switchNativeFsCacheSize: 32 + switchIsHoldTypeHorizontal: 1 + switchSupportedNpadCount: 8 + switchEnableTouchScreen: 1 + switchSocketConfigEnabled: 0 + switchTcpInitialSendBufferSize: 32 + switchTcpInitialReceiveBufferSize: 64 + switchTcpAutoSendBufferSizeMax: 256 + switchTcpAutoReceiveBufferSizeMax: 256 + switchUdpSendBufferSize: 9 + switchUdpReceiveBufferSize: 42 + switchSocketBufferEfficiency: 4 + switchSocketInitializeEnabled: 1 + switchNetworkInterfaceManagerInitializeEnabled: 1 + switchDisableHTCSPlayerConnection: 0 + switchUseNewStyleFilepaths: 1 + switchUseLegacyFmodPriorities: 0 + switchUseMicroSleepForYield: 1 + switchEnableRamDiskSupport: 0 + switchMicroSleepForYieldTime: 25 + switchRamDiskSpaceSize: 12 + switchUpgradedPlayerSettingsToNMETA: 0 + ps4NPAgeRating: 12 + ps4NPTitleSecret: + ps4NPTrophyPackPath: + ps4ParentalLevel: 11 + ps4ContentID: ED1633-NPXX51362_00-0000000000000000 + ps4Category: 0 + ps4MasterVersion: 01.00 + ps4AppVersion: 01.00 + ps4AppType: 0 + ps4ParamSfxPath: + ps4VideoOutPixelFormat: 0 + ps4VideoOutInitialWidth: 1920 + ps4VideoOutBaseModeInitialWidth: 1920 + ps4VideoOutReprojectionRate: 60 + ps4PronunciationXMLPath: + ps4PronunciationSIGPath: + ps4BackgroundImagePath: + ps4StartupImagePath: + ps4StartupImagesFolder: + ps4IconImagesFolder: + ps4SaveDataImagePath: + ps4SdkOverride: + ps4BGMPath: + ps4ShareFilePath: + ps4ShareOverlayImagePath: + ps4PrivacyGuardImagePath: + ps4ExtraSceSysFile: + ps4NPtitleDatPath: + ps4RemotePlayKeyAssignment: -1 + ps4RemotePlayKeyMappingDir: + ps4PlayTogetherPlayerCount: 0 + ps4EnterButtonAssignment: 2 + ps4ApplicationParam1: 0 + ps4ApplicationParam2: 0 + ps4ApplicationParam3: 0 + ps4ApplicationParam4: 0 + ps4DownloadDataSize: 0 + ps4GarlicHeapSize: 2048 + ps4ProGarlicHeapSize: 2560 + playerPrefsMaxSize: 32768 + ps4Passcode: ECp4dfdfR9jy4dcWcL8JnVortaXumDPN + ps4pnSessions: 1 + ps4pnPresence: 1 + ps4pnFriends: 1 + ps4pnGameCustomData: 1 + playerPrefsSupport: 0 + enableApplicationExit: 0 + resetTempFolder: 1 + restrictedAudioUsageRights: 0 + ps4UseResolutionFallback: 0 + ps4ReprojectionSupport: 0 + ps4UseAudio3dBackend: 0 + ps4UseLowGarlicFragmentationMode: 1 + ps4SocialScreenEnabled: 0 + ps4ScriptOptimizationLevel: 2 + ps4Audio3dVirtualSpeakerCount: 14 + ps4attribCpuUsage: 0 + ps4PatchPkgPath: + ps4PatchLatestPkgPath: + ps4PatchChangeinfoPath: + ps4PatchDayOne: 0 + ps4attribUserManagement: 0 + ps4attribMoveSupport: 0 + ps4attrib3DSupport: 0 + ps4attribShareSupport: 0 + ps4attribExclusiveVR: 0 + ps4disableAutoHideSplash: 0 + ps4videoRecordingFeaturesUsed: 0 + ps4contentSearchFeaturesUsed: 0 + ps4CompatibilityPS5: 0 + ps4AllowPS5Detection: 0 + ps4GPU800MHz: 1 + ps4attribEyeToEyeDistanceSettingVR: 0 + ps4IncludedModules: [] + ps4attribVROutputEnabled: 0 + monoEnv: + splashScreenBackgroundSourceLandscape: {fileID: 0} + splashScreenBackgroundSourcePortrait: {fileID: 0} + blurSplashScreenBackground: 1 + spritePackerPolicy: + webGLMemorySize: 32 + webGLExceptionSupport: 1 + webGLNameFilesAsHashes: 0 + webGLShowDiagnostics: 0 + webGLDataCaching: 1 + webGLDebugSymbols: 0 + webGLEmscriptenArgs: + webGLModulesDirectory: + webGLTemplate: APPLICATION:Default + webGLAnalyzeBuildSize: 0 + webGLUseEmbeddedResources: 0 + webGLCompressionFormat: 1 + webGLWasmArithmeticExceptions: 0 + webGLLinkerTarget: 1 + webGLThreadsSupport: 0 + webGLDecompressionFallback: 0 + webGLInitialMemorySize: 32 + webGLMaximumMemorySize: 2048 + webGLMemoryGrowthMode: 2 + webGLMemoryLinearGrowthStep: 16 + webGLMemoryGeometricGrowthStep: 0.2 + webGLMemoryGeometricGrowthCap: 96 + webGLPowerPreference: 2 + webGLWebAssemblyTable: 0 + webGLWebAssemblyBigInt: 0 + webGLCloseOnQuit: 0 + webWasm2023: 0 + webEnableSubmoduleStrippingCompatibility: 0 + scriptingDefineSymbols: {} + additionalCompilerArguments: {} + platformArchitecture: {} + scriptingBackend: {} + il2cppCompilerConfiguration: {} + il2cppCodeGeneration: {} + il2cppStacktraceInformation: {} + managedStrippingLevel: {} + incrementalIl2cppBuild: {} + suppressCommonWarnings: 1 + allowUnsafeCode: 0 + useDeterministicCompilation: 1 + additionalIl2CppArgs: + scriptingRuntimeVersion: 1 + gcIncremental: 1 + gcWBarrierValidation: 0 + apiCompatibilityLevelPerPlatform: {} + editorAssembliesCompatibilityLevel: 1 + m_RenderingPath: 1 + m_MobileRenderingPath: 1 + metroPackageName: First-Principles + metroPackageVersion: + metroCertificatePath: + metroCertificatePassword: + metroCertificateSubject: + metroCertificateIssuer: + metroCertificateNotAfter: 0000000000000000 + metroApplicationDescription: First-Principles + wsaImages: {} + metroTileShortName: + metroTileShowName: 0 + metroMediumTileShowName: 0 + metroLargeTileShowName: 0 + metroWideTileShowName: 0 + metroSupportStreamingInstall: 0 + metroLastRequiredScene: 0 + metroDefaultTileSize: 1 + metroTileForegroundText: 2 + metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} + metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, a: 1} + metroSplashScreenUseBackgroundColor: 0 + syncCapabilities: 0 + platformCapabilities: {} + metroTargetDeviceFamilies: {} + metroFTAName: + metroFTAFileTypes: [] + metroProtocolName: + vcxProjDefaultLanguage: + XboxOneProductId: + XboxOneUpdateKey: + XboxOneSandboxId: + XboxOneContentId: + XboxOneTitleId: + XboxOneSCId: + XboxOneGameOsOverridePath: + XboxOnePackagingOverridePath: + XboxOneAppManifestOverridePath: + XboxOneVersion: 1.0.0.0 + XboxOnePackageEncryption: 0 + XboxOnePackageUpdateGranularity: 2 + XboxOneDescription: + XboxOneLanguage: + - enus + XboxOneCapability: [] + XboxOneGameRating: {} + XboxOneIsContentPackage: 0 + XboxOneEnhancedXboxCompatibilityMode: 0 + XboxOneEnableGPUVariability: 1 + XboxOneSockets: {} + XboxOneSplashScreen: {fileID: 0} + XboxOneAllowedProductIds: [] + XboxOnePersistentLocalStorageSize: 0 + XboxOneXTitleMemory: 8 + XboxOneOverrideIdentityName: + XboxOneOverrideIdentityPublisher: + vrEditorSettings: {} + cloudServicesEnabled: {} + luminIcon: + m_Name: + m_ModelFolderPath: + m_PortalFolderPath: + luminCert: + m_CertPath: + m_SignPackage: 1 + luminIsChannelApp: 0 + luminVersion: + m_VersionCode: 1 + m_VersionName: + hmiPlayerDataPath: + hmiForceSRGBBlit: 0 + embeddedLinuxEnableGamepadInput: 0 + hmiCpuConfiguration: + hmiLogStartupTiming: 0 + qnxGraphicConfPath: + apiCompatibilityLevel: 6 + captureStartupLogs: {} + activeInputHandler: 0 + windowsGamepadBackendHint: 0 + cloudProjectId: + framebufferDepthMemorylessMode: 0 + qualitySettingsNames: [] + projectName: + organizationId: + cloudEnabled: 0 + legacyClampBlendShapeWeights: 0 + hmiLoadingImage: {fileID: 0} + platformRequiresReadableAssets: 0 + virtualTexturingSupportEnabled: 0 + insecureHttpOption: 0 + androidVulkanDenyFilterList: [] + androidVulkanAllowFilterList: [] + androidVulkanDeviceFilterListAsset: {fileID: 0} + d3d12DeviceFilterListAsset: {fileID: 0} + allowedHttpConnections: 3 diff --git a/ProjectSettings/ProjectVersion.txt b/ProjectSettings/ProjectVersion.txt new file mode 100644 index 0000000..8a87982 --- /dev/null +++ b/ProjectSettings/ProjectVersion.txt @@ -0,0 +1,2 @@ +m_EditorVersion: 6000.4.0f1 +m_EditorVersionWithRevision: 6000.4.0f1 (8cf496087c8f) diff --git a/ProjectSettings/QualitySettings.asset b/ProjectSettings/QualitySettings.asset new file mode 100644 index 0000000..64f8aba --- /dev/null +++ b/ProjectSettings/QualitySettings.asset @@ -0,0 +1,347 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!47 &1 +QualitySettings: + m_ObjectHideFlags: 0 + serializedVersion: 5 + m_CurrentQuality: 5 + m_QualitySettings: + - serializedVersion: 5 + name: Very Low + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 15 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + skinWeights: 1 + globalTextureMipmapLimit: 1 + textureMipmapLimitSettings: [] + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + useLegacyDetailDistribution: 0 + adaptiveVsync: 0 + vSyncCount: 0 + realtimeGICPUUsage: 25 + adaptiveVsyncExtraA: 0 + adaptiveVsyncExtraB: 0 + lodBias: 0.3 + meshLodThreshold: 1 + maximumLODLevel: 0 + enableLODCrossFade: 1 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 4 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + customRenderPipeline: {fileID: 0} + terrainQualityOverrides: 0 + terrainPixelError: 1 + terrainDetailDensityScale: 1 + terrainBasemapDistance: 1000 + terrainDetailDistance: 80 + terrainTreeDistance: 5000 + terrainBillboardStart: 50 + terrainFadeLength: 5 + terrainMaxTrees: 50 + excludedTargetPlatforms: [] + - serializedVersion: 5 + name: Low + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + skinWeights: 2 + globalTextureMipmapLimit: 0 + textureMipmapLimitSettings: [] + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + useLegacyDetailDistribution: 0 + adaptiveVsync: 0 + vSyncCount: 0 + realtimeGICPUUsage: 25 + adaptiveVsyncExtraA: 0 + adaptiveVsyncExtraB: 0 + lodBias: 0.4 + meshLodThreshold: 1 + maximumLODLevel: 0 + enableLODCrossFade: 1 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 16 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + customRenderPipeline: {fileID: 0} + terrainQualityOverrides: 0 + terrainPixelError: 1 + terrainDetailDensityScale: 1 + terrainBasemapDistance: 1000 + terrainDetailDistance: 80 + terrainTreeDistance: 5000 + terrainBillboardStart: 50 + terrainFadeLength: 5 + terrainMaxTrees: 50 + excludedTargetPlatforms: [] + - serializedVersion: 5 + name: Medium + pixelLightCount: 1 + shadows: 1 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + skinWeights: 2 + globalTextureMipmapLimit: 0 + textureMipmapLimitSettings: [] + anisotropicTextures: 1 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + useLegacyDetailDistribution: 0 + adaptiveVsync: 0 + vSyncCount: 1 + realtimeGICPUUsage: 25 + adaptiveVsyncExtraA: 0 + adaptiveVsyncExtraB: 0 + lodBias: 0.7 + meshLodThreshold: 1 + maximumLODLevel: 0 + enableLODCrossFade: 1 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 64 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + customRenderPipeline: {fileID: 0} + terrainQualityOverrides: 0 + terrainPixelError: 1 + terrainDetailDensityScale: 1 + terrainBasemapDistance: 1000 + terrainDetailDistance: 80 + terrainTreeDistance: 5000 + terrainBillboardStart: 50 + terrainFadeLength: 5 + terrainMaxTrees: 50 + excludedTargetPlatforms: [] + - serializedVersion: 5 + name: High + pixelLightCount: 2 + shadows: 2 + shadowResolution: 1 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 40 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + skinWeights: 2 + globalTextureMipmapLimit: 0 + textureMipmapLimitSettings: [] + anisotropicTextures: 1 + antiAliasing: 0 + softParticles: 0 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + useLegacyDetailDistribution: 0 + adaptiveVsync: 0 + vSyncCount: 1 + realtimeGICPUUsage: 50 + adaptiveVsyncExtraA: 0 + adaptiveVsyncExtraB: 0 + lodBias: 1 + meshLodThreshold: 1 + maximumLODLevel: 0 + enableLODCrossFade: 1 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 256 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + customRenderPipeline: {fileID: 0} + terrainQualityOverrides: 0 + terrainPixelError: 1 + terrainDetailDensityScale: 1 + terrainBasemapDistance: 1000 + terrainDetailDistance: 80 + terrainTreeDistance: 5000 + terrainBillboardStart: 50 + terrainFadeLength: 5 + terrainMaxTrees: 50 + excludedTargetPlatforms: [] + - serializedVersion: 5 + name: Very High + pixelLightCount: 3 + shadows: 2 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 70 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + skinWeights: 4 + globalTextureMipmapLimit: 0 + textureMipmapLimitSettings: [] + anisotropicTextures: 2 + antiAliasing: 2 + softParticles: 1 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + useLegacyDetailDistribution: 0 + adaptiveVsync: 0 + vSyncCount: 1 + realtimeGICPUUsage: 50 + adaptiveVsyncExtraA: 0 + adaptiveVsyncExtraB: 0 + lodBias: 1.5 + meshLodThreshold: 1 + maximumLODLevel: 0 + enableLODCrossFade: 1 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 1024 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + customRenderPipeline: {fileID: 0} + terrainQualityOverrides: 0 + terrainPixelError: 1 + terrainDetailDensityScale: 1 + terrainBasemapDistance: 1000 + terrainDetailDistance: 80 + terrainTreeDistance: 5000 + terrainBillboardStart: 50 + terrainFadeLength: 5 + terrainMaxTrees: 50 + excludedTargetPlatforms: [] + - serializedVersion: 5 + name: Ultra + pixelLightCount: 4 + shadows: 2 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 4 + shadowDistance: 150 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + skinWeights: 255 + globalTextureMipmapLimit: 0 + textureMipmapLimitSettings: [] + anisotropicTextures: 2 + antiAliasing: 2 + softParticles: 1 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + useLegacyDetailDistribution: 0 + adaptiveVsync: 0 + vSyncCount: 1 + realtimeGICPUUsage: 100 + adaptiveVsyncExtraA: 0 + adaptiveVsyncExtraB: 0 + lodBias: 2 + meshLodThreshold: 1 + maximumLODLevel: 0 + enableLODCrossFade: 1 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 4096 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + customRenderPipeline: {fileID: 0} + terrainQualityOverrides: 0 + terrainPixelError: 1 + terrainDetailDensityScale: 1 + terrainBasemapDistance: 1000 + terrainDetailDistance: 80 + terrainTreeDistance: 5000 + terrainBillboardStart: 50 + terrainFadeLength: 5 + terrainMaxTrees: 50 + excludedTargetPlatforms: [] + m_TextureMipmapLimitGroupNames: [] + m_PerPlatformDefaultQuality: + Android: 2 + EmbeddedLinux: 5 + GameCoreScarlett: 5 + GameCoreXboxOne: 5 + Kepler: 5 + LinuxHeadlessSimulation: 5 + Nintendo Switch: 5 + Nintendo Switch 2: 5 + PS4: 5 + PS5: 5 + QNX: 5 + Server: 5 + Standalone: 5 + VisionOS: 5 + WebGL: 3 + Windows Store Apps: 5 + XboxOne: 5 + iPhone: 2 + tvOS: 2 diff --git a/ProjectSettings/TagManager.asset b/ProjectSettings/TagManager.asset new file mode 100644 index 0000000..6abf33d --- /dev/null +++ b/ProjectSettings/TagManager.asset @@ -0,0 +1,46 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!78 &1 +TagManager: + serializedVersion: 3 + tags: [] + layers: + - Default + - TransparentFX + - Ignore Raycast + - + - Water + - UI + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + m_SortingLayers: + - name: Default + uniqueID: 0 + locked: 0 + m_RenderingLayers: + - Default + m_MigratedRenderPipelines: [] diff --git a/ProjectSettings/TimeManager.asset b/ProjectSettings/TimeManager.asset new file mode 100644 index 0000000..2e23a1f --- /dev/null +++ b/ProjectSettings/TimeManager.asset @@ -0,0 +1,14 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!5 &1 +TimeManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + Fixed Timestep: + m_Count: 2822399 + m_Rate: + m_Denominator: 1 + m_Numerator: 141120000 + Maximum Allowed Timestep: 0.33333334 + m_TimeScale: 1 + Maximum Particle Timestep: 0.03 diff --git a/ProjectSettings/UnityConnectSettings.asset b/ProjectSettings/UnityConnectSettings.asset new file mode 100644 index 0000000..5ef5698 --- /dev/null +++ b/ProjectSettings/UnityConnectSettings.asset @@ -0,0 +1,40 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!310 &1 +UnityConnectSettings: + m_ObjectHideFlags: 0 + serializedVersion: 1 + m_Enabled: 0 + m_TestMode: 0 + m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events + m_EventUrl: https://cdp.cloud.unity3d.com/v1/events + m_ConfigUrl: https://config.uca.cloud.unity3d.com + m_DashboardUrl: https://dashboard.unity3d.com + m_TestInitMode: 0 + InsightsSettings: + m_EngineDiagnosticsEnabled: 0 + m_Enabled: 0 + CrashReportingSettings: + serializedVersion: 2 + m_EventUrl: https://perf-events.cloud.unity3d.com + m_EnableCloudDiagnosticsReporting: 0 + m_LogBufferSize: 10 + m_CaptureEditorExceptions: 1 + UnityPurchasingSettings: + m_Enabled: 0 + m_TestMode: 0 + UnityAnalyticsSettings: + m_Enabled: 0 + m_TestMode: 0 + m_InitializeOnStartup: 1 + m_PackageRequiringCoreStatsPresent: 0 + UnityAdsSettings: + m_Enabled: 0 + m_InitializeOnStartup: 1 + m_TestMode: 0 + m_IosGameId: + m_AndroidGameId: + m_GameIds: {} + m_GameId: + PerformanceReportingSettings: + m_Enabled: 0 diff --git a/ProjectSettings/VFXManager.asset b/ProjectSettings/VFXManager.asset new file mode 100644 index 0000000..56783bb --- /dev/null +++ b/ProjectSettings/VFXManager.asset @@ -0,0 +1,20 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!937362698 &1 +VFXManager: + m_ObjectHideFlags: 0 + m_IndirectShader: {fileID: 0} + m_CopyBufferShader: {fileID: 0} + m_PrefixSumShader: {fileID: 0} + m_SortShader: {fileID: 0} + m_StripUpdateShader: {fileID: 0} + m_EmptyShader: {fileID: 0} + m_RenderPipeSettingsPath: + m_FixedTimeStep: 0.016666668 + m_MaxDeltaTime: 0.05 + m_MaxScrubTime: 30 + m_MaxCapacity: 100000000 + m_CompiledVersion: 0 + m_RuntimeVersion: 0 + m_RuntimeResources: {fileID: 0} + m_BatchEmptyLifetime: 300 diff --git a/ProjectSettings/VersionControlSettings.asset b/ProjectSettings/VersionControlSettings.asset new file mode 100644 index 0000000..979fd8e --- /dev/null +++ b/ProjectSettings/VersionControlSettings.asset @@ -0,0 +1,7 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!890905787 &1 +VersionControlSettings: + m_ObjectHideFlags: 0 + m_Mode: Visible Meta Files + m_TrackPackagesOutsideProject: 0