From 2f0acaef34b65cc0129fe34e71f567fc4203108a Mon Sep 17 00:00:00 2001 From: okenic03-code Date: Fri, 13 Feb 2026 03:28:14 +0900 Subject: [PATCH 001/115] feat(core): add trace model and extend board state with wire support Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- .../10_Runtime/10_Core/Board/BoardState.cs | 112 ++++++++++++++++++ .../10_Runtime/10_Core/Board/TraceSegment.cs | 50 ++++++++ .../10_Core/Board/TraceSegment.cs.meta | 11 ++ 3 files changed, 173 insertions(+) create mode 100644 Assets/10_Scripts/10_Runtime/10_Core/Board/TraceSegment.cs create mode 100644 Assets/10_Scripts/10_Runtime/10_Core/Board/TraceSegment.cs.meta diff --git a/Assets/10_Scripts/10_Runtime/10_Core/Board/BoardState.cs b/Assets/10_Scripts/10_Runtime/10_Core/Board/BoardState.cs index ca762cd..37900dd 100644 --- a/Assets/10_Scripts/10_Runtime/10_Core/Board/BoardState.cs +++ b/Assets/10_Scripts/10_Runtime/10_Core/Board/BoardState.cs @@ -13,9 +13,12 @@ public class BoardState private readonly List _components = new List(); private readonly Dictionary _componentsByPosition = new Dictionary(); private readonly List _nets = new List(); + private readonly List _traces = new List(); private readonly IReadOnlyList _readOnlyComponents; + private readonly IReadOnlyList _readOnlyTraces; private int _nextComponentId = 1; private int _nextNetId = 1; + private int _nextTraceId = 1; /// Gets the board boundaries. public BoardBounds Bounds { get; } @@ -26,6 +29,9 @@ public class BoardState /// Gets the read-only list of nets. public IReadOnlyList Nets => _nets.AsReadOnly(); + /// Gets the read-only list of traces. + public IReadOnlyList Traces => _readOnlyTraces; + /// Event raised when a component is placed on the board. public event Action OnComponentPlaced; @@ -38,6 +44,12 @@ public class BoardState /// Event raised when two pins are connected via a net. public event Action OnPinsConnected; + /// Event raised when a trace is added to the board. + public event Action OnTraceAdded; + + /// Event raised when a trace is removed from the board. + public event Action OnTraceRemoved; + /// /// Creates a new board state. /// @@ -47,6 +59,7 @@ public BoardState(int width, int height) { Bounds = new BoardBounds(width, height); _readOnlyComponents = _components.AsReadOnly(); + _readOnlyTraces = _traces.AsReadOnly(); } /// @@ -86,6 +99,12 @@ public bool RemoveComponent(int instanceId) if (component == null) return false; + var removedPinPositions = new HashSet(); + foreach (var pin in component.Pins) + { + removedPinPositions.Add(component.GetPinWorldPosition(pin.PinIndex)); + } + // Remove component's pins from all nets var netsToCheck = new List(); foreach (var net in _nets) @@ -114,12 +133,92 @@ public bool RemoveComponent(int instanceId) } } + // Remove any traces that start or end on removed component pins. + for (int i = _traces.Count - 1; i >= 0; i--) + { + var trace = _traces[i]; + if (removedPinPositions.Contains(trace.Start) || removedPinPositions.Contains(trace.End)) + { + RemoveTrace(trace.SegmentId); + } + } + _components.Remove(component); _componentsByPosition.Remove(component.Position); OnComponentRemoved?.Invoke(instanceId); return true; } + /// + /// Adds a trace segment to an existing net. + /// + /// Target net ID. + /// Trace start position. + /// Trace end position. + /// The created trace segment. + public TraceSegment AddTrace(int netId, GridPosition start, GridPosition end) + { + var net = GetNet(netId); + if (net == null) + throw new ArgumentException($"Net {netId} not found.", nameof(netId)); + if (!Bounds.Contains(start) || !Bounds.Contains(end)) + throw new ArgumentException("Trace endpoints must be within board bounds."); + + var trace = new TraceSegment(_nextTraceId++, netId, start, end); + _traces.Add(trace); + OnTraceAdded?.Invoke(trace); + return trace; + } + + /// + /// Removes a trace segment by ID. + /// + /// Trace segment ID. + /// True when removed. + public bool RemoveTrace(int segmentId) + { + var trace = _traces.FirstOrDefault(t => t.SegmentId == segmentId); + if (trace == null) + return false; + + _traces.Remove(trace); + OnTraceRemoved?.Invoke(segmentId); + + // If the net has no remaining traces, clear pin links and remove it. + if (!_traces.Any(t => t.NetId == trace.NetId)) + { + var net = GetNet(trace.NetId); + if (net != null) + { + foreach (var pin in net.ConnectedPins.ToList()) + { + var component = GetComponent(pin.ComponentInstanceId); + var pinInstance = component?.Pins.FirstOrDefault(p => p.PinIndex == pin.PinIndex); + if (pinInstance != null && pinInstance.ConnectedNetId == net.NetId) + { + pinInstance.ConnectedNetId = null; + } + + net.RemovePin(pin); + } + + _nets.Remove(net); + } + } + + return true; + } + + /// + /// Gets all trace segments that belong to the specified net. + /// + /// Net ID. + /// Matching trace segments. + public IReadOnlyList GetTraces(int netId) + { + return _traces.Where(t => t.NetId == netId).ToList(); + } + /// /// Creates a new net. /// @@ -155,6 +254,19 @@ public void ConnectPinToNet(int netId, PinReference pin) if (pinInstance == null) throw new ArgumentException($"Pin {pin.PinIndex} not found on component {pin.ComponentInstanceId}."); + if (pinInstance.ConnectedNetId.HasValue && pinInstance.ConnectedNetId.Value != netId) + { + var previousNet = GetNet(pinInstance.ConnectedNetId.Value); + if (previousNet != null) + { + previousNet.RemovePin(pin); + if (previousNet.ConnectedPins.Count == 0) + { + _nets.Remove(previousNet); + } + } + } + pinInstance.ConnectedNetId = netId; net.AddPin(pin); diff --git a/Assets/10_Scripts/10_Runtime/10_Core/Board/TraceSegment.cs b/Assets/10_Scripts/10_Runtime/10_Core/Board/TraceSegment.cs new file mode 100644 index 0000000..142682b --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/10_Core/Board/TraceSegment.cs @@ -0,0 +1,50 @@ +using System; + +namespace CircuitCraft.Core +{ + /// + /// Represents a routed board trace segment between two orthogonal grid points. + /// + public class TraceSegment + { + /// Gets the unique segment identifier. + public int SegmentId { get; } + + /// Gets the net this trace segment belongs to. + public int NetId { get; } + + /// Gets the segment start position. + public GridPosition Start { get; } + + /// Gets the segment end position. + public GridPosition End { get; } + + /// + /// Creates a new orthogonal trace segment. + /// + public TraceSegment(int segmentId, int netId, GridPosition start, GridPosition end) + { + if (segmentId <= 0) + throw new ArgumentOutOfRangeException(nameof(segmentId), "Segment ID must be positive."); + if (netId <= 0) + throw new ArgumentOutOfRangeException(nameof(netId), "Net ID must be positive."); + if (start == end) + throw new ArgumentException("Trace segment start and end cannot be the same point."); + if (start.X != end.X && start.Y != end.Y) + throw new ArgumentException("Trace segment must be Manhattan (horizontal or vertical).", nameof(end)); + + SegmentId = segmentId; + NetId = netId; + Start = start; + End = end; + } + + /// + /// Returns a string representation of this trace segment. + /// + public override string ToString() + { + return $"Trace[{SegmentId}] Net{NetId}: {Start} -> {End}"; + } + } +} diff --git a/Assets/10_Scripts/10_Runtime/10_Core/Board/TraceSegment.cs.meta b/Assets/10_Scripts/10_Runtime/10_Core/Board/TraceSegment.cs.meta new file mode 100644 index 0000000..b9dd6cc --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/10_Core/Board/TraceSegment.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6ec2ea0ac29005848809e37ab5859115 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 4592e562e24fb830e0a2b8b9f49ba212d3642b14 Mon Sep 17 00:00:00 2001 From: okenic03-code Date: Fri, 13 Feb 2026 03:28:32 +0900 Subject: [PATCH 002/115] feat(core): add DRC validation and scoring/objective system Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- .../10_Runtime/10_Core/Scoring.meta | 8 + .../10_Core/Scoring/EvaluationResult.cs | 98 ++++++++++ .../10_Core/Scoring/EvaluationResult.cs.meta | 11 ++ .../10_Core/Scoring/ObjectiveEvaluator.cs | 107 +++++++++++ .../Scoring/ObjectiveEvaluator.cs.meta | 11 ++ .../10_Core/Scoring/ScoreBreakdown.cs | 117 ++++++++++++ .../10_Core/Scoring/ScoreBreakdown.cs.meta | 11 ++ .../10_Core/Scoring/ScoringSystem.cs | 169 ++++++++++++++++++ .../10_Core/Scoring/ScoringSystem.cs.meta | 11 ++ .../10_Runtime/10_Core/Validation.meta | 8 + .../10_Core/Validation/DRCChecker.cs | 128 +++++++++++++ .../10_Core/Validation/DRCChecker.cs.meta | 11 ++ .../10_Core/Validation/DRCResult.cs | 94 ++++++++++ .../10_Core/Validation/DRCResult.cs.meta | 11 ++ 14 files changed, 795 insertions(+) create mode 100644 Assets/10_Scripts/10_Runtime/10_Core/Scoring.meta create mode 100644 Assets/10_Scripts/10_Runtime/10_Core/Scoring/EvaluationResult.cs create mode 100644 Assets/10_Scripts/10_Runtime/10_Core/Scoring/EvaluationResult.cs.meta create mode 100644 Assets/10_Scripts/10_Runtime/10_Core/Scoring/ObjectiveEvaluator.cs create mode 100644 Assets/10_Scripts/10_Runtime/10_Core/Scoring/ObjectiveEvaluator.cs.meta create mode 100644 Assets/10_Scripts/10_Runtime/10_Core/Scoring/ScoreBreakdown.cs create mode 100644 Assets/10_Scripts/10_Runtime/10_Core/Scoring/ScoreBreakdown.cs.meta create mode 100644 Assets/10_Scripts/10_Runtime/10_Core/Scoring/ScoringSystem.cs create mode 100644 Assets/10_Scripts/10_Runtime/10_Core/Scoring/ScoringSystem.cs.meta create mode 100644 Assets/10_Scripts/10_Runtime/10_Core/Validation.meta create mode 100644 Assets/10_Scripts/10_Runtime/10_Core/Validation/DRCChecker.cs create mode 100644 Assets/10_Scripts/10_Runtime/10_Core/Validation/DRCChecker.cs.meta create mode 100644 Assets/10_Scripts/10_Runtime/10_Core/Validation/DRCResult.cs create mode 100644 Assets/10_Scripts/10_Runtime/10_Core/Validation/DRCResult.cs.meta diff --git a/Assets/10_Scripts/10_Runtime/10_Core/Scoring.meta b/Assets/10_Scripts/10_Runtime/10_Core/Scoring.meta new file mode 100644 index 0000000..9103370 --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/10_Core/Scoring.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7bfd09495d79a4645943f8397a7ca8b5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/10_Scripts/10_Runtime/10_Core/Scoring/EvaluationResult.cs b/Assets/10_Scripts/10_Runtime/10_Core/Scoring/EvaluationResult.cs new file mode 100644 index 0000000..b72c4f5 --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/10_Core/Scoring/EvaluationResult.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace CircuitCraft.Core +{ + /// + /// Pure C# DTO that mirrors the data needed from StageTestCase + /// so the evaluator stays Unity-free. The Unity caller converts + /// StageTestCase[] to TestCaseInput[]. + /// + public readonly struct TestCaseInput + { + /// Node name used in SimulationResult.GetVoltage(). + public string TestName { get; } + + /// Expected voltage value. + public double ExpectedVoltage { get; } + + /// Allowable error margin. + public double Tolerance { get; } + + public TestCaseInput(string testName, double expectedVoltage, double tolerance) + { + TestName = testName ?? throw new ArgumentNullException(nameof(testName)); + ExpectedVoltage = expectedVoltage; + Tolerance = tolerance; + } + } + + /// + /// Result of evaluating a single test case against simulation output. + /// + public class TestCaseResult + { + /// Name of the test case / node. + public string TestName { get; } + + /// Expected voltage value from the test case. + public double ExpectedValue { get; } + + /// Actual voltage value from the simulation. + public double ActualValue { get; } + + /// Allowable error margin. + public double Tolerance { get; } + + /// Whether this individual test case passed. + public bool Passed { get; } + + /// Human-readable message describing the result. + public string Message { get; } + + public TestCaseResult(string testName, double expectedValue, double actualValue, double tolerance, bool passed, string message) + { + TestName = testName; + ExpectedValue = expectedValue; + ActualValue = actualValue; + Tolerance = tolerance; + Passed = passed; + Message = message; + } + } + + /// + /// Aggregated result of evaluating all test cases against a simulation result. + /// + public class EvaluationResult + { + /// True only if ALL test cases passed. + public bool Passed { get; } + + /// Individual results per test case. + public List Results { get; } + + /// Human-readable summary of the evaluation. + public string Summary { get; } + + public EvaluationResult(bool passed, List results, string summary) + { + Passed = passed; + Results = results ?? new List(); + Summary = summary ?? string.Empty; + } + + /// + /// Creates a failed evaluation result for when the simulation itself failed. + /// + public static EvaluationResult SimulationFailed(string reason) + { + return new EvaluationResult( + false, + new List(), + $"Evaluation failed: simulation did not succeed. {reason}" + ); + } + } +} diff --git a/Assets/10_Scripts/10_Runtime/10_Core/Scoring/EvaluationResult.cs.meta b/Assets/10_Scripts/10_Runtime/10_Core/Scoring/EvaluationResult.cs.meta new file mode 100644 index 0000000..57b7cef --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/10_Core/Scoring/EvaluationResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 521fb7cad4d47924399234986d88ebc1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/10_Scripts/10_Runtime/10_Core/Scoring/ObjectiveEvaluator.cs b/Assets/10_Scripts/10_Runtime/10_Core/Scoring/ObjectiveEvaluator.cs new file mode 100644 index 0000000..b7da355 --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/10_Core/Scoring/ObjectiveEvaluator.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using System.Text; +using CircuitCraft.Simulation; + +namespace CircuitCraft.Core +{ + /// + /// Evaluates simulation results against test case expectations. + /// Pure C# — no Unity dependencies. Lives in the Domain layer. + /// + public class ObjectiveEvaluator + { + /// + /// Evaluates a simulation result against a set of test case inputs. + /// + /// The simulation result to evaluate. + /// Test case inputs (converted from StageTestCase by the caller). + /// An EvaluationResult with pass/fail and per-test details. + public EvaluationResult Evaluate(SimulationResult simResult, TestCaseInput[] testCases) + { + if (simResult == null) + throw new ArgumentNullException(nameof(simResult)); + if (testCases == null) + throw new ArgumentNullException(nameof(testCases)); + + // If simulation itself failed, auto-fail the evaluation + if (!simResult.IsSuccess) + { + return EvaluationResult.SimulationFailed( + simResult.StatusMessage ?? "Unknown simulation failure" + ); + } + + var results = new List(testCases.Length); + bool allPassed = true; + + foreach (var testCase in testCases) + { + var result = EvaluateTestCase(simResult, testCase); + results.Add(result); + + if (!result.Passed) + allPassed = false; + } + + string summary = BuildSummary(allPassed, results); + return new EvaluationResult(allPassed, results, summary); + } + + private TestCaseResult EvaluateTestCase(SimulationResult simResult, TestCaseInput testCase) + { + double? actualVoltage = simResult.GetVoltage(testCase.TestName); + + if (!actualVoltage.HasValue) + { + return new TestCaseResult( + testCase.TestName, + testCase.ExpectedVoltage, + double.NaN, + testCase.Tolerance, + false, + $"No voltage reading found for node '{testCase.TestName}'" + ); + } + + double actual = actualVoltage.Value; + double difference = Math.Abs(actual - testCase.ExpectedVoltage); + bool passed = difference <= testCase.Tolerance; + + string message = passed + ? $"PASS: '{testCase.TestName}' = {actual:F4}V (expected {testCase.ExpectedVoltage:F4}V ±{testCase.Tolerance:F4}V)" + : $"FAIL: '{testCase.TestName}' = {actual:F4}V (expected {testCase.ExpectedVoltage:F4}V ±{testCase.Tolerance:F4}V, off by {difference:F4}V)"; + + return new TestCaseResult( + testCase.TestName, + testCase.ExpectedVoltage, + actual, + testCase.Tolerance, + passed, + message + ); + } + + private static string BuildSummary(bool allPassed, List results) + { + int passCount = 0; + foreach (var r in results) + { + if (r.Passed) passCount++; + } + + var sb = new StringBuilder(); + sb.Append(allPassed ? "PASSED" : "FAILED"); + sb.Append($" ({passCount}/{results.Count} test cases)"); + + foreach (var r in results) + { + sb.AppendLine(); + sb.Append(" "); + sb.Append(r.Message); + } + + return sb.ToString(); + } + } +} diff --git a/Assets/10_Scripts/10_Runtime/10_Core/Scoring/ObjectiveEvaluator.cs.meta b/Assets/10_Scripts/10_Runtime/10_Core/Scoring/ObjectiveEvaluator.cs.meta new file mode 100644 index 0000000..3e186a6 --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/10_Core/Scoring/ObjectiveEvaluator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: adf29c854a897cf45b28ef5907358cee +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/10_Scripts/10_Runtime/10_Core/Scoring/ScoreBreakdown.cs b/Assets/10_Scripts/10_Runtime/10_Core/Scoring/ScoreBreakdown.cs new file mode 100644 index 0000000..b3f6ce1 --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/10_Core/Scoring/ScoreBreakdown.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; + +namespace CircuitCraft.Core +{ + /// + /// Pure C# DTO carrying all inputs needed for score calculation. + /// The Unity caller constructs this from StageDefinition + BoardState data. + /// + public readonly struct ScoringInput + { + /// Whether the circuit passed all test cases. + public bool CircuitPassed { get; } + + /// Sum of BaseCost for every placed component. + public float TotalComponentCost { get; } + + /// Budget limit from StageDefinition. 0 = no limit (auto-pass). + public float BudgetLimit { get; } + + /// Number of components placed on the board. + public int ComponentCount { get; } + + /// Max component count from StageConstraints. 0 = no limit (auto-pass). + public int MaxComponentCount { get; } + + /// Number of traces (wires) on the board. + public int TraceCount { get; } + + public ScoringInput( + bool circuitPassed, + float totalComponentCost, + float budgetLimit, + int componentCount, + int maxComponentCount, + int traceCount) + { + CircuitPassed = circuitPassed; + TotalComponentCost = totalComponentCost; + BudgetLimit = budgetLimit; + ComponentCount = componentCount; + MaxComponentCount = maxComponentCount; + TraceCount = traceCount; + } + } + + /// + /// A single line in the score breakdown (e.g. "Circuit Works: +1000"). + /// + public class ScoreLineItem + { + /// Human-readable label for this score component. + public string Label { get; } + + /// Points awarded (or 0 if not earned). + public int Points { get; } + + public ScoreLineItem(string label, int points) + { + Label = label ?? throw new ArgumentNullException(nameof(label)); + Points = points; + } + + public override string ToString() => $"{Label}: {(Points >= 0 ? "+" : "")}{Points}"; + } + + /// + /// Immutable result of scoring a completed circuit. + /// Contains point totals, star rating, and a detailed line-item breakdown. + /// + public class ScoreBreakdown + { + /// 1000 if circuit works, 0 otherwise. + public int BaseScore { get; } + + /// +500 if total component cost is within budget. + public int BudgetBonus { get; } + + /// +300 if component count is within the limit. + public int CompactBonus { get; } + + /// Sum of BaseScore + BudgetBonus + CompactBonus. + public int TotalScore { get; } + + /// 0-3 star rating. + public int Stars { get; } + + /// Whether the circuit passed evaluation. + public bool Passed { get; } + + /// Detailed line-item breakdown of the score. + public List LineItems { get; } + + /// Human-readable summary of the score. + public string Summary { get; } + + public ScoreBreakdown( + int baseScore, + int budgetBonus, + int compactBonus, + int totalScore, + int stars, + bool passed, + List lineItems, + string summary) + { + BaseScore = baseScore; + BudgetBonus = budgetBonus; + CompactBonus = compactBonus; + TotalScore = totalScore; + Stars = stars; + Passed = passed; + LineItems = lineItems ?? new List(); + Summary = summary ?? string.Empty; + } + } +} diff --git a/Assets/10_Scripts/10_Runtime/10_Core/Scoring/ScoreBreakdown.cs.meta b/Assets/10_Scripts/10_Runtime/10_Core/Scoring/ScoreBreakdown.cs.meta new file mode 100644 index 0000000..67e826b --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/10_Core/Scoring/ScoreBreakdown.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 12cf4ce8e97f8c248a22c0f57bb0eb29 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/10_Scripts/10_Runtime/10_Core/Scoring/ScoringSystem.cs b/Assets/10_Scripts/10_Runtime/10_Core/Scoring/ScoringSystem.cs new file mode 100644 index 0000000..ffb89a6 --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/10_Core/Scoring/ScoringSystem.cs @@ -0,0 +1,169 @@ +using System.Collections.Generic; +using System.Text; + +namespace CircuitCraft.Core +{ + /// + /// Calculates a 3-star score after a circuit passes evaluation. + /// Pure C# — no Unity dependencies. Lives in the Domain layer. + /// + /// Star logic: + /// 0★ = circuit didn't pass + /// 1★ = circuit works (base score) + /// 2★ = circuit works + (under budget OR within component limit) + /// 3★ = circuit works + under budget + within component limit + /// + public class ScoringSystem + { + private const int BASE_SCORE = 1000; + private const int BUDGET_BONUS = 500; + private const int COMPACT_BONUS = 300; + + /// + /// Calculates score breakdown from the given scoring input. + /// + /// Scoring data assembled by the caller from stage + board state. + /// Immutable score breakdown with star rating and line items. + public ScoreBreakdown Calculate(ScoringInput input) + { + var lineItems = new List(); + + // --- Base score --- + int baseScore = 0; + if (input.CircuitPassed) + { + baseScore = BASE_SCORE; + lineItems.Add(new ScoreLineItem("Circuit Works", BASE_SCORE)); + } + else + { + lineItems.Add(new ScoreLineItem("Circuit Failed", 0)); + return BuildResult(baseScore, 0, 0, false, lineItems); + } + + // --- Budget bonus --- + bool underBudget = IsUnderBudget(input); + int budgetBonus = 0; + if (underBudget) + { + budgetBonus = BUDGET_BONUS; + if (input.BudgetLimit > 0f) + lineItems.Add(new ScoreLineItem( + $"Under Budget ({input.TotalComponentCost:F0}/{input.BudgetLimit:F0})", + BUDGET_BONUS)); + else + lineItems.Add(new ScoreLineItem("Budget: No Limit", BUDGET_BONUS)); + } + else + { + lineItems.Add(new ScoreLineItem( + $"Over Budget ({input.TotalComponentCost:F0}/{input.BudgetLimit:F0})", + 0)); + } + + // --- Compact bonus --- + bool withinComponentLimit = IsWithinComponentLimit(input); + int compactBonus = 0; + if (withinComponentLimit) + { + compactBonus = COMPACT_BONUS; + if (input.MaxComponentCount > 0) + lineItems.Add(new ScoreLineItem( + $"Compact Build ({input.ComponentCount}/{input.MaxComponentCount})", + COMPACT_BONUS)); + else + lineItems.Add(new ScoreLineItem("Components: No Limit", COMPACT_BONUS)); + } + else + { + lineItems.Add(new ScoreLineItem( + $"Too Many Components ({input.ComponentCount}/{input.MaxComponentCount})", + 0)); + } + + return BuildResult(baseScore, budgetBonus, compactBonus, true, lineItems); + } + + /// + /// Under budget if no limit is set (0) or cost <= limit. + /// + private static bool IsUnderBudget(ScoringInput input) + { + if (input.BudgetLimit <= 0f) return true; // no limit → auto-pass + return input.TotalComponentCost <= input.BudgetLimit; + } + + /// + /// Within component limit if no limit is set (0) or count <= max. + /// + private static bool IsWithinComponentLimit(ScoringInput input) + { + if (input.MaxComponentCount <= 0) return true; // no limit → auto-pass + return input.ComponentCount <= input.MaxComponentCount; + } + + /// + /// Calculates star count from bonus flags. + /// + private static int CalculateStars(bool passed, bool underBudget, bool withinComponentLimit) + { + if (!passed) return 0; + + int bonusCount = 0; + if (underBudget) bonusCount++; + if (withinComponentLimit) bonusCount++; + + // 1★ base + bonuses (max 3★) + return 1 + bonusCount; + } + + private static ScoreBreakdown BuildResult( + int baseScore, + int budgetBonus, + int compactBonus, + bool passed, + List lineItems) + { + int totalScore = baseScore + budgetBonus + compactBonus; + bool underBudget = budgetBonus > 0; + bool withinLimit = compactBonus > 0; + int stars = CalculateStars(passed, underBudget, withinLimit); + + string summary = BuildSummary(passed, stars, totalScore, lineItems); + + return new ScoreBreakdown( + baseScore, + budgetBonus, + compactBonus, + totalScore, + stars, + passed, + lineItems, + summary); + } + + private static string BuildSummary(bool passed, int stars, int totalScore, List lineItems) + { + var sb = new StringBuilder(); + + if (!passed) + { + sb.Append("FAILED — 0 Stars"); + return sb.ToString(); + } + + sb.Append(stars); + sb.Append(stars == 1 ? " Star" : " Stars"); + sb.Append($" — {totalScore} pts"); + + foreach (var item in lineItems) + { + sb.AppendLine(); + sb.Append(" "); + sb.Append(item.ToString()); + } + + return sb.ToString(); + } + } +} diff --git a/Assets/10_Scripts/10_Runtime/10_Core/Scoring/ScoringSystem.cs.meta b/Assets/10_Scripts/10_Runtime/10_Core/Scoring/ScoringSystem.cs.meta new file mode 100644 index 0000000..74427ac --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/10_Core/Scoring/ScoringSystem.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1515110bc8eb13248b467d5d99dc3e6a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/10_Scripts/10_Runtime/10_Core/Validation.meta b/Assets/10_Scripts/10_Runtime/10_Core/Validation.meta new file mode 100644 index 0000000..09ea0ed --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/10_Core/Validation.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 38b83dbca6e8c90418850360e7422e91 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/10_Scripts/10_Runtime/10_Core/Validation/DRCChecker.cs b/Assets/10_Scripts/10_Runtime/10_Core/Validation/DRCChecker.cs new file mode 100644 index 0000000..87e0409 --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/10_Core/Validation/DRCChecker.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; + +namespace CircuitCraft.Core +{ + /// + /// Performs design rule checks on a board state. + /// Detects shorts (overlapping nets) and unconnected pins. + /// Pure domain logic — no Unity dependencies. + /// + public class DRCChecker + { + /// + /// Runs all design rule checks on the given board state. + /// + /// The board state to check. + /// A DRCResult containing all detected violations. + public DRCResult Check(BoardState board) + { + if (board == null) + throw new ArgumentNullException(nameof(board)); + + var violations = new List(); + + DetectShorts(board, violations); + DetectUnconnectedPins(board, violations); + + return new DRCResult(violations); + } + + /// + /// Detects shorts: two different nets with traces passing through the same grid position. + /// Walks each trace segment from Start to End, building a position-to-netIds map. + /// Any position occupied by 2+ different nets is a short. + /// + private void DetectShorts(BoardState board, List violations) + { + // Map each grid position to the set of net IDs that pass through it + var positionToNets = new Dictionary>(); + + foreach (var trace in board.Traces) + { + EnumerateTracePositions(trace, position => + { + if (!positionToNets.TryGetValue(position, out var netIds)) + { + netIds = new HashSet(); + positionToNets[position] = netIds; + } + netIds.Add(trace.NetId); + }); + } + + // Any position with 2+ different net IDs is a short + foreach (var kvp in positionToNets) + { + if (kvp.Value.Count >= 2) + { + var netIdList = new List(kvp.Value); + netIdList.Sort(); + var netNames = new List(); + foreach (var netId in netIdList) + { + var net = board.GetNet(netId); + netNames.Add(net != null ? net.NetName : $"Net{netId}"); + } + + violations.Add(new DRCViolationItem( + DRCViolationType.Short, + kvp.Key, + $"Short: nets [{string.Join(", ", netNames)}] overlap at {kvp.Key}" + )); + } + } + } + + /// + /// Detects unconnected pins: pins on placed components that are not connected to any net. + /// + private void DetectUnconnectedPins(BoardState board, List violations) + { + foreach (var component in board.Components) + { + foreach (var pin in component.Pins) + { + if (!pin.ConnectedNetId.HasValue) + { + var worldPos = component.GetPinWorldPosition(pin.PinIndex); + violations.Add(new DRCViolationItem( + DRCViolationType.UnconnectedPin, + worldPos, + $"Unconnected pin: {pin.PinName} (index {pin.PinIndex}) on component {component.ComponentDefinitionId} (instance {component.InstanceId})" + )); + } + } + } + } + + /// + /// Enumerates all grid positions along a Manhattan (orthogonal) trace segment, + /// including both Start and End positions. + /// + /// The trace segment to walk. + /// Action invoked for each grid position on the trace. + private void EnumerateTracePositions(TraceSegment trace, Action action) + { + var start = trace.Start; + var end = trace.End; + + int dx = end.X > start.X ? 1 : (end.X < start.X ? -1 : 0); + int dy = end.Y > start.Y ? 1 : (end.Y < start.Y ? -1 : 0); + + int x = start.X; + int y = start.Y; + + while (true) + { + action(new GridPosition(x, y)); + + if (x == end.X && y == end.Y) + break; + + x += dx; + y += dy; + } + } + } +} diff --git a/Assets/10_Scripts/10_Runtime/10_Core/Validation/DRCChecker.cs.meta b/Assets/10_Scripts/10_Runtime/10_Core/Validation/DRCChecker.cs.meta new file mode 100644 index 0000000..f1a0679 --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/10_Core/Validation/DRCChecker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f5d393731eecfc842a80dec40568c448 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/10_Scripts/10_Runtime/10_Core/Validation/DRCResult.cs b/Assets/10_Scripts/10_Runtime/10_Core/Validation/DRCResult.cs new file mode 100644 index 0000000..852bafc --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/10_Core/Validation/DRCResult.cs @@ -0,0 +1,94 @@ +using System.Collections.Generic; +using System.Linq; + +namespace CircuitCraft.Core +{ + /// + /// Types of design rule violations. + /// + public enum DRCViolationType + { + /// Two different nets overlap at the same grid position. + Short, + + /// A pin is not connected to any net. + UnconnectedPin + } + + /// + /// A single design rule violation with type, location, and description. + /// + public class DRCViolationItem + { + /// Gets the type of violation. + public DRCViolationType ViolationType { get; } + + /// Gets the grid position where the violation occurs. + public GridPosition Location { get; } + + /// Gets a human-readable description of the violation. + public string Message { get; } + + /// + /// Creates a new DRC violation item. + /// + /// Type of violation. + /// Grid position of the violation. + /// Description of the violation. + public DRCViolationItem(DRCViolationType violationType, GridPosition location, string message) + { + ViolationType = violationType; + Location = location; + Message = message; + } + + /// + /// Returns a string representation of this violation. + /// + public override string ToString() + { + return $"[{ViolationType}] {Location}: {Message}"; + } + } + + /// + /// Result of a design rule check containing all detected violations. + /// + public class DRCResult + { + private readonly List _violations; + + /// Gets the read-only list of all violations. + public IReadOnlyList Violations { get; } + + /// Gets whether any violations were detected. + public bool HasViolations => _violations.Count > 0; + + /// Gets the number of short violations. + public int ShortCount => _violations.Count(v => v.ViolationType == DRCViolationType.Short); + + /// Gets the number of unconnected pin violations. + public int UnconnectedCount => _violations.Count(v => v.ViolationType == DRCViolationType.UnconnectedPin); + + /// + /// Creates a new DRC result. + /// + /// List of detected violations. + public DRCResult(List violations) + { + _violations = violations ?? new List(); + Violations = _violations.AsReadOnly(); + } + + /// + /// Returns a string summary of the DRC result. + /// + public override string ToString() + { + if (!HasViolations) + return "DRC: No violations"; + + return $"DRC: {_violations.Count} violation(s) ({ShortCount} shorts, {UnconnectedCount} unconnected pins)"; + } + } +} diff --git a/Assets/10_Scripts/10_Runtime/10_Core/Validation/DRCResult.cs.meta b/Assets/10_Scripts/10_Runtime/10_Core/Validation/DRCResult.cs.meta new file mode 100644 index 0000000..174d717 --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/10_Core/Validation/DRCResult.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 29ca4d546dfed204abc0ba959256cb0c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 76e81f12de107552d4f6d53ee5776f7aed940971 Mon Sep 17 00:00:00 2001 From: okenic03-code Date: Fri, 13 Feb 2026 03:28:51 +0900 Subject: [PATCH 003/115] feat: add wire routing system with controller, renderer, and undo support Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- .../10_Runtime/10_Views/TraceRenderer.cs | 146 +++++++ .../10_Runtime/10_Views/TraceRenderer.cs.meta | 11 + .../20_Controllers/WireRoutingController.cs | 402 ++++++++++++++++++ .../WireRoutingController.cs.meta | 11 + .../60_Commands/RouteTraceCommand.cs | 194 +++++++++ .../60_Commands/RouteTraceCommand.cs.meta | 11 + 6 files changed, 775 insertions(+) create mode 100644 Assets/10_Scripts/10_Runtime/10_Views/TraceRenderer.cs create mode 100644 Assets/10_Scripts/10_Runtime/10_Views/TraceRenderer.cs.meta create mode 100644 Assets/10_Scripts/10_Runtime/20_Controllers/WireRoutingController.cs create mode 100644 Assets/10_Scripts/10_Runtime/20_Controllers/WireRoutingController.cs.meta create mode 100644 Assets/10_Scripts/10_Runtime/60_Commands/RouteTraceCommand.cs create mode 100644 Assets/10_Scripts/10_Runtime/60_Commands/RouteTraceCommand.cs.meta diff --git a/Assets/10_Scripts/10_Runtime/10_Views/TraceRenderer.cs b/Assets/10_Scripts/10_Runtime/10_Views/TraceRenderer.cs new file mode 100644 index 0000000..7890959 --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/10_Views/TraceRenderer.cs @@ -0,0 +1,146 @@ +using System.Collections.Generic; +using CircuitCraft.Core; +using CircuitCraft.Data; +using CircuitCraft.Managers; +using CircuitCraft.Utils; +using UnityEngine; + +namespace CircuitCraft.Views +{ + /// + /// Renders board trace segments using LineRenderer components. + /// + public class TraceRenderer : MonoBehaviour + { + [Header("Dependencies")] + [SerializeField] private GameManager _gameManager; + [SerializeField] private GridSettings _gridSettings; + + [Header("Visual Settings")] + [SerializeField] private Color _wireColor = new Color(0.1f, 0.85f, 1f, 1f); + [SerializeField] private float _wireWidth = 0.08f; + [SerializeField] private float _wireY = 0.05f; + + private BoardState _boardState; + private Material _lineMaterial; + private readonly Dictionary _traceLines = new Dictionary(); + + private void Start() + { + if (_gameManager == null) + { + Debug.LogError("TraceRenderer: GameManager reference is missing!"); + return; + } + + if (_gridSettings == null) + { + Debug.LogError("TraceRenderer: GridSettings reference is missing!"); + return; + } + + _boardState = _gameManager.BoardState; + if (_boardState == null) + { + Debug.LogWarning("TraceRenderer: BoardState is not available."); + return; + } + + _lineMaterial = new Material(Shader.Find("Sprites/Default")); + Subscribe(); + + foreach (var trace in _boardState.Traces) + { + CreateTraceLine(trace); + } + } + + private void OnDestroy() + { + Unsubscribe(); + + foreach (var pair in _traceLines) + { + if (pair.Value != null) + { + Destroy(pair.Value.gameObject); + } + } + _traceLines.Clear(); + + if (_lineMaterial != null) + { + Destroy(_lineMaterial); + } + } + + private void Subscribe() + { + _boardState.OnTraceAdded += HandleTraceAdded; + _boardState.OnTraceRemoved += HandleTraceRemoved; + } + + private void Unsubscribe() + { + if (_boardState == null) + return; + + _boardState.OnTraceAdded -= HandleTraceAdded; + _boardState.OnTraceRemoved -= HandleTraceRemoved; + } + + private void HandleTraceAdded(TraceSegment trace) + { + CreateTraceLine(trace); + } + + private void HandleTraceRemoved(int segmentId) + { + if (_traceLines.TryGetValue(segmentId, out var line)) + { + if (line != null) + { + Destroy(line.gameObject); + } + + _traceLines.Remove(segmentId); + } + } + + private void CreateTraceLine(TraceSegment trace) + { + if (trace == null || _traceLines.ContainsKey(trace.SegmentId)) + return; + + var lineObject = new GameObject($"Trace_{trace.SegmentId}"); + lineObject.transform.SetParent(transform, false); + + var line = lineObject.AddComponent(); + line.useWorldSpace = true; + line.positionCount = 2; + line.startWidth = _wireWidth; + line.endWidth = _wireWidth; + line.startColor = _wireColor; + line.endColor = _wireColor; + line.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; + line.receiveShadows = false; + line.material = _lineMaterial; + + line.SetPosition(0, GridToWireWorld(trace.Start)); + line.SetPosition(1, GridToWireWorld(trace.End)); + + _traceLines[trace.SegmentId] = line; + } + + private Vector3 GridToWireWorld(GridPosition pos) + { + Vector3 world = GridUtility.GridToWorldPosition( + new Vector2Int(pos.X, pos.Y), + _gridSettings.CellSize, + _gridSettings.GridOrigin + ); + world.y += _wireY; + return world; + } + } +} diff --git a/Assets/10_Scripts/10_Runtime/10_Views/TraceRenderer.cs.meta b/Assets/10_Scripts/10_Runtime/10_Views/TraceRenderer.cs.meta new file mode 100644 index 0000000..f9b03a2 --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/10_Views/TraceRenderer.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 842c81da4d59de64baeec0a4910139fe +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/10_Scripts/10_Runtime/20_Controllers/WireRoutingController.cs b/Assets/10_Scripts/10_Runtime/20_Controllers/WireRoutingController.cs new file mode 100644 index 0000000..9de9ffa --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/20_Controllers/WireRoutingController.cs @@ -0,0 +1,402 @@ +using System.Collections.Generic; +using System.Linq; +using CircuitCraft.Commands; +using CircuitCraft.Components; +using CircuitCraft.Core; +using CircuitCraft.Data; +using CircuitCraft.Managers; +using CircuitCraft.Utils; +using UnityEngine; + +namespace CircuitCraft.Controllers +{ + /// + /// Handles mouse-driven wire routing between component pins. + /// + public class WireRoutingController : MonoBehaviour + { + [Header("Dependencies")] + [SerializeField] private GameManager _gameManager; + [SerializeField] private GridSettings _gridSettings; + [SerializeField] private Camera _mainCamera; + + [Header("Command History")] + [SerializeField] private CommandHistory _commandHistory = new CommandHistory(); + + [Header("Raycast Settings")] + [SerializeField] private float _raycastDistance = 100f; + + [Header("Preview")] + [SerializeField] private Color _previewColor = Color.yellow; + [SerializeField] private float _previewWidth = 0.08f; + [SerializeField] private float _previewY = 0.06f; + + private enum RoutingState + { + Idle, + PinSelected, + Drawing + } + + private RoutingState _state = RoutingState.Idle; + private BoardState _boardState; + private PinReference _startPin; + private int _selectedTraceSegmentId = -1; + private LineRenderer _previewLine; + + private void Awake() + { + if (_mainCamera == null) + { + _mainCamera = Camera.main; + } + + if (_gameManager != null) + { + _boardState = _gameManager.BoardState; + } + + EnsurePreviewLine(); + HidePreview(); + } + + private void Update() + { + if (_boardState == null || _gridSettings == null || _mainCamera == null) + return; + + HandleUndoRedoInput(); + HandleCancelInput(); + HandleDeleteSelectedTrace(); + HandleLeftClick(); + + if (_state == RoutingState.Drawing) + { + UpdatePreviewPath(); + } + } + + private void HandleUndoRedoInput() + { + // Only handle undo/redo when not actively routing + if (_state != RoutingState.Idle) + return; + + bool ctrl = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl); + if (!ctrl) + return; + + if (Input.GetKeyDown(KeyCode.Z)) + { + _commandHistory.Undo(); + } + else if (Input.GetKeyDown(KeyCode.Y)) + { + _commandHistory.Redo(); + } + } + + private void HandleLeftClick() + { + if (!Input.GetMouseButtonDown(0)) + return; + + if (TryGetClickedPin(out var clickedPin)) + { + if (_state == RoutingState.Idle) + { + StartRouting(clickedPin); + } + else if (_state == RoutingState.Drawing || _state == RoutingState.PinSelected) + { + CommitRouting(clickedPin); + } + + return; + } + + if (_state == RoutingState.Idle) + { + TrySelectTraceAtMouse(); + } + } + + private void HandleCancelInput() + { + if (Input.GetMouseButtonDown(1) || Input.GetKeyDown(KeyCode.Escape)) + { + CancelRouting(); + } + } + + private void HandleDeleteSelectedTrace() + { + if (!Input.GetKeyDown(KeyCode.Delete) || _selectedTraceSegmentId < 0) + return; + + var selectedTrace = _boardState.Traces.FirstOrDefault(t => t.SegmentId == _selectedTraceSegmentId); + if (selectedTrace == null) + { + _selectedTraceSegmentId = -1; + return; + } + + foreach (var trace in _boardState.GetTraces(selectedTrace.NetId).ToList()) + { + _boardState.RemoveTrace(trace.SegmentId); + } + + _selectedTraceSegmentId = -1; + } + + private void StartRouting(PinReference startPin) + { + _startPin = startPin; + _state = RoutingState.PinSelected; + _selectedTraceSegmentId = -1; + _state = RoutingState.Drawing; + ShowPreview(); + UpdatePreviewPath(); + } + + private void CommitRouting(PinReference endPin) + { + if (_startPin.ComponentInstanceId == endPin.ComponentInstanceId && _startPin.PinIndex == endPin.PinIndex) + { + CancelRouting(); + return; + } + + var segments = BuildManhattanSegments(_startPin.Position, endPin.Position); + var command = new RouteTraceCommand(_boardState, _startPin, endPin, segments); + _commandHistory.ExecuteCommand(command); + + CancelRouting(); + } + + private List<(GridPosition start, GridPosition end)> BuildManhattanSegments(GridPosition start, GridPosition end) + { + var segments = new List<(GridPosition start, GridPosition end)>(); + + if (start.X == end.X || start.Y == end.Y) + { + segments.Add((start, end)); + return segments; + } + + var corner = new GridPosition(end.X, start.Y); + segments.Add((start, corner)); + segments.Add((corner, end)); + + return segments; + } + + private void UpdatePreviewPath() + { + Vector2Int mouseGrid = GridUtility.ScreenToGridPosition( + Input.mousePosition, + _mainCamera, + _gridSettings.CellSize, + _gridSettings.GridOrigin + ); + + var current = new GridPosition(mouseGrid.x, mouseGrid.y); + + if (_startPin.Position.X == current.X || _startPin.Position.Y == current.Y) + { + _previewLine.positionCount = 2; + SetPreviewPosition(0, _startPin.Position); + SetPreviewPosition(1, current); + } + else + { + var corner = new GridPosition(current.X, _startPin.Position.Y); + _previewLine.positionCount = 3; + SetPreviewPosition(0, _startPin.Position); + SetPreviewPosition(1, corner); + SetPreviewPosition(2, current); + } + } + + private void SetPreviewPosition(int index, GridPosition gridPos) + { + Vector3 worldPos = GridUtility.GridToWorldPosition( + new Vector2Int(gridPos.X, gridPos.Y), + _gridSettings.CellSize, + _gridSettings.GridOrigin + ); + worldPos.y += _previewY; + _previewLine.SetPosition(index, worldPos); + } + + private bool TryGetClickedPin(out PinReference pinRef) + { + pinRef = default; + + Ray ray = _mainCamera.ScreenPointToRay(Input.mousePosition); + if (!Physics.Raycast(ray, out var hit, _raycastDistance)) + return false; + + ComponentView componentView = hit.collider.GetComponent(); + if (componentView == null) + { + componentView = hit.collider.GetComponentInParent(); + } + + if (componentView == null) + return false; + + var boardPos = new GridPosition(componentView.GridPosition.x, componentView.GridPosition.y); + var component = _boardState.GetComponentAt(boardPos); + if (component == null) + return false; + + Vector2Int mouseGrid = GridUtility.ScreenToGridPosition( + Input.mousePosition, + _mainCamera, + _gridSettings.CellSize, + _gridSettings.GridOrigin + ); + var mouseGridPos = new GridPosition(mouseGrid.x, mouseGrid.y); + + PinReference? bestPin = null; + int bestDistance = int.MaxValue; + + foreach (var pin in component.Pins) + { + GridPosition pinWorld = component.GetPinWorldPosition(pin.PinIndex); + int distance = pinWorld.ManhattanDistance(mouseGridPos); + if (distance < bestDistance) + { + bestDistance = distance; + bestPin = new PinReference(component.InstanceId, pin.PinIndex, pinWorld); + } + } + + if (!bestPin.HasValue) + return false; + + if (bestDistance > 1) + return false; + + pinRef = bestPin.Value; + return true; + } + + private void TrySelectTraceAtMouse() + { + Vector2Int mouseGrid = GridUtility.ScreenToGridPosition( + Input.mousePosition, + _mainCamera, + _gridSettings.CellSize, + _gridSettings.GridOrigin + ); + var pos = new GridPosition(mouseGrid.x, mouseGrid.y); + + _selectedTraceSegmentId = -1; + foreach (var trace in _boardState.Traces) + { + if (IsPointOnTrace(trace, pos)) + { + _selectedTraceSegmentId = trace.SegmentId; + break; + } + } + } + + private static bool IsPointOnTrace(TraceSegment trace, GridPosition point) + { + if (trace.Start.X == trace.End.X) + { + if (point.X != trace.Start.X) + return false; + + int minY = Mathf.Min(trace.Start.Y, trace.End.Y); + int maxY = Mathf.Max(trace.Start.Y, trace.End.Y); + return point.Y >= minY && point.Y <= maxY; + } + + if (point.Y != trace.Start.Y) + return false; + + int minX = Mathf.Min(trace.Start.X, trace.End.X); + int maxX = Mathf.Max(trace.Start.X, trace.End.X); + return point.X >= minX && point.X <= maxX; + } + + private void CancelRouting() + { + _state = RoutingState.Idle; + _startPin = default; + HidePreview(); + } + + private void EnsurePreviewLine() + { + var previewObject = new GameObject("WirePreview"); + previewObject.transform.SetParent(transform, false); + + _previewLine = previewObject.AddComponent(); + _previewLine.useWorldSpace = true; + _previewLine.positionCount = 0; + _previewLine.startWidth = _previewWidth; + _previewLine.endWidth = _previewWidth; + _previewLine.startColor = _previewColor; + _previewLine.endColor = _previewColor; + _previewLine.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; + _previewLine.receiveShadows = false; + _previewLine.material = new Material(Shader.Find("Sprites/Default")); + } + + private void ShowPreview() + { + if (_previewLine != null) + { + _previewLine.enabled = true; + } + } + + private void HidePreview() + { + if (_previewLine != null) + { + _previewLine.positionCount = 0; + _previewLine.enabled = false; + } + } + + private void OnDestroy() + { + if (_previewLine != null && _previewLine.material != null) + { + Destroy(_previewLine.material); + } + } + + /// + /// Undoes the last executed routing command. + /// + public void UndoLastAction() + { + _commandHistory.Undo(); + } + + /// + /// Redoes the most recently undone routing command. + /// + public void RedoLastAction() + { + _commandHistory.Redo(); + } + + /// + /// Gets whether there is at least one command available to undo. + /// + public bool CanUndo => _commandHistory.CanUndo; + + /// + /// Gets whether there is at least one command available to redo. + /// + public bool CanRedo => _commandHistory.CanRedo; + } +} diff --git a/Assets/10_Scripts/10_Runtime/20_Controllers/WireRoutingController.cs.meta b/Assets/10_Scripts/10_Runtime/20_Controllers/WireRoutingController.cs.meta new file mode 100644 index 0000000..f4006d9 --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/20_Controllers/WireRoutingController.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 89941ec19c90f854e850ab5a3bcecba7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/10_Scripts/10_Runtime/60_Commands/RouteTraceCommand.cs b/Assets/10_Scripts/10_Runtime/60_Commands/RouteTraceCommand.cs new file mode 100644 index 0000000..41997ea --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/60_Commands/RouteTraceCommand.cs @@ -0,0 +1,194 @@ +using System.Collections.Generic; +using System.Linq; +using CircuitCraft.Core; + +namespace CircuitCraft.Commands +{ + /// + /// Command that routes trace segments between two pins and manages net connections. + /// Supports undo/redo through the CommandHistory system. + /// + public class RouteTraceCommand : ICommand + { + private readonly BoardState _boardState; + private readonly PinReference _startPin; + private readonly PinReference _endPin; + private readonly List<(GridPosition start, GridPosition end)> _segments; + + // State captured during Execute for Undo + private int _netId; + private readonly List _addedSegmentIds = new List(); + private bool _createdNewNet; + private int? _startPinPreviousNetId; + private int? _endPinPreviousNetId; + + public string Description => $"Route trace from {_startPin} to {_endPin}"; + + /// + /// Creates a new route trace command. + /// + /// The board state to operate on. + /// The starting pin reference. + /// The ending pin reference. + /// Manhattan trace segments to add. + public RouteTraceCommand( + BoardState boardState, + PinReference startPin, + PinReference endPin, + List<(GridPosition start, GridPosition end)> segments) + { + _boardState = boardState; + _startPin = startPin; + _endPin = endPin; + _segments = segments; + } + + public void Execute() + { + // Capture previous pin net connections for undo + _startPinPreviousNetId = GetPinConnectedNetId(_startPin); + _endPinPreviousNetId = GetPinConnectedNetId(_endPin); + + // Resolve which net to use (may create a new one) + _netId = ResolveNetId(); + + // Connect pins to the net + _boardState.ConnectPinToNet(_netId, _startPin); + _boardState.ConnectPinToNet(_netId, _endPin); + + // Add trace segments + _addedSegmentIds.Clear(); + foreach (var segment in _segments) + { + var trace = _boardState.AddTrace(_netId, segment.start, segment.end); + _addedSegmentIds.Add(trace.SegmentId); + } + } + + public void Undo() + { + // Remove all trace segments added by this command (reverse order) + for (int i = _addedSegmentIds.Count - 1; i >= 0; i--) + { + _boardState.RemoveTrace(_addedSegmentIds[i]); + } + _addedSegmentIds.Clear(); + + // BoardState.RemoveTrace auto-cleans the net when no traces remain + // (disconnects all pins, removes net). Check if net still exists. + var net = _boardState.GetNet(_netId); + + if (net != null) + { + // Net still has other traces. Only disconnect pins that we newly + // connected (skip pins that were already on this net before Execute). + if (!_startPinPreviousNetId.HasValue || _startPinPreviousNetId.Value != _netId) + { + DisconnectPinFromNet(_startPin, net); + } + + if (!_endPinPreviousNetId.HasValue || _endPinPreviousNetId.Value != _netId) + { + DisconnectPinFromNet(_endPin, net); + } + } + + // Restore previous pin connections if they were on different nets + RestorePreviousPinConnection(_startPin, _startPinPreviousNetId); + RestorePreviousPinConnection(_endPin, _endPinPreviousNetId); + } + + private int ResolveNetId() + { + int? startNetId = _startPinPreviousNetId; + int? endNetId = _endPinPreviousNetId; + + if (startNetId.HasValue && endNetId.HasValue) + { + if (startNetId.Value != endNetId.Value) + { + MergeNets(startNetId.Value, endNetId.Value); + } + + _createdNewNet = false; + return startNetId.Value; + } + + if (startNetId.HasValue) + { + _createdNewNet = false; + return startNetId.Value; + } + + if (endNetId.HasValue) + { + _createdNewNet = false; + return endNetId.Value; + } + + // Neither pin connected — create a new net + string netName = $"NET{_boardState.Nets.Count + 1}"; + _createdNewNet = true; + return _boardState.CreateNet(netName).NetId; + } + + private void MergeNets(int targetNetId, int sourceNetId) + { + if (targetNetId == sourceNetId) + return; + + var sourceNet = _boardState.GetNet(sourceNetId); + if (sourceNet == null) + return; + + foreach (var pin in sourceNet.ConnectedPins.ToList()) + { + _boardState.ConnectPinToNet(targetNetId, pin); + } + + foreach (var trace in _boardState.GetTraces(sourceNetId).ToList()) + { + _boardState.AddTrace(targetNetId, trace.Start, trace.End); + _boardState.RemoveTrace(trace.SegmentId); + } + } + + private int? GetPinConnectedNetId(PinReference pinRef) + { + var component = _boardState.GetComponent(pinRef.ComponentInstanceId); + if (component == null) + return null; + + var pin = component.Pins.FirstOrDefault(p => p.PinIndex == pinRef.PinIndex); + return pin?.ConnectedNetId; + } + + private void DisconnectPinFromNet(PinReference pinRef, Net net) + { + net.RemovePin(pinRef); + + var component = _boardState.GetComponent(pinRef.ComponentInstanceId); + if (component == null) + return; + + var pinInstance = component.Pins.FirstOrDefault(p => p.PinIndex == pinRef.PinIndex); + if (pinInstance != null && pinInstance.ConnectedNetId == _netId) + { + pinInstance.ConnectedNetId = null; + } + } + + private void RestorePreviousPinConnection(PinReference pinRef, int? previousNetId) + { + if (!previousNetId.HasValue || previousNetId.Value == _netId) + return; + + // Only restore if the previous net still exists + var previousNet = _boardState.GetNet(previousNetId.Value); + if (previousNet == null) + return; + + _boardState.ConnectPinToNet(previousNetId.Value, pinRef); + } + } +} diff --git a/Assets/10_Scripts/10_Runtime/60_Commands/RouteTraceCommand.cs.meta b/Assets/10_Scripts/10_Runtime/60_Commands/RouteTraceCommand.cs.meta new file mode 100644 index 0000000..07a7ead --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/60_Commands/RouteTraceCommand.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8c2919614572b184faf869264d6c21e6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 9bf8eb8ab94ffa485a6f8f627e6d9b4628ea6c05 Mon Sep 17 00:00:00 2001 From: okenic03-code Date: Fri, 13 Feb 2026 03:29:14 +0900 Subject: [PATCH 004/115] feat: add component improvements, new art assets, and sprite icons Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- .../20_Controllers/PlacementController.cs | 37 +++++- .../10_Runtime/30_Components/ComponentView.cs | 12 +- .../10_Runtime/50_Data/ComponentDefinition.cs | 8 ++ Assets/40_Art/Components/BJT.png | Bin 0 -> 264 bytes Assets/40_Art/Components/BJT.png.meta | 114 ++++++++++++++++++ Assets/40_Art/Components/Diode.png | Bin 0 -> 212 bytes Assets/40_Art/Components/Diode.png.meta | 114 ++++++++++++++++++ Assets/40_Art/Components/Inductor.png | Bin 0 -> 147 bytes Assets/40_Art/Components/Inductor.png.meta | 114 ++++++++++++++++++ Assets/40_Art/Components/LED.png | Bin 0 -> 256 bytes Assets/40_Art/Components/LED.png.meta | 114 ++++++++++++++++++ Assets/40_Art/Components/MOSFET.png | Bin 0 -> 181 bytes Assets/40_Art/Components/MOSFET.png.meta | 114 ++++++++++++++++++ Assets/60_UI/10_Sprites/MainMenu.meta | 8 ++ Assets/60_UI/10_Sprites/MainMenu/IconPlay.png | Bin 0 -> 1745 bytes .../10_Sprites/MainMenu/IconPlay.png.meta | 114 ++++++++++++++++++ Assets/60_UI/10_Sprites/MainMenu/IconQuit.png | Bin 0 -> 1067 bytes .../10_Sprites/MainMenu/IconQuit.png.meta | 114 ++++++++++++++++++ .../10_Sprites/MainMenu/IconSettings.png | Bin 0 -> 3152 bytes .../10_Sprites/MainMenu/IconSettings.png.meta | 114 ++++++++++++++++++ .../Components/Diode_1N4148.asset | 40 ++++++ .../Components/Diode_1N4148.asset.meta | 8 ++ .../Components/LED_Red.asset | 40 ++++++ .../Components/LED_Red.asset.meta | 8 ++ 24 files changed, 1063 insertions(+), 10 deletions(-) create mode 100644 Assets/40_Art/Components/BJT.png create mode 100644 Assets/40_Art/Components/BJT.png.meta create mode 100644 Assets/40_Art/Components/Diode.png create mode 100644 Assets/40_Art/Components/Diode.png.meta create mode 100644 Assets/40_Art/Components/Inductor.png create mode 100644 Assets/40_Art/Components/Inductor.png.meta create mode 100644 Assets/40_Art/Components/LED.png create mode 100644 Assets/40_Art/Components/LED.png.meta create mode 100644 Assets/40_Art/Components/MOSFET.png create mode 100644 Assets/40_Art/Components/MOSFET.png.meta create mode 100644 Assets/60_UI/10_Sprites/MainMenu.meta create mode 100644 Assets/60_UI/10_Sprites/MainMenu/IconPlay.png create mode 100644 Assets/60_UI/10_Sprites/MainMenu/IconPlay.png.meta create mode 100644 Assets/60_UI/10_Sprites/MainMenu/IconQuit.png create mode 100644 Assets/60_UI/10_Sprites/MainMenu/IconQuit.png.meta create mode 100644 Assets/60_UI/10_Sprites/MainMenu/IconSettings.png create mode 100644 Assets/60_UI/10_Sprites/MainMenu/IconSettings.png.meta create mode 100644 Assets/70_Data/10_ScriptableObjects/Components/Diode_1N4148.asset create mode 100644 Assets/70_Data/10_ScriptableObjects/Components/Diode_1N4148.asset.meta create mode 100644 Assets/70_Data/10_ScriptableObjects/Components/LED_Red.asset create mode 100644 Assets/70_Data/10_ScriptableObjects/Components/LED_Red.asset.meta diff --git a/Assets/10_Scripts/10_Runtime/20_Controllers/PlacementController.cs b/Assets/10_Scripts/10_Runtime/20_Controllers/PlacementController.cs index f383dac..4f7a3c6 100644 --- a/Assets/10_Scripts/10_Runtime/20_Controllers/PlacementController.cs +++ b/Assets/10_Scripts/10_Runtime/20_Controllers/PlacementController.cs @@ -42,6 +42,7 @@ public class PlacementController : MonoBehaviour // State private ComponentDefinition _selectedComponent; private GameObject _previewInstance; + private int _currentRotation = 0; // Cached preview component references private ComponentView _cachedPreviewView; @@ -94,6 +95,7 @@ private void OnDestroy() private void Update() { HandleCancellation(); + HandleRotation(); UpdatePreview(); HandlePlacement(); } @@ -113,6 +115,29 @@ private void HandleCancellation() } } + /// + /// Handles R key input to rotate component preview by 90° clockwise. + /// + private void HandleRotation() + { + // R key to rotate component preview + if (Input.GetKeyDown(KeyCode.R)) + { + if (_selectedComponent != null) + { + // Cycle rotation: 0 → 90 → 180 → 270 → 0 + _currentRotation = (_currentRotation + 90) % 360; + + // Apply rotation to preview instance + if (_previewInstance != null) + { + // Negative because Unity Z-rotation is counter-clockwise, we want clockwise visual + _previewInstance.transform.rotation = Quaternion.Euler(0, 0, -_currentRotation); + } + } + } + } + /// /// Updates the preview instance position and visual state. /// Preview follows cursor and shows valid/invalid placement state. @@ -274,12 +299,11 @@ private void PlaceComponent(Vector2Int gridPos) var pinDef = _selectedComponent.Pins[i]; // Convert PinDefinition local position to GridPosition - // Assuming PinDefinition has a LocalPosition field - if not, use default (0,0) - GridPosition pinLocalPos = new GridPosition(0, 0); // TODO: Get from pinDef.LocalPosition when available + GridPosition pinLocalPos = new GridPosition(pinDef.LocalPosition.x, pinDef.LocalPosition.y); PinInstance pinInstance = new PinInstance( pinIndex: i, - pinName: pinDef.ToString(), // TODO: Get actual pin name from PinDefinition + pinName: pinDef.PinName, localPosition: pinLocalPos ); @@ -293,7 +317,7 @@ private void PlaceComponent(Vector2Int gridPos) _gameManager.BoardState, _selectedComponent.Id, position, - 0, + _currentRotation, pinInstances ); _commandHistory.ExecuteCommand(placeCommand); @@ -304,7 +328,7 @@ private void PlaceComponent(Vector2Int gridPos) if (_componentViewPrefab != null && _gridSettings != null) { Vector3 worldPos = GridUtility.GridToWorldPosition(gridPos, _gridSettings.CellSize, _gridSettings.GridOrigin); - GameObject viewObject = Instantiate(_componentViewPrefab, worldPos, Quaternion.identity); + GameObject viewObject = Instantiate(_componentViewPrefab, worldPos, Quaternion.Euler(0, 0, -_currentRotation)); // Initialize ComponentView with definition ComponentView componentView = viewObject.GetComponent(); @@ -329,6 +353,9 @@ public void SetSelectedComponent(ComponentDefinition definition) { _selectedComponent = definition; + // Reset rotation when selecting a new component + _currentRotation = 0; + // Destroy old preview DestroyPreview(); diff --git a/Assets/10_Scripts/10_Runtime/30_Components/ComponentView.cs b/Assets/10_Scripts/10_Runtime/30_Components/ComponentView.cs index 5225698..9ae975d 100644 --- a/Assets/10_Scripts/10_Runtime/30_Components/ComponentView.cs +++ b/Assets/10_Scripts/10_Runtime/30_Components/ComponentView.cs @@ -115,13 +115,15 @@ public void Initialize(ComponentDefinition definition) return; } - // Set sprite from definition prefab (if available) - // Note: Prefab field contains the full prefab - we'll assume it has a SpriteRenderer - // For now, we'll log and wait for proper sprite asset integration + // Set sprite from definition if (_spriteRenderer != null) { - // TODO: Extract sprite from definition.Prefab or add Sprite field to ComponentDefinition - Debug.Log($"ComponentView.Initialize: {_definition.DisplayName} ({_definition.Id})"); + if (_definition.Icon != null) + { + _spriteRenderer.sprite = _definition.Icon; + } + Debug.Log($"ComponentView.Initialize: {_definition.DisplayName} ({_definition.Id})" + + (_definition.Icon == null ? " - Warning: Icon is null" : "")); } // Set label text diff --git a/Assets/10_Scripts/10_Runtime/50_Data/ComponentDefinition.cs b/Assets/10_Scripts/10_Runtime/50_Data/ComponentDefinition.cs index 359ca39..ebb6c2e 100644 --- a/Assets/10_Scripts/10_Runtime/50_Data/ComponentDefinition.cs +++ b/Assets/10_Scripts/10_Runtime/50_Data/ComponentDefinition.cs @@ -45,6 +45,11 @@ public class ComponentDefinition : ScriptableObject [FormerlySerializedAs("prefab")] private GameObject _prefab; + [SerializeField] + [Tooltip("Icon sprite displayed in the game world and UI palette.")] + [FormerlySerializedAs("icon")] + private Sprite _icon; + // Electrical value fields for simulation [Header("Electrical Values")] [SerializeField] @@ -139,6 +144,9 @@ public class ComponentDefinition : ScriptableObject /// The visual prefab used when this component is placed. public GameObject Prefab => _prefab; + /// Icon sprite displayed in the game world and UI palette. + public Sprite Icon => _icon; + // Electrical value properties for simulation /// Resistance in Ohms (for Resistor components). public float ResistanceOhms => _resistanceOhms; diff --git a/Assets/40_Art/Components/BJT.png b/Assets/40_Art/Components/BJT.png new file mode 100644 index 0000000000000000000000000000000000000000..81b2dc33fe6482ca243947fba743753600efa141 GIT binary patch literal 264 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC==RI8~)ofXa3V!**r{onh# zbi~p9kVij-6?yP^L-^=b=^Yhgt7@+nLU@lEvl71GNWVcAu~aoAQ%` z@tKf-LQQ^p2Rq}vU^ym%15ynQf=oXIW~n6n(K%ppqK?7Z=?&*5?LV8(+@8ms@wKX3 z_|e7m=Iz0YT|=iv3rB@CxcP7Yb^FYVC#ESCXGESp(FMEm!UM*Bj|IQ>)f;aE@jYGr KT-G@yGywnx1Z;2s literal 0 HcmV?d00001 diff --git a/Assets/40_Art/Components/BJT.png.meta b/Assets/40_Art/Components/BJT.png.meta new file mode 100644 index 0000000..16f28a6 --- /dev/null +++ b/Assets/40_Art/Components/BJT.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: 5eebf1a7ef3f22946abd3502c539b4c8 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/40_Art/Components/Diode.png b/Assets/40_Art/Components/Diode.png new file mode 100644 index 0000000000000000000000000000000000000000..320f38da324226cf6a3ca089b3eecbc46c8f70dd GIT binary patch literal 212 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=vproLLn>~)y?KzgK|#RP@prz| z`*{Hhh2PJI9M~rzx}2QT)|9+bP0 Hl+XkKdpt>M literal 0 HcmV?d00001 diff --git a/Assets/40_Art/Components/Diode.png.meta b/Assets/40_Art/Components/Diode.png.meta new file mode 100644 index 0000000..25a2c01 --- /dev/null +++ b/Assets/40_Art/Components/Diode.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: 2856c4bf77b4fe14cb5a17313352e163 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/40_Art/Components/Inductor.png b/Assets/40_Art/Components/Inductor.png new file mode 100644 index 0000000000000000000000000000000000000000..dc6530505021226234de9dc022bdbeda4739f179 GIT binary patch literal 147 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=QJyZ2Ar-gYUa{tCaNuD*aOeM} zEaeWJ+fSR%g`ED>r82<~)oq3S=fC3Nm?*Erc z8kLxorsmxL`|B{f24}4tP!Yq01Rngkc1{N(1jOxropW#Lz4LQw!-@m(_svoZ z#1;s7L>*Yw6Un{eN})I7Vh`7b5ap1_H+>8%{Wk2nu!>=(^8Ve<%Tv#%dEI`={N~Vn zjt#TV`dc}!cIWIoFt_xElf!d^Bb)`(6*M25*Ge#abc_4N8cjTRAx~7!FTC#^d zqN_uo;J5FEUr|T?zv=mRUtTjom4y-HHW1+5!z}YRe8D+xXAsZR)z4*}Q$iB}M@wVL literal 0 HcmV?d00001 diff --git a/Assets/40_Art/Components/LED.png.meta b/Assets/40_Art/Components/LED.png.meta new file mode 100644 index 0000000..a55d998 --- /dev/null +++ b/Assets/40_Art/Components/LED.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: 3cf2e1d3d97a4714e984609488d90065 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/40_Art/Components/MOSFET.png b/Assets/40_Art/Components/MOSFET.png new file mode 100644 index 0000000000000000000000000000000000000000..95a4eec786e550eca8341392589826d44105bfbd GIT binary patch literal 181 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=HJ&bxAr-gY-a5$1pvdFu_&eWf z+k&PVk7svnEfNYMuTN6(?0l8Xz|dm$ao4u9mLQ!C(>3`S4jhoY@X3xJ$c2H1y4kz` zu3DYIz%YXmCI+S_Fn*|(Y52}~JR2x(pwBSxH1iBz1y8Q+j6xqA408%zbAyz5y85}S Ib4q9e0F2Hwp#T5? literal 0 HcmV?d00001 diff --git a/Assets/40_Art/Components/MOSFET.png.meta b/Assets/40_Art/Components/MOSFET.png.meta new file mode 100644 index 0000000..9942d02 --- /dev/null +++ b/Assets/40_Art/Components/MOSFET.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: d14b76e31e4c4c64ca56f9b11fdb2d64 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/60_UI/10_Sprites/MainMenu.meta b/Assets/60_UI/10_Sprites/MainMenu.meta new file mode 100644 index 0000000..fd5c78f --- /dev/null +++ b/Assets/60_UI/10_Sprites/MainMenu.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1c0d6f24bbf95144ea74cedd131a6c41 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/60_UI/10_Sprites/MainMenu/IconPlay.png b/Assets/60_UI/10_Sprites/MainMenu/IconPlay.png new file mode 100644 index 0000000000000000000000000000000000000000..ed08b26bcf4036b157d2863a38c355fe32059f7a GIT binary patch literal 1745 zcmd6o=~t3@6vuxL_#mjE*`ih=x#p5tS#IUNV2PTh;!^ISykR|@mj{<7`FhkBmRcu9YFIw5XNk=_10Uphw}z4m?+{HLxp@Mt*Qqsr_vKez zil?OvCB12*oH3MDYd}!G*(x7&nOfLVGj)8NF?2LDH8qv=)(QPZmEZWF0>U9T@#X-B zWMQfbnwEK@GHM|C%QW~bsG=fS^D&S)kQ-$Xx+DLak?}Gwm94}5D4skEd!J?`a;db& zugvuTeID9&+`%>R$r*;v@NqS>?=v)wnvd%ux!+hh`7S!QbmG8nm_K9^-j@Dki9lfa z^GvReN{ip{-i&Ty)NIe>>6Kr+JBQE_A9D5Mu}YQ%)-%o4vg&~}nSQsg?xkV2Ee2-Q zx(Cpixznb|0vzpwIkFUSDttdhikrJMNt0P6*gXm%Kk($Bh=+Ai6I+U&neAVI=9e25 z&CsOh8-P9Q1{>LnRA4Z*ehVhZ!GuJgc>2IiEuvnpNfAMFH?YT0dp{B8j{!MLZY!2{ z9x?DFa^_$aRSy#A;3eEI&c`RQc*Hj3WU6n5v4w?hpj~VY-AR)CK=y(OnZC*nL_?LJzKxa zLYsN7C3_xr(8|F|zy}57xC#zN@x42nAHjO0Tc^)CfhTy*58xtI56GF7bzgAr6?9>V zdVh?gYcMq$6t^oIzZWa&6$&z7O)qhd#vgziHK@HU^VeIWptBz<5i4ZPv=Oq9=W5%o zP(%ZkqTl)Dxd2;M`0Z$#U8BMd5;+VMke{N4K<=P`G5Gdw>mmWz7k{iAWX~JBVxHbb z+&n)eQE_!qU?xs;7UHifMz8PhR2%PIF<#Mm>Mh%|McpRaGlydiJdZ|Um(J1u<<11C zCc94CxNQd=;V+aq`qI{QYCTD6`mhy}+YtM&w`zp?r7+^#f55jsZ?P4ZSAUz_Q#V8) zf%UG!j<2!Db~9H~3Jke{0KL77&7x)c6taVERKm4E?%3vR!`9r92UaDR8qq7 z2gpYK$*)^yL|r((H(u0+5(R(whJ9|y3^Ab5Qbm;1w_l3*u6T(#)9rGCPVR|AwuuoA z$#!d}Ac1$Yc>f)9rqZ!k7FOCfaGAWBgFgiE?JsOluV$=$xK9XhZ+N5JYOje%=J*`> zg2pgsxzg@CkXep$cll0Kf`$Sf8TGD&Fm~+=?f6ljxwQS`x(b-G$?=fBXH~t$e#?t1 zUrE2Gz2WQ|lZMQWJPk6y)m_k1F14(10|yCgBRWy-GkwyRTB$MIFUl5V(uW4>*H3Wv zy1S?>kko{7OGq@_j=F3Dr6tFeQ6-6@1=cPkf|zy=d>@BY1d2pw+MtVT95C?_H2mzx zr9vX~$ylZod4<{h?S*@h$H?$HVR93SqRGRf`d1hVPs~;$myv<|?&!^oC7wM=F=Kxk zW7^S@EiwG8#fYhcKwI{7(?MnNb8E+LOx2mAHosl_3ECISBU?0=!VdZ7pFhTwC&l3E z7#RPIl-VS)@@0qc`mf9Cu53tmTOpjY_XE9UDZ+5E@}UF{Jy6kZ%$73bHq2N3ZBpxW zdQv0Gxy0d&{b>887RJ;n7#UjNF5AIl!_JlIc7^Bn*o}V98@>eM^{Ug^1X@V4OCyNr zvu+HEUG_R|UVWi0N#dJC;fF&pe`6C|+8@57CQ@BO}0kuW2(= zUbkkyw9qQZP}T?aBjFT0iu8+S$6iX0X2$lQ-w_Mu&Wg>h9F2tY+?}JPAS_Az&RL(i zV^0`)JBn16a%qAD{EGrNt;G=|cx;XtWN2aexXt|kW0IhPGbUF%6)=SAR|Nw7f_)pk H6HfdCjm!(H literal 0 HcmV?d00001 diff --git a/Assets/60_UI/10_Sprites/MainMenu/IconPlay.png.meta b/Assets/60_UI/10_Sprites/MainMenu/IconPlay.png.meta new file mode 100644 index 0000000..5135ee1 --- /dev/null +++ b/Assets/60_UI/10_Sprites/MainMenu/IconPlay.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: 9beda06ba4b0b0a45b4f244f3b006f2d +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/60_UI/10_Sprites/MainMenu/IconQuit.png b/Assets/60_UI/10_Sprites/MainMenu/IconQuit.png new file mode 100644 index 0000000000000000000000000000000000000000..ef2cad48a584d67848a0610cbbfdaf95ca19d6cc GIT binary patch literal 1067 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrVE*Lk;uuoF_;#-2y2}m%E9lqGQRa{zyf~lF{4mu$Ir_o|LIdw^hn6-CeH}S@vIEH8@n?w$G&VzTWiH*7-5) z_llQBS6U=6JdlxKU}h+1(7P{tfZ>2_!|8H%1BL?j2cPaT@-W%9#RZ}R4Rsk$EXEobtkW&Md{+>shIV}@)~^uzm?COyj!UDmKP zF>-nH)(^>N<}ppv%$svOMzXk0VtMp2zYU^w8J_0<+c(Z!-mv4rYKDXJK3tC5lg6gN zaF);U<%h!$-Y}%JEvWes%5Z|ivHOEI;{?tovxni#3d}5P53T1opsko8UKh#`$LM(a zgEsRAAC6mX@v;r+4i~Kc@G;Ecbo~8cH$wp%OUDOm#sU?V86S2t7O=3a_+ZWSfrDko zhuusC{46Iv9A2?TyD2HhJ*T><_j>2jw9}>?pSNyaXE*C{^^Y5}4F(z9O%*&we+2v( z6iU`P3jDvm_OEq4*SZY~DScljKE8EIsW#5%hvFP2hm5<-j9N8P3=6N%ws3gGP`!@X zNY8Tmi9TIThBut`R^3ev3{Uy zKa80b>UP;2ZagE;eE!1g=OXMp4H8b;ybQX97qc0T2t;KvWOR1NF)OrP@M3oGj`gTe~DWM4f*0sH> literal 0 HcmV?d00001 diff --git a/Assets/60_UI/10_Sprites/MainMenu/IconQuit.png.meta b/Assets/60_UI/10_Sprites/MainMenu/IconQuit.png.meta new file mode 100644 index 0000000..46e5b3d --- /dev/null +++ b/Assets/60_UI/10_Sprites/MainMenu/IconQuit.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: 55caaa19b097d87419d3dc4a0391f6af +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/60_UI/10_Sprites/MainMenu/IconSettings.png b/Assets/60_UI/10_Sprites/MainMenu/IconSettings.png new file mode 100644 index 0000000000000000000000000000000000000000..2b067b99bb1777af3246ff8d9b4430af8dbbd5ee GIT binary patch literal 3152 zcmai1X*84p7k-U(WX%!{*+TZE8q3JOFOyx7y^_q7JzI>eqOpZkjBJIOEJL_&@5lG!KF>M#o^zi+_dfUBBx|?{JL_3i007v{Obu;M81*k$m`;$W z?b!zaY-h|2_3XpwHZZQ;!k-1Zwy}muVq5feOe&J*VkuJ4ogyx)pbUXi&lwPG_IijO zho?@3j2TM`Psn5(8E1}r9>%TThVrlr^2E|9A`G+<|&C7oV0 z;MDob=yP;|!1;Tz9U}u0|I_Rko3Qg*X*y?MRi}7uf)|;wAm?G8dQ`FLKHn;DN?dfa zy_7x9X;7K*Anlae-sbO?&+hVhlz^6?^Z0Fh#_QsL-L&;MMI-{$@+W?4&?in@PVOn+a;Sy zeR&DNXdKExRftC^FSKn=$Gk=K@S3_5Ti{WoEb)7qjaRJoC`~p3FCS9&lg0wyWx~Y0%1pAs>ZjNwa|O|A>_K7WfhR0s%8?U z1;?Jdx*F8(Bhh=o1zE{@kGmeMmR<3^ce?bDuFFpnVh1Q2K9UN0+!13zHEgu=2=Cft z!@rF&4s*OSxpjBJ!cbI8QcHn1lG!Kgc2k&rqa*dXf6iP|&!Xl4LPEq2*v#)JWBhBE zL}9teNOYyxoQsc{qb`yZZQ>ceyGLAVzH#W3Xtbo=<{TR5iye85mH}Q|y6#+PskA&5 zn3*ocG7}(-38XpJs8oWK8HmwNd1=}!aqvN#cXX|=7C+uMa23W@lg>p;D#6%M8s~?L z=;Q^e1T2)NC}*!@-c?qt3fck9NclF~D!-c{HH3Psk30_8-Ax0B`tp93Z!)HgJ8)Rc zRIygP7Vc05t*5KJ+s?)iHCyDqhv+#4-@|yZpt5V)rF_7lRFeA4d7nW>jC|omLW8*q z1F%fXAD=-6KBgG=_!Rs0pG>b`GMN#hl^DEt>ui6+73MjMb1i!9Z6u`rbmW2G`Ambn zy7qqkCscd%!w8OSw==8f>zj_nzI{&!bo3wJ>dZmX?)?7T+O(Q>_ty~d*>XDMUv_ZF{%DkEnOzOKVe0UyJ>f^!#X@xQqQ=tS_9ah6bTk zqXO)?ya zF|c5cXT{{~F^BUPwCm@zv<*d)d$#0ng-IKH(QpI{>CDO|tnjGFEMDEwzjd(nd}ZmN zQa5sz`Td`xCg+X(2TDZZuM4ihSugw1WPXUp-h|W2~rC>C}4pY#JPln{Mp*?SpUKZ(&7(?Pt!;rS!7)u-0jy zqk@eev@moSkF(}phT9ps5IgXSUHPGboo(IXu~r$HD+vkLXd<#{hnh)MSsSM_K5Ylp zYCicSacnNZMia_ZTP+Ac11%Y+M>STuDcfs-+OTLh?X^QfPhW}EWMzCcBNU$yg&4bV zSs2(JIq1SL!LoH0!W?Q43t^gbf|tJ=s2U*CCV8Q4(C5{{Pz3rF2QWJHDaG}&U(iEc zH$3r7<7HL3^B0GAyV=W%8rbWJk5V!oz`faTwFNjA`~+TPOuDO&sC|eUk-vERY6wSv z;(GcQ>nS6eP2~)9oC5+iwqkC*zH?|acF>jOzIq~DSoqQ)mmu@6W!Z)o55gNflXHA#;rXd{l}D$gEq94Ka>-2 z@w|u_lTQhnvO(hefBtL~2$!QibEqEdcKJXY6?QRr>rGQ$Ic9b@JIBOFcV^#3cUD=? zHVd-U%bX{+ANzvXjlWe6DZ+|8Ey9&L9)(&D;ZSarsxgonmc$&b^fHn@Z~~6u*ks0+ z@k}PaVV}h6i@6#=%fA{o5m*f%TZ`t~v`i7uwzQ`L)k~n5}0L7w_DgI%)f$!;#m z=<4uOMQcR0pUnyUsg1Ll@3q;m&|iVId3O9J#n@BtyfDAgOX7Q7Je#<5RBApens>1o zFFEy!p-7aK68OsNg+i*@UH->cE<{~b*No#@wLT*lqW)U3AU8x?3qela_HFLxM(yT+ zADaqjmj6NO3m2ofVLmCU>Zow$V#_CCniKPp@G#f1%&>h8*pt<+LL@W5#9_rmlZttj z%g$ZJ9QRIrK5Ji8kJiD^-ukB-x(qJ~6_5q#sqVcVWsF9#95)6(!$dGHA=;rSo(u&dv@}D{ME(np zxPdwvA__Nnj5d29=^LW|Un>OzYynmHPKeZWcF9Q3>LfP$#JmkUPn%c~R7v z5)Tp?K^>{{7u##w8&i5`j_lfp^zl7J+q4O79_<+#+d-kUh--1dHE5i2r|f(`cSWG> zj=IhqSLsjP)-54fd=-T=v_sZtuY5SxRuZBZY()J1m^)4H(9>*UUwy#|R2n|T_~-`# z{IdHk`{daX+KNEp_DI^D`naDKdT55B_PepA6{7G}H|`n!Xqj9BNmNUp##=BcW{K6mWm@I%Jh0X`GbpC-zEn|k!N zZ>}~uCn@ODe$<4>eUzG6url{X|B-oYX_lmy-n#HN z1tA%M+Oao;Pjb9|5#wLRX*W|!n`c*wrZUZ3Ie@i{o!-MX)vOtrO(Vtk*TdGmR=?_S z$~NuU*5{Vng8<6LnQP9^#hxQ(747`L_LcAg)YUBiX`mD{`gg%^p3X@6c(+86-lXoZ z0z2*pdSdy@MoQ3J0U-6&BE(g4kK4muUefw+ZiCN580P-+M=cvPnlzbPUSh|AvXA=a zG%)N&_b?@6pF*U+B_{#!^Tc09wV?atSaUTr*x40y+g`q=JBwm5|~f4!|4Do2dcV{vix% jFr!qAlY9Q3%rU2<|1|7alV|JXQvl42;D(j@9&!HxOyTd* literal 0 HcmV?d00001 diff --git a/Assets/60_UI/10_Sprites/MainMenu/IconSettings.png.meta b/Assets/60_UI/10_Sprites/MainMenu/IconSettings.png.meta new file mode 100644 index 0000000..6942758 --- /dev/null +++ b/Assets/60_UI/10_Sprites/MainMenu/IconSettings.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: 04cec792562d8af4c9030aac3e04a6f7 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/70_Data/10_ScriptableObjects/Components/Diode_1N4148.asset b/Assets/70_Data/10_ScriptableObjects/Components/Diode_1N4148.asset new file mode 100644 index 0000000..c982768 --- /dev/null +++ b/Assets/70_Data/10_ScriptableObjects/Components/Diode_1N4148.asset @@ -0,0 +1,40 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + 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: 11500000, guid: 60c684b44d897ec448ff093554857a02, type: 3} + m_Name: Diode_1N4148 + m_EditorClassIdentifier: + _id: diode_1n4148 + _displayName: 1N4148 Diode + _kind: 3 + _pins: [] + _footprint: + _size: {x: 0, y: 0} + _baseCost: 2 + _prefab: {fileID: 0} + _icon: {fileID: 0} + _resistanceOhms: 0 + _voltageVolts: 0 + _capacitanceFarads: 0 + _inductanceHenrys: 0 + _currentAmps: 0 + _bjtPolarity: 0 + _bjtModel: 0 + _beta: 100 + _earlyVoltage: 75 + _fetPolarity: 0 + _mosfetModel: 0 + _thresholdVoltage: 2 + _transconductance: 0.3 + _diodeModel: 0 + _saturationCurrent: 2.52e-9 + _emissionCoefficient: 1.752 + _forwardVoltage: 0.7 diff --git a/Assets/70_Data/10_ScriptableObjects/Components/Diode_1N4148.asset.meta b/Assets/70_Data/10_ScriptableObjects/Components/Diode_1N4148.asset.meta new file mode 100644 index 0000000..b660397 --- /dev/null +++ b/Assets/70_Data/10_ScriptableObjects/Components/Diode_1N4148.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f2efa2aa19683584aa5554d883ecb215 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/70_Data/10_ScriptableObjects/Components/LED_Red.asset b/Assets/70_Data/10_ScriptableObjects/Components/LED_Red.asset new file mode 100644 index 0000000..923c6ef --- /dev/null +++ b/Assets/70_Data/10_ScriptableObjects/Components/LED_Red.asset @@ -0,0 +1,40 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + 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: 11500000, guid: 60c684b44d897ec448ff093554857a02, type: 3} + m_Name: LED_Red + m_EditorClassIdentifier: + _id: led_red + _displayName: Red LED + _kind: 4 + _pins: [] + _footprint: + _size: {x: 0, y: 0} + _baseCost: 3 + _prefab: {fileID: 0} + _icon: {fileID: 0} + _resistanceOhms: 0 + _voltageVolts: 0 + _capacitanceFarads: 0 + _inductanceHenrys: 0 + _currentAmps: 0 + _bjtPolarity: 0 + _bjtModel: 0 + _beta: 100 + _earlyVoltage: 75 + _fetPolarity: 0 + _mosfetModel: 0 + _thresholdVoltage: 2 + _transconductance: 0.3 + _diodeModel: 0 + _saturationCurrent: 1e-14 + _emissionCoefficient: 2.0 + _forwardVoltage: 1.8 diff --git a/Assets/70_Data/10_ScriptableObjects/Components/LED_Red.asset.meta b/Assets/70_Data/10_ScriptableObjects/Components/LED_Red.asset.meta new file mode 100644 index 0000000..ca8f19b --- /dev/null +++ b/Assets/70_Data/10_ScriptableObjects/Components/LED_Red.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f448ff2a8f75f874886a7d9b90a504bd +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: From 33df478e23e9f656c570f8b139b7c45c81423e27 Mon Sep 17 00:00:00 2001 From: okenic03-code Date: Fri, 13 Feb 2026 03:29:39 +0900 Subject: [PATCH 005/115] feat: add stage manager, progression system, and World 1 stage content Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- .../10_Runtime/20_Managers/GameManager.cs | 14 + .../20_Managers/ProgressionManager.cs | 274 ++++++++++++++++++ .../20_Managers/ProgressionManager.cs.meta | 11 + .../10_Runtime/20_Managers/StageManager.cs | 136 +++++++++ .../20_Managers/StageManager.cs.meta | 11 + .../Events/BoardEventChannel.asset | 14 + .../Events/BoardEventChannel.asset.meta | 8 + .../Events/SimulationEventChannel.asset | 14 + .../Events/SimulationEventChannel.asset.meta | 8 + .../Events/StageEventChannel.asset | 14 + .../Events/StageEventChannel.asset.meta | 8 + .../Stages/Stage1-2_VoltageDivider.asset | 31 ++ .../Stages/Stage1-2_VoltageDivider.asset.meta | 8 + .../Stages/Stage1-3_LEDCircuit.asset | 31 ++ .../Stages/Stage1-3_LEDCircuit.asset.meta | 8 + .../Stages/Stage1-4_ParallelResistors.asset | 31 ++ .../Stage1-4_ParallelResistors.asset.meta | 8 + .../Stages/Stage1-5_ComplexDC.asset | 32 ++ .../Stages/Stage1-5_ComplexDC.asset.meta | 8 + 19 files changed, 669 insertions(+) create mode 100644 Assets/10_Scripts/10_Runtime/20_Managers/ProgressionManager.cs create mode 100644 Assets/10_Scripts/10_Runtime/20_Managers/ProgressionManager.cs.meta create mode 100644 Assets/10_Scripts/10_Runtime/20_Managers/StageManager.cs create mode 100644 Assets/10_Scripts/10_Runtime/20_Managers/StageManager.cs.meta create mode 100644 Assets/70_Data/10_ScriptableObjects/Events/BoardEventChannel.asset create mode 100644 Assets/70_Data/10_ScriptableObjects/Events/BoardEventChannel.asset.meta create mode 100644 Assets/70_Data/10_ScriptableObjects/Events/SimulationEventChannel.asset create mode 100644 Assets/70_Data/10_ScriptableObjects/Events/SimulationEventChannel.asset.meta create mode 100644 Assets/70_Data/10_ScriptableObjects/Events/StageEventChannel.asset create mode 100644 Assets/70_Data/10_ScriptableObjects/Events/StageEventChannel.asset.meta create mode 100644 Assets/70_Data/10_ScriptableObjects/Stages/Stage1-2_VoltageDivider.asset create mode 100644 Assets/70_Data/10_ScriptableObjects/Stages/Stage1-2_VoltageDivider.asset.meta create mode 100644 Assets/70_Data/10_ScriptableObjects/Stages/Stage1-3_LEDCircuit.asset create mode 100644 Assets/70_Data/10_ScriptableObjects/Stages/Stage1-3_LEDCircuit.asset.meta create mode 100644 Assets/70_Data/10_ScriptableObjects/Stages/Stage1-4_ParallelResistors.asset create mode 100644 Assets/70_Data/10_ScriptableObjects/Stages/Stage1-4_ParallelResistors.asset.meta create mode 100644 Assets/70_Data/10_ScriptableObjects/Stages/Stage1-5_ComplexDC.asset create mode 100644 Assets/70_Data/10_ScriptableObjects/Stages/Stage1-5_ComplexDC.asset.meta diff --git a/Assets/10_Scripts/10_Runtime/20_Managers/GameManager.cs b/Assets/10_Scripts/10_Runtime/20_Managers/GameManager.cs index cdcc61f..bce0bc2 100644 --- a/Assets/10_Scripts/10_Runtime/20_Managers/GameManager.cs +++ b/Assets/10_Scripts/10_Runtime/20_Managers/GameManager.cs @@ -57,6 +57,20 @@ private void InitializeBoardState() /// public BoardState BoardState => _boardState; + /// + /// Resets the board to a new empty state with the specified dimensions. + /// Used by StageManager when loading a new stage. + /// + /// Board width in grid cells. + /// Board height in grid cells. + public void ResetBoard(int width, int height) + { + _boardWidth = width; + _boardHeight = height; + _boardState = new BoardState(width, height); + Debug.Log($"GameManager: Board reset ({width}x{height})"); + } + /// /// Whether a simulation is currently in progress. /// diff --git a/Assets/10_Scripts/10_Runtime/20_Managers/ProgressionManager.cs b/Assets/10_Scripts/10_Runtime/20_Managers/ProgressionManager.cs new file mode 100644 index 0000000..4cacff3 --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/20_Managers/ProgressionManager.cs @@ -0,0 +1,274 @@ +using System; +using System.Collections.Generic; +using CircuitCraft.Core; +using CircuitCraft.Data; +using UnityEngine; + +namespace CircuitCraft.Managers +{ + /// + /// Tracks stage unlock state and best star ratings. + /// Completing a stage automatically unlocks the next stage in the same world. + /// Persistence (save/load) is handled separately by a future system. + /// + public class ProgressionManager : MonoBehaviour + { + [Header("Dependencies")] + [SerializeField] private StageManager _stageManager; + + [Header("Stage Data")] + [SerializeField] + [Tooltip("All stages in the game, used to resolve next-stage lookups.")] + private StageDefinition[] _allStages; + + private readonly Dictionary _unlockedStages = new(); + private readonly Dictionary _bestStars = new(); + + /// Raised when a stage becomes newly unlocked. Parameter is the stageId. + public event Action OnStageUnlocked; + + private void Awake() + { + InitializeDefaults(); + LoadProgress(); + } + + private void OnEnable() + { + if (_stageManager != null) + _stageManager.OnStageCompleted += HandleStageCompleted; + } + + private void OnDisable() + { + if (_stageManager != null) + _stageManager.OnStageCompleted -= HandleStageCompleted; + } + + /// + /// Unlocks the first stage of each world by default. + /// + private void InitializeDefaults() + { + if (_allStages == null) return; + + foreach (var stage in _allStages) + { + if (stage == null) continue; + if (stage.StageNumber == 1) + _unlockedStages[stage.StageId] = true; + } + } + + /// + /// Handles the StageManager.OnStageCompleted event by recording + /// the completion of the current stage with the earned stars. + /// + private void HandleStageCompleted(ScoreBreakdown breakdown) + { + if (breakdown == null) return; + + var currentStage = _stageManager.CurrentStage; + if (currentStage == null) + { + Debug.LogWarning("ProgressionManager: OnStageCompleted fired but CurrentStage is null."); + return; + } + + // Only record progression if the player actually passed + if (!breakdown.Passed) return; + + RecordStageCompletion(currentStage.StageId, breakdown.Stars); + } + + /// + /// Records a stage completion: updates the best star rating (if improved) + /// and unlocks the next stage in the same world. + /// + /// The unique stage identifier. + /// Star rating earned (0-3). + public void RecordStageCompletion(string stageId, int stars) + { + if (string.IsNullOrEmpty(stageId)) + { + Debug.LogWarning("ProgressionManager: Cannot record completion for null/empty stageId."); + return; + } + + // Update best stars if this attempt is better + if (!_bestStars.TryGetValue(stageId, out int previousBest) || stars > previousBest) + { + _bestStars[stageId] = stars; + } + + // Mark the completed stage as unlocked (in case it wasn't already) + _unlockedStages[stageId] = true; + + // Find and unlock the next stage in the same world + var nextStage = FindNextStage(stageId); + if (nextStage != null) + { + UnlockStage(nextStage.StageId); + } + + // Save progress after recording completion + SaveProgress(); + } + + /// + /// Returns whether the specified stage is unlocked. + /// + /// The unique stage identifier. + /// True if the stage is unlocked, false otherwise. + public bool IsStageUnlocked(string stageId) + { + if (string.IsNullOrEmpty(stageId)) return false; + return _unlockedStages.TryGetValue(stageId, out bool unlocked) && unlocked; + } + + /// + /// Returns the best star rating achieved for the specified stage. + /// + /// The unique stage identifier. + /// Best star count (0 if never completed). + public int GetBestStars(string stageId) + { + if (string.IsNullOrEmpty(stageId)) return 0; + return _bestStars.TryGetValue(stageId, out int stars) ? stars : 0; + } + + /// + /// Manually unlocks a stage. Fires OnStageUnlocked if the stage was not already unlocked. + /// + /// The unique stage identifier to unlock. + public void UnlockStage(string stageId) + { + if (string.IsNullOrEmpty(stageId)) + { + Debug.LogWarning("ProgressionManager: Cannot unlock null/empty stageId."); + return; + } + + if (_unlockedStages.TryGetValue(stageId, out bool alreadyUnlocked) && alreadyUnlocked) + return; + + _unlockedStages[stageId] = true; + Debug.Log($"ProgressionManager: Stage '{stageId}' unlocked."); + OnStageUnlocked?.Invoke(stageId); + } + + /// + /// Finds the next stage in the same world (stageNumber + 1). + /// + /// The stageId of the current stage. + /// The next StageDefinition, or null if there is no next stage. + private StageDefinition FindNextStage(string currentStageId) + { + if (_allStages == null) return null; + + // First, find the current stage definition to get worldId and stageNumber + StageDefinition current = null; + foreach (var stage in _allStages) + { + if (stage != null && stage.StageId == currentStageId) + { + current = stage; + break; + } + } + + if (current == null) return null; + + // Find the stage in the same world with stageNumber + 1 + int nextNumber = current.StageNumber + 1; + string worldId = current.WorldId; + + foreach (var stage in _allStages) + { + if (stage != null && stage.WorldId == worldId && stage.StageNumber == nextNumber) + return stage; + } + + return null; + } + + /// + /// Saves all progression data (unlock states and star ratings) to PlayerPrefs. + /// + public void SaveProgress() + { + if (_allStages == null) return; + + foreach (var stage in _allStages) + { + if (stage == null) continue; + + string stageId = stage.StageId; + + // Save unlock state + bool isUnlocked = _unlockedStages.TryGetValue(stageId, out bool unlocked) && unlocked; + PlayerPrefs.SetInt($"progress_unlock_{stageId}", isUnlocked ? 1 : 0); + + // Save best stars + int bestStars = _bestStars.TryGetValue(stageId, out int stars) ? stars : 0; + PlayerPrefs.SetInt($"progress_stars_{stageId}", bestStars); + } + + PlayerPrefs.Save(); + Debug.Log("ProgressionManager: Progress saved."); + } + + /// + /// Loads all progression data from PlayerPrefs and restores dictionaries. + /// + public void LoadProgress() + { + if (_allStages == null) return; + + foreach (var stage in _allStages) + { + if (stage == null) continue; + + string stageId = stage.StageId; + + // Load unlock state + string unlockKey = $"progress_unlock_{stageId}"; + if (PlayerPrefs.HasKey(unlockKey)) + { + bool isUnlocked = PlayerPrefs.GetInt(unlockKey) == 1; + _unlockedStages[stageId] = isUnlocked; + } + + // Load best stars + string starsKey = $"progress_stars_{stageId}"; + if (PlayerPrefs.HasKey(starsKey)) + { + int bestStars = PlayerPrefs.GetInt(starsKey); + _bestStars[stageId] = bestStars; + } + } + + Debug.Log("ProgressionManager: Progress loaded."); + } + + /// + /// Clears all saved progression data from PlayerPrefs (for testing/reset). + /// + public void ClearProgress() + { + if (_allStages == null) return; + + foreach (var stage in _allStages) + { + if (stage == null) continue; + + string stageId = stage.StageId; + PlayerPrefs.DeleteKey($"progress_unlock_{stageId}"); + PlayerPrefs.DeleteKey($"progress_stars_{stageId}"); + } + + PlayerPrefs.Save(); + Debug.Log("ProgressionManager: Progress cleared."); + } + } +} diff --git a/Assets/10_Scripts/10_Runtime/20_Managers/ProgressionManager.cs.meta b/Assets/10_Scripts/10_Runtime/20_Managers/ProgressionManager.cs.meta new file mode 100644 index 0000000..971a9d2 --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/20_Managers/ProgressionManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2949f1183b3f9054eba2e104e36686d9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/10_Scripts/10_Runtime/20_Managers/StageManager.cs b/Assets/10_Scripts/10_Runtime/20_Managers/StageManager.cs new file mode 100644 index 0000000..c86d021 --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/20_Managers/StageManager.cs @@ -0,0 +1,136 @@ +using System; +using CircuitCraft.Core; +using CircuitCraft.Data; +using CircuitCraft.Simulation; +using Cysharp.Threading.Tasks; +using UnityEngine; + +namespace CircuitCraft.Managers +{ + /// + /// Bootstraps a stage from a StageDefinition. + /// Resets the board, populates the component palette, and orchestrates + /// the simulation → evaluation → scoring flow. + /// + public class StageManager : MonoBehaviour + { + [Header("Dependencies")] + [SerializeField] private GameManager _gameManager; + [SerializeField] private SimulationManager _simulationManager; + + private StageDefinition _currentStage; + private ObjectiveEvaluator _objectiveEvaluator; + private ScoringSystem _scoringSystem; + + /// Raised after a stage is loaded and ready for play. + public event Action OnStageLoaded; + + /// Raised when simulation + evaluation + scoring completes. + public event Action OnStageCompleted; + + /// The currently loaded stage, or null. + public StageDefinition CurrentStage => _currentStage; + + private void Awake() + { + _objectiveEvaluator = new ObjectiveEvaluator(); + _scoringSystem = new ScoringSystem(); + } + + /// + /// Loads a stage: resets the board to the stage grid size, + /// populates the palette with allowed components, and fires OnStageLoaded. + /// + /// The stage definition to load. + public void LoadStage(StageDefinition stage) + { + if (stage == null) + throw new ArgumentNullException(nameof(stage)); + + _currentStage = stage; + + // Reset board to stage grid dimensions + _gameManager.ResetBoard(stage.GridSize.x, stage.GridSize.y); + + Debug.Log($"StageManager: Loaded stage '{stage.DisplayName}' ({stage.GridSize.x}x{stage.GridSize.y})"); + OnStageLoaded?.Invoke(); + } + + /// + /// Runs simulation on the current board, evaluates against stage test cases, + /// calculates the score, and fires OnStageCompleted with the breakdown. + /// + public void RunSimulationAndEvaluate() + { + if (_currentStage == null) + { + Debug.LogWarning("StageManager: No stage loaded. Call LoadStage first."); + return; + } + + if (_simulationManager.IsSimulating) + { + Debug.LogWarning("StageManager: Simulation already in progress."); + return; + } + + RunSimulationAndEvaluateAsync().Forget(); + } + + private async UniTaskVoid RunSimulationAndEvaluateAsync() + { + var boardState = _gameManager.BoardState; + + // Run simulation and await completion + await _simulationManager.RunSimulationAsync(boardState); + var simResult = _simulationManager.LastSimulationResult; + + // Convert StageTestCase[] → TestCaseInput[] (domain DTO bridge) + var stageTestCases = _currentStage.TestCases; + var testCaseInputs = new TestCaseInput[stageTestCases != null ? stageTestCases.Length : 0]; + for (int i = 0; i < testCaseInputs.Length; i++) + { + var stc = stageTestCases[i]; + testCaseInputs[i] = new TestCaseInput( + stc.TestName, + stc.ExpectedVoltage, + stc.Tolerance + ); + } + + // Evaluate objectives against test cases + var evalResult = _objectiveEvaluator.Evaluate(simResult, testCaseInputs); + + // Calculate total component cost by summing BaseCost of each placed component + float totalCost = 0f; + foreach (var component in boardState.Components) + { + var def = _simulationManager.GetComponentDefinition(component.ComponentDefinitionId); + if (def != null) + { + totalCost += def.BaseCost; + } + } + + // Build scoring input from evaluation + board data + stage constraints + int maxComponentCount = _currentStage.Constraints != null + ? _currentStage.Constraints.MaxComponentCount + : 0; + + var scoringInput = new ScoringInput( + circuitPassed: evalResult.Passed, + totalComponentCost: totalCost, + budgetLimit: _currentStage.BudgetLimit, + componentCount: boardState.Components.Count, + maxComponentCount: maxComponentCount, + traceCount: boardState.Traces.Count + ); + + // Calculate final score breakdown + var scoreBreakdown = _scoringSystem.Calculate(scoringInput); + + Debug.Log($"StageManager: Stage '{_currentStage.DisplayName}' completed — {scoreBreakdown.Summary}"); + OnStageCompleted?.Invoke(scoreBreakdown); + } + } +} diff --git a/Assets/10_Scripts/10_Runtime/20_Managers/StageManager.cs.meta b/Assets/10_Scripts/10_Runtime/20_Managers/StageManager.cs.meta new file mode 100644 index 0000000..abaa481 --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/20_Managers/StageManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 29d19ef505509b842a69eaa037715c91 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/70_Data/10_ScriptableObjects/Events/BoardEventChannel.asset b/Assets/70_Data/10_ScriptableObjects/Events/BoardEventChannel.asset new file mode 100644 index 0000000..59825d7 --- /dev/null +++ b/Assets/70_Data/10_ScriptableObjects/Events/BoardEventChannel.asset @@ -0,0 +1,14 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + 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: 11500000, guid: db45b4e086eb6c9408922e502f4d41f7, type: 3} + m_Name: BoardEventChannel + m_EditorClassIdentifier: diff --git a/Assets/70_Data/10_ScriptableObjects/Events/BoardEventChannel.asset.meta b/Assets/70_Data/10_ScriptableObjects/Events/BoardEventChannel.asset.meta new file mode 100644 index 0000000..0893c7b --- /dev/null +++ b/Assets/70_Data/10_ScriptableObjects/Events/BoardEventChannel.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 702270412d4438b49a9105f644d352ae +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/70_Data/10_ScriptableObjects/Events/SimulationEventChannel.asset b/Assets/70_Data/10_ScriptableObjects/Events/SimulationEventChannel.asset new file mode 100644 index 0000000..cfa9672 --- /dev/null +++ b/Assets/70_Data/10_ScriptableObjects/Events/SimulationEventChannel.asset @@ -0,0 +1,14 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + 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: 11500000, guid: 5d4122263845127429c40d6ad4bc661a, type: 3} + m_Name: SimulationEventChannel + m_EditorClassIdentifier: diff --git a/Assets/70_Data/10_ScriptableObjects/Events/SimulationEventChannel.asset.meta b/Assets/70_Data/10_ScriptableObjects/Events/SimulationEventChannel.asset.meta new file mode 100644 index 0000000..975cb2c --- /dev/null +++ b/Assets/70_Data/10_ScriptableObjects/Events/SimulationEventChannel.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c3d4e5f607182930415a6b7c8d9e0fb2 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/70_Data/10_ScriptableObjects/Events/StageEventChannel.asset b/Assets/70_Data/10_ScriptableObjects/Events/StageEventChannel.asset new file mode 100644 index 0000000..6bfae2a --- /dev/null +++ b/Assets/70_Data/10_ScriptableObjects/Events/StageEventChannel.asset @@ -0,0 +1,14 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + 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: 11500000, guid: 6a16a3db38137f94696f79fb7ae42e21, type: 3} + m_Name: StageEventChannel + m_EditorClassIdentifier: diff --git a/Assets/70_Data/10_ScriptableObjects/Events/StageEventChannel.asset.meta b/Assets/70_Data/10_ScriptableObjects/Events/StageEventChannel.asset.meta new file mode 100644 index 0000000..9d4fff3 --- /dev/null +++ b/Assets/70_Data/10_ScriptableObjects/Events/StageEventChannel.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b2c3d4e5f6071829304a5b6c7d8e9fa1 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-2_VoltageDivider.asset b/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-2_VoltageDivider.asset new file mode 100644 index 0000000..2c9132b --- /dev/null +++ b/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-2_VoltageDivider.asset @@ -0,0 +1,31 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + 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: 11500000, guid: ed85e5a7b3856be449b831e8bdb2abfe, type: 3} + m_Name: Stage1-2_VoltageDivider + m_EditorClassIdentifier: + _stageId: 1-2 + _displayName: Voltage Divider + _worldId: world1 + _stageNumber: 2 + _gridSize: {x: 10, y: 10} + _allowedComponents: + - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} + - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} + - {fileID: 11400000, guid: 66e631d4439b5d34d9b358060a2fd734, type: 2} + - {fileID: 11400000, guid: a59f82134262bd6478d58c4667b5e989, type: 2} + _testCases: + - _testName: VOUT Voltage Check + _expectedVoltage: 3.33 + _tolerance: 0.2 + _budgetLimit: 10 + _constraints: + _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-2_VoltageDivider.asset.meta b/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-2_VoltageDivider.asset.meta new file mode 100644 index 0000000..e918f6c --- /dev/null +++ b/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-2_VoltageDivider.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a1b2c3d4e5f60718293a4b5c6d7e8f90 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-3_LEDCircuit.asset b/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-3_LEDCircuit.asset new file mode 100644 index 0000000..f0744a2 --- /dev/null +++ b/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-3_LEDCircuit.asset @@ -0,0 +1,31 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + 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: 11500000, guid: ed85e5a7b3856be449b831e8bdb2abfe, type: 3} + m_Name: Stage1-3_LEDCircuit + m_EditorClassIdentifier: + _stageId: 1-3 + _displayName: LED Circuit + _worldId: world1 + _stageNumber: 3 + _gridSize: {x: 12, y: 12} + _allowedComponents: + - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} + - {fileID: 11400000, guid: 66e631d4439b5d34d9b358060a2fd734, type: 2} + - {fileID: 11400000, guid: a59f82134262bd6478d58c4667b5e989, type: 2} + - {fileID: 11400000, guid: adbd9050ec83469bbe3f4926739eb08e, type: 2} + _testCases: + - _testName: Resistor Voltage Drop Check + _expectedVoltage: 3.3 + _tolerance: 0.3 + _budgetLimit: 15 + _constraints: + _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-3_LEDCircuit.asset.meta b/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-3_LEDCircuit.asset.meta new file mode 100644 index 0000000..963e37e --- /dev/null +++ b/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-3_LEDCircuit.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b2c3d4e5f6071829304a5b6c7d8e9f01 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-4_ParallelResistors.asset b/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-4_ParallelResistors.asset new file mode 100644 index 0000000..1d2e3f5 --- /dev/null +++ b/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-4_ParallelResistors.asset @@ -0,0 +1,31 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + 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: 11500000, guid: ed85e5a7b3856be449b831e8bdb2abfe, type: 3} + m_Name: Stage1-4_ParallelResistors + m_EditorClassIdentifier: + _stageId: 1-4 + _displayName: Parallel Resistors + _worldId: world1 + _stageNumber: 4 + _gridSize: {x: 12, y: 12} + _allowedComponents: + - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} + - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} + - {fileID: 11400000, guid: 66e631d4439b5d34d9b358060a2fd734, type: 2} + - {fileID: 11400000, guid: a59f82134262bd6478d58c4667b5e989, type: 2} + _testCases: + - _testName: Junction Voltage Check + _expectedVoltage: 5 + _tolerance: 0.1 + _budgetLimit: 15 + _constraints: + _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-4_ParallelResistors.asset.meta b/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-4_ParallelResistors.asset.meta new file mode 100644 index 0000000..c60e86c --- /dev/null +++ b/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-4_ParallelResistors.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c3d4e5f607182930415a6b7c8d9e0f12 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-5_ComplexDC.asset b/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-5_ComplexDC.asset new file mode 100644 index 0000000..3fff530 --- /dev/null +++ b/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-5_ComplexDC.asset @@ -0,0 +1,32 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + 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: 11500000, guid: ed85e5a7b3856be449b831e8bdb2abfe, type: 3} + m_Name: Stage1-5_ComplexDC + m_EditorClassIdentifier: + _stageId: 1-5 + _displayName: Complex DC Circuit + _worldId: world1 + _stageNumber: 5 + _gridSize: {x: 14, y: 14} + _allowedComponents: + - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} + - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} + - {fileID: 11400000, guid: 66e631d4439b5d34d9b358060a2fd734, type: 2} + - {fileID: 11400000, guid: a59f82134262bd6478d58c4667b5e989, type: 2} + - {fileID: 11400000, guid: 82b7cdda793441b89b68bd4c2dc3db74, type: 2} + _testCases: + - _testName: Output Voltage After Diode + _expectedVoltage: 4.3 + _tolerance: 0.2 + _budgetLimit: 20 + _constraints: + _maxComponentCount: 8 diff --git a/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-5_ComplexDC.asset.meta b/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-5_ComplexDC.asset.meta new file mode 100644 index 0000000..2351053 --- /dev/null +++ b/Assets/70_Data/10_ScriptableObjects/Stages/Stage1-5_ComplexDC.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d4e5f6071829304152a6b7c8d9e0f123 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: From 651c22f20bd74ae2dce3cd199718565dbe1c3ab6 Mon Sep 17 00:00:00 2001 From: okenic03-code Date: Fri, 13 Feb 2026 03:30:01 +0900 Subject: [PATCH 006/115] feat: add save/load persistence and simulation pipeline integration Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- .../30_UI/ComponentPaletteController.cs | 29 +- .../30_UI/ResultsPanelController.cs | 84 +++++- .../30_UI/SimulationButtonController.cs | 21 +- .../10_Runtime/40_Systems/Persistence.meta | 8 + .../40_Systems/Persistence/BoardSaveData.cs | 135 ++++++++++ .../Persistence/BoardSaveData.cs.meta | 11 + .../40_Systems/Persistence/SaveLoadService.cs | 255 ++++++++++++++++++ .../Persistence/SaveLoadService.cs.meta | 11 + Assets/20_UI/USS/GameUI.uss | 81 ++++++ Assets/20_UI/UXML/GameUI.uxml | 13 + 10 files changed, 633 insertions(+), 15 deletions(-) create mode 100644 Assets/10_Scripts/10_Runtime/40_Systems/Persistence.meta create mode 100644 Assets/10_Scripts/10_Runtime/40_Systems/Persistence/BoardSaveData.cs create mode 100644 Assets/10_Scripts/10_Runtime/40_Systems/Persistence/BoardSaveData.cs.meta create mode 100644 Assets/10_Scripts/10_Runtime/40_Systems/Persistence/SaveLoadService.cs create mode 100644 Assets/10_Scripts/10_Runtime/40_Systems/Persistence/SaveLoadService.cs.meta diff --git a/Assets/10_Scripts/10_Runtime/30_UI/ComponentPaletteController.cs b/Assets/10_Scripts/10_Runtime/30_UI/ComponentPaletteController.cs index 14c700a..d364197 100644 --- a/Assets/10_Scripts/10_Runtime/30_UI/ComponentPaletteController.cs +++ b/Assets/10_Scripts/10_Runtime/30_UI/ComponentPaletteController.cs @@ -35,6 +35,7 @@ public class ComponentPaletteController : MonoBehaviour private List<(Button btn, Action action)> _registeredCallbacks; private VisualElement _root; + private Button _selectedButton; private void Awake() => Init(); @@ -136,6 +137,22 @@ private void UnregisterCallbacks() _registeredCallbacks.Clear(); } + /// + /// Sets the available component definitions at runtime (e.g. when loading a new stage). + /// Replaces the current definitions and re-registers button callbacks. + /// + /// The component definitions to make available in the palette. + public void SetAvailableComponents(ComponentDefinition[] components) + { + _componentDefinitions = components; + + // Re-register callbacks if we have a live root element + if (_root != null) + { + RegisterCallbacks(); + } + } + /// /// Handler for component button clicks. /// Notifies PlacementController to select the component. @@ -146,8 +163,16 @@ private void OnComponentButtonClicked(ComponentDefinition def) { _placementController.SetSelectedComponent(def); - // TODO: Add visual feedback (highlight selected button) if needed. - // This could be handled via USS pseudo-states or manually setting classes. + // Remove "selected" class from previously selected button + if (_selectedButton != null) + { + _selectedButton.RemoveFromClassList("selected"); + } + + // Find and highlight the newly selected button + var btn = _root.Q public class ScoringSystem { private const int BASE_SCORE = 1000; private const int BUDGET_BONUS = 500; - private const int COMPACT_BONUS = 300; + private const int AREA_BONUS = 300; /// /// Calculates score breakdown from the given scoring input. @@ -38,7 +39,7 @@ public ScoreBreakdown Calculate(ScoringInput input) else { lineItems.Add(new ScoreLineItem("Circuit Failed", 0)); - return BuildResult(baseScore, 0, 0, false, lineItems); + return BuildResult(baseScore, 0, 0, false, lineItems, false); } // --- Budget bonus --- @@ -61,27 +62,15 @@ public ScoreBreakdown Calculate(ScoringInput input) 0)); } - // --- Compact bonus --- - bool withinComponentLimit = IsWithinComponentLimit(input); - int compactBonus = 0; - if (withinComponentLimit) - { - compactBonus = COMPACT_BONUS; - if (input.MaxComponentCount > 0) - lineItems.Add(new ScoreLineItem( - $"Compact Build ({input.ComponentCount}/{input.MaxComponentCount})", - COMPACT_BONUS)); - else - lineItems.Add(new ScoreLineItem("Components: No Limit", COMPACT_BONUS)); - } - else - { - lineItems.Add(new ScoreLineItem( - $"Too Many Components ({input.ComponentCount}/{input.MaxComponentCount})", - 0)); - } + // --- Area bonus --- + bool withinTarget = IsWithinAreaTarget(input); + int areaBonus = CalculateAreaBonus(input); + string areaLabel = withinTarget + ? $"Small Footprint ({input.BoardArea}/{input.TargetArea})" + : $"Over Footprint Target ({input.BoardArea}/{input.TargetArea})"; + lineItems.Add(new ScoreLineItem(areaLabel, areaBonus)); - return BuildResult(baseScore, budgetBonus, compactBonus, true, lineItems); + return BuildResult(baseScore, budgetBonus, areaBonus, true, lineItems, withinTarget); } /// @@ -94,24 +83,37 @@ private static bool IsUnderBudget(ScoringInput input) } /// - /// Within component limit if no limit is set (0) or count <= max. + /// Within target area if no target is set (0) or board area is within target. + /// + private static bool IsWithinAreaTarget(ScoringInput input) + { + float targetArea = Math.Max(1f, input.TargetArea); + float boardArea = Math.Max(1f, input.BoardArea); + return boardArea <= targetArea; + } + + /// + /// Compute linear area bonus points from board-to-target area ratio. /// - private static bool IsWithinComponentLimit(ScoringInput input) + private static int CalculateAreaBonus(ScoringInput input) { - if (input.MaxComponentCount <= 0) return true; // no limit → auto-pass - return input.ComponentCount <= input.MaxComponentCount; + float targetArea = Math.Max(1f, input.TargetArea); + float boardArea = Math.Max(1, input.BoardArea); + float areaRatio = boardArea / targetArea; + float areaFactor = Math.Max(0f, Math.Min(1f, 2f - areaRatio)); + return (int)Math.Round(AREA_BONUS * areaFactor); } /// /// Calculates star count from bonus flags. /// - private static int CalculateStars(bool passed, bool underBudget, bool withinComponentLimit) + private static int CalculateStars(bool passed, bool underBudget, bool withinTarget) { if (!passed) return 0; int bonusCount = 0; if (underBudget) bonusCount++; - if (withinComponentLimit) bonusCount++; + if (withinTarget) bonusCount++; // 1★ base + bonuses (max 3★) return 1 + bonusCount; @@ -120,21 +122,21 @@ private static int CalculateStars(bool passed, bool underBudget, bool withinComp private static ScoreBreakdown BuildResult( int baseScore, int budgetBonus, - int compactBonus, + int areaBonus, bool passed, - List lineItems) + List lineItems, + bool withinTarget) { - int totalScore = baseScore + budgetBonus + compactBonus; + int totalScore = baseScore + budgetBonus + areaBonus; bool underBudget = budgetBonus > 0; - bool withinLimit = compactBonus > 0; - int stars = CalculateStars(passed, underBudget, withinLimit); + int stars = CalculateStars(passed, underBudget, withinTarget); string summary = BuildSummary(passed, stars, totalScore, lineItems); return new ScoreBreakdown( baseScore, budgetBonus, - compactBonus, + areaBonus, totalScore, stars, passed, diff --git a/Assets/10_Scripts/10_Runtime/20_Views/GridRenderer.cs b/Assets/10_Scripts/10_Runtime/20_Views/GridRenderer.cs index 7a98967..066069f 100644 --- a/Assets/10_Scripts/10_Runtime/20_Views/GridRenderer.cs +++ b/Assets/10_Scripts/10_Runtime/20_Views/GridRenderer.cs @@ -16,14 +16,9 @@ public class GridRenderer : MonoBehaviour [SerializeField] private Material _lineMaterial; [SerializeField] private Shader _defaultShader; - [Header("Suggested Area")] - [SerializeField] private Color _suggestedAreaBorderColor = new Color(0.3f, 0.5f, 0.8f, 1f); - [SerializeField] private float _suggestedAreaBorderWidth = 0.06f; - private GameObject _gridContainer; private readonly List _horizontalLines = new List(); private readonly List _verticalLines = new List(); - private readonly List _suggestedAreaLines = new List(4); private Vector3 _cachedCamPos; private float _cachedOrthoSize; @@ -89,7 +84,6 @@ private void LateUpdate() UpdateHorizontalLines(gridMinY, gridMaxY, gridMinX, gridMaxX, origin, cellSize); UpdateVerticalLines(gridMinX, gridMaxX, gridMinY, gridMaxY, origin, cellSize); - UpdateSuggestedAreaBorder(origin, cellSize); } if (_visualsDirty) @@ -187,30 +181,6 @@ private void UpdateVerticalLines(int gridMinX, int gridMaxX, int gridMinY, int g DisableUnusedLines(_verticalLines, neededCount); } - private void UpdateSuggestedAreaBorder(Vector3 origin, float cellSize) - { - EnsureLinePoolSize(_suggestedAreaLines, 4, "SuggestedBorder", _suggestedAreaBorderColor, _suggestedAreaBorderWidth); - - float x0 = origin.x; - float z0 = origin.z; - float x1 = origin.x + (_gridSettings.SuggestedWidth * cellSize); - float z1 = origin.z + (_gridSettings.SuggestedHeight * cellSize); - float y = origin.y; - - SetBorderLine(_suggestedAreaLines[0], new Vector3(x0, y, z0), new Vector3(x1, y, z0)); - SetBorderLine(_suggestedAreaLines[1], new Vector3(x1, y, z0), new Vector3(x1, y, z1)); - SetBorderLine(_suggestedAreaLines[2], new Vector3(x1, y, z1), new Vector3(x0, y, z1)); - SetBorderLine(_suggestedAreaLines[3], new Vector3(x0, y, z1), new Vector3(x0, y, z0)); - } - - private void SetBorderLine(LineRenderer line, Vector3 start, Vector3 end) - { - line.enabled = true; - line.positionCount = 2; - line.SetPosition(0, start); - line.SetPosition(1, end); - } - private void EnsureLinePoolSize(List pool, int requiredCount, string linePrefix, Color lineColor, float lineWidth) { while (pool.Count < requiredCount) @@ -239,10 +209,6 @@ private void UpdateLineVisuals() SetLineVisual(_verticalLines[i], _gridColor, _lineWidth); } - for (int i = 0; i < _suggestedAreaLines.Count; i++) - { - SetLineVisual(_suggestedAreaLines[i], _suggestedAreaBorderColor, _suggestedAreaBorderWidth); - } } private void DisableUnusedLines(List pool, int usedCount) diff --git a/Assets/10_Scripts/10_Runtime/40_Managers/StageManager.cs b/Assets/10_Scripts/10_Runtime/40_Managers/StageManager.cs index 3258696..46931fb 100644 --- a/Assets/10_Scripts/10_Runtime/40_Managers/StageManager.cs +++ b/Assets/10_Scripts/10_Runtime/40_Managers/StageManager.cs @@ -44,7 +44,7 @@ private void Awake() } /// - /// Loads a stage: resets the board to the stage grid size, + /// Loads a stage: resets the board to the derived suggested area, /// populates the palette with allowed components, and fires OnStageLoaded. /// /// The stage definition to load. @@ -55,10 +55,11 @@ public void LoadStage(StageDefinition stage) _currentStage = stage; - // Reset board to stage grid dimensions - _gameManager.ResetBoard(stage.GridSize.x, stage.GridSize.y); + // Derive a square suggested board from the stage target area. + int side = (int)Math.Ceiling(Math.Sqrt(stage.TargetArea)); + _gameManager.ResetBoard(side, side); - Debug.Log($"StageManager: Loaded stage '{stage.DisplayName}' (suggested area {stage.GridSize.x}x{stage.GridSize.y})"); + Debug.Log($"StageManager: Loaded stage '{stage.DisplayName}' (suggested area {side}x{side})"); OnStageLoaded?.Invoke(); } @@ -159,17 +160,17 @@ private async UniTaskVoid RunSimulationAndEvaluateAsync() } } - // Build scoring input from evaluation + board data + stage constraints - int maxComponentCount = _currentStage.Constraints != null - ? _currentStage.Constraints.MaxComponentCount - : 0; + // Build scoring input from evaluation + board size + stage target. + var contentBounds = _gameManager.BoardState.ComputeContentBounds(); + int boardArea = Math.Max(1, contentBounds.Width * contentBounds.Height); + int targetArea = _currentStage.TargetArea; var scoringInput = new ScoringInput( circuitPassed: evalResult.Passed, totalComponentCost: totalCost, budgetLimit: _currentStage.BudgetLimit, - componentCount: boardState.Components.Count, - maxComponentCount: maxComponentCount, + boardArea: boardArea, + targetArea: targetArea, traceCount: boardState.Traces.Count ); @@ -202,7 +203,7 @@ private static ScoreBreakdown CreateDRCFailedBreakdown(DRCResult drcResult) return new ScoreBreakdown( baseScore: 0, budgetBonus: 0, - compactBonus: 0, + areaBonus: 0, totalScore: 0, stars: 0, passed: false, diff --git a/Assets/10_Scripts/10_Runtime/80_Data/StageConstraints.cs b/Assets/10_Scripts/10_Runtime/80_Data/StageConstraints.cs deleted file mode 100644 index c58c93c..0000000 --- a/Assets/10_Scripts/10_Runtime/80_Data/StageConstraints.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using UnityEngine; -using UnityEngine.Serialization; - -namespace CircuitCraft.Data -{ - /// - /// Defines additional constraints for a stage, such as component limits or forbidden areas. - /// - [Serializable] - public class StageConstraints - { - [SerializeField] - [Tooltip("Maximum number of components allowed on the board. 0 means no limit.")] - [FormerlySerializedAs("maxComponentCount")] - private int _maxComponentCount; - - /// Maximum number of components allowed on the board. 0 means no limit. - public int MaxComponentCount => _maxComponentCount; - - // Note: Future constraints like forbidden zones or specific component type limits - // can be added here as the system evolves. - } -} diff --git a/Assets/10_Scripts/10_Runtime/80_Data/StageDefinition.cs b/Assets/10_Scripts/10_Runtime/80_Data/StageDefinition.cs index 61edfb4..96f5478 100644 --- a/Assets/10_Scripts/10_Runtime/80_Data/StageDefinition.cs +++ b/Assets/10_Scripts/10_Runtime/80_Data/StageDefinition.cs @@ -34,9 +34,15 @@ public class StageDefinition : ScriptableObject [Header("Grid Configuration")] [SerializeField] [Tooltip("The dimensions of the playable grid.")] + [HideInInspector] [FormerlySerializedAs("gridSize")] private Vector2Int _gridSize; + [Header("Footprint Target")] + [SerializeField] + [Tooltip("Target footprint area for scoring. 0 falls back to legacy grid area.")] + private int _targetArea; + [Header("Allowed Components")] [SerializeField] [Tooltip("The set of components the player is allowed to use in this stage.")] @@ -54,12 +60,6 @@ public class StageDefinition : ScriptableObject [FormerlySerializedAs("budgetLimit")] private float _budgetLimit; - [Header("Additional Constraints")] - [SerializeField] - [Tooltip("Extra constraints for this stage.")] - [FormerlySerializedAs("constraints")] - private StageConstraints _constraints; - /// Unique internal identifier for the stage. public string StageId => _stageId; @@ -72,8 +72,8 @@ public class StageDefinition : ScriptableObject /// The sequential number of the stage within its world. public int StageNumber => _stageNumber; - /// The dimensions of the playable grid. - public Vector2Int GridSize => _gridSize; + /// Target footprint area used in scoring. + public int TargetArea => _targetArea > 0 ? _targetArea : Mathf.Max(1, _gridSize.x * _gridSize.y); /// The set of components the player is allowed to use in this stage. public ComponentDefinition[] AllowedComponents => _allowedComponents; @@ -84,7 +84,5 @@ public class StageDefinition : ScriptableObject /// Maximum budget allowed for the circuit. 0 means no limit. public float BudgetLimit => _budgetLimit; - /// Extra constraints for this stage. - public StageConstraints Constraints => _constraints; } } diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-10_TripleDivider.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-10_TripleDivider.asset index 9471dcd..5e3fb8f 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-10_TripleDivider.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-10_TripleDivider.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world1 _stageNumber: 10 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} - {fileID: 11400000, guid: cdc6bbd9197b5c04eae917d4e6c7de79, type: 2} @@ -26,5 +27,3 @@ MonoBehaviour: _expectedVoltage: 3.0 _tolerance: 0.2 _budgetLimit: 12 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-1_VoltageDivider.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-1_VoltageDivider.asset index 7eadd29..084e736 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-1_VoltageDivider.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-1_VoltageDivider.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world1 _stageNumber: 1 _gridSize: {x: 10, y: 10} + _targetArea: 100 _allowedComponents: - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} - {fileID: 11400000, guid: 66e631d4439b5d34d9b358060a2fd734, type: 2} @@ -26,5 +27,3 @@ MonoBehaviour: _expectedVoltage: 5 _tolerance: 0.1 _budgetLimit: 0 - _constraints: - _maxComponentCount: 0 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-2_VoltageDivider.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-2_VoltageDivider.asset index 4d99c83..498ae30 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-2_VoltageDivider.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-2_VoltageDivider.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world1 _stageNumber: 2 _gridSize: {x: 10, y: 10} + _targetArea: 100 _allowedComponents: - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} - {fileID: 11400000, guid: 66e631d4439b5d34d9b358060a2fd734, type: 2} @@ -26,5 +27,3 @@ MonoBehaviour: _expectedVoltage: 3.33 _tolerance: 0.2 _budgetLimit: 10 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-3_LEDCircuit.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-3_LEDCircuit.asset index f0744a2..080c522 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-3_LEDCircuit.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-3_LEDCircuit.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world1 _stageNumber: 3 _gridSize: {x: 12, y: 12} + _targetArea: 144 _allowedComponents: - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} - {fileID: 11400000, guid: 66e631d4439b5d34d9b358060a2fd734, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 3.3 _tolerance: 0.3 _budgetLimit: 15 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-4_ParallelResistors.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-4_ParallelResistors.asset index b7cbe86..a0d3d93 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-4_ParallelResistors.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-4_ParallelResistors.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world1 _stageNumber: 4 _gridSize: {x: 12, y: 12} + _targetArea: 144 _allowedComponents: - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} - {fileID: 11400000, guid: 66e631d4439b5d34d9b358060a2fd734, type: 2} @@ -26,5 +27,3 @@ MonoBehaviour: _expectedVoltage: 5 _tolerance: 0.1 _budgetLimit: 15 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-5_ComplexDC.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-5_ComplexDC.asset index e2fb3ae..a13da46 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-5_ComplexDC.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-5_ComplexDC.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world1 _stageNumber: 5 _gridSize: {x: 14, y: 14} + _targetArea: 196 _allowedComponents: - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} - {fileID: 11400000, guid: 66e631d4439b5d34d9b358060a2fd734, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 4.3 _tolerance: 0.2 _budgetLimit: 20 - _constraints: - _maxComponentCount: 8 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-6_LED_CurrentLimit.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-6_LED_CurrentLimit.asset index 1e46f9f..0e294ca 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-6_LED_CurrentLimit.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-6_LED_CurrentLimit.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world1 _stageNumber: 6 _gridSize: {x: 10, y: 10} + _targetArea: 100 _allowedComponents: - {fileID: 11400000, guid: 750562e6434ddb941b62ba6e951fa594, type: 2} - {fileID: 11400000, guid: adbd9050ec83469bbe3f4926739eb08e, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 3.0 _tolerance: 0.3 _budgetLimit: 10 - _constraints: - _maxComponentCount: 3 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-7_SeriesLED.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-7_SeriesLED.asset index 5af1535..4269059 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-7_SeriesLED.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-7_SeriesLED.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world1 _stageNumber: 7 _gridSize: {x: 10, y: 10} + _targetArea: 100 _allowedComponents: - {fileID: 11400000, guid: 3a80a319f7b98a74abaaf2def5c9363e, type: 2} - {fileID: 11400000, guid: adbd9050ec83469bbe3f4926739eb08e, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 5.0 _tolerance: 0.5 _budgetLimit: 12 - _constraints: - _maxComponentCount: 4 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-8_TwoSourceSeries.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-8_TwoSourceSeries.asset index 3bd49b0..3ca9cf7 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-8_TwoSourceSeries.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-8_TwoSourceSeries.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world1 _stageNumber: 8 _gridSize: {x: 10, y: 10} + _targetArea: 100 _allowedComponents: - {fileID: 11400000, guid: 66e631d4439b5d34d9b358060a2fd734, type: 2} - {fileID: 11400000, guid: cdc6bbd9197b5c04eae917d4e6c7de79, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 14.0 _tolerance: 0.1 _budgetLimit: 10 - _constraints: - _maxComponentCount: 4 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-9_GroundReference.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-9_GroundReference.asset index b7f6e8f..e08010f 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-9_GroundReference.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage1-9_GroundReference.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world1 _stageNumber: 9 _gridSize: {x: 10, y: 10} + _targetArea: 100 _allowedComponents: - {fileID: 11400000, guid: b03b4a56d58e03b4087fc1f1ea898d17, type: 2} - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} @@ -26,5 +27,3 @@ MonoBehaviour: _expectedVoltage: 6.0 _tolerance: 0.1 _budgetLimit: 10 - _constraints: - _maxComponentCount: 4 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-10_FoldbackPower.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-10_FoldbackPower.asset index 8f9f736..04c6289 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-10_FoldbackPower.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-10_FoldbackPower.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world10 _stageNumber: 10 _gridSize: {x: 16, y: 16} + _targetArea: 256 _allowedComponents: - {fileID: 11400000, guid: 9b692629bff19d04782aef9e060c7dbe, type: 2} - {fileID: 11400000, guid: a1b80d670bf44f30a08c63c5d44fd416, type: 2} @@ -32,5 +33,3 @@ MonoBehaviour: _expectedVoltage: 5.0 _tolerance: 0.5 _budgetLimit: 45 - _constraints: - _maxComponentCount: 12 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-1_CompletePowerSupply.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-1_CompletePowerSupply.asset index 5df2d5e..7c22c1e 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-1_CompletePowerSupply.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-1_CompletePowerSupply.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world10 _stageNumber: 1 _gridSize: {x: 16, y: 16} + _targetArea: 256 _allowedComponents: - {fileID: 11400000, guid: 2c7ca548091743d44a30a1f75a19f0a8, type: 2} - {fileID: 11400000, guid: 484668953908bf141b66ebf617c111c0, type: 2} @@ -30,5 +31,3 @@ MonoBehaviour: _expectedVoltage: 5.0 _tolerance: 0.3 _budgetLimit: 40 - _constraints: - _maxComponentCount: 10 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-2_ConstCurrentLED.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-2_ConstCurrentLED.asset index 83e31a5..92460dc 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-2_ConstCurrentLED.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-2_ConstCurrentLED.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world10 _stageNumber: 2 _gridSize: {x: 14, y: 12} + _targetArea: 168 _allowedComponents: - {fileID: 11400000, guid: a1b80d670bf44f30a08c63c5d44fd416, type: 2} - {fileID: 11400000, guid: 750562e6434ddb941b62ba6e951fa594, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 8.5 _tolerance: 0.5 _budgetLimit: 25 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-3_TempCompBias.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-3_TempCompBias.asset index c066031..1de9903 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-3_TempCompBias.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-3_TempCompBias.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world10 _stageNumber: 3 _gridSize: {x: 14, y: 14} + _targetArea: 196 _allowedComponents: - {fileID: 11400000, guid: a1b80d670bf44f30a08c63c5d44fd416, type: 2} - {fileID: 11400000, guid: 82b7cdda793441b89b68bd4c2dc3db74, type: 2} @@ -29,5 +30,3 @@ MonoBehaviour: _expectedVoltage: 6.0 _tolerance: 0.5 _budgetLimit: 28 - _constraints: - _maxComponentCount: 7 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-4_BandgapRef.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-4_BandgapRef.asset index bcc559f..41e2fcf 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-4_BandgapRef.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-4_BandgapRef.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world10 _stageNumber: 4 _gridSize: {x: 16, y: 14} + _targetArea: 224 _allowedComponents: - {fileID: 11400000, guid: 570e48d4587c147488de5d83a4a764ef, type: 2} - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} @@ -29,5 +30,3 @@ MonoBehaviour: _expectedVoltage: 1.25 _tolerance: 0.2 _budgetLimit: 35 - _constraints: - _maxComponentCount: 8 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-5_CascodeMirror.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-5_CascodeMirror.asset index 49435b0..3febfa8 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-5_CascodeMirror.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-5_CascodeMirror.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world10 _stageNumber: 5 _gridSize: {x: 16, y: 14} + _targetArea: 224 _allowedComponents: - {fileID: 11400000, guid: 3718e41ce2aa1c14899faf780aaba2d6, type: 2} - {fileID: 11400000, guid: 7ca4f65367656f449afdd499f69190d9, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 2.4 _tolerance: 0.3 _budgetLimit: 30 - _constraints: - _maxComponentCount: 8 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-6_BiCMOSInverter.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-6_BiCMOSInverter.asset index 83f64f8..a421ac3 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-6_BiCMOSInverter.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-6_BiCMOSInverter.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world10 _stageNumber: 6 _gridSize: {x: 14, y: 14} + _targetArea: 196 _allowedComponents: - {fileID: 11400000, guid: a1b80d670bf44f30a08c63c5d44fd416, type: 2} - {fileID: 11400000, guid: b87f30b1ef7c4dea86d22af6425edaab, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 0.0 _tolerance: 0.2 _budgetLimit: 25 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-7_SoftStart.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-7_SoftStart.asset index ff69f3e..dfb4702 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-7_SoftStart.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-7_SoftStart.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world10 _stageNumber: 7 _gridSize: {x: 14, y: 14} + _targetArea: 196 _allowedComponents: - {fileID: 11400000, guid: a1b80d670bf44f30a08c63c5d44fd416, type: 2} - {fileID: 11400000, guid: 484668953908bf141b66ebf617c111c0, type: 2} @@ -29,5 +30,3 @@ MonoBehaviour: _expectedVoltage: 6.0 _tolerance: 0.5 _budgetLimit: 28 - _constraints: - _maxComponentCount: 7 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-8_OVPCircuit.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-8_OVPCircuit.asset index e067a30..74c0cc6 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-8_OVPCircuit.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-8_OVPCircuit.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world10 _stageNumber: 8 _gridSize: {x: 14, y: 14} + _targetArea: 196 _allowedComponents: - {fileID: 11400000, guid: a1b80d670bf44f30a08c63c5d44fd416, type: 2} - {fileID: 11400000, guid: 028768e5281d1e94a82d1237161f4c3e, type: 2} @@ -30,5 +31,3 @@ MonoBehaviour: _expectedVoltage: 12.0 _tolerance: 0.5 _budgetLimit: 28 - _constraints: - _maxComponentCount: 7 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-9_TwoStageDiffAmp.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-9_TwoStageDiffAmp.asset index 61a1dd4..9be3af0 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-9_TwoStageDiffAmp.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage10-9_TwoStageDiffAmp.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world10 _stageNumber: 9 _gridSize: {x: 16, y: 16} + _targetArea: 256 _allowedComponents: - {fileID: 11400000, guid: 570e48d4587c147488de5d83a4a764ef, type: 2} - {fileID: 11400000, guid: 58487cb9ae6c41ab83efada188f8083b, type: 2} @@ -30,5 +31,3 @@ MonoBehaviour: _expectedVoltage: 6.0 _tolerance: 1.0 _budgetLimit: 40 - _constraints: - _maxComponentCount: 12 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-10_KirchhoffTwoLoop.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-10_KirchhoffTwoLoop.asset index 22f80fc..95dddb5 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-10_KirchhoffTwoLoop.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-10_KirchhoffTwoLoop.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world2 _stageNumber: 10 _gridSize: {x: 14, y: 12} + _targetArea: 168 _allowedComponents: - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} - {fileID: 11400000, guid: ebc16846293594d4db0feea5af68ab84, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 4.8 _tolerance: 0.3 _budgetLimit: 20 - _constraints: - _maxComponentCount: 7 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-1_LoadedDivider.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-1_LoadedDivider.asset index 74ac1b5..e428512 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-1_LoadedDivider.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-1_LoadedDivider.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world2 _stageNumber: 1 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} - {fileID: 11400000, guid: ebc16846293594d4db0feea5af68ab84, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 5.4 _tolerance: 0.3 _budgetLimit: 15 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-2_LadderNetwork.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-2_LadderNetwork.asset index 2261670..8a0a15a 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-2_LadderNetwork.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-2_LadderNetwork.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world2 _stageNumber: 2 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} - {fileID: 11400000, guid: ebc16846293594d4db0feea5af68ab84, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 1.25 _tolerance: 0.2 _budgetLimit: 15 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-3_WheatstoneBalanced.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-3_WheatstoneBalanced.asset index 557b801..0824db1 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-3_WheatstoneBalanced.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-3_WheatstoneBalanced.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world2 _stageNumber: 3 _gridSize: {x: 12, y: 12} + _targetArea: 144 _allowedComponents: - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} - {fileID: 11400000, guid: cdc6bbd9197b5c04eae917d4e6c7de79, type: 2} @@ -26,5 +27,3 @@ MonoBehaviour: _expectedVoltage: 0.0 _tolerance: 0.1 _budgetLimit: 15 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-4_WheatstoneUnbalanced.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-4_WheatstoneUnbalanced.asset index 79c724a..92df05d 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-4_WheatstoneUnbalanced.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-4_WheatstoneUnbalanced.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world2 _stageNumber: 4 _gridSize: {x: 12, y: 12} + _targetArea: 144 _allowedComponents: - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} - {fileID: 11400000, guid: ebc16846293594d4db0feea5af68ab84, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 1.5 _tolerance: 0.3 _budgetLimit: 18 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-5_TNetworkAtten.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-5_TNetworkAtten.asset index 899ba78..598c3ad 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-5_TNetworkAtten.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-5_TNetworkAtten.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world2 _stageNumber: 5 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: 750562e6434ddb941b62ba6e951fa594, type: 2} - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 6.2 _tolerance: 0.3 _budgetLimit: 15 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-6_PiNetworkAtten.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-6_PiNetworkAtten.asset index 95b1f6b..9ff298e 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-6_PiNetworkAtten.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-6_PiNetworkAtten.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world2 _stageNumber: 6 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} - {fileID: 11400000, guid: ebc16846293594d4db0feea5af68ab84, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 4.5 _tolerance: 0.3 _budgetLimit: 15 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-7_SuperpositionCircuit.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-7_SuperpositionCircuit.asset index 8ec741b..097cf87 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-7_SuperpositionCircuit.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-7_SuperpositionCircuit.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world2 _stageNumber: 7 _gridSize: {x: 12, y: 12} + _targetArea: 144 _allowedComponents: - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} - {fileID: 11400000, guid: ebc16846293594d4db0feea5af68ab84, type: 2} @@ -29,5 +30,3 @@ MonoBehaviour: _expectedVoltage: 5.8 _tolerance: 0.3 _budgetLimit: 20 - _constraints: - _maxComponentCount: 7 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-8_TheveninCircuit.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-8_TheveninCircuit.asset index b5fc368..b529121 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-8_TheveninCircuit.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-8_TheveninCircuit.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world2 _stageNumber: 8 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} - {fileID: 11400000, guid: ebc16846293594d4db0feea5af68ab84, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 5.0 _tolerance: 0.2 _budgetLimit: 18 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-9_MaxPowerTransfer.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-9_MaxPowerTransfer.asset index 1fb33bf..5d3aecd 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-9_MaxPowerTransfer.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage2-9_MaxPowerTransfer.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world2 _stageNumber: 9 _gridSize: {x: 10, y: 10} + _targetArea: 100 _allowedComponents: - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} - {fileID: 11400000, guid: cdc6bbd9197b5c04eae917d4e6c7de79, type: 2} @@ -26,5 +27,3 @@ MonoBehaviour: _expectedVoltage: 4.5 _tolerance: 0.1 _budgetLimit: 12 - _constraints: - _maxComponentCount: 4 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-10_DiodeVoltageDrop.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-10_DiodeVoltageDrop.asset index 9efecae..92419fe 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-10_DiodeVoltageDrop.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-10_DiodeVoltageDrop.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world3 _stageNumber: 10 _gridSize: {x: 10, y: 10} + _targetArea: 100 _allowedComponents: - {fileID: 11400000, guid: 82b7cdda793441b89b68bd4c2dc3db74, type: 2} - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 3.6 _tolerance: 0.2 _budgetLimit: 12 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-1_DiodeForward.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-1_DiodeForward.asset index ade71d6..35d455a 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-1_DiodeForward.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-1_DiodeForward.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world3 _stageNumber: 1 _gridSize: {x: 10, y: 10} + _targetArea: 100 _allowedComponents: - {fileID: 11400000, guid: 82b7cdda793441b89b68bd4c2dc3db74, type: 2} - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 4.3 _tolerance: 0.2 _budgetLimit: 10 - _constraints: - _maxComponentCount: 4 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-2_HalfWaveRect.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-2_HalfWaveRect.asset index ca775e3..2107c4d 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-2_HalfWaveRect.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-2_HalfWaveRect.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world3 _stageNumber: 2 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: 2c7ca548091743d44a30a1f75a19f0a8, type: 2} - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 5.4 _tolerance: 0.5 _budgetLimit: 15 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-3_DiodeORGate.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-3_DiodeORGate.asset index 185891b..7efe344 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-3_DiodeORGate.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-3_DiodeORGate.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world3 _stageNumber: 3 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: 82b7cdda793441b89b68bd4c2dc3db74, type: 2} - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 4.3 _tolerance: 0.2 _budgetLimit: 15 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-4_DiodeANDGate.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-4_DiodeANDGate.asset index e1c2f3a..9ead2a5 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-4_DiodeANDGate.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-4_DiodeANDGate.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world3 _stageNumber: 4 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: 82b7cdda793441b89b68bd4c2dc3db74, type: 2} - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 4.3 _tolerance: 0.2 _budgetLimit: 15 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-5_PositiveClipper.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-5_PositiveClipper.asset index 8f3fa1a..3f7481e 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-5_PositiveClipper.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-5_PositiveClipper.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world3 _stageNumber: 5 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: 82b7cdda793441b89b68bd4c2dc3db74, type: 2} - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 0.7 _tolerance: 0.2 _budgetLimit: 12 - _constraints: - _maxComponentCount: 4 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-6_NegativeClipper.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-6_NegativeClipper.asset index 334dc10..9d8c10c 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-6_NegativeClipper.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-6_NegativeClipper.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world3 _stageNumber: 6 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: 82b7cdda793441b89b68bd4c2dc3db74, type: 2} - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 0.7 _tolerance: 0.2 _budgetLimit: 12 - _constraints: - _maxComponentCount: 4 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-7_LEDCurrentLimit.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-7_LEDCurrentLimit.asset index 8052008..6d2a291 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-7_LEDCurrentLimit.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-7_LEDCurrentLimit.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world3 _stageNumber: 7 _gridSize: {x: 10, y: 10} + _targetArea: 100 _allowedComponents: - {fileID: 11400000, guid: adbd9050ec83469bbe3f4926739eb08e, type: 2} - {fileID: 11400000, guid: 750562e6434ddb941b62ba6e951fa594, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 7.0 _tolerance: 0.3 _budgetLimit: 10 - _constraints: - _maxComponentCount: 4 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-8_SeriesLEDArray.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-8_SeriesLEDArray.asset index c0657be..c47ea13 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-8_SeriesLEDArray.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-8_SeriesLEDArray.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world3 _stageNumber: 8 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: adbd9050ec83469bbe3f4926739eb08e, type: 2} - {fileID: 11400000, guid: 3a80a319f7b98a74abaaf2def5c9363e, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 6.0 _tolerance: 0.5 _budgetLimit: 15 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-9_DualClipper.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-9_DualClipper.asset index 5a9f675..e596fb9 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-9_DualClipper.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage3-9_DualClipper.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world3 _stageNumber: 9 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: 82b7cdda793441b89b68bd4c2dc3db74, type: 2} - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 0.7 _tolerance: 0.1 _budgetLimit: 15 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-10_BiasedClipper.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-10_BiasedClipper.asset index a46c3a0..ad8207e 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-10_BiasedClipper.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-10_BiasedClipper.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world4 _stageNumber: 10 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: 82b7cdda793441b89b68bd4c2dc3db74, type: 2} - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 5.7 _tolerance: 0.2 _budgetLimit: 18 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-1_ZenerReg5V.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-1_ZenerReg5V.asset index ec8cc57..bf64e20 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-1_ZenerReg5V.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-1_ZenerReg5V.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world4 _stageNumber: 1 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: 032bfde7a86163443bc08af30d22eef8, type: 2} - {fileID: 11400000, guid: 750562e6434ddb941b62ba6e951fa594, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 5.1 _tolerance: 0.1 _budgetLimit: 15 - _constraints: - _maxComponentCount: 4 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-2_ZenerReg9V.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-2_ZenerReg9V.asset index 7af0081..849e66c 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-2_ZenerReg9V.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-2_ZenerReg9V.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world4 _stageNumber: 2 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: 2cae3343fbe3c9940a094dd213019447, type: 2} - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 9.1 _tolerance: 0.2 _budgetLimit: 15 - _constraints: - _maxComponentCount: 4 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-3_ZenerWithLoad.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-3_ZenerWithLoad.asset index 3e9ea5e..9201cd0 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-3_ZenerWithLoad.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-3_ZenerWithLoad.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world4 _stageNumber: 3 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: 032bfde7a86163443bc08af30d22eef8, type: 2} - {fileID: 11400000, guid: 750562e6434ddb941b62ba6e951fa594, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 5.1 _tolerance: 0.1 _budgetLimit: 18 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-4_BridgeRectifier.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-4_BridgeRectifier.asset index 2ead938..9e66456 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-4_BridgeRectifier.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-4_BridgeRectifier.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world4 _stageNumber: 4 _gridSize: {x: 14, y: 12} + _targetArea: 168 _allowedComponents: - {fileID: 11400000, guid: 2c7ca548091743d44a30a1f75a19f0a8, type: 2} - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 10.6 _tolerance: 0.5 _budgetLimit: 20 - _constraints: - _maxComponentCount: 7 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-5_VoltageDoubler.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-5_VoltageDoubler.asset index 37f5e03..366cce8 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-5_VoltageDoubler.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-5_VoltageDoubler.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world4 _stageNumber: 5 _gridSize: {x: 14, y: 12} + _targetArea: 168 _allowedComponents: - {fileID: 11400000, guid: 82b7cdda793441b89b68bd4c2dc3db74, type: 2} - {fileID: 11400000, guid: daa77e23871833947b8fd68222472733, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 22.0 _tolerance: 1.0 _budgetLimit: 25 - _constraints: - _maxComponentCount: 7 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-6_LEDVoltageIndicator.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-6_LEDVoltageIndicator.asset index a0fd63d..fcae59f 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-6_LEDVoltageIndicator.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-6_LEDVoltageIndicator.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world4 _stageNumber: 6 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: f234567890123d0aabcdef12abcdef0b, type: 2} - {fileID: 11400000, guid: e84a6a75f132c3945926484c481c5905, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 2.0 _tolerance: 0.3 _budgetLimit: 15 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-7_PeakDetector.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-7_PeakDetector.asset index cad530c..bf83710 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-7_PeakDetector.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-7_PeakDetector.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world4 _stageNumber: 7 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: 82b7cdda793441b89b68bd4c2dc3db74, type: 2} - {fileID: 11400000, guid: 7600b0307f210524988f9d65cf569108, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 11.3 _tolerance: 0.5 _budgetLimit: 18 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-8_DualZenerRef.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-8_DualZenerRef.asset index 69b9a37..c9a356d 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-8_DualZenerRef.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-8_DualZenerRef.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world4 _stageNumber: 8 _gridSize: {x: 14, y: 12} + _targetArea: 168 _allowedComponents: - {fileID: 11400000, guid: 028768e5281d1e94a82d1237161f4c3e, type: 2} - {fileID: 11400000, guid: 032bfde7a86163443bc08af30d22eef8, type: 2} @@ -29,5 +30,3 @@ MonoBehaviour: _expectedVoltage: 12.0 _tolerance: 0.2 _budgetLimit: 22 - _constraints: - _maxComponentCount: 7 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-9_ZenerOVP.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-9_ZenerOVP.asset index b3ce62a..94f9eb7 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-9_ZenerOVP.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage4-9_ZenerOVP.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world4 _stageNumber: 9 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: f6ac19c5a9c1e5e49a74c93035c41c44, type: 2} - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 15.0 _tolerance: 0.3 _budgetLimit: 18 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-10_BJTLevelShifter.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-10_BJTLevelShifter.asset index b6676d0..e46d992 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-10_BJTLevelShifter.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-10_BJTLevelShifter.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world5 _stageNumber: 10 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: a1b80d670bf44f30a08c63c5d44fd416, type: 2} - {fileID: 11400000, guid: 7ca4f65367656f449afdd499f69190d9, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 4.0 _tolerance: 0.5 _budgetLimit: 18 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-1_NPNSwitch.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-1_NPNSwitch.asset index fda5ff4..64e1d24 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-1_NPNSwitch.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-1_NPNSwitch.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world5 _stageNumber: 1 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: a1b80d670bf44f30a08c63c5d44fd416, type: 2} - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 0.2 _tolerance: 0.1 _budgetLimit: 15 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-2_PNPSwitch.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-2_PNPSwitch.asset index d028ac7..914cf24 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-2_PNPSwitch.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-2_PNPSwitch.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world5 _stageNumber: 2 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: 58487cb9ae6c41ab83efada188f8083b, type: 2} - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 0.2 _tolerance: 0.1 _budgetLimit: 15 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-3_NPNLEDDriver.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-3_NPNLEDDriver.asset index 144faf7..e69b92d 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-3_NPNLEDDriver.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-3_NPNLEDDriver.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world5 _stageNumber: 3 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: a1b80d670bf44f30a08c63c5d44fd416, type: 2} - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} @@ -29,5 +30,3 @@ MonoBehaviour: _expectedVoltage: 2.0 _tolerance: 0.3 _budgetLimit: 18 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-4_FixedBias.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-4_FixedBias.asset index 2cbe0a1..09c3f56 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-4_FixedBias.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-4_FixedBias.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world5 _stageNumber: 4 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: 3718e41ce2aa1c14899faf780aaba2d6, type: 2} - {fileID: 11400000, guid: 4c9aab249654aaa44b48d4d47e732456, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 6.0 _tolerance: 1.0 _budgetLimit: 15 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-5_CollectorFeedback.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-5_CollectorFeedback.asset index 890b64a..e87bbe5 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-5_CollectorFeedback.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-5_CollectorFeedback.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world5 _stageNumber: 5 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: 3718e41ce2aa1c14899faf780aaba2d6, type: 2} - {fileID: 11400000, guid: 4c9aab249654aaa44b48d4d47e732456, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 6.0 _tolerance: 1.0 _budgetLimit: 15 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-6_VoltageDividerBias.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-6_VoltageDividerBias.asset index 9130a14..a415c6b 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-6_VoltageDividerBias.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-6_VoltageDividerBias.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world5 _stageNumber: 6 _gridSize: {x: 14, y: 12} + _targetArea: 168 _allowedComponents: - {fileID: 11400000, guid: a1b80d670bf44f30a08c63c5d44fd416, type: 2} - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} @@ -30,5 +31,3 @@ MonoBehaviour: _expectedVoltage: 6.5 _tolerance: 1.0 _budgetLimit: 22 - _constraints: - _maxComponentCount: 7 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-7_EmitterBias.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-7_EmitterBias.asset index 83553e6..ca7907c 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-7_EmitterBias.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-7_EmitterBias.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world5 _stageNumber: 7 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: a1b2c3d4e5f6789012345678abcdef01, type: 2} - {fileID: 11400000, guid: 4c9aab249654aaa44b48d4d47e732456, type: 2} @@ -29,5 +30,3 @@ MonoBehaviour: _expectedVoltage: 6.0 _tolerance: 1.0 _budgetLimit: 18 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-8_BJTNOTGate.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-8_BJTNOTGate.asset index 74a4515..c4c825e 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-8_BJTNOTGate.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-8_BJTNOTGate.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world5 _stageNumber: 8 _gridSize: {x: 10, y: 10} + _targetArea: 100 _allowedComponents: - {fileID: 11400000, guid: a1b80d670bf44f30a08c63c5d44fd416, type: 2} - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 0.2 _tolerance: 0.2 _budgetLimit: 15 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-9_TransistorCurrentSource.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-9_TransistorCurrentSource.asset index bc0669a..123a527 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-9_TransistorCurrentSource.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage5-9_TransistorCurrentSource.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world5 _stageNumber: 9 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: 3718e41ce2aa1c14899faf780aaba2d6, type: 2} - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} @@ -29,5 +30,3 @@ MonoBehaviour: _expectedVoltage: 4.0 _tolerance: 0.5 _budgetLimit: 20 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-10_TwoStageCECC.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-10_TwoStageCECC.asset index cb6df05..c91554f 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-10_TwoStageCECC.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-10_TwoStageCECC.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world6 _stageNumber: 10 _gridSize: {x: 16, y: 14} + _targetArea: 224 _allowedComponents: - {fileID: 11400000, guid: a1b80d670bf44f30a08c63c5d44fd416, type: 2} - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} @@ -30,5 +31,3 @@ MonoBehaviour: _expectedVoltage: 4.0 _tolerance: 0.5 _budgetLimit: 35 - _constraints: - _maxComponentCount: 10 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-1_CommonEmitterAmp.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-1_CommonEmitterAmp.asset index 52ceab2..2e8746b 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-1_CommonEmitterAmp.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-1_CommonEmitterAmp.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world6 _stageNumber: 1 _gridSize: {x: 14, y: 12} + _targetArea: 168 _allowedComponents: - {fileID: 11400000, guid: a1b80d670bf44f30a08c63c5d44fd416, type: 2} - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} @@ -30,5 +31,3 @@ MonoBehaviour: _expectedVoltage: 6.0 _tolerance: 0.5 _budgetLimit: 25 - _constraints: - _maxComponentCount: 7 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-2_CEBypassCap.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-2_CEBypassCap.asset index fce47ca..82ee3fb 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-2_CEBypassCap.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-2_CEBypassCap.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world6 _stageNumber: 2 _gridSize: {x: 14, y: 12} + _targetArea: 168 _allowedComponents: - {fileID: 11400000, guid: 3718e41ce2aa1c14899faf780aaba2d6, type: 2} - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} @@ -31,5 +32,3 @@ MonoBehaviour: _expectedVoltage: 6.0 _tolerance: 0.5 _budgetLimit: 28 - _constraints: - _maxComponentCount: 8 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-3_EmitterFollower.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-3_EmitterFollower.asset index 8c41421..6589d3b 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-3_EmitterFollower.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-3_EmitterFollower.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world6 _stageNumber: 3 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: a1b80d670bf44f30a08c63c5d44fd416, type: 2} - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} @@ -29,5 +30,3 @@ MonoBehaviour: _expectedVoltage: 2.5 _tolerance: 0.3 _budgetLimit: 20 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-4_CommonBaseAmp.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-4_CommonBaseAmp.asset index 1f3fca8..78c4dea 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-4_CommonBaseAmp.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-4_CommonBaseAmp.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world6 _stageNumber: 4 _gridSize: {x: 14, y: 12} + _targetArea: 168 _allowedComponents: - {fileID: 11400000, guid: 3718e41ce2aa1c14899faf780aaba2d6, type: 2} - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 6.0 _tolerance: 1.0 _budgetLimit: 22 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-5_DarlingtonPair.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-5_DarlingtonPair.asset index 250e2ca..acef063 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-5_DarlingtonPair.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-5_DarlingtonPair.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world6 _stageNumber: 5 _gridSize: {x: 14, y: 12} + _targetArea: 168 _allowedComponents: - {fileID: 11400000, guid: a1b80d670bf44f30a08c63c5d44fd416, type: 2} - {fileID: 11400000, guid: 4c9aab249654aaa44b48d4d47e732456, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 5.0 _tolerance: 0.5 _budgetLimit: 25 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-6_BasicCurrentMirror.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-6_BasicCurrentMirror.asset index fa03de9..6ea2f80 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-6_BasicCurrentMirror.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-6_BasicCurrentMirror.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world6 _stageNumber: 6 _gridSize: {x: 14, y: 12} + _targetArea: 168 _allowedComponents: - {fileID: 11400000, guid: 570e48d4587c147488de5d83a4a764ef, type: 2} - {fileID: 11400000, guid: 7ca4f65367656f449afdd499f69190d9, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 2.4 _tolerance: 0.3 _budgetLimit: 22 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-7_PNPCurrentSource.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-7_PNPCurrentSource.asset index eccbb3e..bc1af96 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-7_PNPCurrentSource.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-7_PNPCurrentSource.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world6 _stageNumber: 7 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: 58487cb9ae6c41ab83efada188f8083b, type: 2} - {fileID: 11400000, guid: ebc16846293594d4db0feea5af68ab84, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 5.0 _tolerance: 0.5 _budgetLimit: 18 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-8_ActiveLoadCE.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-8_ActiveLoadCE.asset index 4e69fc5..aa6488d 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-8_ActiveLoadCE.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-8_ActiveLoadCE.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world6 _stageNumber: 8 _gridSize: {x: 14, y: 14} + _targetArea: 196 _allowedComponents: - {fileID: 11400000, guid: a1b80d670bf44f30a08c63c5d44fd416, type: 2} - {fileID: 11400000, guid: 58487cb9ae6c41ab83efada188f8083b, type: 2} @@ -29,5 +30,3 @@ MonoBehaviour: _expectedVoltage: 6.0 _tolerance: 0.5 _budgetLimit: 28 - _constraints: - _maxComponentCount: 8 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-9_CascodeAmp.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-9_CascodeAmp.asset index 66f0a7a..bef225c 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-9_CascodeAmp.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage6-9_CascodeAmp.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world6 _stageNumber: 9 _gridSize: {x: 14, y: 14} + _targetArea: 196 _allowedComponents: - {fileID: 11400000, guid: 3718e41ce2aa1c14899faf780aaba2d6, type: 2} - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} @@ -30,5 +31,3 @@ MonoBehaviour: _expectedVoltage: 6.0 _tolerance: 1.0 _budgetLimit: 30 - _constraints: - _maxComponentCount: 8 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-10_LogicLevelShifter.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-10_LogicLevelShifter.asset index 5064bbc..e5095d6 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-10_LogicLevelShifter.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-10_LogicLevelShifter.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world7 _stageNumber: 10 _gridSize: {x: 14, y: 12} + _targetArea: 168 _allowedComponents: - {fileID: 11400000, guid: b87f30b1ef7c4dea86d22af6425edaab, type: 2} - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 12.0 _tolerance: 0.3 _budgetLimit: 20 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-1_NMOSSwitch.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-1_NMOSSwitch.asset index 4ddbd76..a9b71c1 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-1_NMOSSwitch.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-1_NMOSSwitch.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world7 _stageNumber: 1 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: b87f30b1ef7c4dea86d22af6425edaab, type: 2} - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 0.1 _tolerance: 0.1 _budgetLimit: 15 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-2_PMOSSwitch.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-2_PMOSSwitch.asset index c1dafdd..13bc411 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-2_PMOSSwitch.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-2_PMOSSwitch.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world7 _stageNumber: 2 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: 5eb27cee7de638343b29ef84e57f4a0d, type: 2} - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 0.1 _tolerance: 0.1 _budgetLimit: 15 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-3_MOSFETLEDDriver.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-3_MOSFETLEDDriver.asset index d51271a..5a8679a 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-3_MOSFETLEDDriver.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-3_MOSFETLEDDriver.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world7 _stageNumber: 3 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: b87f30b1ef7c4dea86d22af6425edaab, type: 2} - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} @@ -29,5 +30,3 @@ MonoBehaviour: _expectedVoltage: 2.0 _tolerance: 0.3 _budgetLimit: 18 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-4_CMOSInverter.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-4_CMOSInverter.asset index a26e701..b3e1711 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-4_CMOSInverter.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-4_CMOSInverter.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world7 _stageNumber: 4 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: b87f30b1ef7c4dea86d22af6425edaab, type: 2} - {fileID: 11400000, guid: 5eb27cee7de638343b29ef84e57f4a0d, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 0.0 _tolerance: 0.1 _budgetLimit: 15 - _constraints: - _maxComponentCount: 4 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-5_CommonSourceAmp.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-5_CommonSourceAmp.asset index 967ce13..1256790 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-5_CommonSourceAmp.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-5_CommonSourceAmp.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world7 _stageNumber: 5 _gridSize: {x: 14, y: 12} + _targetArea: 168 _allowedComponents: - {fileID: 11400000, guid: b87f30b1ef7c4dea86d22af6425edaab, type: 2} - {fileID: 11400000, guid: 7ca4f65367656f449afdd499f69190d9, type: 2} @@ -29,5 +30,3 @@ MonoBehaviour: _expectedVoltage: 6.0 _tolerance: 1.0 _budgetLimit: 25 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-6_SourceFollower.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-6_SourceFollower.asset index 41dd987..f43f776 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-6_SourceFollower.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-6_SourceFollower.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world7 _stageNumber: 6 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: b87f30b1ef7c4dea86d22af6425edaab, type: 2} - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 3.0 _tolerance: 0.5 _budgetLimit: 18 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-7_CommonGateAmp.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-7_CommonGateAmp.asset index a8434d5..93a430b 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-7_CommonGateAmp.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-7_CommonGateAmp.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world7 _stageNumber: 7 _gridSize: {x: 14, y: 12} + _targetArea: 168 _allowedComponents: - {fileID: 11400000, guid: b87f30b1ef7c4dea86d22af6425edaab, type: 2} - {fileID: 11400000, guid: 7ca4f65367656f449afdd499f69190d9, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 6.0 _tolerance: 1.0 _budgetLimit: 22 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-8_MOSFETCurrentSource.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-8_MOSFETCurrentSource.asset index 3997845..4887a77 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-8_MOSFETCurrentSource.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-8_MOSFETCurrentSource.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world7 _stageNumber: 8 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: b87f30b1ef7c4dea86d22af6425edaab, type: 2} - {fileID: 11400000, guid: f6bb8507e14dd9c4d98804edfc204890, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 2.0 _tolerance: 0.5 _budgetLimit: 15 - _constraints: - _maxComponentCount: 4 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-9_NMOSPowerSwitch.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-9_NMOSPowerSwitch.asset index 63b60cb..f67a8f2 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-9_NMOSPowerSwitch.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage7-9_NMOSPowerSwitch.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world7 _stageNumber: 9 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: f6789012345678abcdef06abcdef02ab, type: 2} - {fileID: 11400000, guid: 0c79e726dffe59d4280ecdf78eb557df, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 11.9 _tolerance: 0.3 _budgetLimit: 15 - _constraints: - _maxComponentCount: 4 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-10_MOSFETFollower.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-10_MOSFETFollower.asset index 5866bf5..6be365c 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-10_MOSFETFollower.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-10_MOSFETFollower.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world8 _stageNumber: 10 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: 31718a60891caec40baaa80a773ea4ac, type: 2} - {fileID: 11400000, guid: 032bfde7a86163443bc08af30d22eef8, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 5.0 _tolerance: 0.3 _budgetLimit: 18 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-1_CMOSNANDGate.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-1_CMOSNANDGate.asset index 8ee120a..a8f0183 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-1_CMOSNANDGate.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-1_CMOSNANDGate.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world8 _stageNumber: 1 _gridSize: {x: 14, y: 12} + _targetArea: 168 _allowedComponents: - {fileID: 11400000, guid: b87f30b1ef7c4dea86d22af6425edaab, type: 2} - {fileID: 11400000, guid: 5eb27cee7de638343b29ef84e57f4a0d, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 5.0 _tolerance: 0.1 _budgetLimit: 20 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-2_CMOSNORGate.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-2_CMOSNORGate.asset index b263782..d7aace6 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-2_CMOSNORGate.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-2_CMOSNORGate.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world8 _stageNumber: 2 _gridSize: {x: 14, y: 12} + _targetArea: 168 _allowedComponents: - {fileID: 11400000, guid: b87f30b1ef7c4dea86d22af6425edaab, type: 2} - {fileID: 11400000, guid: 5eb27cee7de638343b29ef84e57f4a0d, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 0.0 _tolerance: 0.1 _budgetLimit: 20 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-3_CSSourceDegen.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-3_CSSourceDegen.asset index a215172..b75fc1f 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-3_CSSourceDegen.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-3_CSSourceDegen.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world8 _stageNumber: 3 _gridSize: {x: 14, y: 12} + _targetArea: 168 _allowedComponents: - {fileID: 11400000, guid: b87f30b1ef7c4dea86d22af6425edaab, type: 2} - {fileID: 11400000, guid: 7ca4f65367656f449afdd499f69190d9, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 6.0 _tolerance: 1.0 _budgetLimit: 22 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-4_MOSFETCurrentMirror.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-4_MOSFETCurrentMirror.asset index 10e7bdd..3feebd7 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-4_MOSFETCurrentMirror.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-4_MOSFETCurrentMirror.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world8 _stageNumber: 4 _gridSize: {x: 14, y: 12} + _targetArea: 168 _allowedComponents: - {fileID: 11400000, guid: b87f30b1ef7c4dea86d22af6425edaab, type: 2} - {fileID: 11400000, guid: 7ca4f65367656f449afdd499f69190d9, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 2.4 _tolerance: 0.5 _budgetLimit: 22 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-5_PMOSActiveLoad.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-5_PMOSActiveLoad.asset index 58d84d7..b1c0395 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-5_PMOSActiveLoad.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-5_PMOSActiveLoad.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world8 _stageNumber: 5 _gridSize: {x: 14, y: 14} + _targetArea: 196 _allowedComponents: - {fileID: 11400000, guid: b87f30b1ef7c4dea86d22af6425edaab, type: 2} - {fileID: 11400000, guid: 5eb27cee7de638343b29ef84e57f4a0d, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 6.0 _tolerance: 1.0 _budgetLimit: 25 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-6_CascodeMOSFET.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-6_CascodeMOSFET.asset index ba8e35a..8955cae 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-6_CascodeMOSFET.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-6_CascodeMOSFET.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world8 _stageNumber: 6 _gridSize: {x: 14, y: 14} + _targetArea: 196 _allowedComponents: - {fileID: 11400000, guid: b87f30b1ef7c4dea86d22af6425edaab, type: 2} - {fileID: 11400000, guid: 7ca4f65367656f449afdd499f69190d9, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 6.0 _tolerance: 1.0 _budgetLimit: 28 - _constraints: - _maxComponentCount: 7 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-7_MOSFETHBridge.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-7_MOSFETHBridge.asset index 0412700..efbf61a 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-7_MOSFETHBridge.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-7_MOSFETHBridge.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world8 _stageNumber: 7 _gridSize: {x: 16, y: 14} + _targetArea: 224 _allowedComponents: - {fileID: 11400000, guid: b87f30b1ef7c4dea86d22af6425edaab, type: 2} - {fileID: 11400000, guid: 5eb27cee7de638343b29ef84e57f4a0d, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 12.0 _tolerance: 0.5 _budgetLimit: 35 - _constraints: - _maxComponentCount: 8 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-8_MOSFETVoltageReg.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-8_MOSFETVoltageReg.asset index d15382a..a110233 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-8_MOSFETVoltageReg.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-8_MOSFETVoltageReg.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world8 _stageNumber: 8 _gridSize: {x: 14, y: 12} + _targetArea: 168 _allowedComponents: - {fileID: 11400000, guid: 31718a60891caec40baaa80a773ea4ac, type: 2} - {fileID: 11400000, guid: 032bfde7a86163443bc08af30d22eef8, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 5.1 _tolerance: 0.2 _budgetLimit: 22 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-9_HighSideMOSFET.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-9_HighSideMOSFET.asset index bb9c1df..4727f54 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-9_HighSideMOSFET.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage8-9_HighSideMOSFET.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world8 _stageNumber: 9 _gridSize: {x: 12, y: 10} + _targetArea: 120 _allowedComponents: - {fileID: 11400000, guid: ba82eb4e155040ddb8720c0680899a3d, type: 2} - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 12.0 _tolerance: 0.3 _budgetLimit: 18 - _constraints: - _maxComponentCount: 5 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-10_SeriesPassReg.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-10_SeriesPassReg.asset index 74f3458..cbc0007 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-10_SeriesPassReg.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-10_SeriesPassReg.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world9 _stageNumber: 10 _gridSize: {x: 14, y: 12} + _targetArea: 168 _allowedComponents: - {fileID: 11400000, guid: 9b692629bff19d04782aef9e060c7dbe, type: 2} - {fileID: 11400000, guid: 032bfde7a86163443bc08af30d22eef8, type: 2} @@ -29,5 +30,3 @@ MonoBehaviour: _expectedVoltage: 4.4 _tolerance: 0.3 _budgetLimit: 25 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-1_WilsonMirror.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-1_WilsonMirror.asset index a5ab70b..76e7e0c 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-1_WilsonMirror.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-1_WilsonMirror.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world9 _stageNumber: 1 _gridSize: {x: 14, y: 14} + _targetArea: 196 _allowedComponents: - {fileID: 11400000, guid: 3718e41ce2aa1c14899faf780aaba2d6, type: 2} - {fileID: 11400000, guid: 7ca4f65367656f449afdd499f69190d9, type: 2} @@ -27,5 +28,3 @@ MonoBehaviour: _expectedVoltage: 2.4 _tolerance: 0.3 _budgetLimit: 25 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-2_WidlarSource.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-2_WidlarSource.asset index 61728c6..575c3d0 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-2_WidlarSource.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-2_WidlarSource.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world9 _stageNumber: 2 _gridSize: {x: 14, y: 14} + _targetArea: 196 _allowedComponents: - {fileID: 11400000, guid: 3718e41ce2aa1c14899faf780aaba2d6, type: 2} - {fileID: 11400000, guid: 7ca4f65367656f449afdd499f69190d9, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 0.5 _tolerance: 0.3 _budgetLimit: 25 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-3_DiffPair.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-3_DiffPair.asset index 93d514b..312afe2 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-3_DiffPair.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-3_DiffPair.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world9 _stageNumber: 3 _gridSize: {x: 16, y: 14} + _targetArea: 224 _allowedComponents: - {fileID: 11400000, guid: 570e48d4587c147488de5d83a4a764ef, type: 2} - {fileID: 11400000, guid: 7ca4f65367656f449afdd499f69190d9, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 6.0 _tolerance: 0.5 _budgetLimit: 30 - _constraints: - _maxComponentCount: 8 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-4_DiffPairActiveLoad.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-4_DiffPairActiveLoad.asset index a16ee45..d6f25c5 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-4_DiffPairActiveLoad.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-4_DiffPairActiveLoad.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world9 _stageNumber: 4 _gridSize: {x: 16, y: 14} + _targetArea: 224 _allowedComponents: - {fileID: 11400000, guid: 570e48d4587c147488de5d83a4a764ef, type: 2} - {fileID: 11400000, guid: 58487cb9ae6c41ab83efada188f8083b, type: 2} @@ -29,5 +30,3 @@ MonoBehaviour: _expectedVoltage: 6.0 _tolerance: 1.0 _budgetLimit: 35 - _constraints: - _maxComponentCount: 10 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-5_PushPullClassB.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-5_PushPullClassB.asset index e4b5734..0a2229c 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-5_PushPullClassB.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-5_PushPullClassB.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world9 _stageNumber: 5 _gridSize: {x: 16, y: 14} + _targetArea: 224 _allowedComponents: - {fileID: 11400000, guid: 9b692629bff19d04782aef9e060c7dbe, type: 2} - {fileID: 11400000, guid: b204b5e036dee3d4a9bcf33b27903ce9, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 0.0 _tolerance: 0.5 _budgetLimit: 30 - _constraints: - _maxComponentCount: 6 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-6_ClassABVbe.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-6_ClassABVbe.asset index 61b5c1e..db730cb 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-6_ClassABVbe.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-6_ClassABVbe.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world9 _stageNumber: 6 _gridSize: {x: 16, y: 14} + _targetArea: 224 _allowedComponents: - {fileID: 11400000, guid: a1b80d670bf44f30a08c63c5d44fd416, type: 2} - {fileID: 11400000, guid: 9b692629bff19d04782aef9e060c7dbe, type: 2} @@ -30,5 +31,3 @@ MonoBehaviour: _expectedVoltage: 0.0 _tolerance: 0.5 _budgetLimit: 35 - _constraints: - _maxComponentCount: 8 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-7_SchmittTrigger.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-7_SchmittTrigger.asset index cf2cc0c..743d73c 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-7_SchmittTrigger.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-7_SchmittTrigger.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world9 _stageNumber: 7 _gridSize: {x: 14, y: 12} + _targetArea: 168 _allowedComponents: - {fileID: 11400000, guid: a1b80d670bf44f30a08c63c5d44fd416, type: 2} - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} @@ -29,5 +30,3 @@ MonoBehaviour: _expectedVoltage: 0.2 _tolerance: 0.3 _budgetLimit: 25 - _constraints: - _maxComponentCount: 7 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-8_AstableMulti.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-8_AstableMulti.asset index a8853ba..6587499 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-8_AstableMulti.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-8_AstableMulti.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world9 _stageNumber: 8 _gridSize: {x: 16, y: 14} + _targetArea: 224 _allowedComponents: - {fileID: 11400000, guid: a1b80d670bf44f30a08c63c5d44fd416, type: 2} - {fileID: 11400000, guid: e8da7b3c2a7ca494eaa819665e3eea83, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 5.0 _tolerance: 0.5 _budgetLimit: 28 - _constraints: - _maxComponentCount: 8 diff --git a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-9_ShuntRegulator.asset b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-9_ShuntRegulator.asset index 014d053..3d6325f 100644 --- a/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-9_ShuntRegulator.asset +++ b/Assets/70_Data/10_ScriptableObjects/60_Stages/Stage9-9_ShuntRegulator.asset @@ -17,6 +17,7 @@ MonoBehaviour: _worldId: world9 _stageNumber: 9 _gridSize: {x: 14, y: 12} + _targetArea: 168 _allowedComponents: - {fileID: 11400000, guid: a1b80d670bf44f30a08c63c5d44fd416, type: 2} - {fileID: 11400000, guid: 032bfde7a86163443bc08af30d22eef8, type: 2} @@ -28,5 +29,3 @@ MonoBehaviour: _expectedVoltage: 5.8 _tolerance: 0.2 _budgetLimit: 22 - _constraints: - _maxComponentCount: 5 From 2b58ac23ca2a1c26a5be56c1e14988238c794334 Mon Sep 17 00:00:00 2001 From: okenic03-code Date: Tue, 17 Feb 2026 20:57:29 +0900 Subject: [PATCH 041/115] chore(scoring): remove StageConstraints metadata file Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- .../10_Runtime/80_Data/StageConstraints.cs.meta | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 Assets/10_Scripts/10_Runtime/80_Data/StageConstraints.cs.meta diff --git a/Assets/10_Scripts/10_Runtime/80_Data/StageConstraints.cs.meta b/Assets/10_Scripts/10_Runtime/80_Data/StageConstraints.cs.meta deleted file mode 100644 index e4f2af0..0000000 --- a/Assets/10_Scripts/10_Runtime/80_Data/StageConstraints.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 664830c86a23c96408a8f41e7c558871 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: From cdcc73c2e77bdd717f8b85a8d5758f30d03ae05b Mon Sep 17 00:00:00 2001 From: okenic03-code Date: Tue, 17 Feb 2026 21:04:51 +0900 Subject: [PATCH 042/115] fix(scoring): update UIController to use TargetArea instead of removed GridSize Replace GridSize references in OnClearBoard() with TargetArea-based board dimension calculation, matching the pattern used in StageManager. --- Assets/60_UI/40_Scripts/UIController.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Assets/60_UI/40_Scripts/UIController.cs b/Assets/60_UI/40_Scripts/UIController.cs index 62e476e..4ca9a06 100644 --- a/Assets/60_UI/40_Scripts/UIController.cs +++ b/Assets/60_UI/40_Scripts/UIController.cs @@ -366,12 +366,13 @@ private void OnClearBoard() { if (_gameManager == null) return; - // Use current stage grid size, or default + // Use current stage target area to derive board size, or default int width = 20, height = 15; if (_stageManager != null && _stageManager.CurrentStage != null) { - width = _stageManager.CurrentStage.GridSize.x; - height = _stageManager.CurrentStage.GridSize.y; + int side = (int)Math.Ceiling(Math.Sqrt(_stageManager.CurrentStage.TargetArea)); + width = side; + height = side; } _gameManager.ResetBoard(width, height); From be5fda3afadd453244b198abdd5a61beafbf274d Mon Sep 17 00:00:00 2001 From: okenic03-code Date: Tue, 17 Feb 2026 21:10:22 +0900 Subject: [PATCH 043/115] chore(references): add missing Unity meta files for circuit diagrams --- .../50_superposition_circuit.svg.meta | 7 ++ .../51_thevenin_equivalent.svg.meta | 7 ++ .../27_current_mirror.jpg.meta | 114 ++++++++++++++++++ .../28_pnp_darlington.jpg.meta | 114 ++++++++++++++++++ .../29_push_pull_class_b.svg.meta | 7 ++ .../30_differential_amplifier.svg.meta | 7 ++ ...41_wilson_current_mirror_labelled.png.meta | 114 ++++++++++++++++++ .../42_wilson_current_mirror.png.meta | 114 ++++++++++++++++++ .../43_widlar_current_source.png.meta | 114 ++++++++++++++++++ .../31_nmos_high_side_switch.png.meta | 114 ++++++++++++++++++ .../33_cmos_inverter.svg.meta | 7 ++ .../34_nmos_common_source_amp.png.meta | 114 ++++++++++++++++++ .../35_nmos_jfet_source_follower.svg.meta | 7 ++ .../36_wide_swing_mirror.svg.meta | 7 ++ .../04_MOSFET_Circuits/47_h_bridge.png.meta | 114 ++++++++++++++++++ .../48_h_bridge_v2.png.meta | 114 ++++++++++++++++++ .../53_common_source_amplifier_exact.png.meta | 114 ++++++++++++++++++ .../32_undervoltage_battery_switch.png.meta | 114 ++++++++++++++++++ .../44_low_dropout_regulator.png.meta | 114 ++++++++++++++++++ .../45_feedback_linear_regulator.png.meta | 114 ++++++++++++++++++ .../46_shunt_regulator.png.meta | 114 ++++++++++++++++++ .../52_dickson_voltage_doubler.svg.meta | 7 ++ .../39_inverting_schmitt_symbol.png.meta | 114 ++++++++++++++++++ .../40_astable_multivibrator.png.meta | 114 ++++++++++++++++++ .../54_schmitt_trigger_by_transistor.svg.meta | 7 ++ .../49_rc_charging.svg.meta | 7 ++ .../38_cmos_nor_two_inputs.svg.meta | 7 ++ 27 files changed, 1901 insertions(+) create mode 100644 Assets/90_References/CircuitDiagrams/01_Passive_Basic/50_superposition_circuit.svg.meta create mode 100644 Assets/90_References/CircuitDiagrams/01_Passive_Basic/51_thevenin_equivalent.svg.meta create mode 100644 Assets/90_References/CircuitDiagrams/03_BJT_Circuits/27_current_mirror.jpg.meta create mode 100644 Assets/90_References/CircuitDiagrams/03_BJT_Circuits/28_pnp_darlington.jpg.meta create mode 100644 Assets/90_References/CircuitDiagrams/03_BJT_Circuits/29_push_pull_class_b.svg.meta create mode 100644 Assets/90_References/CircuitDiagrams/03_BJT_Circuits/30_differential_amplifier.svg.meta create mode 100644 Assets/90_References/CircuitDiagrams/03_BJT_Circuits/41_wilson_current_mirror_labelled.png.meta create mode 100644 Assets/90_References/CircuitDiagrams/03_BJT_Circuits/42_wilson_current_mirror.png.meta create mode 100644 Assets/90_References/CircuitDiagrams/03_BJT_Circuits/43_widlar_current_source.png.meta create mode 100644 Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/31_nmos_high_side_switch.png.meta create mode 100644 Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/33_cmos_inverter.svg.meta create mode 100644 Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/34_nmos_common_source_amp.png.meta create mode 100644 Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/35_nmos_jfet_source_follower.svg.meta create mode 100644 Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/36_wide_swing_mirror.svg.meta create mode 100644 Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/47_h_bridge.png.meta create mode 100644 Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/48_h_bridge_v2.png.meta create mode 100644 Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/53_common_source_amplifier_exact.png.meta create mode 100644 Assets/90_References/CircuitDiagrams/07_Power_Supply/32_undervoltage_battery_switch.png.meta create mode 100644 Assets/90_References/CircuitDiagrams/07_Power_Supply/44_low_dropout_regulator.png.meta create mode 100644 Assets/90_References/CircuitDiagrams/07_Power_Supply/45_feedback_linear_regulator.png.meta create mode 100644 Assets/90_References/CircuitDiagrams/07_Power_Supply/46_shunt_regulator.png.meta create mode 100644 Assets/90_References/CircuitDiagrams/07_Power_Supply/52_dickson_voltage_doubler.svg.meta create mode 100644 Assets/90_References/CircuitDiagrams/08_Oscillator_Timer/39_inverting_schmitt_symbol.png.meta create mode 100644 Assets/90_References/CircuitDiagrams/08_Oscillator_Timer/40_astable_multivibrator.png.meta create mode 100644 Assets/90_References/CircuitDiagrams/08_Oscillator_Timer/54_schmitt_trigger_by_transistor.svg.meta create mode 100644 Assets/90_References/CircuitDiagrams/09_Filter_Circuits/49_rc_charging.svg.meta create mode 100644 Assets/90_References/CircuitDiagrams/10_Digital_Logic/38_cmos_nor_two_inputs.svg.meta diff --git a/Assets/90_References/CircuitDiagrams/01_Passive_Basic/50_superposition_circuit.svg.meta b/Assets/90_References/CircuitDiagrams/01_Passive_Basic/50_superposition_circuit.svg.meta new file mode 100644 index 0000000..5ad5184 --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/01_Passive_Basic/50_superposition_circuit.svg.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: fad566aec45af124e94c290ef28045f5 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/01_Passive_Basic/51_thevenin_equivalent.svg.meta b/Assets/90_References/CircuitDiagrams/01_Passive_Basic/51_thevenin_equivalent.svg.meta new file mode 100644 index 0000000..746e4e3 --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/01_Passive_Basic/51_thevenin_equivalent.svg.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 32c99ef682875ee44a01844016f25540 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/03_BJT_Circuits/27_current_mirror.jpg.meta b/Assets/90_References/CircuitDiagrams/03_BJT_Circuits/27_current_mirror.jpg.meta new file mode 100644 index 0000000..65aac6c --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/03_BJT_Circuits/27_current_mirror.jpg.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: d15713664debe9d489fbbaa82fd8f3dd +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/03_BJT_Circuits/28_pnp_darlington.jpg.meta b/Assets/90_References/CircuitDiagrams/03_BJT_Circuits/28_pnp_darlington.jpg.meta new file mode 100644 index 0000000..fe16834 --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/03_BJT_Circuits/28_pnp_darlington.jpg.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: fe2c327478ef5f741ab08e40170c43ff +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/03_BJT_Circuits/29_push_pull_class_b.svg.meta b/Assets/90_References/CircuitDiagrams/03_BJT_Circuits/29_push_pull_class_b.svg.meta new file mode 100644 index 0000000..3da26a5 --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/03_BJT_Circuits/29_push_pull_class_b.svg.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 83fba0807bbb8c14b8013ddee2b15b68 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/03_BJT_Circuits/30_differential_amplifier.svg.meta b/Assets/90_References/CircuitDiagrams/03_BJT_Circuits/30_differential_amplifier.svg.meta new file mode 100644 index 0000000..ea9aa28 --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/03_BJT_Circuits/30_differential_amplifier.svg.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 49a1847ea02d29142b4e767472685ede +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/03_BJT_Circuits/41_wilson_current_mirror_labelled.png.meta b/Assets/90_References/CircuitDiagrams/03_BJT_Circuits/41_wilson_current_mirror_labelled.png.meta new file mode 100644 index 0000000..2c92d5e --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/03_BJT_Circuits/41_wilson_current_mirror_labelled.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: 27572d02be8c56a40b596b513ada2acd +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/03_BJT_Circuits/42_wilson_current_mirror.png.meta b/Assets/90_References/CircuitDiagrams/03_BJT_Circuits/42_wilson_current_mirror.png.meta new file mode 100644 index 0000000..1f7d0d1 --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/03_BJT_Circuits/42_wilson_current_mirror.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: 8b3e75803c71ba24ca77dcb94edbd417 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/03_BJT_Circuits/43_widlar_current_source.png.meta b/Assets/90_References/CircuitDiagrams/03_BJT_Circuits/43_widlar_current_source.png.meta new file mode 100644 index 0000000..41d6708 --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/03_BJT_Circuits/43_widlar_current_source.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: d6b1e3f13d98f394599488ac8e074a70 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/31_nmos_high_side_switch.png.meta b/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/31_nmos_high_side_switch.png.meta new file mode 100644 index 0000000..62999fa --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/31_nmos_high_side_switch.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: 39729abf9920e8e46bbdcabab8481592 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/33_cmos_inverter.svg.meta b/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/33_cmos_inverter.svg.meta new file mode 100644 index 0000000..7fb1410 --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/33_cmos_inverter.svg.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5861fd6b1a2920144b7baeba82f2f7e6 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/34_nmos_common_source_amp.png.meta b/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/34_nmos_common_source_amp.png.meta new file mode 100644 index 0000000..52b877c --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/34_nmos_common_source_amp.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: 6a18e79fc5862834bb9d525670a44dc1 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/35_nmos_jfet_source_follower.svg.meta b/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/35_nmos_jfet_source_follower.svg.meta new file mode 100644 index 0000000..a58b545 --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/35_nmos_jfet_source_follower.svg.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: ce776eb6d1860504b8d6912b9e094a7f +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/36_wide_swing_mirror.svg.meta b/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/36_wide_swing_mirror.svg.meta new file mode 100644 index 0000000..82ace27 --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/36_wide_swing_mirror.svg.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c73df5a8212114449a052f404d89c00a +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/47_h_bridge.png.meta b/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/47_h_bridge.png.meta new file mode 100644 index 0000000..6bf2ba3 --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/47_h_bridge.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: a39c08de25b6eae4baeaf2be87366b51 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/48_h_bridge_v2.png.meta b/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/48_h_bridge_v2.png.meta new file mode 100644 index 0000000..d92be01 --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/48_h_bridge_v2.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: 4abe0bd3fe85d7a4897506899a1bb006 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/53_common_source_amplifier_exact.png.meta b/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/53_common_source_amplifier_exact.png.meta new file mode 100644 index 0000000..815fc69 --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/04_MOSFET_Circuits/53_common_source_amplifier_exact.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: 9b3613b9f7bdfc64f8eb66d1722a9ce4 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/07_Power_Supply/32_undervoltage_battery_switch.png.meta b/Assets/90_References/CircuitDiagrams/07_Power_Supply/32_undervoltage_battery_switch.png.meta new file mode 100644 index 0000000..23f0493 --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/07_Power_Supply/32_undervoltage_battery_switch.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: 1f52c239c6d390f40871c4147eddc10e +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/07_Power_Supply/44_low_dropout_regulator.png.meta b/Assets/90_References/CircuitDiagrams/07_Power_Supply/44_low_dropout_regulator.png.meta new file mode 100644 index 0000000..d9c1c69 --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/07_Power_Supply/44_low_dropout_regulator.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: 6f30acf67caccf940b0bc12598555f07 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/07_Power_Supply/45_feedback_linear_regulator.png.meta b/Assets/90_References/CircuitDiagrams/07_Power_Supply/45_feedback_linear_regulator.png.meta new file mode 100644 index 0000000..9ac3ec1 --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/07_Power_Supply/45_feedback_linear_regulator.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: 48d2c63ea5349a944a59fbed25710493 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/07_Power_Supply/46_shunt_regulator.png.meta b/Assets/90_References/CircuitDiagrams/07_Power_Supply/46_shunt_regulator.png.meta new file mode 100644 index 0000000..412ae77 --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/07_Power_Supply/46_shunt_regulator.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: 1c62e340feb07d746938846effe643d1 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/07_Power_Supply/52_dickson_voltage_doubler.svg.meta b/Assets/90_References/CircuitDiagrams/07_Power_Supply/52_dickson_voltage_doubler.svg.meta new file mode 100644 index 0000000..97455ab --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/07_Power_Supply/52_dickson_voltage_doubler.svg.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 957e051c87e87a545b399b40b52661f9 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/08_Oscillator_Timer/39_inverting_schmitt_symbol.png.meta b/Assets/90_References/CircuitDiagrams/08_Oscillator_Timer/39_inverting_schmitt_symbol.png.meta new file mode 100644 index 0000000..de2066b --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/08_Oscillator_Timer/39_inverting_schmitt_symbol.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: 0b2cebe5fa3a08a47ae8887183d218df +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/08_Oscillator_Timer/40_astable_multivibrator.png.meta b/Assets/90_References/CircuitDiagrams/08_Oscillator_Timer/40_astable_multivibrator.png.meta new file mode 100644 index 0000000..5d4120b --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/08_Oscillator_Timer/40_astable_multivibrator.png.meta @@ -0,0 +1,114 @@ +fileFormatVersion: 2 +guid: 8f8088fd9d1c4be47aeb90698d3726ee +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 13 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + flipGreenChannel: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + vTOnly: 0 + ignoreMipmapLimit: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 1 + aniso: 1 + mipBias: 0 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 1 + singleChannelComponent: 0 + flipbookRows: 1 + flipbookColumns: 1 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + ignorePngGamma: 0 + applyGammaDecoding: 0 + swizzle: 50462976 + cookieLightType: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Standalone + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + ignorePlatformSupport: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + nameFileIdTable: {} + mipmapLimitGroupName: + pSDRemoveMatte: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/08_Oscillator_Timer/54_schmitt_trigger_by_transistor.svg.meta b/Assets/90_References/CircuitDiagrams/08_Oscillator_Timer/54_schmitt_trigger_by_transistor.svg.meta new file mode 100644 index 0000000..49bdc93 --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/08_Oscillator_Timer/54_schmitt_trigger_by_transistor.svg.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f92447e70e3385043bce47a693d7ba06 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/09_Filter_Circuits/49_rc_charging.svg.meta b/Assets/90_References/CircuitDiagrams/09_Filter_Circuits/49_rc_charging.svg.meta new file mode 100644 index 0000000..2bd7f2d --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/09_Filter_Circuits/49_rc_charging.svg.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e152f3f7a4a681f47bbc7d7c91b0859b +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/90_References/CircuitDiagrams/10_Digital_Logic/38_cmos_nor_two_inputs.svg.meta b/Assets/90_References/CircuitDiagrams/10_Digital_Logic/38_cmos_nor_two_inputs.svg.meta new file mode 100644 index 0000000..8d7c3d0 --- /dev/null +++ b/Assets/90_References/CircuitDiagrams/10_Digital_Logic/38_cmos_nor_two_inputs.svg.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: edf005e777f59bb48a8432e8e75a1cc3 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: From 7dc003626c6af4d3484968f5914080966fd57dac Mon Sep 17 00:00:00 2001 From: okenic03-code Date: Wed, 18 Feb 2026 10:41:15 +0900 Subject: [PATCH 044/115] fix(core): address Codex PR review feedback - undo/redo, null guards, ground nets - Route component delete through CommandHistory (ComponentInteraction) - Add DeleteTraceNetCommand for undoable wire deletion (WireRoutingController) - Guard HandleStageClick against null _stages (StageSelectController) - Clear undo history on LoadBoard to match ResetBoard (GameManager) - Clear active placement when stage palette is replaced (ComponentPaletteController) - Name ground-connected nets as '0' for valid SPICE reference (RouteTraceCommand) --- .../30_Controllers/ComponentInteraction.cs | 27 +++---- .../30_Controllers/WireRoutingController.cs | 5 +- .../10_Runtime/40_Managers/GameManager.cs | 1 + .../60_UI/ComponentPaletteController.cs | 7 ++ .../10_Runtime/60_UI/StageSelectController.cs | 2 +- .../85_Commands/DeleteTraceNetCommand.cs | 74 +++++++++++++++++++ .../85_Commands/DeleteTraceNetCommand.cs.meta | 11 +++ .../85_Commands/RouteTraceCommand.cs | 53 ++++++++++++- 8 files changed, 158 insertions(+), 22 deletions(-) create mode 100644 Assets/10_Scripts/10_Runtime/85_Commands/DeleteTraceNetCommand.cs create mode 100644 Assets/10_Scripts/10_Runtime/85_Commands/DeleteTraceNetCommand.cs.meta diff --git a/Assets/10_Scripts/10_Runtime/30_Controllers/ComponentInteraction.cs b/Assets/10_Scripts/10_Runtime/30_Controllers/ComponentInteraction.cs index 08c1b42..431866e 100644 --- a/Assets/10_Scripts/10_Runtime/30_Controllers/ComponentInteraction.cs +++ b/Assets/10_Scripts/10_Runtime/30_Controllers/ComponentInteraction.cs @@ -2,6 +2,7 @@ using CircuitCraft.Core; using CircuitCraft.Components; using CircuitCraft.Managers; +using CircuitCraft.Commands; namespace CircuitCraft.Controllers { @@ -32,6 +33,7 @@ public class ComponentInteraction : MonoBehaviour // State private ComponentView _selectedComponent; private BoardState _boardState; + private CommandHistory _commandHistory; private void Awake() => Init(); @@ -58,6 +60,7 @@ private void Start() if (_gameManager != null) { _boardState = _gameManager.BoardState; + _commandHistory = _gameManager.CommandHistory; } else { @@ -165,7 +168,10 @@ private void HandleBoardReset() DeselectAll(); if (_gameManager != null) + { _boardState = _gameManager.BoardState; + _commandHistory = _gameManager.CommandHistory; + } } /// @@ -188,24 +194,15 @@ private void DeleteSelectedComponent() { int instanceId = placedComponent.InstanceId; - // Remove from BoardState - bool isRemoved = _boardState.RemoveComponent(instanceId); + // Remove from BoardState via command history (enables undo) + _commandHistory.ExecuteCommand(new RemoveComponentCommand(_boardState, instanceId)); + + // BoardView handles GameObject destruction via OnComponentRemoved event + _selectedComponent = null; - if (isRemoved) - { - // Destroy the GameObject - GameObject componentObject = _selectedComponent.gameObject; - _selectedComponent = null; // Clear reference before destroying - Destroy(componentObject); - #if UNITY_EDITOR - Debug.Log($"ComponentInteraction: Deleted component {instanceId} at position {gridPos}"); + Debug.Log($"ComponentInteraction: Deleted component {instanceId} at position {gridPos}"); #endif - } - else - { - Debug.LogWarning($"ComponentInteraction: Failed to remove component {instanceId} from BoardState.", this); - } } else { diff --git a/Assets/10_Scripts/10_Runtime/30_Controllers/WireRoutingController.cs b/Assets/10_Scripts/10_Runtime/30_Controllers/WireRoutingController.cs index dd57ce7..047e94a 100644 --- a/Assets/10_Scripts/10_Runtime/30_Controllers/WireRoutingController.cs +++ b/Assets/10_Scripts/10_Runtime/30_Controllers/WireRoutingController.cs @@ -160,10 +160,7 @@ private void HandleDeleteSelectedTrace() return; } - foreach (var trace in _boardState.GetTraces(selectedTrace.NetId).ToList()) - { - _boardState.RemoveTrace(trace.SegmentId); - } + _commandHistory.ExecuteCommand(new DeleteTraceNetCommand(_boardState, selectedTrace.NetId)); _selectedTraceSegmentId = -1; } diff --git a/Assets/10_Scripts/10_Runtime/40_Managers/GameManager.cs b/Assets/10_Scripts/10_Runtime/40_Managers/GameManager.cs index ff2954d..51a563f 100644 --- a/Assets/10_Scripts/10_Runtime/40_Managers/GameManager.cs +++ b/Assets/10_Scripts/10_Runtime/40_Managers/GameManager.cs @@ -193,6 +193,7 @@ public void LoadBoard(string stageId) var newBoardState = new BoardState(data.boardWidth, data.boardHeight); _saveLoadService.RestoreToBoard(newBoardState, data); _boardState = newBoardState; + _commandHistory.Clear(); _suggestedWidth = data.boardWidth; _suggestedHeight = data.boardHeight; Debug.Log($"GameManager: Board loaded for stage '{stageId}' with suggested area ({data.boardWidth}x{data.boardHeight})"); diff --git a/Assets/10_Scripts/10_Runtime/60_UI/ComponentPaletteController.cs b/Assets/10_Scripts/10_Runtime/60_UI/ComponentPaletteController.cs index e40b5e2..5bb2e18 100644 --- a/Assets/10_Scripts/10_Runtime/60_UI/ComponentPaletteController.cs +++ b/Assets/10_Scripts/10_Runtime/60_UI/ComponentPaletteController.cs @@ -238,6 +238,13 @@ private void UnregisterCallbacks() public void SetAvailableComponents(ComponentDefinition[] components) { _componentDefinitions = components; + + // Clear active placement when palette is replaced to prevent placing components from prior stage + if (_placementController != null) + { + _placementController.SetSelectedComponent(null); + } + _selectedButton = null; // Rebuild palette if UI has been initialized. if (_root != null) diff --git a/Assets/10_Scripts/10_Runtime/60_UI/StageSelectController.cs b/Assets/10_Scripts/10_Runtime/60_UI/StageSelectController.cs index 17fd7ca..ce68c5e 100644 --- a/Assets/10_Scripts/10_Runtime/60_UI/StageSelectController.cs +++ b/Assets/10_Scripts/10_Runtime/60_UI/StageSelectController.cs @@ -125,7 +125,7 @@ private void HandleBackClicked() private void HandleStageClick(int index) { // Check bounds - if (index < 0 || index >= _stages.Length) return; + if (_stages == null || index < 0 || index >= _stages.Length) return; // Check locked state if (!_unlockedStages[index]) return; diff --git a/Assets/10_Scripts/10_Runtime/85_Commands/DeleteTraceNetCommand.cs b/Assets/10_Scripts/10_Runtime/85_Commands/DeleteTraceNetCommand.cs new file mode 100644 index 0000000..004c342 --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/85_Commands/DeleteTraceNetCommand.cs @@ -0,0 +1,74 @@ +using System.Collections.Generic; +using System.Linq; +using CircuitCraft.Core; + +namespace CircuitCraft.Commands +{ + public class DeleteTraceNetCommand : ICommand + { + private readonly BoardState _boardState; + private readonly int _initialNetId; + + private int _currentNetId; + private string _savedNetName; + private readonly List<(GridPosition start, GridPosition end)> _savedTraces = new List<(GridPosition, GridPosition)>(); + private readonly List _savedPins = new List(); + private bool _hasCapturedState; + + public string Description => $"Delete trace net {_initialNetId}"; + + public DeleteTraceNetCommand(BoardState boardState, int netId) + { + _boardState = boardState; + _initialNetId = netId; + _currentNetId = netId; + } + + public void Execute() + { + var net = _boardState.GetNet(_currentNetId); + if (net == null) + { + _hasCapturedState = false; + return; + } + + _savedNetName = net.NetName; + + _savedTraces.Clear(); + foreach (var trace in _boardState.GetTraces(_currentNetId).ToList()) + { + _savedTraces.Add((trace.Start, trace.End)); + } + + _savedPins.Clear(); + _savedPins.AddRange(net.ConnectedPins.ToList()); + + _hasCapturedState = true; + + foreach (var trace in _boardState.GetTraces(_currentNetId).ToList()) + { + _boardState.RemoveTrace(trace.SegmentId); + } + } + + public void Undo() + { + if (!_hasCapturedState) + return; + + var recreatedNet = _boardState.CreateNet(_savedNetName); + _currentNetId = recreatedNet.NetId; + + foreach (var (start, end) in _savedTraces) + { + _boardState.AddTrace(_currentNetId, start, end); + } + + foreach (var pin in _savedPins) + { + _boardState.ConnectPinToNet(_currentNetId, pin); + } + } + } +} diff --git a/Assets/10_Scripts/10_Runtime/85_Commands/DeleteTraceNetCommand.cs.meta b/Assets/10_Scripts/10_Runtime/85_Commands/DeleteTraceNetCommand.cs.meta new file mode 100644 index 0000000..452744b --- /dev/null +++ b/Assets/10_Scripts/10_Runtime/85_Commands/DeleteTraceNetCommand.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 452cc8274c6eb3742bcf7cf6c95f7556 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/10_Scripts/10_Runtime/85_Commands/RouteTraceCommand.cs b/Assets/10_Scripts/10_Runtime/85_Commands/RouteTraceCommand.cs index 2befd17..39c4455 100644 --- a/Assets/10_Scripts/10_Runtime/85_Commands/RouteTraceCommand.cs +++ b/Assets/10_Scripts/10_Runtime/85_Commands/RouteTraceCommand.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using CircuitCraft.Core; @@ -10,6 +11,10 @@ namespace CircuitCraft.Commands /// public class RouteTraceCommand : ICommand { + private const string GroundNetName = "0"; + private const string GroundNetAlias = "GND"; + private const string GroundComponentDefinitionId = "ground"; + private readonly BoardState _boardState; private readonly PinReference _startPin; private readonly PinReference _endPin; @@ -119,7 +124,12 @@ private int ResolveNetId() { if (startNetId.Value != endNetId.Value) { - MergeNets(startNetId.Value, endNetId.Value); + int targetNetId = GetPreferredMergeTargetNetId(startNetId.Value, endNetId.Value); + int sourceNetId = targetNetId == startNetId.Value ? endNetId.Value : startNetId.Value; + MergeNets(targetNetId, sourceNetId); + + _createdNewNet = false; + return targetNetId; } _createdNewNet = false; @@ -139,11 +149,50 @@ private int ResolveNetId() } // Neither pin connected — create a new net - string netName = $"NET{_boardState.Nets.Count + 1}"; + string netName = IsGroundPin(_startPin) || IsGroundPin(_endPin) + ? GroundNetName + : $"NET{_boardState.Nets.Count + 1}"; _createdNewNet = true; return _boardState.CreateNet(netName).NetId; } + private int GetPreferredMergeTargetNetId(int firstNetId, int secondNetId) + { + var firstNet = _boardState.GetNet(firstNetId); + var secondNet = _boardState.GetNet(secondNetId); + + bool firstIsGround = IsGroundNet(firstNet); + bool secondIsGround = IsGroundNet(secondNet); + + if (firstIsGround && !secondIsGround) + return firstNetId; + + if (!firstIsGround && secondIsGround) + return secondNetId; + + return firstNetId; + } + + private bool IsGroundPin(PinReference pinRef) + { + var component = _boardState.GetComponent(pinRef.ComponentInstanceId); + if (component == null) + return false; + + return string.Equals(component.ComponentDefinitionId, GroundComponentDefinitionId, StringComparison.OrdinalIgnoreCase); + } + + private static bool IsGroundNet(Net net) + { + return net != null && IsGroundNetName(net.NetName); + } + + private static bool IsGroundNetName(string netName) + { + return string.Equals(netName, GroundNetName, StringComparison.OrdinalIgnoreCase) + || string.Equals(netName, GroundNetAlias, StringComparison.OrdinalIgnoreCase); + } + private void MergeNets(int targetNetId, int sourceNetId) { if (targetNetId == sourceNetId) From 9ce4414153fa57f84d7349d8477f56cb4ebe6ef5 Mon Sep 17 00:00:00 2001 From: okenic03-code Date: Wed, 18 Feb 2026 12:35:53 +0900 Subject: [PATCH 045/115] feat(ui): restyle all screens with sci-fi engineering blueprint theme - Create shared Theme.uss design system with 30+ CSS custom properties - Restyle all 6 screens (MainMenu, Settings, GameUI, Ending, PauseMenu, StageSelect) - Add picking-mode=Ignore to GameUI Root/MainContainer for click-through - Add reference images used for design extraction --- Assets/60_UI/50_USS/Ending.uss | 115 ++++-- Assets/60_UI/50_USS/GameUI.uss | 337 ++++++++---------- Assets/60_UI/50_USS/MainMenu.uss | 117 ++++-- Assets/60_UI/50_USS/PauseMenu.uss | 114 +++--- Assets/60_UI/50_USS/Settings.uss | 178 +++++---- Assets/60_UI/50_USS/StageSelect.uss | 127 ++++--- Assets/60_UI/50_USS/Theme.uss | 178 +++++++++ Assets/60_UI/50_USS/Theme.uss.meta | 11 + Assets/60_UI/60_UXML/Ending.uxml | 37 +- Assets/60_UI/60_UXML/GameUI.uxml | 7 +- Assets/60_UI/60_UXML/MainMenu.uxml | 49 +-- Assets/60_UI/60_UXML/PauseMenu.uxml | 16 +- Assets/60_UI/60_UXML/Settings.uxml | 141 ++++---- Assets/60_UI/60_UXML/StageSelect.uxml | 52 ++- Assets/90_References/Ref_Image.meta | 8 + .../90_References/Ref_Image/Game_MainMenu.png | Bin 0 -> 7813647 bytes .../Ref_Image/Game_MainMenu.png.meta | 114 ++++++ Assets/90_References/Ref_Image/Game_Play.png | Bin 0 -> 8510842 bytes .../Ref_Image/Game_Play.png.meta | 114 ++++++ .../90_References/Ref_Image/Game_Settings.png | Bin 0 -> 7690160 bytes .../Ref_Image/Game_Settings.png.meta | 114 ++++++ .../Ref_Image/Game_Success_Fail.png | Bin 0 -> 8510796 bytes .../Ref_Image/Game_Success_Fail.png.meta | 114 ++++++ 23 files changed, 1408 insertions(+), 535 deletions(-) create mode 100644 Assets/60_UI/50_USS/Theme.uss create mode 100644 Assets/60_UI/50_USS/Theme.uss.meta create mode 100644 Assets/90_References/Ref_Image.meta create mode 100644 Assets/90_References/Ref_Image/Game_MainMenu.png create mode 100644 Assets/90_References/Ref_Image/Game_MainMenu.png.meta create mode 100644 Assets/90_References/Ref_Image/Game_Play.png create mode 100644 Assets/90_References/Ref_Image/Game_Play.png.meta create mode 100644 Assets/90_References/Ref_Image/Game_Settings.png create mode 100644 Assets/90_References/Ref_Image/Game_Settings.png.meta create mode 100644 Assets/90_References/Ref_Image/Game_Success_Fail.png create mode 100644 Assets/90_References/Ref_Image/Game_Success_Fail.png.meta diff --git a/Assets/60_UI/50_USS/Ending.uss b/Assets/60_UI/50_USS/Ending.uss index f1e98f9..cf798b2 100644 --- a/Assets/60_UI/50_USS/Ending.uss +++ b/Assets/60_UI/50_USS/Ending.uss @@ -1,66 +1,119 @@ /* ============================================================ - CircuitCraft Ending Screen — Professional CAD Theme - Matching MainMenu / StageSelect aesthetic + CircuitCraft Ending Screen — Sci-Fi Mission Complete ============================================================ */ /* === Root Container === */ .ending-root { flex-grow: 1; - background-color: rgb(30, 30, 30); + background-color: var(--bg-void); justify-content: center; align-items: center; - color: rgb(220, 220, 220); } -/* === Title === */ +/* === Main Card === */ +.ending-card { + width: 480px; + background-color: var(--bg-panel); + border-width: 1px; + border-color: var(--border-primary); + border-radius: var(--radius-lg); + align-items: center; + overflow: hidden; +} + +/* === Header Strip === */ +.ending-header { + width: 100%; + padding: 12px 24px; + background-color: var(--bg-header); + border-bottom-width: 1px; + border-bottom-color: var(--border-primary); +} + +.ending-header-text { + font-size: 14px; + color: var(--text-secondary); + text-transform: uppercase; + letter-spacing: 2px; + -unity-text-align: middle-left; +} + +/* === Status Section === */ +.ending-status-section { + padding: 32px 24px 16px; + align-items: center; + width: 100%; +} + .ending-title { - font-size: 48px; - color: rgb(255, 255, 255); + font-size: 28px; -unity-font-style: bold; - margin-bottom: 16px; + color: var(--accent-neon-green); + text-transform: uppercase; -unity-text-align: middle-center; + margin-bottom: 8px; + text-shadow: 0 0 10px rgba(110, 255, 124, 0.4); } -/* === Subtitle === */ .ending-subtitle { - font-size: 18px; - color: rgb(180, 180, 180); - margin-bottom: 48px; + font-size: 16px; + color: var(--text-secondary); -unity-text-align: middle-center; } -/* === Stats === */ +/* === Stars Section === */ +.ending-stars-section { + padding: 16px 24px 24px; + align-items: center; + width: 100%; +} + .ending-stats { - font-size: 36px; - color: #FFD700; /* Gold */ + font-size: 32px; + color: var(--color-star); -unity-font-style: bold; - margin-bottom: 64px; -unity-text-align: middle-center; + text-shadow: 0 0 10px rgba(255, 215, 0, 0.3); +} + +/* === Divider === */ +.ending-divider { + width: 85%; + height: 1px; + background-color: var(--border-primary); + margin-bottom: 24px; +} + +/* === Action Section === */ +.ending-actions { + padding: 0 24px 24px; + width: 100%; + align-items: center; } -/* === Buttons === */ .ending-button-primary { - width: 240px; - height: 48px; - background-color: rgb(55, 148, 255); - color: rgb(255, 255, 255); - border-radius: 4px; - border-width: 0; - font-size: 16px; + width: 80%; + height: 44px; + background-color: rgba(90, 141, 171, 0.15); + border-width: 1px; + border-color: var(--accent-blue); + color: var(--accent-blue); + border-radius: var(--radius-sm); + font-size: 14px; -unity-font-style: bold; - flex-direction: row; + text-transform: uppercase; + letter-spacing: 1px; + transition-property: background-color, color; + transition-duration: 0.15s; align-items: center; justify-content: center; - transition-property: background-color, scale; - transition-duration: 0.1s; } .ending-button-primary:hover { - background-color: rgb(75, 163, 255); - scale: 1.02; + background-color: var(--accent-blue); + color: #000000; } .ending-button-primary:active { - background-color: rgb(30, 120, 220); - scale: 0.98; + background-color: rgba(90, 141, 171, 0.3); } diff --git a/Assets/60_UI/50_USS/GameUI.uss b/Assets/60_UI/50_USS/GameUI.uss index fc1a504..bfc5ee2 100644 --- a/Assets/60_UI/50_USS/GameUI.uss +++ b/Assets/60_UI/50_USS/GameUI.uss @@ -1,46 +1,23 @@ -/* GameUI.uss - Dark CAD/EDA Theme */ - -/* Variables */ -:root { - --color-background: #1E1E1E; - --color-surface: #252525; - --color-surface-lighter: #333333; - --color-toolbar: #2D2D2D; - --color-accent: #3794FF; - --color-accent-hover: #4BA3FF; - --color-accent-active: #1E78DC; - --color-text-primary: #DCDCDC; - --color-text-secondary: #888888; - --color-border: #3C3C3C; - --color-success: #4CAF50; - --color-error: #F44336; - --color-warning: #FFD740; - --color-star: #FFD700; -} - -/* Global Reset */ -* { - color: var(--color-text-primary); -} +/* GameUI.uss - Cyberpunk Engineering Workspace */ /* Root Container */ .root { flex-grow: 1; - background-color: var(--color-background); + background-color: var(--bg-void); font-size: 14px; } /* Toolbar */ .toolbar { height: 48px; - background-color: var(--color-toolbar); + background-color: var(--bg-panel); border-bottom-width: 1px; - border-bottom-color: var(--color-border); + border-bottom-color: var(--border-primary); flex-direction: row; align-items: center; justify-content: space-between; - padding-left: 12px; - padding-right: 12px; + padding-left: 16px; + padding-right: 16px; } .toolbar-group { @@ -49,43 +26,44 @@ } .toolbar-button { - height: 32px; + height: 34px; background-color: transparent; border-width: 1px; - border-color: var(--color-border); - border-radius: 4px; + border-color: var(--border-primary); + border-radius: var(--radius-sm); margin-right: 8px; - padding-left: 12px; - padding-right: 12px; - color: var(--color-text-primary); - -unity-text-align: middle-center; - transition: background-color 0.1s, border-color 0.1s; + padding-left: 14px; + padding-right: 14px; + color: var(--text-secondary); + text-transform: uppercase; + font-size: 12px; + transition-property: background-color, border-color; + transition-duration: 0.1s; } .toolbar-button:hover { - background-color: var(--color-surface-lighter); - border-color: var(--color-accent); - color: var(--color-accent); + background-color: var(--bg-surface); + border-color: var(--accent-blue); + color: var(--accent-blue); } .toolbar-button:active { - background-color: var(--color-surface); + background-color: var(--bg-panel); } .toolbar-button:disabled { opacity: 0.4; } -/* Simulate Button Special Style */ #simulate-button { - background-color: rgba(55, 148, 255, 0.15); - border-color: var(--color-accent); - color: var(--color-accent); + background-color: rgba(76, 175, 80, 0.12); + border-color: var(--accent-run-green); + color: var(--accent-run-green); -unity-font-style: bold; } #simulate-button:hover { - background-color: var(--color-accent); + background-color: var(--accent-run-green); color: #000000; } @@ -99,9 +77,9 @@ .component-palette { width: 240px; min-width: 240px; - background-color: var(--color-surface); + background-color: var(--bg-panel); border-right-width: 1px; - border-right-color: var(--color-border); + border-right-color: var(--border-primary); padding: 12px; } @@ -110,72 +88,64 @@ } .section-header { - font-size: 12px; - color: var(--color-text-secondary); + font-size: 11px; + color: var(--text-muted); -unity-font-style: bold; + text-transform: uppercase; + letter-spacing: 1px; margin-top: 16px; margin-bottom: 8px; - text-transform: uppercase; border-bottom-width: 1px; - border-bottom-color: var(--color-border); + border-bottom-color: var(--border-subtle); padding-bottom: 4px; } -/* Note: :first-child not supported in Unity UI Toolkit */ - -.sub-section-header { - font-size: 11px; - color: var(--color-text-secondary); - margin-top: 12px; - margin-bottom: 6px; - padding-left: 4px; - opacity: 0.8; -} - .component-button { height: 40px; flex-direction: row; align-items: center; - background-color: var(--color-surface-lighter); - border-radius: 4px; + background-color: var(--bg-surface); + border-radius: var(--radius-sm); margin-bottom: 6px; padding-left: 12px; padding-right: 12px; border-width: 1px; border-color: transparent; - transition: all 0.1s; + transition-property: all; + transition-duration: 0.1s; } .component-button:hover { - border-color: var(--color-accent); - background-color: rgba(55, 148, 255, 0.05); + border-color: var(--accent-blue); + background-color: rgba(90, 141, 171, 0.08); } .component-button.selected { - border-color: var(--color-accent); - background-color: rgba(55, 148, 255, 0.1); + border-color: var(--border-selected); + background-color: rgba(211, 84, 0, 0.1); } .component-button Label { - color: var(--color-text-primary); + color: var(--text-primary); font-size: 13px; white-space: normal; } -/* Property Editor Panel */ +/* Property Editor */ .property-editor { border-top-width: 1px; - border-top-color: var(--color-border); + border-top-color: var(--border-primary); padding: 12px; - background-color: var(--color-surface); + background-color: var(--bg-panel); flex-shrink: 0; } .prop-editor-title { font-size: 13px; -unity-font-style: bold; - color: var(--color-accent); + color: var(--accent-blue); margin-bottom: 8px; + text-transform: uppercase; } .prop-editor-section { @@ -184,7 +154,7 @@ .prop-label { font-size: 11px; - color: var(--color-text-secondary); + color: var(--text-secondary); margin-bottom: 4px; } @@ -195,45 +165,45 @@ .prop-value-field { flex-grow: 1; - height: 28px; - background-color: var(--color-surface-lighter); + height: 30px; + background-color: var(--bg-input); border-width: 1px; - border-color: var(--color-border); - border-radius: 4px; - color: var(--color-text-primary); + border-color: var(--border-primary); + border-radius: var(--radius-sm); + color: var(--text-primary); font-size: 13px; padding-left: 8px; padding-right: 8px; } .prop-value-field:focus { - border-color: var(--color-accent); + border-color: var(--accent-green); } .prop-unit-label { font-size: 13px; - color: var(--color-accent); + color: var(--accent-cyan); margin-left: 8px; - min-width: 20px; -unity-font-style: bold; + min-width: 20px; } .prop-default-hint { font-size: 10px; - color: var(--color-text-secondary); + color: var(--text-secondary); opacity: 0.6; margin-top: 4px; } .prop-specs-text { font-size: 12px; - color: var(--color-text-secondary); + color: var(--text-secondary); white-space: pre-wrap; padding: 8px; background-color: rgba(0, 0, 0, 0.2); - border-radius: 4px; + border-radius: var(--radius-sm); border-width: 1px; - border-color: var(--color-border); + border-color: var(--border-primary); } /* Game View */ @@ -248,23 +218,50 @@ top: 20px; left: 50%; translate: -50% 0; - background-color: rgba(45, 45, 45, 0.9); - padding: 8px 16px; + background-color: rgba(31, 36, 41, 0.92); + padding: 8px 20px; border-radius: 20px; border-width: 1px; - border-color: var(--color-accent); - color: var(--color-accent); + border-color: var(--accent-blue); + color: var(--accent-blue); font-size: 14px; -unity-font-style: bold; + text-transform: uppercase; display: none; } +.stage-objectives { + position: absolute; + top: 8px; + right: 8px; + background-color: rgba(31, 36, 41, 0.88); + border-width: 1px; + border-color: var(--border-primary); + border-radius: var(--radius-lg); + padding: 12px 16px; + max-width: 280px; +} + +.stage-title { + font-size: 14px; + -unity-font-style: bold; + color: var(--accent-blue); + margin-bottom: 6px; + text-transform: uppercase; +} + +.stage-targets { + font-size: 12px; + color: var(--text-secondary); + white-space: pre-wrap; +} + /* Status Bar */ .status-bar { height: 28px; - background-color: var(--color-toolbar); + background-color: var(--bg-panel); border-top-width: 1px; - border-top-color: var(--color-border); + border-top-color: var(--border-primary); flex-direction: row; align-items: center; padding-left: 12px; @@ -273,40 +270,44 @@ .status-label { font-size: 12px; - color: var(--color-text-secondary); + color: var(--text-muted); margin-right: 16px; -unity-text-align: middle-left; } -#StatusText { - flex-grow: 1; - color: var(--color-text-primary); +.status-budget { + color: var(--accent-blue); + -unity-font-style: bold; } .status-separator { width: 1px; height: 16px; - background-color: var(--color-border); + background-color: var(--border-subtle); margin-left: 8px; margin-right: 8px; } +#StatusText { + flex-grow: 1; + color: var(--text-primary); +} + /* Results Panel Overlay */ .results-panel { position: absolute; top: 50%; left: 50%; translate: -50% -50%; - width: 420px; + width: 440px; max-height: 85%; - background-color: var(--color-surface); + background-color: var(--bg-panel); border-width: 1px; - border-color: var(--color-border); - border-radius: 12px; - padding: 24px; + border-color: var(--border-primary); + border-radius: var(--radius-xl); + padding: 28px; align-items: center; display: flex; - /* Box shadow is not fully supported in all Unity versions via USS standard property, using minimal approach */ } .result-status { @@ -314,7 +315,7 @@ -unity-font-style: bold; margin-bottom: 12px; -unity-text-align: middle-center; - color: var(--color-success); + color: var(--text-primary); } .star-display { @@ -329,10 +330,10 @@ font-size: 13px; white-space: pre-wrap; margin-bottom: 16px; - color: var(--color-text-secondary); + color: var(--text-secondary); width: 100%; border-bottom-width: 1px; - border-bottom-color: var(--color-border); + border-bottom-color: var(--border-primary); padding-bottom: 12px; } @@ -340,78 +341,43 @@ font-size: 24px; -unity-font-style: bold; margin-bottom: 20px; - color: var(--color-text-primary); - width: 100%; + color: var(--text-primary); -unity-text-align: middle-center; + width: 100%; } .results-log-scroll { flex-grow: 1; width: 100%; margin-bottom: 16px; - background-color: rgba(0, 0, 0, 0.3); - border-radius: 6px; + background-color: rgba(5, 5, 5, 0.4); + border-radius: var(--radius-md); padding: 8px; border-width: 1px; - border-color: var(--color-border); + border-color: var(--border-primary); min-height: 100px; } .results-text { font-size: 12px; - color: var(--color-text-secondary); + color: var(--text-secondary); white-space: pre-wrap; - -unity-font-definition: initial; /* Fallback to standard font if monospace not available easily */ + -unity-font-definition: initial; } -.close-button { - width: 100%; - height: 36px; - background-color: var(--color-surface-lighter); - border-width: 1px; - border-color: var(--color-border); - border-radius: 6px; - color: var(--color-text-primary); - -unity-font-style: bold; - transition: background-color 0.1s; -} - -.close-button:hover { - background-color: var(--color-border); - color: #FFFFFF; -} - -.status-budget { - color: var(--color-accent); - -unity-font-style: bold; -} - -.stage-objectives { - position: absolute; - top: 8px; - right: 8px; - background-color: rgba(37, 37, 37, 0.85); +.rechallenge-prompt { + font-size: 13px; + color: var(--color-star); + -unity-text-align: middle-center; + margin-bottom: 12px; + padding: 8px 12px; + background-color: rgba(255, 215, 0, 0.06); + border-radius: var(--radius-md); border-width: 1px; - border-color: var(--color-border); - border-radius: 8px; - padding: 12px 16px; - max-width: 280px; -} - -.stage-title { - font-size: 14px; - -unity-font-style: bold; - color: var(--color-accent); - margin-bottom: 6px; -} - -.stage-targets { - font-size: 12px; - color: var(--color-text-secondary); - white-space: pre-wrap; + border-color: rgba(255, 215, 0, 0.15); + width: 100%; } -/* Results Navigation Buttons */ .results-button-row { flex-direction: row; width: 100%; @@ -421,42 +387,51 @@ .results-nav-button { flex-grow: 1; - height: 36px; - background-color: var(--color-surface-lighter); + height: 38px; + background-color: transparent; border-width: 1px; - border-color: var(--color-border); - border-radius: 6px; - color: var(--color-text-primary); + border-color: var(--border-primary); + border-radius: var(--radius-sm); + color: var(--text-secondary); margin-left: 4px; margin-right: 4px; -unity-font-style: bold; - transition: background-color 0.1s; + text-transform: uppercase; + transition-property: background-color; + transition-duration: 0.1s; } .results-nav-button:hover { - background-color: var(--color-border); + background-color: var(--bg-surface); + border-color: var(--border-focus); } .results-nav-primary { - background-color: rgba(55, 148, 255, 0.15); - border-color: var(--color-accent); - color: var(--color-accent); + background-color: rgba(90, 141, 171, 0.15); + border-color: var(--accent-blue); + color: var(--accent-blue); } .results-nav-primary:hover { - background-color: var(--color-accent); + background-color: var(--accent-blue); color: #000000; } -.rechallenge-prompt { - font-size: 13px; - color: var(--color-warning); - -unity-text-align: middle-center; - margin-bottom: 12px; - padding: 8px 12px; - background-color: rgba(255, 215, 64, 0.08); - border-radius: 6px; - border-width: 1px; - border-color: rgba(255, 215, 64, 0.2); +.close-button { width: 100%; + height: 38px; + background-color: transparent; + border-width: 1px; + border-color: var(--border-primary); + border-radius: var(--radius-md); + color: var(--text-secondary); + -unity-font-style: bold; + text-transform: uppercase; + transition-property: background-color; + transition-duration: 0.1s; +} + +.close-button:hover { + background-color: var(--bg-surface); + color: var(--text-primary); } diff --git a/Assets/60_UI/50_USS/MainMenu.uss b/Assets/60_UI/50_USS/MainMenu.uss index 71ea95b..3f4dbc1 100644 --- a/Assets/60_UI/50_USS/MainMenu.uss +++ b/Assets/60_UI/50_USS/MainMenu.uss @@ -1,67 +1,98 @@ /* ============================================================ - CircuitCraft MainMenu — Professional CAD Theme - Matching Fusion 360 / GameHUD aesthetic + CircuitCraft MainMenu — Sci-Fi Engineering Blueprint Theme ============================================================ */ -/* === Root Container === */ .main-menu-container { flex-grow: 1; - background-color: rgb(30, 30, 30); + background-color: var(--bg-void); justify-content: center; align-items: center; - color: rgb(220, 220, 220); } -/* === Title === */ +/* === Centered Panel === */ +.main-panel { + width: 380px; + padding: 40px; + background-color: var(--bg-panel); + border-width: 1px; + border-color: var(--border-primary); + border-radius: var(--radius-lg); + align-items: center; +} + +/* === Typography === */ .title-container { align-items: center; - margin-bottom: 48px; + width: 100%; + margin-bottom: 24px; } .title-text { - font-size: 36px; - color: rgb(255, 255, 255); + font-size: 32px; -unity-font-style: bold; + color: var(--text-primary); + letter-spacing: 4px; + text-transform: uppercase; + margin: 0; + padding: 0; +} + +.subtitle-text { + font-size: 10px; + color: var(--text-muted); letter-spacing: 2px; + margin-top: 4px; + text-transform: uppercase; + -unity-font-style: normal; +} + +.panel-divider { + width: 100%; + height: 1px; + background-color: var(--border-subtle); + margin-top: 16px; + margin-bottom: 8px; } /* === Buttons === */ .menu-button-primary { - width: 240px; - height: 40px; - background-color: rgb(55, 148, 255); - color: rgb(255, 255, 255); - border-radius: 3px; - border-width: 0; - font-size: 13px; + width: 100%; + height: 44px; + background-color: rgba(90, 141, 171, 0.15); + border-width: 1px; + border-color: var(--accent-blue); + color: var(--accent-blue); + border-radius: var(--radius-sm); + font-size: 14px; -unity-font-style: bold; - margin-bottom: 8px; + text-transform: uppercase; + margin-bottom: 12px; flex-direction: row; align-items: center; justify-content: center; - transition-property: background-color, scale; - transition-duration: 0.1s; + transition-property: background-color, border-color, color; + transition-duration: 0.15s; } .menu-button-primary:hover { - background-color: rgb(75, 163, 255); - scale: 1.02; + background-color: var(--accent-blue); + color: #000000; } .menu-button-primary:active { - background-color: rgb(30, 120, 220); - scale: 0.98; + background-color: rgba(90, 141, 171, 0.3); } .menu-button-secondary { - width: 240px; + width: 100%; height: 40px; background-color: transparent; - color: rgb(200, 200, 200); border-width: 1px; - border-color: rgb(70, 70, 70); - border-radius: 3px; + border-color: var(--border-primary); + color: var(--text-secondary); + border-radius: var(--radius-sm); font-size: 13px; + text-transform: uppercase; margin-bottom: 8px; flex-direction: row; align-items: center; @@ -71,20 +102,33 @@ } .menu-button-secondary:hover { - background-color: rgb(50, 50, 50); - border-color: rgb(100, 100, 100); - color: rgb(255, 255, 255); + background-color: var(--bg-surface); + border-color: var(--border-focus); + color: var(--text-primary); } .menu-button-secondary:active { - background-color: rgb(70, 70, 70); + background-color: var(--bg-input); +} + +/* Danger Button Variation */ +.menu-button-danger { + border-color: var(--border-primary); +} + +.menu-button-danger:hover { + background-color: rgba(217, 126, 74, 0.15); + border-color: var(--accent-orange); + color: var(--accent-orange); } -/* === Button Icons === */ +/* === Icons === */ .button-icon { - width: 20px; - height: 20px; + width: 18px; + height: 18px; margin-right: 8px; + -unity-background-scale-mode: scale-to-fit; + -unity-background-image-tint-color: currentColor; } .icon-play { @@ -101,6 +145,8 @@ .button-label { -unity-text-align: middle-center; + padding: 0; + margin: 0; } /* === Version Text === */ @@ -108,6 +154,7 @@ position: absolute; bottom: 16px; right: 16px; - color: rgb(100, 100, 100); + color: var(--text-muted); font-size: 11px; + letter-spacing: 1px; } diff --git a/Assets/60_UI/50_USS/PauseMenu.uss b/Assets/60_UI/50_USS/PauseMenu.uss index caedc0d..2f44d3e 100644 --- a/Assets/60_UI/50_USS/PauseMenu.uss +++ b/Assets/60_UI/50_USS/PauseMenu.uss @@ -4,90 +4,92 @@ top: 0; right: 0; bottom: 0; - background-color: rgba(0, 0, 0, 0.7); + background-color: rgba(15, 19, 22, 0.8); align-items: center; justify-content: center; - display: none; /* Hidden by default, toggled by controller */ + display: none; } .pause-panel { - width: 300px; - background-color: rgb(30, 30, 30); - border-left-color: rgb(70, 70, 70); - border-right-color: rgb(70, 70, 70); - border-top-color: rgb(70, 70, 70); - border-bottom-color: rgb(70, 70, 70); - border-left-width: 1px; - border-right-width: 1px; - border-top-width: 1px; - border-bottom-width: 1px; - border-top-left-radius: 8px; - border-top-right-radius: 8px; - border-bottom-right-radius: 8px; - border-bottom-left-radius: 8px; - padding-left: 32px; - padding-right: 32px; - padding-top: 32px; - padding-bottom: 32px; + width: 340px; + background-color: var(--bg-panel); + border-width: 1px; + border-color: var(--border-primary); + border-radius: var(--radius-lg); + overflow: hidden; +} + +.pause-header { + padding: 20px 24px 16px 24px; align-items: center; } .pause-title { - font-size: 24px; + font-size: 22px; -unity-font-style: bold; - color: rgb(255, 255, 255); - margin-bottom: 24px; + color: var(--text-primary); + letter-spacing: 3px; + text-transform: uppercase; -unity-text-align: middle-center; } +.pause-divider { + width: 80%; + height: 1px; + background-color: var(--border-primary); + align-self: center; + margin-bottom: 16px; +} + +.pause-buttons { + padding: 0 24px 24px 24px; + align-items: center; +} + .pause-button { - width: 100%; /* Fill the panel padding area */ - height: 40px; - margin-bottom: 12px; - border-top-left-radius: 3px; - border-top-right-radius: 3px; - border-bottom-right-radius: 3px; - border-bottom-left-radius: 3px; + width: 100%; + height: 42px; + margin-bottom: 10px; + border-radius: var(--radius-sm); font-size: 13px; - color: rgb(220, 220, 220); - background-color: rgba(0, 0, 0, 0); - border-left-color: rgb(70, 70, 70); - border-right-color: rgb(70, 70, 70); - border-top-color: rgb(70, 70, 70); - border-bottom-color: rgb(70, 70, 70); - border-left-width: 1px; - border-right-width: 1px; - border-top-width: 1px; - border-bottom-width: 1px; - transition-duration: 0.1s; + text-transform: uppercase; + letter-spacing: 1px; + color: var(--text-secondary); + background-color: transparent; + border-width: 1px; + border-color: var(--border-primary); + transition-property: background-color, border-color, color; + transition-duration: 0.15s; } .pause-button:hover { - background-color: rgb(50, 50, 50); - border-left-color: rgb(100, 100, 100); - border-right-color: rgb(100, 100, 100); - border-top-color: rgb(100, 100, 100); - border-bottom-color: rgb(100, 100, 100); + background-color: var(--bg-surface); + border-color: var(--border-focus); + color: var(--text-primary); } .pause-button:active { - background-color: rgb(70, 70, 70); + background-color: var(--bg-input); } .pause-button-primary { - background-color: rgb(55, 148, 255); - border-left-width: 0; - border-right-width: 0; - border-top-width: 0; - border-bottom-width: 0; + background-color: rgba(90, 141, 171, 0.15); + border-color: var(--accent-blue); + color: var(--accent-blue); -unity-font-style: bold; - color: rgb(255, 255, 255); } .pause-button-primary:hover { - background-color: rgb(75, 163, 255); + background-color: var(--accent-blue); + color: #000000; +} + +.pause-button-danger { + border-color: var(--accent-orange); + color: var(--accent-orange); } -.pause-button-primary:active { - background-color: rgb(30, 120, 220); +.pause-button-danger:hover { + background-color: rgba(217, 126, 74, 0.15); + border-color: var(--accent-orange); } diff --git a/Assets/60_UI/50_USS/Settings.uss b/Assets/60_UI/50_USS/Settings.uss index 2f30cb6..74b60f4 100644 --- a/Assets/60_UI/50_USS/Settings.uss +++ b/Assets/60_UI/50_USS/Settings.uss @@ -1,6 +1,5 @@ /* ============================================================ - CircuitCraft Settings — Professional CAD Theme - Matching MainMenu.uss + CircuitCraft Settings — Sci-Fi System Configuration ============================================================ */ .settings-container { @@ -9,63 +8,104 @@ top: 0; right: 0; bottom: 0; - background-color: rgba(30, 30, 30, 0.95); + background-color: rgba(21, 25, 28, 0.92); display: flex; + align-items: center; + justify-content: center; + padding: 40px; +} + +.settings-modal { + width: 700px; + max-height: 80%; + background-color: var(--bg-panel); + border-width: 1px; + border-color: var(--border-primary); + border-radius: var(--radius-xl); + overflow: hidden; flex-direction: column; - padding: 32px; } +/* Header */ .header { flex-direction: row; justify-content: space-between; align-items: center; - margin-bottom: 24px; + background-color: var(--bg-header); + padding: 16px 24px; border-bottom-width: 1px; - border-bottom-color: rgb(70, 70, 70); - padding-bottom: 16px; + border-bottom-color: var(--border-primary); } .title-text { - font-size: 24px; - color: rgb(220, 220, 220); + font-size: 18px; + color: var(--text-primary); -unity-font-style: bold; + letter-spacing: 2px; + text-transform: uppercase; } +.back-button { + width: auto; + min-width: 80px; + height: 32px; + background-color: transparent; + border-width: 1px; + border-color: var(--border-primary); + color: var(--text-secondary); + border-radius: var(--radius-sm); + font-size: 13px; + text-transform: uppercase; + transition-duration: 0.15s; +} + +.back-button:hover { + background-color: var(--bg-surface); + border-color: var(--border-focus); + color: var(--text-primary); +} + +/* Tabs */ .tabs-container { flex-direction: row; - margin-bottom: 24px; - background-color: rgb(40, 40, 40); - border-radius: 3px; - padding: 2px; + background-color: var(--bg-tab-bar); + padding: 0 16px; + border-bottom-width: 1px; + border-bottom-color: var(--border-primary); } .tab-button { flex-grow: 1; - height: 32px; + height: 40px; background-color: transparent; border-width: 0; - color: rgb(150, 150, 150); + color: var(--text-secondary); font-size: 14px; -unity-font-style: bold; - border-radius: 2px; - transition-duration: 0.1s; + text-transform: uppercase; + border-bottom-width: 2px; + border-bottom-color: transparent; + transition-duration: 0.15s; + border-radius: 0; + margin: 0; } .tab-button:hover { - background-color: rgb(60, 60, 60); - color: rgb(220, 220, 220); + color: var(--text-primary); + background-color: rgba(95, 168, 114, 0.05); } .tab-button.active { - background-color: rgb(55, 148, 255); - color: white; + color: var(--text-active); + border-bottom-color: var(--accent-green); + background-color: transparent; } +/* Content Area */ .content-area { flex-grow: 1; - background-color: rgb(40, 40, 40); - border-radius: 3px; padding: 24px; + background-color: var(--bg-panel); } .tab-content { @@ -81,23 +121,25 @@ flex-direction: row; justify-content: space-between; align-items: center; - margin-bottom: 16px; + margin-bottom: 20px; height: 40px; + padding: 0 8px; } .setting-label { - color: rgb(200, 200, 200); + color: var(--text-secondary); font-size: 14px; + text-transform: uppercase; } .control-container { - width: 250px; + width: 280px; flex-direction: row; align-items: center; justify-content: flex-end; } -/* Specific Controls */ +/* Unity Controls Overrides */ .unity-base-field { margin: 0; padding: 0; @@ -105,66 +147,80 @@ } .unity-base-field__label { - display: none; /* We use our own labels */ + display: none; } +/* Dropdowns & Text Fields */ .unity-base-popup-field__input { - background-color: rgb(30, 30, 30); - border-color: rgb(70, 70, 70); - border-radius: 3px; - color: rgb(220, 220, 220); + background-color: var(--bg-input); + border-color: var(--border-primary); + border-radius: var(--radius-sm); + color: var(--text-primary); + border-width: 1px; +} + +.unity-base-popup-field__text { + color: var(--text-primary); +} + +.unity-base-popup-field__arrow { + -unity-background-image-tint-color: var(--text-secondary); } +/* Toggles */ .unity-toggle__input { background-color: transparent; } .unity-toggle__checkmark { - background-color: rgb(30, 30, 30); - border-color: rgb(70, 70, 70); - border-radius: 3px; - width: 20px; - height: 20px; + background-color: var(--bg-input); + border-color: var(--border-primary); + border-radius: var(--radius-sm); + border-width: 1px; + width: 22px; + height: 22px; } .unity-toggle__checkmark--checked { - background-color: rgb(55, 148, 255); - border-color: rgb(55, 148, 255); + background-color: var(--accent-green); + border-color: var(--accent-green); + -unity-background-image-tint-color: var(--bg-void); } +/* Sliders */ .unity-slider { min-width: 150px; } .unity-base-slider__tracker { - background-color: rgb(30, 30, 30); - border-color: rgb(70, 70, 70); - height: 4px; + background-color: var(--bg-void); + border-color: var(--border-primary); + border-width: 1px; + height: 6px; + border-radius: 3px; + margin-top: -3px; } .unity-base-slider__dragger { - background-color: rgb(55, 148, 255); - width: 16px; - height: 16px; - border-radius: 8px; + background-color: var(--text-muted); + width: 8px; + height: 20px; + border-radius: 2px; border-width: 0; - margin-top: -6px; + margin-top: -10px; } -.back-button { - width: 100px; - height: 32px; - background-color: transparent; - border-width: 1px; - border-color: rgb(70, 70, 70); - color: rgb(200, 200, 200); - border-radius: 3px; - font-size: 13px; - transition-duration: 0.15s; +.unity-base-slider__dragger:hover { + background-color: var(--text-primary); } -.back-button:hover { - background-color: rgb(50, 50, 50); - border-color: rgb(100, 100, 100); - color: white; +.unity-base-slider__dragger:focus { + background-color: var(--accent-green); +} + +/* Fill part of slider (Unity 2021+ feature, might not show on older versions but good to have) */ +.unity-base-slider__fill { + background-color: var(--accent-green); + height: 6px; + border-radius: 3px; } diff --git a/Assets/60_UI/50_USS/StageSelect.uss b/Assets/60_UI/50_USS/StageSelect.uss index d7057cf..3386eea 100644 --- a/Assets/60_UI/50_USS/StageSelect.uss +++ b/Assets/60_UI/50_USS/StageSelect.uss @@ -3,18 +3,24 @@ /* Root Container */ .stage-select-root { flex-grow: 1; - background-color: #1E1E1E; + background-color: var(--bg-void); justify-content: center; align-items: center; padding: 40px; } /* Header */ +.stage-select-header { + margin-bottom: 40px; + align-items: center; +} + .world-title { - font-size: 32px; - color: #FFFFFF; + font-size: 28px; + color: var(--text-primary); -unity-font-style: bold; - margin-bottom: 40px; + text-transform: uppercase; + letter-spacing: 3px; -unity-text-align: middle-center; } @@ -23,96 +29,125 @@ flex-direction: row; flex-wrap: wrap; justify-content: center; - align-items: center; - margin-bottom: 60px; + align-items: flex-start; + margin-bottom: 40px; width: 100%; } /* Stage Card */ .stage-card { - width: 120px; - height: 140px; - background-color: #252525; - border-radius: 8px; + width: 160px; + height: 180px; + background-color: var(--bg-panel); + border-radius: var(--radius-lg); margin: 10px; - padding: 10px; - align-items: center; - justify-content: space-between; border-width: 1px; - border-color: #3C3C3C; - transition-property: background-color, scale; - transition-duration: 0.1s; + border-color: var(--border-primary); + flex-direction: row; + overflow: hidden; + transition-property: background-color, scale, border-color; + transition-duration: 0.15s; } .stage-card:hover { - background-color: #333333; - scale: 1.05; - border-color: #555555; + background-color: var(--bg-surface); + scale: 1.04; + border-color: var(--border-focus); +} + +/* Status Bar */ +.card-status-bar { + width: 4px; + height: 100%; + border-radius: 0; +} + +.status-blue { + background-color: var(--accent-blue); +} + +.status-green { + background-color: var(--accent-green); +} + +.status-orange { + background-color: var(--accent-orange); +} + +/* Card Content */ +.card-content { + flex-grow: 1; + padding: 14px; + align-items: center; + justify-content: space-between; } /* Locked State */ .stage-card.locked { - opacity: 0.5; - background-color: #1A1A1A; - border-color: #2A2A2A; + opacity: 0.4; + background-color: var(--bg-void); + border-color: var(--border-subtle); } .stage-card.locked:hover { - scale: 1.0; /* No scale effect for locked cards */ - background-color: #1A1A1A; + scale: 1.0; + background-color: var(--bg-void); } /* Completed State */ .stage-card.completed { - border-color: #4CAF50; /* Subtle green border */ - border-width: 1px; + border-color: var(--accent-green); } /* Typography inside Card */ .stage-number { - font-size: 14px; - color: #888888; + font-size: 13px; + color: var(--text-muted); -unity-font-style: bold; - margin-top: 5px; + text-transform: uppercase; + margin-top: 4px; } .stage-name { - font-size: 12px; - color: #FFFFFF; + font-size: 13px; + color: var(--text-primary); white-space: normal; -unity-text-align: middle-center; - margin-top: 5px; - margin-bottom: 5px; + margin-top: 8px; + margin-bottom: 8px; } .stage-stars { - font-size: 18px; - color: #FFD700; /* Gold */ + font-size: 20px; + color: var(--color-star); -unity-text-align: middle-center; - margin-bottom: 5px; + margin-bottom: 4px; + text-shadow: 0 0 6px rgba(255, 215, 0, 0.2); } /* Back Button */ .back-button { - width: 200px; - height: 40px; + width: 220px; + height: 42px; background-color: transparent; border-width: 1px; - border-color: #444444; - border-radius: 4px; - color: #CCCCCC; + border-color: var(--border-primary); + border-radius: var(--radius-sm); + color: var(--text-secondary); font-size: 14px; -unity-font-style: bold; - transition-property: background-color, color; + text-transform: uppercase; + letter-spacing: 1px; + transition-property: background-color, border-color, color; transition-duration: 0.15s; } .back-button:hover { - background-color: #333333; - color: #FFFFFF; - border-color: #666666; + background-color: var(--bg-surface); + border-color: var(--border-focus); + color: var(--text-primary); } .back-button:active { - background-color: #222222; + background-color: var(--bg-input); } diff --git a/Assets/60_UI/50_USS/Theme.uss b/Assets/60_UI/50_USS/Theme.uss new file mode 100644 index 0000000..f5c4731 --- /dev/null +++ b/Assets/60_UI/50_USS/Theme.uss @@ -0,0 +1,178 @@ +:root { + /* Backgrounds */ + --bg-void: #15191C; + --bg-panel: #1F2429; + --bg-surface: #2B3238; + --bg-input: #343D44; + --bg-header: #363F45; + --bg-tab-bar: #2A3035; + + /* Borders */ + --border-primary: #3A454D; + --border-subtle: #2F363B; + --border-focus: #5A8DAB; + --border-selected: #D35400; + + /* Accents */ + --accent-blue: #5A8DAB; + --accent-green: #5FA872; + --accent-orange: #D97E4A; + --accent-red: #FF5C5C; + --accent-neon-green: #6EFF7C; + --accent-neon-red: #FF5C5C; + --accent-run-green: #4CAF50; + --accent-pause-orange: #FF7043; + --accent-cyan: #4DD0E1; + + /* Text */ + --text-primary: #E0E6EB; + --text-secondary: #B0B8BF; + --text-muted: #707A85; + --text-active: #5FA872; + + /* Special */ + --color-star: #FFD700; + --color-visualizer-bg: #050505; + + /* Spacing */ + --spacing-xs: 4px; + --spacing-sm: 8px; + --spacing-md: 16px; + --spacing-lg: 24px; + --spacing-xl: 32px; + --spacing-2xl: 48px; + + /* Border Radius */ + --radius-sm: 4px; + --radius-md: 6px; + --radius-lg: 8px; + --radius-xl: 12px; + + /* Transitions */ + --transition-fast: 0.1s; + --transition-normal: 0.15s; + --transition-slow: 0.2s; +} + +/* ========================================= + Shared Components + ========================================= */ + +/* Reusable panel container */ +.sci-fi-panel { + background-color: var(--bg-panel); + border-width: 1px; + border-color: var(--border-primary); + border-radius: var(--radius-lg); + padding: var(--spacing-md); +} + +/* Section header text */ +.sci-fi-header { + font-size: 20px; + -unity-font-style: bold; + color: var(--text-primary); + letter-spacing: 2px; + text-transform: uppercase; + margin-bottom: var(--spacing-md); +} + +/* Standard label */ +.sci-fi-label { + font-size: 14px; + color: var(--text-secondary); +} + +/* ========================================= + Buttons + ========================================= */ + +/* Base button style */ +.sci-fi-btn { + height: 40px; + border-radius: var(--radius-sm); + background-color: transparent; + border-width: 1px; + border-color: var(--border-primary); + color: var(--text-secondary); + font-size: 14px; + text-transform: uppercase; + transition-property: background-color, border-color, color; + transition-duration: var(--transition-normal); + padding-left: var(--spacing-md); + padding-right: var(--spacing-md); + align-items: center; + justify-content: center; +} + +.sci-fi-btn:hover { + background-color: var(--bg-surface); + border-color: var(--border-focus); + color: var(--text-primary); +} + +.sci-fi-btn:active { + background-color: var(--bg-input); +} + +/* Primary Accent Button */ +.sci-fi-btn-primary { + background-color: rgba(90, 141, 171, 0.15); + border-color: var(--accent-blue); + color: var(--accent-blue); + -unity-font-style: bold; +} + +.sci-fi-btn-primary:hover { + background-color: var(--accent-blue); + color: #000000; +} + +/* Danger / Destructive Button */ +.sci-fi-btn-danger { + border-color: var(--accent-orange); + color: var(--accent-orange); +} + +.sci-fi-btn-danger:hover { + background-color: rgba(217, 126, 74, 0.2); + color: var(--accent-orange); +} + +/* ========================================= + Inputs & Fields + ========================================= */ + +.sci-fi-input { + background-color: var(--bg-input); + border-width: 1px; + border-color: var(--border-primary); + border-radius: var(--radius-sm); + color: var(--text-primary); + height: 36px; + padding: 0 var(--spacing-sm); +} + +.sci-fi-input:focus { + border-color: var(--accent-green); +} + +/* ========================================= + Effects & Status + ========================================= */ + +.glow-text-green { + color: var(--accent-neon-green); + text-shadow: 0 0 8px rgba(110, 255, 124, 0.5); +} + +.glow-text-red { + color: var(--accent-neon-red); + text-shadow: 0 0 8px rgba(255, 92, 92, 0.5); +} + +.status-bar-base { + width: 4px; + height: 100%; + border-radius: 2px; +} diff --git a/Assets/60_UI/50_USS/Theme.uss.meta b/Assets/60_UI/50_USS/Theme.uss.meta new file mode 100644 index 0000000..95c4873 --- /dev/null +++ b/Assets/60_UI/50_USS/Theme.uss.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 71f7b79d57b08204e992a92f1962e100 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 12385, guid: 0000000000000000e000000000000000, type: 0} + disableValidation: 0 diff --git a/Assets/60_UI/60_UXML/Ending.uxml b/Assets/60_UI/60_UXML/Ending.uxml index 18c1f3b..1bc7f79 100644 --- a/Assets/60_UI/60_UXML/Ending.uxml +++ b/Assets/60_UI/60_UXML/Ending.uxml @@ -1,16 +1,31 @@ +