micromissiles-unity/Assets/Scripts/Interceptor.cs

158 lines
5.8 KiB
C#
Raw Normal View History

2024-09-12 00:17:21 -07:00
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
2024-09-24 19:59:25 -07:00
public class Interceptor : Agent {
2024-09-13 22:45:25 -07:00
[SerializeField]
protected bool _showDebugVectors = true;
2024-09-24 19:59:25 -07:00
// Return whether a target can be assigned to the interceptor.
2024-09-13 22:45:25 -07:00
public override bool IsAssignable() {
bool assignable = !HasLaunched() && !HasAssignedTarget();
return assignable;
}
2024-09-24 19:59:25 -07:00
// Assign the given target to the interceptor.
2024-09-13 22:45:25 -07:00
public override void AssignTarget(Agent target) {
base.AssignTarget(target);
}
2024-09-24 19:59:25 -07:00
// Unassign the target from the interceptor.
2024-09-13 22:45:25 -07:00
public override void UnassignTarget() {
base.UnassignTarget();
}
2024-09-13 22:45:25 -07:00
protected override void UpdateReady(double deltaTime) {
Vector3 accelerationInput = Vector3.zero;
Vector3 acceleration = CalculateAcceleration(accelerationInput);
// GetComponent<Rigidbody>().AddForce(acceleration, ForceMode.Acceleration);
}
protected override void FixedUpdate() {
base.FixedUpdate();
2024-09-13 22:45:25 -07:00
if (_showDebugVectors) {
DrawDebugVectors();
2024-09-12 00:17:21 -07:00
}
2024-09-13 22:45:25 -07:00
}
protected override void UpdateBoost(double deltaTime) {
2024-09-24 19:59:25 -07:00
// The interceptor only accelerates along its roll axis (forward in Unity)
2024-09-13 22:45:25 -07:00
Vector3 rollAxis = transform.forward;
// Calculate boost acceleration
float boostAcceleration =
(float)(_staticConfig.boostConfig.boostAcceleration * Constants.kGravity);
2024-09-13 22:45:25 -07:00
Vector3 accelerationInput = boostAcceleration * rollAxis;
// Calculate the total acceleration
Vector3 acceleration = CalculateAcceleration(accelerationInput);
// Apply the acceleration force
GetComponent<Rigidbody>().AddForce(acceleration, ForceMode.Acceleration);
}
2024-09-13 22:45:25 -07:00
protected override void UpdateMidCourse(double deltaTime) {}
protected Vector3 CalculateAcceleration(Vector3 accelerationInput,
bool compensateForGravity = false) {
Vector3 gravity = Physics.gravity;
if (compensateForGravity) {
Vector3 gravityProjection = CalculateGravityProjectionOnPitchAndYaw();
accelerationInput -= gravityProjection;
2024-09-12 00:17:21 -07:00
}
2024-09-13 22:45:25 -07:00
float airDrag = CalculateDrag();
float liftInducedDrag = CalculateLiftInducedDrag(accelerationInput + gravity);
2024-09-13 22:45:25 -07:00
float dragAcceleration = -(airDrag + liftInducedDrag);
2024-09-12 00:17:21 -07:00
2024-09-13 22:45:25 -07:00
// Project the drag acceleration onto the forward direction
Vector3 dragAccelerationAlongRoll = dragAcceleration * transform.forward;
_dragAcceleration = dragAccelerationAlongRoll;
2024-09-12 00:17:21 -07:00
2024-09-13 22:45:25 -07:00
return accelerationInput + gravity + dragAccelerationAlongRoll;
}
2024-09-12 00:17:21 -07:00
2024-09-13 22:45:25 -07:00
private void OnTriggerEnter(Collider other) {
if (other.gameObject.name == "Floor") {
this.MarkAsMiss();
2024-09-12 00:17:21 -07:00
}
2024-09-13 22:45:25 -07:00
// Check if the collision is with another Agent
Agent otherAgent = other.gameObject.GetComponentInParent<Agent>();
2024-09-24 19:24:50 -07:00
if (otherAgent != null && otherAgent.GetComponent<Threat>() != null) {
2024-09-13 22:45:25 -07:00
// Check kill probability before marking as hit
float killProbability = _staticConfig.hitConfig.killProbability;
2024-09-13 22:45:25 -07:00
GameObject markerObject = Instantiate(Resources.Load<GameObject>("Prefabs/HitMarkerPrefab"),
transform.position, Quaternion.identity);
if (Random.value <= killProbability) {
// Set green for hit
markerObject.GetComponent<Renderer>().material.color = new Color(0, 1, 0, 0.15f);
// Mark both this agent and the other agent as hit
this.MarkAsHit();
otherAgent.MarkAsHit();
} else {
// Set red for miss
markerObject.GetComponent<Renderer>().material.color = new Color(1, 0, 0, 0.15f);
this.MarkAsMiss();
// otherAgent.MarkAsMiss();
}
2024-09-12 00:17:21 -07:00
}
2024-09-13 22:45:25 -07:00
}
protected float CalculateMaxAcceleration() {
float maxReferenceAcceleration =
(float)(_staticConfig.accelerationConfig.maxReferenceAcceleration * Constants.kGravity);
float referenceSpeed = _staticConfig.accelerationConfig.referenceSpeed;
2024-09-25 17:51:44 -07:00
return Mathf.Pow(GetComponent<Rigidbody>().linearVelocity.magnitude / referenceSpeed, 2) *
2024-09-13 22:45:25 -07:00
maxReferenceAcceleration;
}
protected Vector3 CalculateGravityProjectionOnPitchAndYaw() {
Vector3 gravity = Physics.gravity;
Vector3 pitchAxis = transform.right;
Vector3 yawAxis = transform.up;
// Project the gravity onto the pitch and yaw axes
float gravityProjectionPitchCoefficient = Vector3.Dot(gravity, pitchAxis);
float gravityProjectionYawCoefficient = Vector3.Dot(gravity, yawAxis);
// Return the sum of the projections
return gravityProjectionPitchCoefficient * pitchAxis +
gravityProjectionYawCoefficient * yawAxis;
}
private float CalculateDrag() {
float dragCoefficient = _staticConfig.liftDragConfig.dragCoefficient;
float crossSectionalArea = _staticConfig.bodyConfig.crossSectionalArea;
float mass = _staticConfig.bodyConfig.mass;
2024-09-13 22:45:25 -07:00
float dynamicPressure = (float)GetDynamicPressure();
float dragForce = dragCoefficient * dynamicPressure * crossSectionalArea;
return dragForce / mass;
}
private float CalculateLiftInducedDrag(Vector3 accelerationInput) {
2024-09-16 22:47:40 -07:00
float liftAcceleration =
(accelerationInput - Vector3.Dot(accelerationInput, transform.up) * transform.up).magnitude;
float liftDragRatio = _staticConfig.liftDragConfig.liftDragRatio;
2024-09-13 22:45:25 -07:00
return Mathf.Abs(liftAcceleration / liftDragRatio);
}
protected virtual void DrawDebugVectors() {
if (_target != null) {
// Line of sight
Debug.DrawLine(transform.position, _target.transform.position, new Color(1, 1, 1, 0.15f));
// Velocity vector
Debug.DrawRay(transform.position, GetVelocity() * 0.01f, new Color(0, 0, 1, 0.15f));
// Current forward direction
Debug.DrawRay(transform.position, transform.forward * 5f, Color.yellow);
// Pitch axis (right)
Debug.DrawRay(transform.position, transform.right * 5f, Color.red);
// Yaw axis (up)
Debug.DrawRay(transform.position, transform.up * 5f, Color.magenta);
2024-09-12 15:44:55 -07:00
}
2024-09-13 22:45:25 -07:00
}
2024-09-12 00:17:21 -07:00
}