< Summary

Class:Threat
Assembly:bamlab.micromissiles
File(s):/github/workspace/Assets/Scripts/Threats/Threat.cs
Covered lines:25
Uncovered lines:76
Coverable lines:101
Total lines:182
Line coverage:24.7% (25 of 101)
Covered branches:0
Total branches:0
Covered methods:6
Total methods:10
Method coverage:60% (6 of 10)

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
SetAttackBehavior(...)0%110100%
PowerTableLookup(...)0%17.587040%
IsAssignable()0%2100%
Start()0%110100%
FixedUpdate()0%110100%
CalculateForwardAcceleration()0%6200%
GetClosestInterceptor()0%16.985021.74%
ShouldEvade()0%5.164058.33%
EvadeInterceptor(...)0%42600%
OnTriggerEnter(...)0%20400%

File(s)

/github/workspace/Assets/Scripts/Threats/Threat.cs

#LineLine coverage
 1using System.Collections;
 2using System.Collections.Generic;
 3using UnityEngine;
 4
 5public abstract class Threat : Agent {
 6  protected AttackBehavior _attackBehavior;
 7  [SerializeField]
 8  protected Vector3 _currentWaypoint;
 9  [SerializeField]
 10  protected PowerSetting _currentPowerSetting;
 11
 12  protected SensorOutput _sensorOutput;
 13  protected Sensor _sensor;
 14
 715  public void SetAttackBehavior(AttackBehavior attackBehavior) {
 716    _attackBehavior = attackBehavior;
 717    _target = SimManager.Instance.CreateDummyAgent(attackBehavior.targetPosition,
 18                                                   attackBehavior.targetVelocity);
 719  }
 20
 35721  protected float PowerTableLookup(PowerSetting powerSetting) {
 35722    switch (powerSetting) {
 23      case PowerSetting.IDLE:
 024        return staticAgentConfig.powerTable.IDLE;
 25      case PowerSetting.LOW:
 026        return staticAgentConfig.powerTable.LOW;
 27      case PowerSetting.CRUISE:
 028        return staticAgentConfig.powerTable.CRUISE;
 29      case PowerSetting.MIL:
 35730        return staticAgentConfig.powerTable.MIL;
 31      case PowerSetting.MAX:
 032        return staticAgentConfig.powerTable.MAX;
 33      default:
 034        Debug.LogError("Invalid power setting");
 035        return 0f;
 36    }
 35737  }
 38
 039  public override bool IsAssignable() {
 040    return false;
 041  }
 42
 743  protected override void Start() {
 744    base.Start();
 745    _sensor = GetComponent<Sensor>();
 746  }
 47
 35748  protected override void FixedUpdate() {
 35749    base.FixedUpdate();
 35750  }
 51
 052  protected Vector3 CalculateForwardAcceleration() {
 053    Vector3 transformVelocity = GetVelocity();
 54
 55    // Get the target speed for the current power setting
 056    float targetSpeed = PowerTableLookup(_currentPowerSetting);
 57
 58    // Calculate the current speed
 059    float currentSpeed = transformVelocity.magnitude;
 60
 61    // Speed error
 062    float speedError = targetSpeed - currentSpeed;
 63
 64    // Proportional gain for speed control
 065    float speedControlGain = 10.0f;  // Adjust this gain as necessary
 66
 67    // Desired acceleration to adjust speed
 068    float desiredAccelerationMagnitude = speedControlGain * speedError;
 69
 70    // Limit the desired acceleration
 071    float maxForwardAcceleration = CalculateMaxForwardAcceleration();
 072    desiredAccelerationMagnitude =
 73        Mathf.Clamp(desiredAccelerationMagnitude, -maxForwardAcceleration, maxForwardAcceleration);
 74
 75    // Acceleration direction (along current velocity direction)
 076    Vector3 accelerationDirection = transformVelocity.normalized;
 77
 78    // Handle zero velocity case
 079    if (accelerationDirection.magnitude < 0.1f) {
 080      accelerationDirection = transform.forward;  // Default direction
 081    }
 82
 83    // Calculate acceleration vector
 084    Vector3 speedAdjustmentAcceleration = accelerationDirection * desiredAccelerationMagnitude;
 085    return speedAdjustmentAcceleration;
 086  }
 87
 35788  protected Agent GetClosestInterceptor() {
 71489    if (_interceptors.Count == 0) {
 35790      return null;
 91    }
 92
 093    Agent closestInterceptor = null;
 094    float minDistance = float.MaxValue;
 095    foreach (var interceptor in _interceptors) {
 096      if (!interceptor.HasTerminated()) {
 097        SensorOutput sensorOutput = _sensor.Sense(interceptor);
 098        if (sensorOutput.position.range < minDistance) {
 099          closestInterceptor = interceptor;
 0100          minDistance = sensorOutput.position.range;
 0101        }
 0102      }
 0103    }
 0104    return closestInterceptor;
 357105  }
 106
 357107  protected bool ShouldEvade() {
 357108    if (!dynamicAgentConfig.dynamic_config.flight_config.evasionEnabled) {
 0109      return false;
 110    }
 111
 357112    Agent closestInterceptor = GetClosestInterceptor();
 714113    if (closestInterceptor == null) {
 357114      return false;
 115    }
 116
 0117    float evasionRangeThreshold =
 118        dynamicAgentConfig.dynamic_config.flight_config.evasionRangeThreshold;
 0119    SensorOutput sensorOutput = _sensor.Sense(closestInterceptor);
 0120    return sensorOutput.position.range <= evasionRangeThreshold && sensorOutput.velocity.range < 0;
 357121  }
 122
 0123  protected Vector3 EvadeInterceptor(Agent interceptor) {
 0124    Vector3 transformVelocity = GetVelocity();
 0125    Vector3 interceptorVelocity = interceptor.GetVelocity();
 0126    Vector3 transformPosition = GetPosition();
 0127    Vector3 interceptorPosition = interceptor.GetPosition();
 128
 129    // Set power setting to maximum
 0130    _currentPowerSetting = PowerSetting.MAX;
 131
 132    // Evade the interceptor by changing the velocity to be normal to the interceptor's velocity
 0133    Vector3 normalVelocity = Vector3.ProjectOnPlane(transformVelocity, interceptorVelocity);
 0134    Vector3 normalAccelerationDirection =
 135        Vector3.ProjectOnPlane(normalVelocity, transformVelocity).normalized;
 136
 137    // Turn away from the interceptor
 0138    Vector3 relativePosition = interceptorPosition - transformPosition;
 0139    if (Vector3.Dot(relativePosition, normalAccelerationDirection) > 0) {
 0140      normalAccelerationDirection *= -1;
 0141    }
 142
 143    // Avoid evading straight down when near the ground
 0144    float altitude = transformPosition.y;
 0145    float groundProximityThreshold =
 146        Mathf.Abs(transformVelocity.y) * 5f;  // Adjust threshold as necessary
 0147    if (transformVelocity.y < 0 && altitude < groundProximityThreshold) {
 148      // Determine evasion direction based on angle to interceptor
 0149      Vector3 toInterceptor = interceptorPosition - transformPosition;
 0150      Vector3 rightDirection = Vector3.Cross(Vector3.up, transform.forward);
 0151      float angle = Vector3.SignedAngle(transform.forward, toInterceptor, Vector3.up);
 152
 153      // Choose the direction that leads away from the interceptor
 0154      Vector3 bestHorizontalDirection = angle > 0 ? -rightDirection : rightDirection;
 155
 156      // Blend between horizontal evasion and slight upward movement
 0157      float blendFactor = 1 - (altitude / groundProximityThreshold);
 0158      normalAccelerationDirection =
 159          Vector3
 160              .Lerp(normalAccelerationDirection, bestHorizontalDirection + transform.up * 5f,
 161                    blendFactor)
 162              .normalized;
 0163    }
 0164    Vector3 normalAcceleration = normalAccelerationDirection * CalculateMaxNormalAcceleration();
 165
 166    // Adjust forward speed
 0167    Vector3 forwardAcceleration = CalculateForwardAcceleration();
 168
 0169    return normalAcceleration + forwardAcceleration;
 0170  }
 171
 0172  private void OnTriggerEnter(Collider other) {
 0173    if (other.gameObject.name == "Floor") {
 0174      this.HandleThreatMiss();
 0175    }
 176    // Check if the collision is with another Agent
 0177    DummyAgent otherAgent = other.gameObject.GetComponentInParent<DummyAgent>();
 0178    if (otherAgent != null && _target == otherAgent) {
 0179      this.HandleThreatHit();
 0180    }
 0181  }
 182}