Repository navigation
[Accessor] Use init accessor for read-only fields - #116
Conversation
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
Assets/Scripts/Agents/Agent.cs (1)
249-334: Extract these transformation methods to a shared utility class.The methods
GetRelativePositionTransformation,GetRelativeVelocityTransformation, andGetRelativeAccelerationTransformationare duplicated identically in bothAgent.cs(lines 249-334) andAgentBase.cs(lines 144-229). SinceAgentandAgentBaseare independent classes (both inheriting directly fromMonoBehaviourwith no inheritance relationship between them), this duplication should be consolidated into a shared utility class to reduce maintenance burden and ensure consistency.Assets/Scripts/Behavior/FlightPlan.cs (1)
24-26: Problematic approval: Config property change breaks test expectations.The review approves changes that create a critical issue. The code now has
Config { get; init; }(init-only, immutable after construction), but the testWaypoints_IsResetAfterSettingConfig(line 48-65 of FlightPlanTests.cs) explicitly attempts to setConfigafter construction and expects_waypointsto reset and recalculate.With an init-only property, this test cannot work as written. Either:
- The
Configproperty needs a public setter that resets_waypoints = nullto trigger recalculation in theWaypointsgetter, or- The test is now invalid and should be removed.
The claim that "removal of the old setter's
_waypoints = nullreset logic is correct" contradicts the test's expectations and will cause a compilation or runtime failure.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (32)
Assets/Scripts/Agents/Agent.cs(4 hunks)Assets/Scripts/Agents/AgentBase.cs(2 hunks)Assets/Scripts/Algorithms/Planning/ILaunchAnglePlanner.cs(1 hunks)Assets/Scripts/Algorithms/Planning/LaunchAngleDataPoint.cs(1 hunks)Assets/Scripts/Algorithms/Planning/LaunchAngleInput.cs(1 hunks)Assets/Scripts/Algorithms/Planning/LaunchAngleOutput.cs(1 hunks)Assets/Scripts/Algorithms/Planning/LaunchAnglePlannerBase.cs(1 hunks)Assets/Scripts/Algorithms/Planning/LaunchPlan.cs(1 hunks)Assets/Scripts/Algorithms/Prediction/IPredictor.cs(1 hunks)Assets/Scripts/Algorithms/Prediction/PredictorBase.cs(1 hunks)Assets/Scripts/Algorithms/Prediction/PredictorState.cs(1 hunks)Assets/Scripts/Assignment/AssignmentItem.cs(1 hunks)Assets/Scripts/Assignment/CostBasedAssignment.cs(0 hunks)Assets/Scripts/Behavior/AttackBehaviorBase.cs(1 hunks)Assets/Scripts/Behavior/FlightPlan.cs(1 hunks)Assets/Scripts/Behavior/IAttackBehavior.cs(1 hunks)Assets/Scripts/Controller/ControllerBase.cs(1 hunks)Assets/Scripts/Controller/IController.cs(1 hunks)Assets/Scripts/Evasion/EvasionBase.cs(1 hunks)Assets/Scripts/Evasion/IEvasion.cs(1 hunks)Assets/Scripts/Hierarchical/HierarchicalAgent.cs(1 hunks)Assets/Scripts/Movements/IMovement.cs(1 hunks)Assets/Scripts/Movements/MovementBase.cs(1 hunks)Assets/Scripts/Sensors/ISensor.cs(1 hunks)Assets/Scripts/Sensors/IdealSensorLegacy.cs(1 hunks)Assets/Scripts/Sensors/SensorBase.cs(1 hunks)Assets/Scripts/Sensors/SensorOutput.cs(1 hunks)Assets/Scripts/Utils/Direction.cs(1 hunks)Assets/Scripts/Utils/Interpolator2DDataPoint.cs(1 hunks)Assets/Scripts/Utils/IsExternalInit.cs(1 hunks)Assets/Scripts/Utils/IsExternalInit.cs.meta(1 hunks)Assets/Scripts/Utils/Transformation.cs(1 hunks)
💤 Files with no reviewable changes (1)
- Assets/Scripts/Assignment/CostBasedAssignment.cs
🧰 Additional context used
🧬 Code graph analysis (7)
Assets/Scripts/Sensors/ISensor.cs (1)
Assets/Scripts/Threats/Threat.cs (1)
Agent(85-102)
Assets/Scripts/Movements/MovementBase.cs (2)
Assets/Scripts/Agents/Agent.cs (3)
Agent(5-442)Agent(104-106)Agent(112-114)Assets/Scripts/Managers/SimManager.cs (1)
Agent(356-370)
Assets/Scripts/Sensors/SensorOutput.cs (2)
Assets/Scripts/Agents/AgentBase.cs (2)
PositionTransformation(145-165)VelocityTransformation(167-223)Assets/Scripts/Agents/Agent.cs (2)
PositionTransformation(249-269)VelocityTransformation(271-327)
Assets/Scripts/Behavior/FlightPlan.cs (1)
Assets/Scripts/Config/ConfigLoader.cs (4)
Configs(44-49)Configs(51-60)Configs(62-66)Configs(68-73)
Assets/Scripts/Agents/Agent.cs (1)
Assets/Scripts/Agents/AgentBase.cs (7)
PositionTransformation(145-165)VelocityTransformation(167-223)AccelerationTransformation(225-230)Transformation(93-95)Transformation(97-99)Transformation(101-103)Transformation(122-143)
Assets/Scripts/Agents/AgentBase.cs (1)
Assets/Scripts/Agents/Agent.cs (9)
PositionTransformation(249-269)VelocityTransformation(271-327)AccelerationTransformation(329-334)Transformation(214-232)Transformation(234-247)Vector3(186-188)Vector3(198-200)Vector3(206-208)Vector3(404-415)
Assets/Scripts/Utils/Transformation.cs (3)
Assets/Scripts/Agents/AgentBase.cs (3)
PositionTransformation(145-165)VelocityTransformation(167-223)AccelerationTransformation(225-230)Assets/Scripts/Agents/Agent.cs (7)
PositionTransformation(249-269)VelocityTransformation(271-327)AccelerationTransformation(329-334)Vector3(186-188)Vector3(198-200)Vector3(206-208)Vector3(404-415)Assets/Scripts/Controller/WaypointController.cs (1)
Vector3(12-29)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Build plugins for macos-latest
- GitHub Check: Build plugins for windows-latest
- GitHub Check: Test plugins on ubuntu-latest
- GitHub Check: Test plugins on windows-latest
- GitHub Check: Test plugins on macos-latest
🔇 Additional comments (35)
Assets/Scripts/Evasion/IEvasion.cs (1)
8-8: Init‑only Agent on IEvasion aligns with immutability goalSwitching
IAgent Agenttoget; init;is consistent with treating the mounted agent as fixed after construction. Just ensure there are no existing usages that reassignAgenton anIEvasionimplementation at runtime; those will now be compile‑time errors and need to be migrated to initialization patterns (e.g., constructors/object initializers).Assets/Scripts/Movements/IMovement.cs (1)
8-8: Init‑only Agent on IMovement is consistent and low‑riskMaking
IAgent Agentinit‑only fits the idea that a movement behavior is bound to a specific agent and not swapped arbitrarily later. This looks good and mirrors the broader pattern in the PR, assuming any prior runtime reassignments have been removed or refactored.Assets/Scripts/Utils/IsExternalInit.cs (1)
1-5: IsExternalInit shim is minimal and correctly guardedThe conditional
#if !NET5_0_OR_GREATERandinternal static class IsExternalInitunderSystem.Runtime.CompilerServicesis the typical minimal shim for init‑only support on older targets. This should be safe and non‑conflicting when upgrading to .NET 5+.Assets/Scripts/Utils/IsExternalInit.cs.meta (1)
1-2: Meta file is valid Unity asset metadataThe
.metacontents look standard (format version + GUID) and correctly accompany the newIsExternalInit.csscript.Assets/Scripts/Algorithms/Planning/LaunchAngleInput.cs (1)
4-7: Making LaunchAngleInput fields init‑only is appropriate for value data
DistanceandAltitudeasget; init;fits this struct as a pure input DTO. Verify any call sites constructingLaunchAngleInputnow use object initializers or constructors instead of assigning these properties later.Assets/Scripts/Algorithms/Prediction/IPredictor.cs (1)
5-5: Init‑only Hierarchical reference clarifies predictor ownershipChanging
Hierarchicaltoget; init;makes predictors clearly bound to a single hierarchical object for their lifetime, which improves reasoning about prediction state. This is consistent with the rest of the PR’s immutability push.Assets/Scripts/Assignment/AssignmentItem.cs (1)
3-4: AssignmentItem as an immutable pair is a good fitMaking
FirstandSecondget; init;matches AssignmentItem’s role as an output from an assignment algorithm. It avoids accidental mutation of results after computation and should be safe as long as construction sites use initializers.Assets/Scripts/Behavior/IAttackBehavior.cs (1)
7-9: Init‑only Agent and Config solidify attack behavior configurationLocking
AgentandConfigs.AttackBehaviorConfig Configtoget; init;makes attack behaviors properly configured once and then immutable, which is desirable. Please double‑check that no game flow relies on swapping behaviors’AgentorConfigat runtime (e.g., retargeting by reusing the same behavior instance); those patterns would need to move to creating new behavior instances instead.Assets/Scripts/Algorithms/Prediction/PredictorBase.cs (1)
3-7: Init-onlyHierarchicalproperty matches intended immutabilityUsing
inithere keeps the base constructor assignment valid while preventing later reassignment, which is appropriate for a predictor’s backing hierarchy. Just ensure there are no remaining call sites that were mutatingHierarchicalafter construction, as those will now fail to compile and may need refactoring to create new predictor instances instead.Assets/Scripts/Utils/Interpolator2DDataPoint.cs (1)
7-10: Immutability onInterpolator2DDataPointproperties is appropriateMaking
CoordinatesandDatainit-only aligns with these being fixed characteristics of a data point and prevents accidental reassignment after construction. Note thatDatabeingIReadOnlyList<float>only protects the reference; callers should still treat the underlying list as immutable by convention to avoid surprising mutations.Assets/Scripts/Algorithms/Prediction/PredictorState.cs (1)
6-12: Init-onlyPredictorStatefields improve value-type safetyConverting
Position,Velocity, andAccelerationto init-only is a good fit for a value-type snapshot of state and helps avoid subtle bugs from mutating copied structs. The main impact is that any callers that previously set these properties after construction must now do so via object initializers (or a ctor), so it’s worth double-checking those usages.Assets/Scripts/Algorithms/Planning/LaunchPlan.cs (1)
6-26: Init-onlyLaunchPlanfields are consistent, but watch forNoLaunch()mutation patternsUsing
initforShouldLaunch,LaunchAngle, andInterceptPositionmakes a launch plan immutable after creation, which matches the “snapshot configuration” intent. One behavioral change to be aware of: any existing code that calledLaunchPlan.NoLaunch()and then setLaunchAngleorInterceptPositionafterward will no longer compile and must instead construct the full plan in a single initializer.Assets/Scripts/Controller/IController.cs (1)
8-14: Init-onlyAgentonIControllertightens API; verify no runtime re-binding is requiredChanging
Agenttoget; init;on the interface means any code holding anIControllerreference can no longer reassignAgentafter initialization (even if the concrete implementation still has aset). That’s consistent with making controllers bound to a single agent, but it is a source-breaking change for any patterns that reused a controller across agents; those call sites will need to be updated to create new controller instances instead.Assets/Scripts/Algorithms/Planning/ILaunchAnglePlanner.cs (1)
8-15: Launch angle plannerAgentnow effectively one-time boundMaking
Agentinit-only here is consistent with other components and enforces that a planner is configured for a single launcher agent. That’s desirable for immutability, but do confirm there are no usages that reassignAgenton anILaunchAnglePlannerinstance at runtime (e.g., reusing planners across agents), as those will now fail to compile and should instead create separate planner instances.Assets/Scripts/Movements/MovementBase.cs (1)
7-27: MovementBase’s init-onlyAgentis consistent with usage
MovementBasealready treatsAgentas a fixed dependency set in the constructor and only read thereafter, so changing it toget; init;is semantically neutral here and simply enforces that constraint at the type level. This aligns with the broader immutability pattern across controllers/behaviors.Assets/Scripts/Sensors/IdealSensorLegacy.cs (1)
7-10: Object initializers correctly adapt to init-onlySensorOutputSwitching to
new SensorOutput { Position = ..., Velocity = ... }is the right adjustment for init-only properties and keeps the twoSenseoverloads simple and symmetric. Behavior is unchanged aside from enforcing immutability of the returnedSensorOutputinstances.Also applies to: 16-19
Assets/Scripts/Evasion/EvasionBase.cs (1)
6-10: LGTM!Good use of init-only accessor. The Agent reference is appropriately immutable after construction, and the constructor assignment remains valid.
Assets/Scripts/Sensors/SensorBase.cs (1)
6-10: LGTM!Appropriate use of init accessor. A sensor's owning agent is logically fixed at construction time.
Assets/Scripts/Algorithms/Planning/LaunchAnglePlannerBase.cs (1)
5-9: LGTM!The init accessor correctly enforces that the planner is bound to a specific agent at construction, preventing reassignment during planning operations.
Assets/Scripts/Controller/ControllerBase.cs (1)
6-10: LGTM!Init accessor appropriately enforces that the controller-agent binding is fixed at construction time.
Assets/Scripts/Sensors/ISensor.cs (1)
7-7: Interface change is compatible with all implementations.The
initaccessor is correctly implemented inSensorBase, which is the only class implementingISensor. No post-construction reassignments of theAgentproperty exist in the codebase, confirming the change poses no compatibility issues.Assets/Scripts/Sensors/SensorOutput.cs (1)
3-9: LGTM!The conversion to
initaccessors forPositionandVelocityproperties is appropriate for this immutable data transfer struct. This aligns with the broader codebase pattern of making transformation-related data structures immutable after construction.Assets/Scripts/Hierarchical/HierarchicalAgent.cs (1)
7-13: LGTM!The
initaccessor forAgentis well-suited here since the agent reference is set once in the constructor and should not be reassigned thereafter. This enforces the immutability constraint at the type system level.Assets/Scripts/Algorithms/Planning/LaunchAngleDataPoint.cs (1)
2-8: LGTM!The init-only accessors appropriately enforce immutability for this data point struct, which logically pairs an input with its corresponding output and should not be modified after creation.
Assets/Scripts/Utils/Direction.cs (1)
2-6: LGTM!Converting
DistanceandAltitudeto init-only properties is appropriate for this simple value struct representing directional data.Assets/Scripts/Algorithms/Planning/LaunchAngleOutput.cs (1)
2-8: LGTM!Init-only accessors are well-suited for this output struct, ensuring the computed launch angle and time values remain immutable after calculation.
Assets/Scripts/Behavior/AttackBehaviorBase.cs (1)
13-18: LGTM!The init-only accessors for
AgentandConfigcorrectly enforce immutability after construction. Note that the previousConfigsetter had a side effect of invalidating_flightPlan—this removal is appropriate sinceConfigcan no longer be reassigned post-initialization, making the invalidation logic unnecessary.Assets/Scripts/Utils/Transformation.cs (1)
3-25: LGTM!The conversion of all transformation structs to init-only properties is well-aligned with their usage pattern—they are constructed via object initializers in methods like
GetRelativePositionTransformation,GetRelativeVelocityTransformation, andGetRelativeAccelerationTransformation, then returned as immutable values. This enforces the intended read-only semantics at the type system level.Assets/Scripts/Agents/Agent.cs (2)
11-12: LGTM!The epsilon constant is appropriately defined for numerical stability checks when dealing with near-zero magnitudes in transformation calculations.
214-231: Addresses previous feedback on redundant calculation.The
relativePositionis now computed once and reused across the helper methods, eliminating the redundant calculation that was flagged in the previous review.Assets/Scripts/Agents/AgentBase.cs (4)
126-142: LGTM! Clean refactor to object initializer pattern.The refactor from incremental assignment to direct object construction improves immutability and aligns with the PR's init-only accessor goals. The logic flow remains identical: compute relative position, delegate to three transformation helpers, and return a fully-initialized
Transformation.
145-165: LGTM! Proper epsilon guard for azimuth calculation.The epsilon check at line 155 correctly guards against computing azimuth when the flat relative position is near zero (target directly above/below), defaulting to 0 in that case. The object initializer pattern cleanly returns all position transformation fields.
167-223: LGTM! Robust handling of edge cases with epsilon guards.The epsilon-guarded early return at line 169 properly handles the case where the target is at the same position, avoiding division by zero in the tangential velocity calculations. The fallback logic (lines 192-196) correctly handles parallel alignment edge cases by deriving orthogonal vectors. The refactor to object initializers maintains all the original numerical stability safeguards.
225-230: LGTM! Straightforward refactor.Simple conversion to object initializer pattern for acceleration transformation. Consistent with the other transformation method refactors.
Assets/Scripts/Behavior/FlightPlan.cs (1)
11-11: LGTM! Appropriate use of init-only accessor.Converting
Configto an init-only property aligns with the PR's goal of preventing reassignment after object initialization. This improves immutability by ensuring the flight plan configuration cannot be changed after the object is constructed.
| public Transformation GetRelativeTransformationToWaypoint(Vector3 waypoint) { | ||
| Transformation transformation = new Transformation(); | ||
|
|
||
| // Get the relative position transformation. | ||
| transformation.Position = GetRelativePositionTransformation(waypoint - GetPosition()); | ||
| PositionTransformation positionTransformation = | ||
| GetRelativePositionTransformation(waypoint - GetPosition()); | ||
|
|
||
| // Get the relative velocity transformation. | ||
| transformation.Velocity = | ||
| VelocityTransformation velocityTransformation = | ||
| GetRelativeVelocityTransformation(waypoint - GetPosition(), -GetVelocity()); | ||
|
|
||
| return transformation; | ||
| return new Transformation { | ||
| Position = positionTransformation, | ||
| Velocity = velocityTransformation, | ||
| }; |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Redundant calculation of relative position.
Similar to the issue previously flagged in GetRelativeTransformation, the expression waypoint - GetPosition() is computed twice (lines 237 and 241). Consider storing it in a local variable for consistency with the refactoring applied to GetRelativeTransformation.
public Transformation GetRelativeTransformationToWaypoint(Vector3 waypoint) {
+ Vector3 relativePosition = waypoint - GetPosition();
// Get the relative position transformation.
PositionTransformation positionTransformation =
- GetRelativePositionTransformation(waypoint - GetPosition());
+ GetRelativePositionTransformation(relativePosition);
// Get the relative velocity transformation.
VelocityTransformation velocityTransformation =
- GetRelativeVelocityTransformation(waypoint - GetPosition(), -GetVelocity());
+ GetRelativeVelocityTransformation(relativePosition, -GetVelocity());
return new Transformation {
Position = positionTransformation,
Velocity = velocityTransformation,
};
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| public Transformation GetRelativeTransformationToWaypoint(Vector3 waypoint) { | |
| Transformation transformation = new Transformation(); | |
| // Get the relative position transformation. | |
| transformation.Position = GetRelativePositionTransformation(waypoint - GetPosition()); | |
| PositionTransformation positionTransformation = | |
| GetRelativePositionTransformation(waypoint - GetPosition()); | |
| // Get the relative velocity transformation. | |
| transformation.Velocity = | |
| VelocityTransformation velocityTransformation = | |
| GetRelativeVelocityTransformation(waypoint - GetPosition(), -GetVelocity()); | |
| return transformation; | |
| return new Transformation { | |
| Position = positionTransformation, | |
| Velocity = velocityTransformation, | |
| }; | |
| public Transformation GetRelativeTransformationToWaypoint(Vector3 waypoint) { | |
| Vector3 relativePosition = waypoint - GetPosition(); | |
| // Get the relative position transformation. | |
| PositionTransformation positionTransformation = | |
| GetRelativePositionTransformation(relativePosition); | |
| // Get the relative velocity transformation. | |
| VelocityTransformation velocityTransformation = | |
| GetRelativeVelocityTransformation(relativePosition, -GetVelocity()); | |
| return new Transformation { | |
| Position = positionTransformation, | |
| Velocity = velocityTransformation, | |
| }; | |
| } |
🤖 Prompt for AI Agents
In Assets/Scripts/Agents/Agent.cs around lines 234 to 246, the expression
waypoint - GetPosition() is computed twice; store it in a local variable (e.g.,
Vector3 relativePosition = waypoint - GetPosition()) and pass that variable into
GetRelativePositionTransformation and GetRelativeVelocityTransformation so the
subtraction is only done once and the code matches the refactored pattern used
in GetRelativeTransformation.
[All] Implement fully hierarchical defense strategy * [Agent] Add agent-related interfaces and base implementations (#95) * [Interceptor/Threat] Add interceptor and threat interfaces (#96) * [Algorithm] Add algorithm interfaces and base implementations (#97) * [Movements] Implement all aerial and ground-based movements (#99) * [Gemini] Disable Gemini pull request summary (#142) * [Sensor] Add sensor interface and ideal sensor implementation (#100) * [Chore] Clean up private properties (#101) * [Evasion] Implement evasion behaviors (#102) * [Agent] Add agent-related interfaces and base implementations (#95) * [Interceptor/Threat] Add interceptor and threat interfaces (#96) * [Algorithm] Add algorithm interfaces and base implementations (#97) * [Movements] Implement all aerial and ground-based movements (#99) * [Sensor] Add sensor interface and ideal sensor implementation (#100) * [Chore] Clean up private properties (#101) * [Evasion] Implement evasion behaviors (#102) * [Attack Behavior] Implement direct attack behavior (#103) * [Controller] Add controller interface and implementations (#105) * [Predictor/Planner] Clean up predictor and planner classes (#108) * [Clustering] Change clustering algorithms to act on hierarchical objects (#111) * [Utils] Clean up coordinates classes and tests (#112) * [Assignment] Refactor assignment algorithms (#113) * [Accessor] Use init accessor for read-only fields (#116) * [Interceptors/Threats] Add Legacy prefix to existing interceptor and threat class names (#121) * [Interceptors/Threats] Implement all interceptor and threat types (#122) * [Proto/Configs] Add launcher types to proto definition and simulation configs (#123) * [IADS] Clean up IADS and simulation manager (#124) * [UI] Remove swarm status dialog and tactical panel (#125) * [All] Remove all legacy code (#127) * [Prefabs] Add prefabs for launchers (#128) * [Release] Adjust minimum distance in proximity release (#129) * [Configs] Add simulation configuration with 2 launchers (#130) * [Simulation] Destroy terminated game objects (#132) * [UI] Draw gizmos for agents (#133) * [UI] Fix summary text label sizes (#134) * [Clustering] Implement recursive clustering within hierarchy (#139) * [UI] Clean up UI scripts (#140) * [Reassignment] Assign new targets to excess interceptors (#141) * [Evasion] Fix threat evasion of interceptors (#143) * [Reassignment] Use capacity remaining to reassign interceptors (#144) * [Agent] Add IsPursuable property (#145) * [Reassignment] Implement threat reassignment (#146) * [Escape] Add escape detectors (#147) * [Escape] Check for escaping targets (#148) * [Movement] Fix missile movement to avoid the ground (#149) * [Reassignment] Fix relaunching multiple carrier interceptors (#150) * [Unity] Fix serializable fields and references (#152) * [Docs] Update docs with hierarchical strategy (#153) * [Utils] Sample from normal distribution (#154) * [Proto] Add run configuration proto (#155) * [Visualization] Fix visualizing simulation monitor logs (#157) * [Tools] Build standalone player (#158) * [Manager] Add run manager to handle run configurations (#159) * [Tools] Refactor common simulation-related constants and utilities (#160) * [Tools] Add metric and aggregator classes (#161) * [Tools] Process the aggregated logs of a simulation run (#162) * [Docs] Update documentation with run configuration and logging (#163) * [Tests] Remove unused Rigidbody variables from unit tests (#166) * [Agent] Add target model API in Agent interface (#167) * [Logging] Emit more detailed events (#168) * [Metrics] Consider only missile interceptors in metrics (#169) * [Logging] Remove logging from CP-SAT solver (#171) * [Tools] Add script to animate telemetry log (#172) * [Docs] Remove unnecessary docs image files (#174) * [Interceptor] Rename IsPursuable to IsPursuer (#175) * [UI] Reimplement tactical panel (#176) * [UI] Add camera to follow and rotate around interceptors or threats (#177) * [Configs] Add configuration for 5 swarms and 1000 UCAVs (#179) * [Agent] Cache the agent transform (#180) * [Agent] Clean up finding relative transformations (#181) * [Configs] Exclude 5_swarms_1000_ucav configuration from CI (#182) * [Agents] Fix collisions with terminated agents (#184) * [Controls] Implement vector proportional navigation (#186) * [Reassignment] Find subhierarchicals with at least one active target (#187)
As @daniellovell pointed out in #100 (comment), it does not make sense to expose a public setter for certain fields that should remain constant after initialization, e.g., which agent a sensor is mounted on, where the planned intercept position is for a launch plan, or what the relative transformation is to another agent after the calculation.
However,
init;is a feature in C# 9 or later, so our Unity project would have to target a newer framework like.NET 5or later. Since Unity manages its own runtime, I had to add a compatibility stub forSystem.Runtime.CompilerServices.IsExternalInit.