using UnityEngine;
// Sci-Fi Ship Controller. Copyright (c) 2018-2023 SCSM Pty Ltd. All rights reserved.
namespace SciFiShipController
{
///
/// Class containing data for a wing.
///
[System.Serializable]
public class Wing
{
#region Public variables and properties
// IMPORTANT - when changing this section also update SetClassDefault()
// Also update ClassName(ClassName className) Clone Constructor (if there is one)
///
/// The name of the wing
///
public string name;
///
/// Angle of attack (in degrees) of the wing relative to the local forwards direction. This is purely achieved by the camber of the wing.
///
[Range(-5f, 15f)] public float angleOfAttack;
///
/// The length of the wing (measured along the local x-axis).
///
public float span;
///
/// The width of the wing (measured along the local z-axis).
///
public float chord;
///
/// Position of the centre of the wing in local space relative to the pivot point of the ship. This is the position where the lift force will be applied at.
///
public Vector3 relativePosition;
///
/// The local space direction of lift provided by the wing. If you modify this, call Initialise().
///
public Vector3 liftDirection;
///
/// The normalised local space direction of lift provided by the wing.
///
public Vector3 liftDirectionNormalised { get; private set; }
///
/// The index of the damage region this wing is associated with. When the damage model of the ship is set to simple, this
/// is irrelevant. A negative value means it is associated with no damage region (so the wing's performance will not be
/// affected by damage). When the damage model of the ship is set to progressive, a value of zero means it is
/// associated with the main damage region. When the damage model of the ship is set to localised, a zero or positive value
/// indicates which damage region it is associated with (using a zero-based indexing system).
///
public int damageRegionIndex;
///
/// The minimum (i.e. when its health reaches zero) performance level of this wing. The performance level affects how much
/// lift is produced by this wing. At a performance level of one it produces the usual value. At a performance level of
/// zero it produces no lift.
///
[Range(0f, 1f)] public float minPerformance;
///
/// The current performance level of this wing (determined by the Health value). The performance level affects how much
/// lift is produced by this wing. At a performance level of one it produces the usual value. At a performance level of
/// zero it produces no lift.
///
public float CurrentPerformance { get; private set; }
///
/// The starting health value of this wing.
///
public float startingHealth;
private float health;
///
/// The current health value of this wing.
///
public float Health
{
get { return health; }
set
{
// Update the health value
health = value;
// Update the current performance value
CurrentPerformance = value / startingHealth;
CurrentPerformance = CurrentPerformance > minPerformance ? CurrentPerformance : minPerformance;
CurrentPerformance = CurrentPerformance < 1f ? CurrentPerformance : 1f;
}
}
///
/// Whether the wing is shown as expanded in the inspector window of the editor.
///
public bool showInEditor;
///
/// Whether the wing node is shown as selected in the scene view of the editor.
///
public bool selectedInSceneView;
///
/// Whether the gizmos for this wing node are shown in the scene view of the editor
///
public bool showGizmosInSceneView;
#endregion
#region Class constructors
public Wing()
{
SetClassDefaults();
}
// Copy constructor
public Wing (Wing wing)
{
if (wing == null) { SetClassDefaults(); }
else
{
this.name = wing.name;
this.angleOfAttack = wing.angleOfAttack;
this.span = wing.span;
this.chord = wing.chord;
this.relativePosition = wing.relativePosition;
this.liftDirection = wing.liftDirection;
this.damageRegionIndex = wing.damageRegionIndex;
this.minPerformance = wing.minPerformance;
this.startingHealth = wing.startingHealth;
this.Health = wing.Health;
this.showInEditor = wing.showInEditor;
this.selectedInSceneView = wing.selectedInSceneView;
this.showGizmosInSceneView = wing.showGizmosInSceneView;
this.Initialise();
}
}
#endregion
#region Public Non-Static Methods
public void SetClassDefaults()
{
this.name = "Wing";
this.angleOfAttack = 5f;
this.span = 10f;
this.chord = 1f;
this.relativePosition = Vector3.zero;
this.liftDirection = Vector3.up;
this.damageRegionIndex = -1;
this.minPerformance = 0.25f;
this.startingHealth = 100f;
this.Health = 100f;
this.showInEditor = true;
this.selectedInSceneView = false;
this.showGizmosInSceneView = true;
this.Initialise();
}
///
/// Initialises data for the wing. This does some precalculation to allow for performance improvements.
/// Call after modifying liftDirection.
///
public void Initialise ()
{
// Calculate normalised vectors
liftDirectionNormalised = liftDirection.normalized;
}
#endregion
}
}