7428 lines
305 KiB
C#
7428 lines
305 KiB
C#
|
using scsmmedia;
|
|||
|
using System.Collections;
|
|||
|
using System.Collections.Generic;
|
|||
|
using UnityEngine;
|
|||
|
using UnityEngine.UI;
|
|||
|
|
|||
|
// Sci-Fi Ship Controller. Copyright (c) 2018-2023 SCSM Pty Ltd. All rights reserved.
|
|||
|
namespace SciFiShipController
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// Heads Up Display - typically used from an in-cockpit player view or setup.
|
|||
|
/// The general approach here is to use RectTransforms that are NOT stretched
|
|||
|
/// and are anchored at the centre.
|
|||
|
/// Setup Notes:
|
|||
|
/// HUDPanel should be anchored at four corners of screen (stretched)
|
|||
|
/// Display Reticle panel should be anchored at the centre of HUD
|
|||
|
/// Altitude Panel should be anchored to centre
|
|||
|
/// Altitude Text pivot point should be 0,0 (left bottom corner of textbox)
|
|||
|
/// </summary>
|
|||
|
[AddComponentMenu("Sci-Fi Ship Controller/Misc/Ship Display Module")]
|
|||
|
[HelpURL("http://scsmmedia.com/ssc-documentation")]
|
|||
|
public class ShipDisplayModule : MonoBehaviour
|
|||
|
{
|
|||
|
#region Enumerations
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public Static Variables
|
|||
|
public readonly static string hudPanelName = "HUDPanel";
|
|||
|
public readonly static string targetsPanelName = "TargetsPanel";
|
|||
|
public readonly static string gaugesPanelName = "GaugesPanel";
|
|||
|
public readonly static string attitudePanelName = "AttitudePanel";
|
|||
|
public readonly static string headingPanelName = "HeadingPanel";
|
|||
|
public readonly static string overlayPanelName = "OverlayPanel";
|
|||
|
public readonly static string attitudeScrollName = "AttitudeScroll";
|
|||
|
public readonly static string headingScrollName = "HeadingScroll";
|
|||
|
public readonly static string headingIndicatorName = "HeadingIndicator";
|
|||
|
|
|||
|
[System.NonSerialized] public static readonly AnimationCurve easeInOutCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public Variables and Properties - General
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// If enabled, the Initialise() will be called as soon as Start() runs. This should be disabled if you are
|
|||
|
/// instantiating the HUD through code.
|
|||
|
/// </summary>
|
|||
|
public bool initialiseOnStart = false;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or Hide the HUD when it is first Initialised
|
|||
|
/// </summary>
|
|||
|
public bool isShowOnInitialise = true;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show overlay image on HUD. At runtime call ShowOverlay() or HideOverlay()
|
|||
|
/// </summary>
|
|||
|
public bool showOverlay = true;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The head-up display's normalised width of the screen. 1.0 is full width, 0.5 is half width.
|
|||
|
/// At runtime call shipDisplayModule.SetHUDSize(..)
|
|||
|
/// </summary>
|
|||
|
[Range(0.1f, 1f)] public float displayWidth = 0.5f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The head-up display's normalised height of the screen. 1.0 is full height, 0.5 is half height.
|
|||
|
/// At runtime call shipDisplayModule.SetHUDSize(..)
|
|||
|
/// </summary>
|
|||
|
[Range(0.1f, 1f)] public float displayHeight = 0.75f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The head-up display's normalised offset between the left (-1) and the right (1) from the centre (0) of the screen.
|
|||
|
/// At runtime call shipDisplayModule.SetHUDOffset(..)
|
|||
|
/// </summary>
|
|||
|
[Range(-1f, 1f)] public float displayOffsetX = 0f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The head-up display's normalised offset between the bottom (-1) and the top (1) from the centre (0) of the screen.
|
|||
|
/// At runtime call shipDisplayModule.SetHUDOffset(..)
|
|||
|
/// </summary>
|
|||
|
[Range(-1f, 1f)] public float displayOffsetY = 0f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Primary colour of the heads-up display.
|
|||
|
/// At runtime call shipDisplayModule.SetPrimaryColour(..)
|
|||
|
/// </summary>
|
|||
|
public Color32 primaryColour = Color.grey;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Automatically hide the screen cursor or mouse pointer after it has been stationary
|
|||
|
/// for a fixed period of time. Automatically show the cursor if the mouse if moved
|
|||
|
/// provided that the Display Reticle is on shown.
|
|||
|
/// </summary>
|
|||
|
public bool autoHideCursor = true;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The number of seconds to wait until after the cursor has not moved before hiding it
|
|||
|
/// </summary>
|
|||
|
public float hideCursorTime = 3f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Is the ship display module initialised? Gets set at runtime when Initialise() is called.
|
|||
|
/// </summary>
|
|||
|
public bool IsInitialised { get; private set; }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Is the heads-up display shown? To set use ShowHUD() or HideHUD().
|
|||
|
/// IsHUDShown should never be true at runtime if IsInitialised is false
|
|||
|
/// </summary>
|
|||
|
public bool IsHUDShown { get; private set; }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get a reference to the HUD canvas
|
|||
|
/// </summary>
|
|||
|
public Canvas GetCanvas { get { return IsInitialised ? canvas : GetComponent<Canvas>(); } }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The overall brightness of the HUD. At runtime use
|
|||
|
/// SetBrightness(value)
|
|||
|
/// </summary>
|
|||
|
[Range(0f, 1f)] public float brightness = 1f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The sort order of the canvas in the scene. Higher numbers are on top.
|
|||
|
/// At runtime call shipDisplayModule.SetCanvasSortOrder(..)
|
|||
|
/// </summary>
|
|||
|
public int canvasSortOrder = 2;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The default size the HUD was designed with. This should always
|
|||
|
/// return 1920x1080
|
|||
|
/// </summary>
|
|||
|
public Vector2 ReferenceResolution { get { return refResolution; } }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The current scaled resolution of the HUD canvas
|
|||
|
/// </summary>
|
|||
|
public Vector2 CanvasResolution { get { return cvsResolutionFull; } }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The current scale factor of the HUD canvas
|
|||
|
/// </summary>
|
|||
|
public Vector3 CanvasScaleFactor { get { return cvsScaleFactor; } }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The current actual screen resolution. This may be different from
|
|||
|
/// what the
|
|||
|
/// </summary>
|
|||
|
public Vector2 ScreenResolution { get { return screenResolution; } }
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public Variables and Properties - Flicker
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Whenever the HUD is shown, should it flicker on?
|
|||
|
/// </summary>
|
|||
|
public bool isShowHUDWithFlicker = false;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Whenever the HUD is hidden, should it flicker off?
|
|||
|
/// </summary>
|
|||
|
public bool isHideHUDWithFlicker = false;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The time, in seconds, the effect takes to reach a steady state
|
|||
|
/// </summary>
|
|||
|
[Range(0.01f, 5f)] public float flickerDefaultDuration = 1f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The minimum time, in seconds, that the effect is inactive or off
|
|||
|
/// </summary>
|
|||
|
[Range(0f, 2f)] public float flickerMinInactiveTime = 0.1f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The maximum time, in seconds, that the effect is inactive or off
|
|||
|
/// </summary>
|
|||
|
[Range(0f, 2f)] public float flickerMaxInactiveTime = 0.2f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The minimum time, in seconds, that the effect is active or on
|
|||
|
/// </summary>
|
|||
|
[Range(0f, 2f)] public float flickerMinActiveTime = 0.1f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The maximum time, in seconds, that the effect is active or on
|
|||
|
/// </summary>
|
|||
|
[Range(0f, 2f)] public float flickerMaxActiveTime = 0.2f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Smooth the flickering effect. Higher values give a smoother effect
|
|||
|
/// </summary>
|
|||
|
[Range(0, 5)] public float flickerSmoothing = 3f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The intensity of the effect will randomly change
|
|||
|
/// </summary>
|
|||
|
public bool flickerVariableIntensity = false;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The maximum intensity of the effect used during the on cycle when
|
|||
|
/// flickerVariableIntensity is enabled.
|
|||
|
/// This is a multiplier of the starting intensity of the effect.
|
|||
|
/// Value must be between 0.01 and 1.0.
|
|||
|
/// </summary>
|
|||
|
[Range(0.01f, 1f)] public float flickerMaxIntensity = 1f;
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public Variables and Properties - Reticles
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The guidHash of the currently selected / displayed reticle
|
|||
|
/// </summary>
|
|||
|
public int guidHashActiveDisplayReticle = 0;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The list of display reticles that can be used with
|
|||
|
/// this Ship Display. Call ReinitialiseVariables() if
|
|||
|
/// you modify the list at runtime.
|
|||
|
/// </summary>
|
|||
|
public List<DisplayReticle> displayReticleList;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get the current number of display reticles
|
|||
|
/// </summary>
|
|||
|
public int GetNumberDisplayReticles { get { return IsInitialised ? numDisplayReticles : displayReticleList == null ? 0 : displayReticleList.Count; } }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL USE ONLY]
|
|||
|
/// </summary>
|
|||
|
public bool isDisplayReticleListExpanded = true;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// For consistency, is the display reticle currently shown when the
|
|||
|
/// module has already been initialised?
|
|||
|
/// </summary>
|
|||
|
public bool IsDisplayReticleShown { get { return showActiveDisplayReticle; } }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get the Display Reticle position on the screen in Viewport coordinates. x = 0.0-1.0, y = 0.0-1.0. 0,0 is bottom left corner.
|
|||
|
/// </summary>
|
|||
|
public Vector2 DisplayReticleViewportPoint { get { return new Vector2((displayReticleOffsetX + 1f) * 0.5f, (displayReticleOffsetY + 1f) * 0.5f); } }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show the current (active) Display Reticle
|
|||
|
/// on the HUD. At runtime use ShowDisplayReticle()
|
|||
|
/// or HideDisplayReticle().
|
|||
|
/// </summary>
|
|||
|
public bool showActiveDisplayReticle = false;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The Display Reticle's normalised offset between the left (-1) and the right (1) from the centre (0) of the screen.
|
|||
|
/// At runtime call shipDisplayModule.SetDisplayReticleOffset(..)
|
|||
|
/// </summary>
|
|||
|
[Range(-1f, 1f)] public float displayReticleOffsetX = 0f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The Display Reticle's normalised offset between the bottom (-1) and the top (1) from the centre (0) of the screen.
|
|||
|
/// At runtime call shipDisplayModule.SetDisplayReticleOffset(..)
|
|||
|
/// </summary>
|
|||
|
[Range(-1f, 1f)] public float displayReticleOffsetY = 0f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Should the Display Reticle follow the cursor or mouse screen position?
|
|||
|
/// </summary>
|
|||
|
public bool lockDisplayReticleToCursor = false;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Colour of the active Display Reticle.
|
|||
|
/// At runtime call shipDisplayModule.SetDisplayReticleColour(..)
|
|||
|
/// </summary>
|
|||
|
public Color32 activeDisplayReticleColour = Color.white;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// This is the main camera that HUD will reference. If left empty, this will
|
|||
|
/// be auto-populated with your first Camera with a tag of MainCamera.
|
|||
|
/// Can be changed at runtime with shipDisplayModule.SetCamera(..).
|
|||
|
/// </summary>
|
|||
|
public Camera mainCamera = null;
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public Variables and Properties - Altitude and Speed
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The ship in the scene that will supply the data for this HUD
|
|||
|
/// </summary>
|
|||
|
public ShipControlModule sourceShip = null;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show the Altitude indicator on the HUD. At runtime use ShowAltitude() or HideAltitude().
|
|||
|
/// Typically only used when near the surface of a planet. See also groundPlaneHeight.
|
|||
|
/// </summary>
|
|||
|
public bool showAltitude = false;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Used to determine altitude when near a planet's surface. On Earth this would typically
|
|||
|
/// be sea-level but it can be used to set an artificial zero-height which may be useful
|
|||
|
/// when flying over the surface of a planet.
|
|||
|
/// </summary>
|
|||
|
public float groundPlaneHeight = 0f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The colour of the Altitude text (number).
|
|||
|
/// At runtime call shipDisplayModule.SetAltitudeTextColour(..)
|
|||
|
/// </summary>
|
|||
|
public Color32 altitudeTextColour = Color.grey;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show the air speed indicator on the HUD. At runtime use ShowAirSpeed() or HideAirSpeed().
|
|||
|
/// </summary>
|
|||
|
public bool showAirspeed = false;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The colour of the Air Speed text (number).
|
|||
|
/// At runtime call shipDisplayModule.SetAirSpeedTextColour(..)
|
|||
|
/// </summary>
|
|||
|
public Color32 airspeedTextColour = Color.grey;
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public Variables and Properties - Attitude
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or hide the Attitude.
|
|||
|
/// At runtime use ShowAttitude() or HideAttitude()
|
|||
|
/// </summary>
|
|||
|
public bool showAttitude = false;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Primary colour of the scrollable heading
|
|||
|
/// At runtime call shipDisplayModule.SetDisplayAttitudePrimaryColour(..)
|
|||
|
/// </summary>
|
|||
|
public Color attitudePrimaryColour = Color.white;
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public Variables and Properties - Heading
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or hide the Heading or direction as a scrollable ribbon in the UI.
|
|||
|
/// At runtime use ShowHeading() or HideHeading()
|
|||
|
/// </summary>
|
|||
|
public bool showHeading = false;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or hide the small heading indicator
|
|||
|
/// At runtime use ShowHeadingIndictor() or HideHeadingIndicator()
|
|||
|
/// </summary>
|
|||
|
public bool showHeadingIndicator = true;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Primary colour of the scrollable heading
|
|||
|
/// At runtime call shipDisplayModule.SetDisplayHeadingPrimaryColour(..)
|
|||
|
/// </summary>
|
|||
|
public Color headingPrimaryColour = Color.white;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The small indicator colour of the scrollable heading
|
|||
|
/// At runtime call shipDisplayModule.SetDisplayHeadingIndicatorColour(..)
|
|||
|
/// </summary>
|
|||
|
public Color headingIndicatorColour = Color.green;
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public Variables and Properties - Gauges
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The list of display gauges that can be used with
|
|||
|
/// this Ship Display. Call ReinitialiseVariables() if
|
|||
|
/// you modify this list at runtime. Where possible use the API
|
|||
|
/// methods to Add, Delete, or set gauge attributes.
|
|||
|
/// </summary>
|
|||
|
public List<DisplayGauge> displayGaugeList;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get the current number of display gauge
|
|||
|
/// </summary>
|
|||
|
public int GetNumberDisplayGauges { get { return IsInitialised ? numDisplayGauges : displayGaugeList == null ? 0 : displayGaugeList.Count; } }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL USE ONLY]
|
|||
|
/// </summary>
|
|||
|
public bool isDisplayGaugeListExpanded = true;
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public Variables and Properties - Messages
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The list of display messages that can be used with
|
|||
|
/// this Ship Display. Call ReinitialiseVariables() if
|
|||
|
/// you modify this list at runtime. Where possible use the API
|
|||
|
/// methods to Add, Delete, or set messages attributes.
|
|||
|
/// </summary>
|
|||
|
public List<DisplayMessage> displayMessageList;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get the current number of display messages
|
|||
|
/// </summary>
|
|||
|
public int GetNumberDisplayMessages { get { return IsInitialised ? numDisplayMessages : displayMessageList == null ? 0 : displayMessageList.Count; } }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL USE ONLY]
|
|||
|
/// </summary>
|
|||
|
public bool isDisplayMessageListExpanded = true;
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public Variables and Properties - Targets
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The list of display targets that can be used with
|
|||
|
/// this Ship Display. Call ReinitialiseVariables() if
|
|||
|
/// you modify this list at runtime. Where possible use the API
|
|||
|
/// methods to Add, Delete, or set target attributes.
|
|||
|
/// </summary>
|
|||
|
public List<DisplayTarget> displayTargetList;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get the current number of Display Targets.
|
|||
|
/// </summary>
|
|||
|
public int GetNumberDisplayTargets { get { return IsInitialised ? numDisplayTargets : displayTargetList == null ? 0 : displayTargetList.Count; } }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get the size of the Targets viewport as a normalised (0.0-1.0) value of the current screensize
|
|||
|
/// </summary>
|
|||
|
public Vector2 GetTargetsViewportSize { get { return new Vector2(targetsViewWidth, targetsViewHeight); } }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get the offset from the screen centre of the Targets viewport. Values are -1.0 to 1.0
|
|||
|
/// </summary>
|
|||
|
public Vector2 GetTargetsViewportOffset { get { return new Vector2(targetsViewOffsetX, targetsViewOffsetY); } }
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// When DisplayTarget slots have an active RadarItem assigned to them, should the reticles be automatically
|
|||
|
/// moved on the HUD?
|
|||
|
/// </summary>
|
|||
|
public bool autoUpdateTargetPositions = true;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The Targets normalised viewable width of the screen.
|
|||
|
/// 1.0 is full width, 0.5 is half width.
|
|||
|
/// At runtime call shipDisplayModule.SetTargetsViewportSize(..)
|
|||
|
/// </summary>
|
|||
|
[Range(0.1f, 1f)] public float targetsViewWidth = 1.0f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The Targets normalised viewable height of the screen.
|
|||
|
/// 1.0 is full height, 0.5 is half height.
|
|||
|
/// At runtime call shipDisplayModule.SetTargetsViewportSize(..)
|
|||
|
/// </summary>
|
|||
|
[Range(0.1f, 1f)] public float targetsViewHeight = 0.5f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The X offset from centre of the screen for the Targets viewport
|
|||
|
/// At runtime call shipDisplayModule.SetTargetsViewportOffset(..)
|
|||
|
/// </summary>
|
|||
|
[Range(-1f, 1f)] public float targetsViewOffsetX = 0f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The Y offset from centre of the screen for the Targets viewport
|
|||
|
/// At runtime call shipDisplayModule.SetTargetsViewportOffset(..)
|
|||
|
/// </summary>
|
|||
|
[Range(-1f, 1f)] public float targetsViewOffsetY = 0.5f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The maximum distance, in metres, that targets can be away from the ship
|
|||
|
/// </summary>
|
|||
|
public float targetingRange = 5000f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL USE ONLY]
|
|||
|
/// </summary>
|
|||
|
public bool isDisplayTargetListExpanded = true;
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public Variables and Properties - FUTURE FEATURES
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// FUTURE
|
|||
|
/// </summary>
|
|||
|
//public bool showArtificialHorizon = false;
|
|||
|
|
|||
|
// FUTURE - FPV indicator
|
|||
|
//public bool showFlightPathVector = false;
|
|||
|
|
|||
|
// FUTURE - wing's angle relative to airflow
|
|||
|
//public bool showAngleOfAttack = false;
|
|||
|
|
|||
|
// FUTURE - target designation indicator
|
|||
|
//public bool showTargetDesignator = false;
|
|||
|
|
|||
|
// Other options could be closing (target) velocity, range (to target), selected weapons, amno available etc.
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public Variables and Properties - INTERNAL ONLY
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL ONLY]
|
|||
|
/// </summary>
|
|||
|
[HideInInspector] public bool allowRepaint = false;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL ONLY]
|
|||
|
/// </summary>
|
|||
|
public bool showGeneralSettingsInEditor = false;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL ONLY]
|
|||
|
/// </summary>
|
|||
|
public bool showReticleSettingsInEditor = false;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL ONLY]
|
|||
|
/// </summary>
|
|||
|
public bool showAltSpeedSettingsInEditor = false;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL ONLY]
|
|||
|
/// </summary>
|
|||
|
public bool showAttitudeSettingsInEditor = false;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL ONLY]
|
|||
|
/// </summary>
|
|||
|
public bool showFlickerSettingsInEditor = false;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL ONLY]
|
|||
|
/// </summary>
|
|||
|
public bool showHeadingSettingsInEditor = false;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL ONLY]
|
|||
|
/// </summary>
|
|||
|
public bool showGaugeSettingsInEditor = false;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL ONLY]
|
|||
|
/// </summary>
|
|||
|
public bool showMessageSettingsInEditor = false;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL ONLY]
|
|||
|
/// </summary>
|
|||
|
public bool showTargetSettingsInEditor = false;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL ONLY]
|
|||
|
/// Outside play mode, show a bounding box for where the HUD will be placed
|
|||
|
/// </summary>
|
|||
|
public bool showHUDOutlineInScene = true;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL ONLY]
|
|||
|
/// Outside play mode, show a bounding box for where Targets can be displayed
|
|||
|
/// </summary>
|
|||
|
public bool showTargetsOutlineInScene = false;
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL ONLY]
|
|||
|
/// </summary>
|
|||
|
public bool IsEditorMode { get { return editorMode; } }
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public Delegates
|
|||
|
|
|||
|
public delegate void CallbackOnBrightnessChange(float newBrightness);
|
|||
|
public delegate void CallbackOnSizeChange(float newWidth, float newHeight);
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The name of the custom method that is called immediately
|
|||
|
/// after brightness has changed. Your method must take 1 float
|
|||
|
/// parameter. This should be a lightweight method to avoid
|
|||
|
/// performance issues. It could be used to update your custom
|
|||
|
/// HUD elements.
|
|||
|
/// </summary>
|
|||
|
public CallbackOnBrightnessChange callbackOnBrightnessChange = null;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The name of the custom method that is called immediately after the
|
|||
|
/// HUD size has changed. This method must take 2 float parameters. It
|
|||
|
/// should be a lightweight method to avoid performance issues. It could
|
|||
|
/// be used to update your custom HUD elements.
|
|||
|
/// </summary>
|
|||
|
public CallbackOnSizeChange callbackOnSizeChange = null;
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Private Variables - General
|
|||
|
private Canvas canvas = null;
|
|||
|
private CanvasScaler canvasScaler = null;
|
|||
|
|
|||
|
// Scaled canvas resolution. See CheckHUDResize()
|
|||
|
private Vector2 cvsResolutionFull = Vector2.one;
|
|||
|
private Vector2 cvsResolutionHalf = Vector2.one;
|
|||
|
private Vector2 prevResolutionFull = Vector2.one;
|
|||
|
// Default reference resolution e.g. 1920x1080
|
|||
|
private Vector2 refResolution = Vector2.one;
|
|||
|
private Vector3 cvsScaleFactor = Vector3.one;
|
|||
|
private Vector2 screenResolution = Vector2.one;
|
|||
|
|
|||
|
private Transform hudPanel = null;
|
|||
|
private bool isMainCameraAssigned = false;
|
|||
|
private Color tempColour = Color.clear;
|
|||
|
|
|||
|
// Used to update HUD from the editor when not in play mode
|
|||
|
private bool editorMode = false;
|
|||
|
|
|||
|
private List<Text> tempTextList = null;
|
|||
|
private List<UnityEngine.UI.Image> tempImgList = null;
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Private Variables - Attitude
|
|||
|
private RectTransform attitudeRectTfrm = null;
|
|||
|
private RectTransform attitudeScrollPanel = null;
|
|||
|
private UnityEngine.UI.Image attitudeScrollImg = null;
|
|||
|
private UnityEngine.UI.Image attitudeMaskImg = null;
|
|||
|
private bool isAttitudeScrolling = false;
|
|||
|
private Vector3 tempAttitudeOffset = Vector3.zero;
|
|||
|
private Vector3 attitudeInitPosition = Vector3.zero;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// This gets calculated in InitialiseAttitude(..) at runtime.
|
|||
|
/// </summary>
|
|||
|
private float attitudePixelsPerDegree = 1080f / 180f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The attitude normalised offset between the left (-1) and the right (1) from the centre (0) of the screen.
|
|||
|
/// At runtime call shipDisplayModule.SetAttitudeOffset(..)
|
|||
|
/// </summary>
|
|||
|
[SerializeField, Range(-1f, 1f)] private float attitudeOffsetX = 0f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The attitude normalised offset between the bottom (-1) and the top (1) from the centre (0) of the screen.
|
|||
|
/// At runtime call shipDisplayModule.SetAttitudeOffset(..)
|
|||
|
/// </summary>
|
|||
|
[SerializeField, Range(-1f, 1f)] private float attitudeOffsetY = 0f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The normalised masked width of the scrollable attitude. 1.0 is full width of the screen, 0.5 is half width.
|
|||
|
/// </summary>
|
|||
|
[SerializeField, Range(0.1f, 1f)] private float attitudeWidth = 0.75f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The normalised masked height of the scrollable attitude. 1.0 is full height of the screen, 0.5 is half height.
|
|||
|
/// </summary>
|
|||
|
[SerializeField, Range(0.1f, 1f)] private float attitudeHeight = 1f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The sprite (texture) that will scroll up/down
|
|||
|
/// </summary>
|
|||
|
[SerializeField] private Sprite attitudeScrollSprite = null;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The sprite (texture) that will mask the scrollable attitude sprite
|
|||
|
/// </summary>
|
|||
|
[SerializeField] private Sprite attitudeMaskSprite = null;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The number of pixels between the top of the scroll sprite and the first (90) pitch line.
|
|||
|
/// It is assumed that this is the same for between the bottom and the -90 pitch line.
|
|||
|
/// </summary>
|
|||
|
[SerializeField, Range(0f, 1000f)] private float attitudeScrollSpriteBorderWidth = 250f;
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Private Variables - Flickering
|
|||
|
/// <summary>
|
|||
|
/// Is the HUD currently flickering and will it end in the Shown state?
|
|||
|
/// This tracks if flickering is currently happening.
|
|||
|
/// </summary>
|
|||
|
private bool isFlickeringEndStateOn = false;
|
|||
|
/// <summary>
|
|||
|
/// Is the HUD currently flickering and will it end in the Hidden state?
|
|||
|
/// This tracks if flickering is currently happening.
|
|||
|
/// </summary>
|
|||
|
private bool isFlickeringEndStateOff = false;
|
|||
|
|
|||
|
private float flickerDurationTimer = 0f;
|
|||
|
private float flickerInactiveTimer = 0f;
|
|||
|
private float flickerActiveTimer = 0f;
|
|||
|
private float flickerDuration = 0f;
|
|||
|
private float flickerActiveTime = 0f;
|
|||
|
private float flickerInactiveTime = 0f;
|
|||
|
private bool isFlickerWaiting = false;
|
|||
|
private SSCRandom hudRandom = null;
|
|||
|
private float flickerIntensity = 0f;
|
|||
|
private float flickerStartIntensity = 0f;
|
|||
|
private Queue<float> flickerHistory = null;
|
|||
|
private float flickerHistoryTotal = 0f;
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Private Variables - Brightness
|
|||
|
private SSCColour baseReticleColour;
|
|||
|
private SSCColour baseOverlayColour;
|
|||
|
private SSCColour baseAltitudeTextColour;
|
|||
|
private SSCColour baseAirspeedTextColour;
|
|||
|
private SSCColour baseAttitudePrimaryColour;
|
|||
|
private SSCColour baseHeadingPrimaryColour;
|
|||
|
private SSCColour baseHeadingIndicatorColour;
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Private Variables - Heading
|
|||
|
private RectTransform headingRectTfrm = null;
|
|||
|
private RectTransform headingScrollPanel = null;
|
|||
|
private RectTransform headingIndicatorPanel = null;
|
|||
|
private UnityEngine.UI.Image headingScrollImg = null;
|
|||
|
private UnityEngine.UI.Image headingMaskImg = null;
|
|||
|
private UnityEngine.UI.Image headingIndicatorImg = null;
|
|||
|
|
|||
|
private bool isHeadingScrolling = false;
|
|||
|
private Vector3 headingInitPosition = Vector3.zero;
|
|||
|
private Vector3 tempHeadingOffset = Vector3.zero;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// This gets calculated in InitialiseHeading(..) at runtime.
|
|||
|
/// </summary>
|
|||
|
private float headingPixelsPerDegree = 1920f / 360f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The heading normalised offset between the left (-1) and the right (1) from the centre (0) of the screen.
|
|||
|
/// At runtime call shipDisplayModule.SetHeadingOffset(..)
|
|||
|
/// </summary>
|
|||
|
[SerializeField, Range(-1f, 1f)] private float headingOffsetX = 0f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The heading normalised offset between the bottom (-1) and the top (1) from the centre (0) of the screen.
|
|||
|
/// At runtime call shipDisplayModule.SetHeadingOffset(..)
|
|||
|
/// </summary>
|
|||
|
[SerializeField, Range(-1f, 1f)] private float headingOffsetY = 0f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The normalised masked width of the scrollable heading. 1.0 is full width of the screen, 0.5 is half width.
|
|||
|
/// </summary>
|
|||
|
[SerializeField, Range(0.1f, 1f)] private float headingWidth = 0.75f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The normalised masked height of the scrollable heading. 1.0 is full height of the screen, 0.5 is half height.
|
|||
|
/// </summary>
|
|||
|
[SerializeField, Range(0.1f, 1f)] private float headingHeight = 1f;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The sprite (texture) that will scroll left/right
|
|||
|
/// </summary>
|
|||
|
[SerializeField] private Sprite headingScrollSprite = null;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The sprite (texture) that will mask the scrollable heading sprite
|
|||
|
/// </summary>
|
|||
|
[SerializeField] private Sprite headingMaskSprite = null;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The small sprite (texture) that will indicate or point to the heading on the HUD
|
|||
|
/// </summary>
|
|||
|
[SerializeField] private Sprite headingIndicatorSprite = null;
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Private Variables - Reticle
|
|||
|
private RectTransform hudRectTfrm = null;
|
|||
|
private Transform reticlePanel = null;
|
|||
|
private float reticleWidth = 1f;
|
|||
|
private float reticleHeight = 1f;
|
|||
|
private DisplayReticle currentDisplayReticle = null;
|
|||
|
private UnityEngine.UI.Image displayReticleImg = null;
|
|||
|
private int numDisplayReticles = 0;
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Private Variables - Gauges
|
|||
|
private int numDisplayGauges = 0;
|
|||
|
private RectTransform gaugesRectTfrm = null;
|
|||
|
private Vector3 tempGaugeOffset = Vector3.zero;
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Private Variables - Message
|
|||
|
private int numDisplayMessages = 0;
|
|||
|
private Vector3 tempMessageOffset;
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Private Variables - Cursor
|
|||
|
private bool isCursorVisible = true;
|
|||
|
private float cursorTimer = 0f;
|
|||
|
|
|||
|
// Switch to using the New Input System if it is available
|
|||
|
#if SSC_UIS
|
|||
|
private Vector2 currentMousePosition = Vector2.zero;
|
|||
|
private Vector2 lastMousePosition = Vector2.zero;
|
|||
|
#else
|
|||
|
private Vector3 currentMousePosition = Vector3.zero;
|
|||
|
private Vector3 lastMousePosition = Vector3.zero;
|
|||
|
#endif
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Private Variables - Altitude and Speed
|
|||
|
private UnityEngine.UI.Image primaryOverlayImg = null;
|
|||
|
private RectTransform overlayPanel = null;
|
|||
|
private RectTransform altitudeTextRectTfrm = null;
|
|||
|
private Text altitudeText = null;
|
|||
|
private Vector3 altitudeInitPosition;
|
|||
|
private Vector3 altitudeCurrentPosition;
|
|||
|
private SCSMString altitudeString = null;
|
|||
|
private RectTransform airspeedTextRectTfrm = null;
|
|||
|
private Text airspeedText = null;
|
|||
|
private Vector3 airspeedInitPosition;
|
|||
|
private Vector3 airspeedCurrentPosition;
|
|||
|
private SCSMString airspeedString = null;
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Private Variables - Targets
|
|||
|
private int numDisplayTargets = 0;
|
|||
|
private RectTransform targetsRectTfrm = null;
|
|||
|
private Vector3 tempTargetOffset;
|
|||
|
private List<int> tempIncludeFactionList = null;
|
|||
|
private List<int> tempIncludeSquadronList = null;
|
|||
|
private SSCRadar sscRadar = null;
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Private Initialisation Methods
|
|||
|
|
|||
|
// Start is called before the first frame update
|
|||
|
void Start()
|
|||
|
{
|
|||
|
if (initialiseOnStart) { Initialise(); }
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Update Methods
|
|||
|
|
|||
|
// Update is called once per frame
|
|||
|
void Update()
|
|||
|
{
|
|||
|
float dTime = Time.deltaTime;
|
|||
|
|
|||
|
#region Flickering
|
|||
|
if (isFlickeringEndStateOn || isFlickeringEndStateOff)
|
|||
|
{
|
|||
|
flickerDurationTimer += dTime;
|
|||
|
// Disable flickering
|
|||
|
if (flickerDurationTimer > flickerDuration)
|
|||
|
{
|
|||
|
flickerHistory.Clear();
|
|||
|
if (isFlickeringEndStateOn)
|
|||
|
{
|
|||
|
isFlickeringEndStateOn = false;
|
|||
|
// Restore the original brightness
|
|||
|
SetBrightness(flickerStartIntensity);
|
|||
|
ShowOrHideHUD(true);
|
|||
|
}
|
|||
|
// FlickeringOff
|
|||
|
else
|
|||
|
{
|
|||
|
isFlickeringEndStateOff = false;
|
|||
|
// Restore the original brightness
|
|||
|
brightness = flickerStartIntensity;
|
|||
|
ShowOrHideHUD(false);
|
|||
|
}
|
|||
|
}
|
|||
|
else if (isFlickerWaiting)
|
|||
|
{
|
|||
|
flickerInactiveTimer += dTime;
|
|||
|
if (flickerInactiveTimer > flickerInactiveTime)
|
|||
|
{
|
|||
|
isFlickerWaiting = false;
|
|||
|
flickerActiveTimer = 0f;
|
|||
|
flickerActiveTime = hudRandom != null ? hudRandom.Range(flickerMinActiveTime, flickerMaxActiveTime + 0.001f): 1f;
|
|||
|
ShowOrHideHUD(true);
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
flickerActiveTimer += dTime;
|
|||
|
if (flickerActiveTimer > flickerActiveTime)
|
|||
|
{
|
|||
|
flickerHistory.Clear();
|
|||
|
flickerHistory.Enqueue(0f);
|
|||
|
flickerInactiveTimer = 0f;
|
|||
|
flickerInactiveTime = hudRandom != null ? hudRandom.Range(flickerMinInactiveTime, flickerMaxInactiveTime + 0.001f) : 1f;
|
|||
|
isFlickerWaiting = true;
|
|||
|
ShowOrHideHUD(false);
|
|||
|
}
|
|||
|
else if (flickerVariableIntensity)
|
|||
|
{
|
|||
|
if (flickerSmoothing > 0)
|
|||
|
{
|
|||
|
// Remove the first value from the queue
|
|||
|
if (flickerHistory.Count > 0 && flickerHistory.Count > flickerSmoothing + 1) { flickerHistoryTotal -= flickerHistory.Dequeue(); }
|
|||
|
|
|||
|
flickerIntensity = hudRandom.Range(0f, flickerStartIntensity * flickerMaxIntensity);
|
|||
|
flickerHistoryTotal += flickerIntensity;
|
|||
|
|
|||
|
// Add the new value to the end of the queue
|
|||
|
flickerHistory.Enqueue(flickerIntensity);
|
|||
|
|
|||
|
SetBrightness(flickerHistoryTotal / (float)flickerHistory.Count);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// No smoothing
|
|||
|
flickerIntensity = hudRandom.Range(0f, flickerStartIntensity * flickerMaxIntensity);
|
|||
|
SetBrightness(flickerIntensity);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Check Window Resize
|
|||
|
if (IsHUDShown)
|
|||
|
{
|
|||
|
// Would be nice to not call this so often
|
|||
|
CheckHUDResize(true);
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region AutoHideCursor and Reticle cursor control
|
|||
|
if (autoHideCursor || (lockDisplayReticleToCursor && showActiveDisplayReticle))
|
|||
|
{
|
|||
|
#if SSC_UIS
|
|||
|
currentMousePosition = UnityEngine.InputSystem.Mouse.current.position.ReadValue();
|
|||
|
#else
|
|||
|
currentMousePosition = Input.mousePosition;
|
|||
|
#endif
|
|||
|
|
|||
|
#region Auto-hide Cursor
|
|||
|
if (autoHideCursor)
|
|||
|
{
|
|||
|
if (isCursorVisible)
|
|||
|
{
|
|||
|
cursorTimer += dTime;
|
|||
|
// If use has move the mouse, reset the timer
|
|||
|
if (lastMousePosition != currentMousePosition) { lastMousePosition = currentMousePosition; cursorTimer = 0f; }
|
|||
|
// After hideCursorTime secs, hide it
|
|||
|
else if (cursorTimer > hideCursorTime) { ShowOrHideCursor(false); }
|
|||
|
}
|
|||
|
// Check if mouse has moved (does user wish to click on something?)
|
|||
|
else if (lastMousePosition != currentMousePosition)
|
|||
|
{
|
|||
|
lastMousePosition = currentMousePosition;
|
|||
|
ShowOrHideCursor(true);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Local Display Reticle to Cursor
|
|||
|
if (IsInitialised && isMainCameraAssigned && lockDisplayReticleToCursor && showActiveDisplayReticle)
|
|||
|
{
|
|||
|
// It is safe to switch between Vector3 and Vector2 as each has an expicit
|
|||
|
// operator which either adds z = 0 or drops the z component.
|
|||
|
Vector2 viewPoint = mainCamera.ScreenToViewportPoint(currentMousePosition);
|
|||
|
|
|||
|
// Convert 0.0 to 1.0 into -1.0 to 1.0.
|
|||
|
SetDisplayReticleOffset(viewPoint.x * 2f - 1f, viewPoint.y * 2f - 1f);
|
|||
|
|
|||
|
// v1.2.8+ cursor should be hidden when reticle is following the cursor.
|
|||
|
if (isCursorVisible && !autoHideCursor && IsHUDShown) { ShowOrHideCursor(false); }
|
|||
|
}
|
|||
|
#endregion
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Update Altitude, Speed, Heading
|
|||
|
|
|||
|
if ((showAltitude || showAirspeed || isHeadingScrolling || isAttitudeScrolling) && IsHUDShown && sourceShip != null && sourceShip.ShipIsEnabled() && sourceShip.IsInitialised)
|
|||
|
{
|
|||
|
if (showAltitude)
|
|||
|
{
|
|||
|
/// TODO - round altitude to 100s
|
|||
|
altitudeString.Set((int)(sourceShip.shipInstance.TransformPosition.y - groundPlaneHeight));
|
|||
|
if (altitudeText != null) { altitudeText.text = altitudeString.ToString(); }
|
|||
|
}
|
|||
|
if (showAirspeed)
|
|||
|
{
|
|||
|
// Show in km/h
|
|||
|
airspeedString.Set((int)(sourceShip.shipInstance.LocalVelocity.z*3.6f));
|
|||
|
if (airspeedText != null) { airspeedText.text = airspeedString.ToString(); }
|
|||
|
}
|
|||
|
|
|||
|
if (isHeadingScrolling)
|
|||
|
{
|
|||
|
Vector3 _shipFwd = sourceShip.shipInstance.TransformForward;
|
|||
|
Vector3 _headingPerpendicular = Vector3.Cross(Vector3.forward, _shipFwd);
|
|||
|
float _headingDir = -Vector3.Dot(_headingPerpendicular, Vector3.up);
|
|||
|
// Get the forward angle of the ship in WS (ignoring the Up axis)
|
|||
|
headingScrollImg.transform.position = headingInitPosition + new Vector3(Vector3.Angle(new Vector3(_shipFwd.x, 0f, _shipFwd.z), Vector3.forward) * Mathf.Sign(_headingDir) * headingPixelsPerDegree, 0f, 0f);
|
|||
|
}
|
|||
|
|
|||
|
if (isAttitudeScrolling)
|
|||
|
{
|
|||
|
float _rollAngle = sourceShip.shipInstance.RollAngle;
|
|||
|
float _rollAngleRAD = -_rollAngle * Mathf.Deg2Rad;
|
|||
|
float _scrollDistance = -sourceShip.shipInstance.PitchAngle * attitudePixelsPerDegree;
|
|||
|
float _scrollRadius = _scrollDistance * Mathf.Sqrt(2 * (1 - Mathf.Cos(_rollAngleRAD)));
|
|||
|
float _scrollX = _scrollRadius * Mathf.Cos(_rollAngleRAD/2f);
|
|||
|
float _scrollY = _scrollRadius * Mathf.Sin(_rollAngleRAD/2f);
|
|||
|
|
|||
|
if (_rollAngle > 0f)
|
|||
|
{
|
|||
|
// Flip values when rolling to the right
|
|||
|
_scrollX = -_scrollX;
|
|||
|
_scrollY = -_scrollY;
|
|||
|
}
|
|||
|
|
|||
|
Vector3 attitudeScrollOffset = new Vector3(_scrollX, _scrollDistance - _scrollY, 0f);
|
|||
|
|
|||
|
// Adjust the position and rotation
|
|||
|
attitudeScrollImg.transform.position = attitudeInitPosition + attitudeScrollOffset;
|
|||
|
// Rotate the panel so that the mask rotates at the same time.
|
|||
|
attitudeRectTfrm.localRotation = Quaternion.Euler(0f, 0f, _rollAngle);
|
|||
|
|
|||
|
// Seems like we can adjust the image WS rotation at the same time, rather than having to do attitudeRectTfrm.localRotation.
|
|||
|
//attitudeScrollImg.transform.SetPositionAndRotation(attitudeInitPosition + attitudeScrollOffset, Quaternion.Euler(0f, 0f, _rollAngle));
|
|||
|
|
|||
|
//Debug.Log("[DEBUG] _rollAngle: " + _rollAngle.ToString("0.00") + " _rollAngleRAD: " + _rollAngleRAD.ToString("0.00") +
|
|||
|
// " _scrollDistance: " + _scrollDistance.ToString("0.00") + " _scrollRadius: " + _scrollRadius.ToString("0.00") +
|
|||
|
// " scrollX: " + _scrollX.ToString("0.00") + " scrollY: " + _scrollY.ToString("0.00"));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Message updates
|
|||
|
if (IsHUDShown)
|
|||
|
{
|
|||
|
// NOTE: It might be cheaper to maintain an int[] of scrollable messages
|
|||
|
for (int dmIdx = 0; dmIdx < numDisplayMessages; dmIdx++)
|
|||
|
{
|
|||
|
DisplayMessage displayMsg = displayMessageList[dmIdx];
|
|||
|
|
|||
|
#region Fade-in Message
|
|||
|
if (displayMsg.fadeinTimer > 0f && displayMsg.fadeinDuration > 0f)
|
|||
|
{
|
|||
|
displayMsg.fadeinTimer -= dTime;
|
|||
|
|
|||
|
if (displayMsg.fadeinTimer <= 0f)
|
|||
|
{
|
|||
|
displayMsg.fadeinTimer = 0f;
|
|||
|
}
|
|||
|
|
|||
|
SetDisplayMessageTextFade(displayMsg, false);
|
|||
|
if (displayMsg.showBackground)
|
|||
|
{
|
|||
|
SetDisplayMessageBackgroundFade(displayMsg, false);
|
|||
|
}
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Fade-out Message
|
|||
|
else if (displayMsg.fadeoutTimer > 0f && displayMsg.fadeoutDuration > 0f)
|
|||
|
{
|
|||
|
displayMsg.fadeoutTimer -= dTime;
|
|||
|
|
|||
|
if (displayMsg.fadeoutTimer <= 0f)
|
|||
|
{
|
|||
|
displayMsg.fadeoutTimer = 0f;
|
|||
|
displayMsg.showMessage = false;
|
|||
|
}
|
|||
|
|
|||
|
SetDisplayMessageTextFade(displayMsg, true);
|
|||
|
if (displayMsg.showBackground)
|
|||
|
{
|
|||
|
SetDisplayMessageBackgroundFade(displayMsg, true);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
if (displayMsg.scrollDirectionInt != DisplayMessage.ScrollDirectionNone)
|
|||
|
{
|
|||
|
ScrollMessage(displayMessageList[dmIdx]);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Target Position Updates
|
|||
|
if (autoUpdateTargetPositions && IsHUDShown) { UpdateTargetPositions(); }
|
|||
|
#endregion
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Private and Internal Methods - General
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or hide the hardware (mouse) cursor in the game view
|
|||
|
/// NOTE: This will sometimes fail to turn off the cursor in the editor
|
|||
|
/// Game View when it doesn't have focus, but will work fine in a build.
|
|||
|
/// </summary>
|
|||
|
/// <param name="isShown"></param>
|
|||
|
private void ShowOrHideCursor(bool isShown)
|
|||
|
{
|
|||
|
Cursor.visible = isShown;
|
|||
|
isCursorVisible = isShown;
|
|||
|
if (isShown) { cursorTimer = 0f; }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or Hide the HUD.
|
|||
|
/// IsHUDShown should never be true at runtime if IsInitialised is false
|
|||
|
/// </summary>
|
|||
|
/// <param name="isShown"></param>
|
|||
|
private void ShowOrHideHUD(bool isShown)
|
|||
|
{
|
|||
|
if (IsInitialised)
|
|||
|
{
|
|||
|
IsHUDShown = isShown;
|
|||
|
hudPanel.gameObject.SetActive(isShown);
|
|||
|
}
|
|||
|
// HUD should never be shown at runtime if IsInitialised is false
|
|||
|
else { IsHUDShown = false; }
|
|||
|
}
|
|||
|
|
|||
|
private IEnumerator UnlockCursor()
|
|||
|
{
|
|||
|
yield return new WaitForEndOfFrame();
|
|||
|
Cursor.lockState = CursorLockMode.None;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Check to see if the window has been resized. Ideally should be
|
|||
|
/// called a max once per frame (less often would be nice).
|
|||
|
/// TODO - trigger a HUD refresh if changed.
|
|||
|
/// </summary>
|
|||
|
private void CheckHUDResize(bool isRefreshIfChanged)
|
|||
|
{
|
|||
|
cvsResolutionFull = GetHUDFullSize(true);
|
|||
|
cvsResolutionHalf.x = cvsResolutionFull.x * 0.5f;
|
|||
|
cvsResolutionHalf.y = cvsResolutionFull.y * 0.5f;
|
|||
|
|
|||
|
if (cvsResolutionFull.x != prevResolutionFull.x || cvsResolutionFull.y != prevResolutionFull.y)
|
|||
|
{
|
|||
|
refResolution = GetHUDFullSize(false);
|
|||
|
|
|||
|
cvsScaleFactor = canvas == null ? Vector3.one : canvas.transform.localScale;
|
|||
|
screenResolution = new Vector2(Screen.width, Screen.height);
|
|||
|
|
|||
|
if (isRefreshIfChanged) { RefreshHUD(); }
|
|||
|
prevResolutionFull.x = cvsResolutionFull.x;
|
|||
|
prevResolutionFull.y = cvsResolutionFull.y;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Return full the width and height of the HUD Panel.
|
|||
|
/// If the module hasn't been initialised it will return 1920x1080.
|
|||
|
/// Assume the dev hasn't changed the CanvasScaler reference resolution settings.
|
|||
|
/// When using the HUD canvas current dimensions, always set isScaled = true.
|
|||
|
/// Returns x,y values in pixels.
|
|||
|
/// </summary>
|
|||
|
/// <param name="isScaled"></param>
|
|||
|
/// <returns></returns>
|
|||
|
private Vector2 GetHUDFullSize(bool isScaled)
|
|||
|
{
|
|||
|
// Default SSC scaler resolution is 1920x1080
|
|||
|
if (isScaled)
|
|||
|
{
|
|||
|
if (IsInitialised || canvas != null)
|
|||
|
{
|
|||
|
// The default [width, height] * inversed scaled [width, height]
|
|||
|
//return new Vector2(canvas.pixelRect.width / canvas.scaleFactor, canvas.pixelRect.height / canvas.scaleFactor);
|
|||
|
return ((RectTransform)canvas.transform).sizeDelta;
|
|||
|
}
|
|||
|
// We don't know, so just return the original size...
|
|||
|
else { return new Vector2(1920f, 1080f); }
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (IsInitialised || canvasScaler != null)
|
|||
|
{
|
|||
|
return canvasScaler.referenceResolution;
|
|||
|
}
|
|||
|
else { return new Vector2(1920f, 1080f); }
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Return half the width and height of the HUD Panel.
|
|||
|
/// If the module hasn't been initialised it will return half 1920x1080.
|
|||
|
/// Assuming the dev hasn't changed it, it should always return the same
|
|||
|
/// when initialised.
|
|||
|
/// When using the HUD canvas current dimensions, always set isScaled = true.
|
|||
|
/// Returns x,y values in pixels.
|
|||
|
/// </summary>
|
|||
|
/// <param name="isScaled"></param>
|
|||
|
/// <returns></returns>
|
|||
|
private Vector2 GetHUDHalfSize(bool isScaled)
|
|||
|
{
|
|||
|
// Default scaler resolution is 1920x1080
|
|||
|
if (isScaled)
|
|||
|
{
|
|||
|
if (IsInitialised || canvas != null)
|
|||
|
{
|
|||
|
// The default [width, height] * inversed scaled [width, height]
|
|||
|
//return new Vector2(canvas.pixelRect.width / canvas.scaleFactor * 0.5f, canvas.pixelRect.height / canvas.scaleFactor * 0.5f);
|
|||
|
return ((RectTransform)canvas.transform).sizeDelta * 0.5f;
|
|||
|
}
|
|||
|
// We don't know, so just return the original half size...
|
|||
|
else { return new Vector2(960f, 540f); }
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (IsInitialised || canvasScaler != null)
|
|||
|
{
|
|||
|
return new Vector2(canvasScaler.referenceResolution.x * 0.5f, canvasScaler.referenceResolution.y * 0.5f);
|
|||
|
}
|
|||
|
else { return new Vector2(960f, 540f); }
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL ONLY]
|
|||
|
/// Call CheckHUDResize(false) before calling this method
|
|||
|
/// </summary>
|
|||
|
private void GetHUDPanels()
|
|||
|
{
|
|||
|
if (hudRectTfrm != null)
|
|||
|
{
|
|||
|
hudPanel = hudRectTfrm.transform;
|
|||
|
reticlePanel = SSCUtils.GetChildTransform(hudPanel, "DisplayReticlePanel", this.name);
|
|||
|
overlayPanel = SSCUtils.GetChildRectTransform(hudPanel, overlayPanelName, this.name);
|
|||
|
|
|||
|
// For backward compatibility with earlier versions of the HUD1 prefab
|
|||
|
if (overlayPanel == null)
|
|||
|
{
|
|||
|
overlayPanel = SSCUtils.GetChildRectTransform(hudPanel, "AltitudePanel", this.name);
|
|||
|
if (overlayPanel != null) { overlayPanel.name = overlayPanelName; }
|
|||
|
}
|
|||
|
|
|||
|
altitudeTextRectTfrm = SSCUtils.GetChildRectTransform(overlayPanel, "AltitudeText", this.name);
|
|||
|
airspeedTextRectTfrm = SSCUtils.GetChildRectTransform(overlayPanel, "AirSpeedText", this.name);
|
|||
|
|
|||
|
targetsRectTfrm = GetTargetsPanel();
|
|||
|
gaugesRectTfrm = GetGaugesPanel();
|
|||
|
headingRectTfrm = GetHeadingPanel();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL ONLY]
|
|||
|
/// </summary>
|
|||
|
private void GetImgComponents()
|
|||
|
{
|
|||
|
if (reticlePanel != null) { displayReticleImg = reticlePanel.GetComponent<Image>(); }
|
|||
|
if (overlayPanel != null) { primaryOverlayImg = overlayPanel.GetComponent<Image>(); }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL ONLY]
|
|||
|
/// </summary>
|
|||
|
private void GetTextComponents()
|
|||
|
{
|
|||
|
if (altitudeTextRectTfrm != null) { altitudeText = altitudeTextRectTfrm.GetComponent<Text>(); }
|
|||
|
if (airspeedTextRectTfrm != null) { airspeedText = airspeedTextRectTfrm.GetComponent<Text>(); }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL ONLY]
|
|||
|
/// Used to change HUD outside play mode
|
|||
|
/// </summary>
|
|||
|
public void InitialiseEditorEssentials()
|
|||
|
{
|
|||
|
if (canvas == null) { canvas = GetCanvas; }
|
|||
|
|
|||
|
hudRectTfrm = SSCUtils.GetChildRectTransform(transform, hudPanelName, this.name);
|
|||
|
|
|||
|
if (hudRectTfrm != null)
|
|||
|
{
|
|||
|
// Call before GetHUDPanels()
|
|||
|
CheckHUDResize(false);
|
|||
|
|
|||
|
GetHUDPanels();
|
|||
|
GetImgComponents();
|
|||
|
GetTextComponents();
|
|||
|
|
|||
|
InitialiseAttitude(true);
|
|||
|
InitialiseHeading(true);
|
|||
|
InitialiseMessages();
|
|||
|
InitialiseTargets();
|
|||
|
editorMode = true;
|
|||
|
|
|||
|
ShowOrHideAttitude(showAttitude);
|
|||
|
ShowOrHideHeading(showHeading);
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: ShipDisplayModule.InitialiseEditorEssentials() could not find canvas HUDPanel. Did you start with the sample HUD prefab from Prefabs/Visuals folder?"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The Overlay Panel contains the Overlay image and child objects
|
|||
|
/// Altitude Text and Airspeed Text.
|
|||
|
/// </summary>
|
|||
|
private void ShowOrHideOverlayPanel()
|
|||
|
{
|
|||
|
// Should the Overlay panel be enabled?
|
|||
|
if ((showAltitude || showAirspeed || showOverlay) && !overlayPanel.gameObject.activeSelf)
|
|||
|
{
|
|||
|
overlayPanel.gameObject.SetActive(true);
|
|||
|
}
|
|||
|
else if (!showAltitude && !showAirspeed && !showOverlay && overlayPanel.gameObject.activeSelf)
|
|||
|
{
|
|||
|
overlayPanel.gameObject.SetActive(false);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or Hide the Overlay image on the HUD. Turn on HUD if required
|
|||
|
/// </summary>
|
|||
|
/// <param name="isShown"></param>
|
|||
|
private void ShowOrHideOverlay(bool isShown)
|
|||
|
{
|
|||
|
if (IsInitialised)
|
|||
|
{
|
|||
|
showOverlay = isShown;
|
|||
|
|
|||
|
ShowOrHideOverlayPanel();
|
|||
|
|
|||
|
if (primaryOverlayImg != null) { primaryOverlayImg.enabled = isShown; }
|
|||
|
|
|||
|
if (showOverlay && !IsHUDShown) { ShowOrHideHUD(true); }
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Private and Internal Methods - Brightness
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Remembers the starting colours of various elements so that they can be
|
|||
|
/// used to apply brightness to those elements at runtime.
|
|||
|
/// Sets the initial brightness.
|
|||
|
/// NOTE: Brightness doesn't work so well if colour has low alpha to begin with.
|
|||
|
/// </summary>
|
|||
|
private void InitialiseBrightness()
|
|||
|
{
|
|||
|
if (displayReticleImg != null) { baseReticleColour = displayReticleImg.color; }
|
|||
|
if (primaryOverlayImg != null) { baseOverlayColour = primaryOverlayImg.color; }
|
|||
|
if (altitudeText != null) { baseAltitudeTextColour = altitudeText.color; }
|
|||
|
if (airspeedText != null) { baseAirspeedTextColour = airspeedText.color; }
|
|||
|
if (attitudeScrollImg != null) { baseAttitudePrimaryColour = attitudeScrollImg.color; }
|
|||
|
if (headingScrollImg != null) { baseHeadingPrimaryColour = headingScrollImg.color; }
|
|||
|
if (headingIndicatorImg != null) { baseHeadingIndicatorColour = headingIndicatorImg.color; }
|
|||
|
|
|||
|
SetBrightness(brightness);
|
|||
|
}
|
|||
|
|
|||
|
private void SetOverlayBrightness()
|
|||
|
{
|
|||
|
if (primaryOverlayImg != null)
|
|||
|
{
|
|||
|
// Skip more expensive HSV->RGBA and new Color op if possible
|
|||
|
if (brightness == 1f)
|
|||
|
{
|
|||
|
SSCUtils.Color32toColorNoAlloc(ref primaryColour, ref tempColour);
|
|||
|
primaryOverlayImg.color = tempColour;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
primaryOverlayImg.color = baseOverlayColour.GetColorWithBrightness(brightness);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void SetReticleBrightness()
|
|||
|
{
|
|||
|
if (displayReticleImg != null)
|
|||
|
{
|
|||
|
// Skip more expensive HSV->RGBA and new Color op if possible
|
|||
|
if (brightness == 1f)
|
|||
|
{
|
|||
|
SSCUtils.Color32toColorNoAlloc(ref activeDisplayReticleColour, ref tempColour);
|
|||
|
displayReticleImg.color = tempColour;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
displayReticleImg.color = baseReticleColour.GetColorWithBrightness(brightness);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void SetAltitudeTextBrightness()
|
|||
|
{
|
|||
|
if (altitudeText != null)
|
|||
|
{
|
|||
|
// Skip more expensive HSV->RGBA and new Color op if possible
|
|||
|
if (brightness == 1f)
|
|||
|
{
|
|||
|
SSCUtils.Color32toColorNoAlloc(ref altitudeTextColour, ref tempColour);
|
|||
|
altitudeText.color = tempColour;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
altitudeText.color = baseAltitudeTextColour.GetColorWithBrightness(brightness);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void SetAirSpeedTextBrightness()
|
|||
|
{
|
|||
|
if (airspeedText != null)
|
|||
|
{
|
|||
|
// Skip more expensive HSV->RGBA and new Color op if possible
|
|||
|
if (brightness == 1f)
|
|||
|
{
|
|||
|
SSCUtils.Color32toColorNoAlloc(ref airspeedTextColour, ref tempColour);
|
|||
|
airspeedText.color = tempColour;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
airspeedText.color = baseAirspeedTextColour.GetColorWithBrightness(brightness);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void SetAttitudeBrightness()
|
|||
|
{
|
|||
|
if (attitudeScrollImg != null)
|
|||
|
{
|
|||
|
// Skip more expensive HSV->RGBA and new Color op if possible
|
|||
|
if (brightness == 1f)
|
|||
|
{
|
|||
|
attitudeScrollImg.color = attitudePrimaryColour;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
attitudeScrollImg.color = baseAttitudePrimaryColour.GetColorWithBrightness(brightness);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void SetHeadingBrightness()
|
|||
|
{
|
|||
|
if (headingScrollImg != null)
|
|||
|
{
|
|||
|
// Skip more expensive HSV->RGBA and new Color op if possible
|
|||
|
if (brightness == 1f)
|
|||
|
{
|
|||
|
headingScrollImg.color = headingPrimaryColour;
|
|||
|
headingIndicatorImg.color = headingIndicatorColour;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
headingScrollImg.color = baseHeadingPrimaryColour.GetColorWithBrightness(brightness);
|
|||
|
headingIndicatorImg.color = baseHeadingIndicatorColour.GetColorWithBrightness(brightness);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void SetDisplayGaugeForegroundBrightness(DisplayGauge displayGauge)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
if (displayGauge.CachedFgImgComponent != null)
|
|||
|
{
|
|||
|
if (brightness == 1f) { displayGauge.CachedFgImgComponent.color = displayGauge.foregroundColour; }
|
|||
|
else { displayGauge.CachedFgImgComponent.color = displayGauge.baseForegroundColour.GetColorWithBrightness(brightness); }
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeForegroundBrightness - displayGauge.CachedFgImgComponent is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeForegroundBrightness - displayGauge is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
private void SetDisplayGaugeBackgroundBrightness(DisplayGauge displayGauge)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
if (displayGauge.CachedBgImgComponent != null)
|
|||
|
{
|
|||
|
if (brightness == 1f) { displayGauge.CachedBgImgComponent.color = displayGauge.backgroundColour; }
|
|||
|
else { displayGauge.CachedBgImgComponent.color = displayGauge.baseBackgroundColour.GetColorWithBrightness(brightness); }
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeBackgroundBrightness - displayGauge.CachedBgImgComponent is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeBackgroundBrightness - displayGauge is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Adjust the brightness of the gauge text. If it is a numeric gauge with a label,
|
|||
|
/// also adjust the brightness of the label.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
private void SetDisplayGaugeTextBrightness(DisplayGauge displayGauge)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
if (displayGauge.CachedTextComponent != null)
|
|||
|
{
|
|||
|
if (brightness == 1f) { displayGauge.CachedTextComponent.color = displayGauge.textColour; }
|
|||
|
else { displayGauge.CachedTextComponent.color = displayGauge.baseTextColour.GetColorWithBrightness(brightness); }
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeTextBrightness - displayGauge.CachedTextComponent is null"); }
|
|||
|
#endif
|
|||
|
|
|||
|
if (displayGauge.CachedLabelTextComponent != null)
|
|||
|
{
|
|||
|
if (brightness == 1f) { displayGauge.CachedLabelTextComponent.color = displayGauge.textColour; }
|
|||
|
else { displayGauge.CachedLabelTextComponent.color = displayGauge.baseTextColour.GetColorWithBrightness(brightness); }
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeTextBrightness - displayGauge is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
private void SetDisplayMessageBackgroundBrightness(DisplayMessage displayMessage)
|
|||
|
{
|
|||
|
if (displayMessage != null)
|
|||
|
{
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
if (displayMessage.CachedBgImgComponent != null)
|
|||
|
{
|
|||
|
if (brightness == 1f) { displayMessage.CachedBgImgComponent.color = displayMessage.backgroundColour; }
|
|||
|
else { displayMessage.CachedBgImgComponent.color = displayMessage.baseBackgroundColour.GetColorWithBrightness(brightness); }
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayMessageBackgroundBrightness - displayMessage.CachedBgImgComponent is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayMessageBackgroundBrightness - displayMessage is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
private void SetDisplayMessageBackgroundFade (DisplayMessage displayMessage, bool isFadeOut)
|
|||
|
{
|
|||
|
if (displayMessage != null)
|
|||
|
{
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
if (displayMessage.CachedBgImgComponent != null)
|
|||
|
{
|
|||
|
float fadeValue = easeInOutCurve.Evaluate(isFadeOut ? displayMessage.GetFadeOutValue() : displayMessage.GetFadeInValue());
|
|||
|
|
|||
|
displayMessage.CachedBgImgComponent.color = displayMessage.baseBackgroundColour.GetColorWithFadedBrightness(brightness, fadeValue);
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayMessageBackgroundFade - displayMessage.CachedBgImgComponent is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayMessageBackgroundFade - displayMessage is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
private void SetDisplayMessageTextBrightness(DisplayMessage displayMessage)
|
|||
|
{
|
|||
|
if (displayMessage != null)
|
|||
|
{
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
if (displayMessage.CachedTextComponent != null)
|
|||
|
{
|
|||
|
if (brightness == 1f) { displayMessage.CachedTextComponent.color = displayMessage.textColour; }
|
|||
|
else { displayMessage.CachedTextComponent.color = displayMessage.baseTextColour.GetColorWithBrightness(brightness); }
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayMessageTextBrightness - displayMessage.CachedTextComponent is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayMessageTextBrightness - displayMessage is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
private void SetDisplayMessageTextFade (DisplayMessage displayMessage, bool isFadeOut)
|
|||
|
{
|
|||
|
if (displayMessage != null)
|
|||
|
{
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
if (displayMessage.CachedTextComponent != null)
|
|||
|
{
|
|||
|
float fadeValue = easeInOutCurve.Evaluate(isFadeOut ? displayMessage.GetFadeOutValue() : displayMessage.GetFadeInValue());
|
|||
|
|
|||
|
//Debug.Log("[DEBUG] msg fadeinTimer: " + displayMessage.fadeinTimer + " fadeValue: " + fadeValue);
|
|||
|
|
|||
|
displayMessage.CachedTextComponent.color = displayMessage.baseTextColour.GetColorWithFadedBrightness(brightness, fadeValue);
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayMessageTextFade - displayMessage.CachedTextComponent is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayMessageTextFade - displayMessage is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the brightness of all slots (copies) of a DisplayTarget
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayTarget"></param>
|
|||
|
private void SetDisplayTargetBrightness(DisplayTarget displayTarget)
|
|||
|
{
|
|||
|
if (displayTarget != null)
|
|||
|
{
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
for (int sIdx = 0; sIdx < displayTarget.maxNumberOfTargets; sIdx++)
|
|||
|
{
|
|||
|
if (displayTarget.displayTargetSlotList[sIdx].CachedImgComponent != null)
|
|||
|
{
|
|||
|
if (brightness == 1f) { displayTarget.displayTargetSlotList[sIdx].CachedImgComponent.color = displayTarget.reticleColour; }
|
|||
|
else { displayTarget.displayTargetSlotList[sIdx].CachedImgComponent.color = displayTarget.baseReticleColour.GetColorWithBrightness(brightness); }
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayTargetBrightness - displayTarget slot " + sIdx + " CachedImgComponent is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayTargetBrightness - displayTarget is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Private or Internal Methods - Reticle
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or Hide the reticle. Turn on the HUD if required.
|
|||
|
/// Always hide the cursor (hardware pointer) when the reticle is shown.
|
|||
|
/// </summary>
|
|||
|
/// <param name="isShown"></param>
|
|||
|
private void ShowOrHideReticle(bool isShown)
|
|||
|
{
|
|||
|
if (IsInitialised)
|
|||
|
{
|
|||
|
showActiveDisplayReticle = isShown;
|
|||
|
|
|||
|
if (isShown)
|
|||
|
{
|
|||
|
// Check the active display reticle
|
|||
|
if (guidHashActiveDisplayReticle == 0)
|
|||
|
{
|
|||
|
showActiveDisplayReticle = false;
|
|||
|
currentDisplayReticle = null;
|
|||
|
LoadDisplayReticleSprite(currentDisplayReticle);
|
|||
|
|
|||
|
#if UNITY_EDITOR
|
|||
|
Debug.LogWarning("ShipDisplayModule - could not show the Display Rectile because there was no active rectile");
|
|||
|
#endif
|
|||
|
}
|
|||
|
// If there is no current reticle, or if we need to change the reticle,
|
|||
|
// look up the hash value and load the sprite (if there is a match)
|
|||
|
else if (currentDisplayReticle == null || (currentDisplayReticle.guidHash != guidHashActiveDisplayReticle))
|
|||
|
{
|
|||
|
currentDisplayReticle = displayReticleList.Find(dr => dr.guidHash == guidHashActiveDisplayReticle);
|
|||
|
LoadDisplayReticleSprite(currentDisplayReticle);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (showActiveDisplayReticle && lockDisplayReticleToCursor) { Cursor.visible = false; }
|
|||
|
|
|||
|
reticlePanel.gameObject.SetActive(showActiveDisplayReticle);
|
|||
|
|
|||
|
if (showActiveDisplayReticle && !IsHUDShown) { ShowOrHideHUD(true); }
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Load the reticle sprite into the UI image on the panel
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayReticle"></param>
|
|||
|
private void LoadDisplayReticleSprite(DisplayReticle displayReticle)
|
|||
|
{
|
|||
|
if (displayReticle != null)
|
|||
|
{
|
|||
|
displayReticleImg.sprite = displayReticle.primarySprite;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
displayReticleImg.sprite = null;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Private or Internal Methods - Overlay, Altitude and Speed
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or Hide the Altitude indicator on the HUD. Turn on HUD if required.
|
|||
|
/// </summary>
|
|||
|
/// <param name="isShown"></param>
|
|||
|
private void ShowOrHideAltitude(bool isShown)
|
|||
|
{
|
|||
|
if (IsInitialised)
|
|||
|
{
|
|||
|
showAltitude = isShown;
|
|||
|
|
|||
|
ShowOrHideOverlayPanel();
|
|||
|
|
|||
|
if (altitudeText != null) { altitudeText.gameObject.SetActive(showAltitude); }
|
|||
|
|
|||
|
if (showAltitude && !IsHUDShown) { ShowOrHideHUD(true); }
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or Hide the Air Speed indicator on the HUD. Turn on HUD if required
|
|||
|
/// </summary>
|
|||
|
/// <param name="isShown"></param>
|
|||
|
private void ShowOrHideAirSpeed(bool isShown)
|
|||
|
{
|
|||
|
if (IsInitialised)
|
|||
|
{
|
|||
|
showAirspeed = isShown;
|
|||
|
|
|||
|
ShowOrHideOverlayPanel();
|
|||
|
|
|||
|
if (airspeedText != null) { airspeedText.gameObject.SetActive(showAirspeed); }
|
|||
|
|
|||
|
if (showAirspeed && !IsHUDShown) { ShowOrHideHUD(true); }
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Private or Internal Methods - Attitude
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get or Create the scrollable attitude.
|
|||
|
/// The attitude image is masked by the parent mask image.
|
|||
|
/// </summary>
|
|||
|
private void GetOrCreateAttitude()
|
|||
|
{
|
|||
|
if (attitudeRectTfrm == null) { attitudeRectTfrm = GetAttitudePanel(); }
|
|||
|
|
|||
|
if (attitudeRectTfrm != null)
|
|||
|
{
|
|||
|
// Find or create the Mask for the scrollable attitude
|
|||
|
if (attitudeMaskImg == null)
|
|||
|
{
|
|||
|
attitudeMaskImg = attitudeRectTfrm.GetComponent<UnityEngine.UI.Image>();
|
|||
|
|
|||
|
if (attitudeMaskImg == null)
|
|||
|
{
|
|||
|
attitudeMaskImg = attitudeRectTfrm.gameObject.AddComponent<UnityEngine.UI.Image>();
|
|||
|
UnityEngine.UI.Mask attitudeMask = attitudeRectTfrm.gameObject.AddComponent<UnityEngine.UI.Mask>();
|
|||
|
|
|||
|
if (attitudeMaskImg != null)
|
|||
|
{
|
|||
|
attitudeMaskImg.raycastTarget = false;
|
|||
|
attitudeMaskImg.preserveAspect = false;
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.GetOrCreateAttitude() - could not add mask image component to Attitude panel"); }
|
|||
|
#endif
|
|||
|
|
|||
|
if (attitudeMask != null)
|
|||
|
{
|
|||
|
attitudeMask.showMaskGraphic = false;
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.GetOrCreateAttitude() - could not add mask component to Attitude panel"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Find or create the scrollable panel and image. This is a child of the attitude panel and mask
|
|||
|
if (attitudeScrollImg == null)
|
|||
|
{
|
|||
|
// The panel width and height are 1.0 which is the full resolution e.g. 1920x1080
|
|||
|
attitudeScrollPanel = SSCUtils.GetOrCreateChildRectTransform(attitudeRectTfrm, cvsResolutionFull, attitudeScrollName,
|
|||
|
0f, 0f, 1f, 1f, 0.5f, 0.5f, 0.5f, 0.5f);
|
|||
|
|
|||
|
if (attitudeScrollPanel != null)
|
|||
|
{
|
|||
|
attitudeScrollImg = attitudeScrollPanel.GetComponent<UnityEngine.UI.Image>();
|
|||
|
|
|||
|
if (attitudeScrollImg == null)
|
|||
|
{
|
|||
|
attitudeScrollImg = attitudeScrollPanel.gameObject.AddComponent<UnityEngine.UI.Image>();
|
|||
|
|
|||
|
if (attitudeScrollImg != null)
|
|||
|
{
|
|||
|
attitudeScrollImg.raycastTarget = false;
|
|||
|
attitudeScrollImg.preserveAspect = true;
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.GetOrCreateAttitude() - could not add background to Attitude panel"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// TODO - Find or create the small indicator panel and image (NOT SURE IF WE NEED THIS YET).
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Initialise the scrollable Attitude.
|
|||
|
/// </summary>
|
|||
|
/// <param name="isInitialising"></param>
|
|||
|
private void InitialiseAttitude(bool isInitialising)
|
|||
|
{
|
|||
|
GetOrCreateAttitude();
|
|||
|
|
|||
|
SetDisplayAttitudeScrollSprite(attitudeScrollSprite);
|
|||
|
SetDisplayAttitudeMaskSprite(attitudeMaskSprite);
|
|||
|
|
|||
|
SetDisplayAttitudeOffset(attitudeOffsetX, attitudeOffsetY);
|
|||
|
SetDisplayAttitudeSize(attitudeWidth, attitudeHeight);
|
|||
|
|
|||
|
if (attitudeScrollImg != null)
|
|||
|
{
|
|||
|
if (isInitialising)
|
|||
|
{
|
|||
|
attitudeInitPosition = attitudeScrollImg.transform.position;
|
|||
|
}
|
|||
|
|
|||
|
RefreshAttitudeAfterResize();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or hide the scrollable Attitude display. Turn on HUD if required.
|
|||
|
/// </summary>
|
|||
|
/// <param name="isShown"></param>
|
|||
|
private void ShowOrHideAttitude(bool isShown)
|
|||
|
{
|
|||
|
if (IsInitialised || IsEditorMode)
|
|||
|
{
|
|||
|
showAttitude = isShown;
|
|||
|
|
|||
|
if (attitudeRectTfrm != null) { attitudeRectTfrm.gameObject.SetActive(showAttitude); }
|
|||
|
|
|||
|
if (attitudeScrollImg != null)
|
|||
|
{
|
|||
|
attitudeScrollImg.enabled = isShown;
|
|||
|
isAttitudeScrolling = isShown;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
isAttitudeScrolling = false;
|
|||
|
}
|
|||
|
|
|||
|
if (showAttitude && !IsHUDShown) { ShowOrHideHUD(true); }
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Private or Internal Methods - Gauges
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL USE ONLY]
|
|||
|
/// Create a new Gauge RectTransform under the HUD GaugesPanel in the hierarchy
|
|||
|
/// Add a background Image
|
|||
|
/// Add a (foreground) fillable iamge
|
|||
|
/// Add a text panel
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public RectTransform CreateGaugePanel(DisplayGauge displayGauge)
|
|||
|
{
|
|||
|
RectTransform gaugePanel = null;
|
|||
|
|
|||
|
if (gaugesRectTfrm == null) { gaugesRectTfrm = GetGaugesPanel(); }
|
|||
|
|
|||
|
if (gaugesRectTfrm != null && displayGauge != null)
|
|||
|
{
|
|||
|
float panelWidth = displayGauge.displayWidth;
|
|||
|
float panelHeight = displayGauge.displayHeight;
|
|||
|
|
|||
|
gaugePanel = SSCUtils.GetOrCreateChildRectTransform(gaugesRectTfrm, cvsResolutionFull, "Gauge_" + displayGauge.guidHash, 0f, 0f,
|
|||
|
panelWidth, panelHeight, 0.5f, 0.5f, 0.5f, 0.5f);
|
|||
|
|
|||
|
if (gaugePanel != null)
|
|||
|
{
|
|||
|
Image bgimgComponent = gaugePanel.gameObject.AddComponent<Image>();
|
|||
|
if (bgimgComponent != null)
|
|||
|
{
|
|||
|
bgimgComponent.raycastTarget = false;
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.CreateGaugePanel() - could not add background to Gauge panel"); }
|
|||
|
#endif
|
|||
|
|
|||
|
RectTransform gaugeAmtPanel = SSCUtils.GetOrCreateChildRectTransform(gaugePanel, cvsResolutionFull, "GaugeAmount", 0f, 0f,
|
|||
|
panelWidth, panelHeight, 0.5f, 0.5f, 0.5f, 0.5f);
|
|||
|
|
|||
|
if (gaugeAmtPanel != null)
|
|||
|
{
|
|||
|
Image amtimgComponent = gaugeAmtPanel.gameObject.AddComponent<Image>();
|
|||
|
if (amtimgComponent != null)
|
|||
|
{
|
|||
|
amtimgComponent.raycastTarget = false;
|
|||
|
amtimgComponent.type = Image.Type.Filled;
|
|||
|
amtimgComponent.fillMethod = (Image.FillMethod)displayGauge.fillMethod;
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.CreateGaugePanel() - could not add fill image to Gauge panel"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
RectTransform gaugeTxtPanel = SSCUtils.GetOrCreateChildRectTransform(gaugePanel, cvsResolutionFull, "GaugeText", 0f, 0f,
|
|||
|
panelWidth, panelHeight, 0.5f, 0.5f, 0.5f, 0.5f);
|
|||
|
|
|||
|
if (gaugeTxtPanel != null)
|
|||
|
{
|
|||
|
UnityEngine.UI.Text textComponent = gaugeTxtPanel.gameObject.AddComponent<UnityEngine.UI.Text>();
|
|||
|
if (textComponent != null)
|
|||
|
{
|
|||
|
textComponent.raycastTarget = false;
|
|||
|
textComponent.resizeTextForBestFit = true;
|
|||
|
// Text is add in InitialiseGauge().
|
|||
|
textComponent.text = string.Empty;
|
|||
|
if (Application.isPlaying)
|
|||
|
{
|
|||
|
textComponent.font = SSCUtils.GetDefaultFont();
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.CreateGaugePanel() - could not add text to Gauge panel"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
// Update the number of gauges. Count the list rather than assume the gauge didn't already exist.
|
|||
|
numDisplayGauges = displayGaugeList == null ? 0 : displayGaugeList.Count;
|
|||
|
InitialiseGauge(displayGauge);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: ShipDisplayModule.CreateGaugePanel() - displayGauge is null or could not find or create " + gaugesPanelName); }
|
|||
|
#endif
|
|||
|
|
|||
|
return gaugePanel;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL USE ONLY]
|
|||
|
/// Find the Gauge RectTransform under the HUD in the hierarchy.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
/// <returns></returns>
|
|||
|
private RectTransform GetGaugePanel(int guidHash)
|
|||
|
{
|
|||
|
if (gaugesRectTfrm == null) { gaugesRectTfrm = GetGaugesPanel(); }
|
|||
|
if (gaugesRectTfrm != null)
|
|||
|
{
|
|||
|
return SSCUtils.GetChildRectTransform(gaugesRectTfrm.transform, "Gauge_" + guidHash, this.name);
|
|||
|
}
|
|||
|
else { return null; }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get or create a gauge label. This only applies to numeric gauges with an additional
|
|||
|
/// text component or label.
|
|||
|
/// If it is the wrong gauge type, remove any secondary label.
|
|||
|
/// This will set or update the displayGauge.CachedLabelTextComponent.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
private void GetOrCreateOrRemoveGaugeLabel(DisplayGauge displayGauge)
|
|||
|
{
|
|||
|
UnityEngine.UI.Text textComponent = null;
|
|||
|
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
int gaugeTypeInt = (int)displayGauge.gaugeType;
|
|||
|
|
|||
|
// Is the component already cached?
|
|||
|
if (displayGauge.CachedLabelTextComponent != null)
|
|||
|
{
|
|||
|
// If this gauge should have a secondary label, set it to the cached component
|
|||
|
if (gaugeTypeInt == DisplayGauge.DGTypeNumberWithLabel1Int)
|
|||
|
{
|
|||
|
textComponent = displayGauge.CachedLabelTextComponent;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// A secondary label (Text component) does not apply to this gauge, so remove it.
|
|||
|
if (Application.isPlaying) { Destroy(displayGauge.CachedLabelTextComponent.gameObject); }
|
|||
|
else
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
UnityEditor.Undo.DestroyObjectImmediate(displayGauge.CachedLabelTextComponent.gameObject);
|
|||
|
#else
|
|||
|
DestroyImmediate(displayGauge.CachedLabelTextComponent.gameObject);
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
// Clear the cached component
|
|||
|
displayGauge.CachedLabelTextComponent = null;
|
|||
|
}
|
|||
|
}
|
|||
|
else if (gaugeTypeInt == DisplayGauge.DGTypeNumberWithLabel1Int)
|
|||
|
{
|
|||
|
// Not cached, so attempt to find it
|
|||
|
RectTransform gaugePanel = displayGauge.CachedGaugePanel == null ? GetGaugePanel(displayGauge.guidHash) : displayGauge.CachedGaugePanel;
|
|||
|
|
|||
|
if (gaugePanel != null)
|
|||
|
{
|
|||
|
float panelWidth = displayGauge.displayWidth;
|
|||
|
float panelHeight = displayGauge.displayHeight / 2f;
|
|||
|
|
|||
|
RectTransform gaugeLabelPanel = SSCUtils.GetOrCreateChildRectTransform(gaugePanel, cvsResolutionFull, "GaugeLabel", 0f, 0f,
|
|||
|
panelWidth, panelHeight, 0.5f, 0.5f, 0.5f, 0.5f);
|
|||
|
|
|||
|
if (gaugeLabelPanel != null)
|
|||
|
{
|
|||
|
textComponent = gaugeLabelPanel.GetComponent<UnityEngine.UI.Text>();
|
|||
|
|
|||
|
if (textComponent == null)
|
|||
|
{
|
|||
|
// Text component doesn't exist, so add and configure it
|
|||
|
textComponent = gaugeLabelPanel.gameObject.AddComponent<UnityEngine.UI.Text>();
|
|||
|
|
|||
|
if (textComponent != null)
|
|||
|
{
|
|||
|
textComponent.raycastTarget = false;
|
|||
|
textComponent.resizeTextForBestFit = true;
|
|||
|
|
|||
|
textComponent.text = displayGauge.gaugeLabel;
|
|||
|
if (Application.isPlaying)
|
|||
|
{
|
|||
|
textComponent.font = SSCUtils.GetDefaultFont();
|
|||
|
}
|
|||
|
|
|||
|
displayGauge.CachedLabelTextComponent = textComponent;
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.CreateGaugePanel() - could not add text to Gauge panel"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
displayGauge.CachedLabelTextComponent = textComponent;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Cache the DisplayGauge RectTransform, Image and Text component.
|
|||
|
/// Set the Text colour.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
private void InitialiseGauge(DisplayGauge displayGauge)
|
|||
|
{
|
|||
|
displayGauge.CachedGaugePanel = GetGaugePanel(displayGauge.guidHash);
|
|||
|
// Cache FillMethod is None to avoid enum lookup at runtime
|
|||
|
displayGauge.isFillMethodNone = displayGauge.fillMethod == DisplayGauge.DGFillMethod.None;
|
|||
|
|
|||
|
if (displayGauge.CachedGaugePanel != null)
|
|||
|
{
|
|||
|
displayGauge.CachedBgImgComponent = displayGauge.CachedGaugePanel.GetComponent<Image>();
|
|||
|
|
|||
|
if (displayGauge.CachedBgImgComponent != null)
|
|||
|
{
|
|||
|
// If there is a sprite but it hasn't been loaded into the image, do it now
|
|||
|
if (displayGauge.backgroundSprite != null && displayGauge.CachedBgImgComponent.sprite == null)
|
|||
|
{
|
|||
|
SetDisplayGaugeBackgroundSprite(displayGauge, displayGauge.backgroundSprite);
|
|||
|
}
|
|||
|
|
|||
|
// Cache the gauge foreground Image component
|
|||
|
if (tempImgList == null) { tempImgList = new List<Image>(1); }
|
|||
|
displayGauge.CachedGaugePanel.GetComponentsInChildren(tempImgList);
|
|||
|
if (tempImgList.Count > 0)
|
|||
|
{
|
|||
|
// GetComponentsInChildren will also return the background image which we don't want
|
|||
|
tempImgList.Remove(displayGauge.CachedBgImgComponent);
|
|||
|
|
|||
|
if (tempImgList.Count > 0)
|
|||
|
{
|
|||
|
displayGauge.CachedFgImgComponent = tempImgList[0];
|
|||
|
|
|||
|
// If there is a sprite but it hasn't been loaded into the image, do it now
|
|||
|
if (displayGauge.foregroundSprite != null && displayGauge.CachedFgImgComponent.sprite == null)
|
|||
|
{
|
|||
|
SetDisplayGaugeForegroundSprite(displayGauge, displayGauge.foregroundSprite);
|
|||
|
}
|
|||
|
|
|||
|
SetDisplayGaugeValue(displayGauge, displayGauge.gaugeValue);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Cache the gauge Text component
|
|||
|
if (tempTextList == null) { tempTextList = new List<Text>(2); }
|
|||
|
displayGauge.CachedGaugePanel.GetComponentsInChildren(tempTextList);
|
|||
|
if (tempTextList.Count > 0)
|
|||
|
{
|
|||
|
displayGauge.CachedTextComponent = tempTextList[0];
|
|||
|
|
|||
|
// NOTE: The order may not be guaranteed here so this might or might not be an issue
|
|||
|
// with numeric gauges.
|
|||
|
if (tempTextList.Count > 1)
|
|||
|
{
|
|||
|
displayGauge.CachedLabelTextComponent = tempTextList[1];
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// SetDisplayGaugeForegroundColour does not update the baseForegroundColour if the foregroundColour has not changed. So do it in here instead
|
|||
|
displayGauge.baseForegroundColour.Set(displayGauge.foregroundColour.r, displayGauge.foregroundColour.g, displayGauge.foregroundColour.b, displayGauge.foregroundColour.a, true);
|
|||
|
SetDisplayGaugeForegroundBrightness(displayGauge);
|
|||
|
|
|||
|
// SetDisplayGaugeBackgroundColour does not update the baseBackgroundColour if the backgroundColour has not changed. So do it in here instead
|
|||
|
displayGauge.baseBackgroundColour.Set(displayGauge.backgroundColour.r, displayGauge.backgroundColour.g, displayGauge.backgroundColour.b, displayGauge.backgroundColour.a, true);
|
|||
|
SetDisplayGaugeBackgroundBrightness(displayGauge);
|
|||
|
|
|||
|
// SetDisplayGaugeTextColour does not update the baseTextColour if the textColour has not changed. So do it in here instead
|
|||
|
displayGauge.baseTextColour.Set(displayGauge.textColour.r, displayGauge.textColour.g, displayGauge.textColour.b, displayGauge.textColour.a, true);
|
|||
|
SetDisplayGaugeTextBrightness(displayGauge);
|
|||
|
|
|||
|
SetDisplayGaugeText(displayGauge, displayGauge.gaugeString);
|
|||
|
SetDisplayGaugeTextAlignment(displayGauge, displayGauge.textAlignment);
|
|||
|
SetDisplayGaugeTextFontStyle(displayGauge, (UnityEngine.FontStyle)displayGauge.fontStyle);
|
|||
|
SetDisplayGaugeTextFontSize(displayGauge, displayGauge.isBestFit, displayGauge.fontMinSize, displayGauge.fontMaxSize);
|
|||
|
|
|||
|
if (displayGauge.CachedLabelTextComponent != null)
|
|||
|
{
|
|||
|
SetDisplayGaugeLabel(displayGauge, displayGauge.gaugeLabel);
|
|||
|
SetDisplayGaugeLabelAlignment(displayGauge, displayGauge.labelAlignment);
|
|||
|
}
|
|||
|
|
|||
|
SetDisplayGaugeSize(displayGauge, displayGauge.displayWidth, displayGauge.displayHeight);
|
|||
|
|
|||
|
SetDisplayGaugeOffset(displayGauge, displayGauge.offsetX, displayGauge.offsetY);
|
|||
|
|
|||
|
// By default gauges are initialised off. This is to prevent them suddenly appearing when first created.
|
|||
|
if (Application.isPlaying)
|
|||
|
{
|
|||
|
displayGauge.CachedGaugePanel.gameObject.SetActive(false);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Initialise all the DisplayGauges by caching the RectTransforms.
|
|||
|
/// </summary>
|
|||
|
private void InitialiseGauges()
|
|||
|
{
|
|||
|
int _numDisplayGauges = GetNumberDisplayGauges;
|
|||
|
|
|||
|
if (_numDisplayGauges > 0)
|
|||
|
{
|
|||
|
RectTransform hudRectTfrm = GetHUDPanel();
|
|||
|
if (hudRectTfrm != null)
|
|||
|
{
|
|||
|
CheckHUDResize(false);
|
|||
|
for (int dgIdx = 0; dgIdx < _numDisplayGauges; dgIdx++)
|
|||
|
{
|
|||
|
InitialiseGauge(displayGaugeList[dgIdx]);
|
|||
|
}
|
|||
|
|
|||
|
if (_numDisplayGauges > 0) { RefreshGaugesSortOrder(); }
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ShipDisplayModule.InitialiseGauges() - could not find HUD Panel"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or Hide the Display Gauge on the HUD. Turn on the HUD if required.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
/// <param name="isShown"></param>
|
|||
|
private void ShowOrHideGauge(DisplayGauge displayGauge, bool isShown)
|
|||
|
{
|
|||
|
if (IsInitialised)
|
|||
|
{
|
|||
|
if (displayGauge.CachedGaugePanel != null)
|
|||
|
{
|
|||
|
displayGauge.showGauge = isShown;
|
|||
|
displayGauge.CachedGaugePanel.gameObject.SetActive(isShown);
|
|||
|
}
|
|||
|
|
|||
|
if (isShown && !IsHUDShown) { ShowOrHideHUD(true); }
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or hide all gauges
|
|||
|
/// </summary>
|
|||
|
/// <param name="isShown"></param>
|
|||
|
private void ShowOrHideGauges(bool isShown)
|
|||
|
{
|
|||
|
if (IsInitialised)
|
|||
|
{
|
|||
|
for (int dmIdx = 0; dmIdx < numDisplayGauges; dmIdx++)
|
|||
|
{
|
|||
|
ShowOrHideGauge(displayGaugeList[dmIdx], isShown);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or Hide all gauges based on their current settings
|
|||
|
/// </summary>
|
|||
|
private void ShowOrHideGauges()
|
|||
|
{
|
|||
|
if (IsInitialised)
|
|||
|
{
|
|||
|
for (int dmIdx = 0; dmIdx < numDisplayGauges; dmIdx++)
|
|||
|
{
|
|||
|
DisplayGauge displayGauge = displayGaugeList[dmIdx];
|
|||
|
ShowOrHideGauge(displayGauge, displayGauge.showGauge);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Private or Internal Methods - Heading
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Initialise the scrollable heading or compass.
|
|||
|
/// </summary>
|
|||
|
/// <param name="isInitialising"></param>
|
|||
|
private void InitialiseHeading(bool isInitialising)
|
|||
|
{
|
|||
|
GetOrCreateHeading();
|
|||
|
|
|||
|
SetDisplayHeadingScrollSprite(headingScrollSprite);
|
|||
|
SetDisplayHeadingMaskSprite(headingMaskSprite);
|
|||
|
SetDisplayHeadingIndicatorSprite(headingIndicatorSprite);
|
|||
|
|
|||
|
SetDisplayHeadingOffset(headingOffsetX, headingOffsetY);
|
|||
|
SetDisplayHeadingSize(headingWidth, headingHeight);
|
|||
|
|
|||
|
if (isInitialising && headingScrollImg != null)
|
|||
|
{
|
|||
|
headingInitPosition = headingScrollImg.transform.position;
|
|||
|
|
|||
|
// The heading img should have 2 sets of 0-360 deg to avoid scrolling partly out of view.
|
|||
|
// The image is autoscaled to the full width of the default HUD screen size.
|
|||
|
headingPixelsPerDegree = cvsResolutionFull.x / 720f;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get or Create the scrollable heading.
|
|||
|
/// The heading image is masked by the parent mask image.
|
|||
|
/// </summary>
|
|||
|
private void GetOrCreateHeading()
|
|||
|
{
|
|||
|
if (headingRectTfrm == null) { headingRectTfrm = GetHeadingPanel(); }
|
|||
|
|
|||
|
if (headingRectTfrm != null)
|
|||
|
{
|
|||
|
// Find or create the Mask for the scrollable heading
|
|||
|
if (headingMaskImg == null)
|
|||
|
{
|
|||
|
headingMaskImg = headingRectTfrm.GetComponent<UnityEngine.UI.Image>();
|
|||
|
|
|||
|
if (headingMaskImg == null)
|
|||
|
{
|
|||
|
headingMaskImg = headingRectTfrm.gameObject.AddComponent<UnityEngine.UI.Image>();
|
|||
|
UnityEngine.UI.Mask headingMask = headingRectTfrm.gameObject.AddComponent<UnityEngine.UI.Mask>();
|
|||
|
|
|||
|
if (headingMaskImg != null)
|
|||
|
{
|
|||
|
headingMaskImg.raycastTarget = false;
|
|||
|
headingMaskImg.preserveAspect = false;
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.GetOrCreateHeading() - could not add mask image component to Heading panel"); }
|
|||
|
#endif
|
|||
|
|
|||
|
if (headingMask != null)
|
|||
|
{
|
|||
|
headingMask.showMaskGraphic = false;
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.GetOrCreateHeading() - could not add mask component to Heading panel"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Find or create the scrollable panel and image. This is a child of the heading panel and mask
|
|||
|
if (headingScrollImg == null)
|
|||
|
{
|
|||
|
// The panel width and height are 1.0 which is the full resolution e.g. 1920x1080
|
|||
|
headingScrollPanel = SSCUtils.GetOrCreateChildRectTransform(headingRectTfrm, cvsResolutionFull, headingScrollName,
|
|||
|
0f, 0f, 1f, 1f, 0.5f, 0.5f, 0.5f, 0.5f);
|
|||
|
|
|||
|
if (headingScrollPanel != null)
|
|||
|
{
|
|||
|
headingScrollImg = headingScrollPanel.GetComponent<UnityEngine.UI.Image>();
|
|||
|
|
|||
|
if (headingScrollImg == null)
|
|||
|
{
|
|||
|
headingScrollImg = headingScrollPanel.gameObject.AddComponent<UnityEngine.UI.Image>();
|
|||
|
|
|||
|
if (headingScrollImg != null)
|
|||
|
{
|
|||
|
headingScrollImg.raycastTarget = false;
|
|||
|
headingScrollImg.preserveAspect = true;
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.GetOrCreateHeading() - could not add background to Heading panel"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Find or create the small indicator panel and image.
|
|||
|
if (headingIndicatorImg == null)
|
|||
|
{
|
|||
|
// The panel width and height are 1.0 which is the full resolution e.g. 1920x1080
|
|||
|
headingIndicatorPanel = SSCUtils.GetOrCreateChildRectTransform(headingRectTfrm, cvsResolutionFull, headingIndicatorName,
|
|||
|
0f, 0f, 16f / cvsResolutionFull.x, 16f / cvsResolutionFull.y, 0.5f, 0.5f, 0.5f, 0.5f);
|
|||
|
|
|||
|
if (headingIndicatorPanel != null)
|
|||
|
{
|
|||
|
headingIndicatorImg = headingIndicatorPanel.GetComponent<UnityEngine.UI.Image>();
|
|||
|
|
|||
|
if (headingIndicatorImg == null)
|
|||
|
{
|
|||
|
headingIndicatorImg = headingIndicatorPanel.gameObject.AddComponent<UnityEngine.UI.Image>();
|
|||
|
|
|||
|
if (headingIndicatorImg != null)
|
|||
|
{
|
|||
|
headingIndicatorImg.raycastTarget = false;
|
|||
|
headingIndicatorImg.preserveAspect = true;
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.GetOrCreateHeading() - could not add indicator to Heading panel"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or Hide the scrollable Heading on the HUD. Turn on HUD if required.
|
|||
|
/// </summary>
|
|||
|
/// <param name="isShown"></param>
|
|||
|
private void ShowOrHideHeading(bool isShown)
|
|||
|
{
|
|||
|
if (IsInitialised || IsEditorMode)
|
|||
|
{
|
|||
|
showHeading = isShown;
|
|||
|
|
|||
|
if (headingRectTfrm != null) { headingRectTfrm.gameObject.SetActive(showHeading); }
|
|||
|
|
|||
|
if (headingScrollImg != null)
|
|||
|
{
|
|||
|
headingScrollImg.enabled = isShown;
|
|||
|
isHeadingScrolling = isShown;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
isHeadingScrolling = false;
|
|||
|
}
|
|||
|
|
|||
|
if (showHeading && !IsHUDShown) { ShowOrHideHUD(true); }
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or Hide the small Heading indicator on the HUD.
|
|||
|
/// </summary>
|
|||
|
/// <param name="isShown"></param>
|
|||
|
private void ShowOrHideHeadingIndicator(bool isShown)
|
|||
|
{
|
|||
|
if (IsInitialised || IsEditorMode)
|
|||
|
{
|
|||
|
showHeadingIndicator = isShown;
|
|||
|
|
|||
|
if (headingIndicatorImg != null)
|
|||
|
{
|
|||
|
headingIndicatorImg.enabled = isShown;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Private or Internal Methods - Messages
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Cache the DisplayMessage RectTransform, Image and Text component.
|
|||
|
/// Set the Text colour.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
/// <param name="hudRectTfrm"></param>
|
|||
|
private void InitialiseMessage(DisplayMessage displayMessage, RectTransform hudRectTfrm)
|
|||
|
{
|
|||
|
displayMessage.CachedMessagePanel = GetMessagePanel(displayMessage.guidHash, hudRectTfrm);
|
|||
|
|
|||
|
displayMessage.scrollDirectionInt = (int)displayMessage.scrollDirection;
|
|||
|
displayMessage.scrollOffsetX = 0f;
|
|||
|
displayMessage.scrollOffsetY = 0f;
|
|||
|
|
|||
|
if (displayMessage.CachedMessagePanel != null)
|
|||
|
{
|
|||
|
displayMessage.CachedBgImgComponent = displayMessage.CachedMessagePanel.GetComponent<Image>();
|
|||
|
|
|||
|
if (displayMessage.CachedBgImgComponent != null)
|
|||
|
{
|
|||
|
displayMessage.CachedBgImgComponent.enabled = displayMessage.showBackground;
|
|||
|
}
|
|||
|
|
|||
|
// Cache the message Text component
|
|||
|
if (tempTextList == null) { tempTextList = new List<Text>(1); }
|
|||
|
displayMessage.CachedMessagePanel.GetComponentsInChildren(tempTextList);
|
|||
|
if (tempTextList.Count > 0)
|
|||
|
{
|
|||
|
displayMessage.CachedTextComponent = tempTextList[0];
|
|||
|
}
|
|||
|
|
|||
|
// SetDisplayMessageBackgroundColour does not update the baseBackgroundColour if the backgroundColour has not changed. So do it in here instead
|
|||
|
displayMessage.baseBackgroundColour.Set(displayMessage.backgroundColour.r, displayMessage.backgroundColour.g, displayMessage.backgroundColour.b, displayMessage.backgroundColour.a, true);
|
|||
|
SetDisplayMessageBackgroundBrightness(displayMessage);
|
|||
|
|
|||
|
// SetDisplayMessageTextColour does not update the baseTextColour if the textColour has not changed. So do it in here instead
|
|||
|
displayMessage.baseTextColour.Set(displayMessage.textColour.r, displayMessage.textColour.g, displayMessage.textColour.b, displayMessage.textColour.a, true);
|
|||
|
SetDisplayMessageTextBrightness(displayMessage);
|
|||
|
|
|||
|
SetDisplayMessageText(displayMessage, displayMessage.messageString);
|
|||
|
SetDisplayMessageTextAlignment(displayMessage, displayMessage.textAlignment);
|
|||
|
SetDisplayMessageTextFontSize(displayMessage, displayMessage.isBestFit, displayMessage.fontMinSize, displayMessage.fontMaxSize);
|
|||
|
SetDisplayMessageSize(displayMessage, displayMessage.displayWidth, displayMessage.displayHeight);
|
|||
|
|
|||
|
if (displayMessage.scrollDirectionInt != DisplayMessage.ScrollDirectionNone)
|
|||
|
{
|
|||
|
// scrollWidth/Height should be the same as those used in ScrollMessage(..)
|
|||
|
// The left/right and top/bottom scroll limits can be ignored OR can consider the width/height of the message.
|
|||
|
// Fullscreen scrolling = +/- half width of message + half the width of canvas
|
|||
|
float scrollWidth = displayMessage.isScrollFullscreen ? displayMessage.displayWidth * cvsResolutionHalf.x + cvsResolutionHalf.x : displayMessage.displayWidth * cvsResolutionFull.x;
|
|||
|
|
|||
|
// Fullscreen scrolling = +/- half height of message + half the height of canvas
|
|||
|
float scrollHeight = displayMessage.isScrollFullscreen ? displayMessage.displayHeight * cvsResolutionHalf.y + cvsResolutionHalf.y : displayMessage.displayHeight * cvsResolutionFull.y;
|
|||
|
|
|||
|
// Start at beginning of scrolling position (e.g. Offscreen left/right)
|
|||
|
if (displayMessage.scrollDirectionInt == DisplayMessage.ScrollDirectionLR)
|
|||
|
{
|
|||
|
displayMessage.scrollOffsetX = -scrollWidth;
|
|||
|
}
|
|||
|
else if (displayMessage.scrollDirectionInt == DisplayMessage.ScrollDirectionRL)
|
|||
|
{
|
|||
|
displayMessage.scrollOffsetX = scrollWidth;
|
|||
|
}
|
|||
|
if (displayMessage.scrollDirectionInt == DisplayMessage.ScrollDirectionBT)
|
|||
|
{
|
|||
|
displayMessage.scrollOffsetY = -scrollHeight;
|
|||
|
}
|
|||
|
else if (displayMessage.scrollDirectionInt == DisplayMessage.ScrollDirectionTB)
|
|||
|
{
|
|||
|
displayMessage.scrollOffsetY = scrollHeight;
|
|||
|
}
|
|||
|
}
|
|||
|
SetDisplayMessageOffset(displayMessage, displayMessage.offsetX, displayMessage.offsetY);
|
|||
|
|
|||
|
// By default messages are initialised off. This is to prevent them suddenly appearing when first created.
|
|||
|
if (Application.isPlaying)
|
|||
|
{
|
|||
|
displayMessage.CachedMessagePanel.gameObject.SetActive(false);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Initialise all the DisplayMessages by caching the RectTransforms.
|
|||
|
/// </summary>
|
|||
|
private void InitialiseMessages()
|
|||
|
{
|
|||
|
int _numDisplayMessages = GetNumberDisplayMessages;
|
|||
|
|
|||
|
if (_numDisplayMessages > 0)
|
|||
|
{
|
|||
|
RectTransform hudRectTfrm = GetHUDPanel();
|
|||
|
if (hudRectTfrm != null)
|
|||
|
{
|
|||
|
CheckHUDResize(false);
|
|||
|
for (int dmIdx = 0; dmIdx < _numDisplayMessages; dmIdx++)
|
|||
|
{
|
|||
|
InitialiseMessage(displayMessageList[dmIdx], hudRectTfrm);
|
|||
|
}
|
|||
|
|
|||
|
if (_numDisplayMessages > 0) { RefreshMessagesSortOrder(); }
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ShipDisplayModule.InitialiseMessages() - could not find HUD Panel"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or Hide the Display Message on the HUD. Turn on the HUD if required.
|
|||
|
/// When fading out a message, it isn't instantly turned off.
|
|||
|
/// Option to override the fade settings and instantly hide or show the message.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
/// <param name="isShown"></param>
|
|||
|
/// <param name="isOverrideFade"></param>
|
|||
|
private void ShowOrHideMessage(DisplayMessage displayMessage, bool isShown, bool isOverrideFade = false)
|
|||
|
{
|
|||
|
if (IsInitialised)
|
|||
|
{
|
|||
|
if (displayMessage.CachedMessagePanel != null)
|
|||
|
{
|
|||
|
if (isShown)
|
|||
|
{
|
|||
|
if (isOverrideFade)
|
|||
|
{
|
|||
|
displayMessage.fadeinTimer = 0f;
|
|||
|
}
|
|||
|
// Is a fade-out already in progress?
|
|||
|
else if (displayMessage.fadeoutDuration > 0f && displayMessage.fadeoutTimer > 0f)
|
|||
|
{
|
|||
|
// (1 - Normalise amount faded out) * fade in duration.
|
|||
|
displayMessage.fadeinTimer = (1f - (displayMessage.fadeoutTimer / displayMessage.fadeoutDuration)) * displayMessage.fadeinDuration;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
displayMessage.fadeinTimer = displayMessage.fadeinDuration;
|
|||
|
|
|||
|
if (displayMessage.fadeinTimer > 0f)
|
|||
|
{
|
|||
|
// Instantly update to avoid flashing the faded in message before Update() is called.
|
|||
|
SetDisplayMessageTextFade(displayMessage, false);
|
|||
|
if (displayMessage.showBackground)
|
|||
|
{
|
|||
|
SetDisplayMessageBackgroundFade(displayMessage, false);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Should never be fading out when turning the message on
|
|||
|
displayMessage.fadeoutTimer = 0f;
|
|||
|
}
|
|||
|
else if (isOverrideFade)
|
|||
|
{
|
|||
|
displayMessage.fadeoutTimer = 0f;
|
|||
|
}
|
|||
|
else if (displayMessage.fadeoutDuration > 0f)
|
|||
|
{
|
|||
|
// Is a fade-in already in progress?
|
|||
|
if (displayMessage.fadeinDuration > 0f && displayMessage.fadeinTimer > 0f)
|
|||
|
{
|
|||
|
// (1 - Normalise amount faded in) * fade out duration.
|
|||
|
displayMessage.fadeoutTimer = (1f - (displayMessage.fadeinTimer / displayMessage.fadeinDuration)) * displayMessage.fadeoutDuration;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
displayMessage.fadeoutTimer = displayMessage.fadeoutDuration;
|
|||
|
}
|
|||
|
|
|||
|
// Should never be fading in when turning the message off
|
|||
|
displayMessage.fadeinTimer = 0f;
|
|||
|
|
|||
|
// Override instantly turning off the message
|
|||
|
isShown = true;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
displayMessage.showMessage = false;
|
|||
|
}
|
|||
|
|
|||
|
displayMessage.showMessage = isShown;
|
|||
|
|
|||
|
displayMessage.CachedMessagePanel.gameObject.SetActive(isShown);
|
|||
|
}
|
|||
|
|
|||
|
if (isShown && !IsHUDShown) { ShowOrHideHUD(true); }
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or hide all messages.
|
|||
|
/// Option to override fade settings and instantly show or hide.
|
|||
|
/// </summary>
|
|||
|
/// <param name="isShown"></param>
|
|||
|
/// <param name="isOverrideFade"></param>
|
|||
|
private void ShowOrHideMessages(bool isShown, bool isOverrideFade = false)
|
|||
|
{
|
|||
|
if (IsInitialised)
|
|||
|
{
|
|||
|
for (int dmIdx = 0; dmIdx < numDisplayMessages; dmIdx++)
|
|||
|
{
|
|||
|
ShowOrHideMessage(displayMessageList[dmIdx], isShown, isOverrideFade);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or Hide all messages based on their current settings.
|
|||
|
/// This is called by
|
|||
|
/// </summary>
|
|||
|
private void ShowOrHideMessages()
|
|||
|
{
|
|||
|
if (IsInitialised)
|
|||
|
{
|
|||
|
for (int dmIdx = 0; dmIdx < numDisplayMessages; dmIdx++)
|
|||
|
{
|
|||
|
DisplayMessage displayMessage = displayMessageList[dmIdx];
|
|||
|
// Shown messages should fade in if required.
|
|||
|
// Hidden messages should be instantly hidden.
|
|||
|
ShowOrHideMessage(displayMessage, displayMessage.showMessage, !displayMessage.showMessage);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL USE ONLY]
|
|||
|
/// Find the Message RectTransform under the HUD in the hierarchy.
|
|||
|
/// If hudRectTrfm is null, it will attempt to find it.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
/// <param name="hudRectTrfm"></param>
|
|||
|
/// <returns></returns>
|
|||
|
private RectTransform GetMessagePanel(int guidHash, RectTransform hudRectTrfm)
|
|||
|
{
|
|||
|
if (hudRectTfrm == null) { hudRectTfrm = GetHUDPanel(); }
|
|||
|
if (hudRectTfrm != null)
|
|||
|
{
|
|||
|
return SSCUtils.GetChildRectTransform(hudRectTfrm.transform, "Message_" + guidHash, this.name);
|
|||
|
}
|
|||
|
else { return null; }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL USE ONLY]
|
|||
|
/// Create a new Message RectTransform under the HUD in the hierarchy
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
/// <param name="hudRectTfrm"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public RectTransform CreateMessagePanel(DisplayMessage displayMessage, RectTransform hudRectTfrm)
|
|||
|
{
|
|||
|
RectTransform messagePanel = null;
|
|||
|
|
|||
|
if (displayMessage != null)
|
|||
|
{
|
|||
|
float panelWidth = displayMessage.displayWidth;
|
|||
|
float panelHeight = displayMessage.displayHeight;
|
|||
|
|
|||
|
//Canvas _canvas = GetCanvas;
|
|||
|
//Vector3 _canvasScale = _canvas == null ? Vector3.one : _canvas.transform.localScale;
|
|||
|
|
|||
|
if (IsInitialised) { numDisplayMessages++; }
|
|||
|
messagePanel = SSCUtils.GetOrCreateChildRectTransform(hudRectTfrm, cvsResolutionFull, "Message_" + displayMessage.guidHash, 0f, 0f,
|
|||
|
panelWidth, panelHeight, 0.5f, 0.5f, 0.5f, 0.5f);
|
|||
|
|
|||
|
if (messagePanel != null)
|
|||
|
{
|
|||
|
Image imgComponent = messagePanel.gameObject.AddComponent<Image>();
|
|||
|
if (imgComponent != null)
|
|||
|
{
|
|||
|
imgComponent.raycastTarget = false;
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.CreateMessagePanel() - could not add background to Message panel"); }
|
|||
|
#endif
|
|||
|
|
|||
|
RectTransform messageTxtPanel = SSCUtils.GetOrCreateChildRectTransform(messagePanel, cvsResolutionFull, "MessageText", 0f, 0f,
|
|||
|
panelWidth, panelHeight, 0.5f, 0.5f, 0.5f, 0.5f);
|
|||
|
|
|||
|
if (messageTxtPanel != null)
|
|||
|
{
|
|||
|
Text textComponent = messageTxtPanel.gameObject.AddComponent<Text>();
|
|||
|
if (textComponent != null)
|
|||
|
{
|
|||
|
textComponent.raycastTarget = false;
|
|||
|
textComponent.resizeTextForBestFit = true;
|
|||
|
// Text is addd in InitialiseMessage().
|
|||
|
textComponent.text = string.Empty;
|
|||
|
if (Application.isPlaying)
|
|||
|
{
|
|||
|
textComponent.font = SSCUtils.GetDefaultFont();
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.CreateMessagePanel() - could not add text to Message panel"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
if (IsInitialised || editorMode) { InitialiseMessage(displayMessage, hudRectTfrm); }
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.CreateMessagePanel() - could not create Message panel"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: ShipDisplayModule.CreateMessagePanel() - displayMessage is null"); }
|
|||
|
#endif
|
|||
|
|
|||
|
return messagePanel;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or hide the message background by enabling or disabling the image script
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
/// <param name="isShown"></param>
|
|||
|
private void ShowOrHideDisplayMessageBackground(DisplayMessage displayMessage, bool isShown)
|
|||
|
{
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
if (!editorMode) { displayMessage.showBackground = isShown; }
|
|||
|
displayMessage.CachedBgImgComponent.enabled = isShown;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Scroll message across the display. Assumes module is initialised, message is not null,
|
|||
|
/// and scrollDirection is not None.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
private void ScrollMessage(DisplayMessage displayMessage)
|
|||
|
{
|
|||
|
if (displayMessage.showMessage)
|
|||
|
{
|
|||
|
// Determine the distance to scroll
|
|||
|
float scrollFactor = displayMessage.scrollSpeed * Time.deltaTime * canvas.scaleFactor * 0.1f;
|
|||
|
float deltaX = scrollFactor * cvsResolutionFull.x;
|
|||
|
float deltaY = scrollFactor * cvsResolutionFull.y;
|
|||
|
|
|||
|
// scrollWidth/Height should be the same as starting positions set in InitialiseMessage(..)
|
|||
|
// The left/right and top/bottom scroll limits can be ignored OR can consider the width/height of the message.
|
|||
|
// Fullscreen scrolling = +/- half width of message + half the width of canvas
|
|||
|
float scrollWidth = displayMessage.isScrollFullscreen ? displayMessage.displayWidth * cvsResolutionHalf.x + cvsResolutionHalf.x : displayMessage.displayWidth * cvsResolutionFull.x;
|
|||
|
|
|||
|
// Fullscreen scrolling = +/- half height of message + half the height of canvas
|
|||
|
float scrollHeight = displayMessage.isScrollFullscreen ? displayMessage.displayHeight * cvsResolutionHalf.y + cvsResolutionHalf.y : displayMessage.displayHeight * cvsResolutionFull.y;
|
|||
|
|
|||
|
// Calc the localPosition of the message
|
|||
|
tempMessageOffset.x = displayMessage.offsetX * cvsResolutionHalf.x;
|
|||
|
tempMessageOffset.y = displayMessage.offsetY * cvsResolutionHalf.y;
|
|||
|
|
|||
|
if (displayMessage.scrollDirectionInt == DisplayMessage.ScrollDirectionLR)
|
|||
|
{
|
|||
|
if (displayMessage.isScrollFullscreen) { tempMessageOffset.x = 0f; }
|
|||
|
displayMessage.scrollOffsetX += deltaX;
|
|||
|
displayMessage.scrollOffsetY = 0f;
|
|||
|
|
|||
|
if (displayMessage.scrollOffsetX > scrollWidth) { displayMessage.scrollOffsetX = -scrollWidth; }
|
|||
|
}
|
|||
|
else if (displayMessage.scrollDirectionInt == DisplayMessage.ScrollDirectionRL)
|
|||
|
{
|
|||
|
if (displayMessage.isScrollFullscreen) { tempMessageOffset.x = 0f; }
|
|||
|
displayMessage.scrollOffsetX -= deltaX;
|
|||
|
displayMessage.scrollOffsetY = 0f;
|
|||
|
|
|||
|
if (displayMessage.scrollOffsetX < -scrollWidth) { displayMessage.scrollOffsetX = scrollWidth; }
|
|||
|
}
|
|||
|
else if (displayMessage.scrollDirectionInt == DisplayMessage.ScrollDirectionBT)
|
|||
|
{
|
|||
|
if (displayMessage.isScrollFullscreen) { tempMessageOffset.y = 0f; }
|
|||
|
displayMessage.scrollOffsetX = 0f;
|
|||
|
displayMessage.scrollOffsetY += deltaY;
|
|||
|
|
|||
|
if (displayMessage.scrollOffsetY > scrollHeight) { displayMessage.scrollOffsetY = -scrollHeight; }
|
|||
|
}
|
|||
|
else // Top to Bottom
|
|||
|
{
|
|||
|
if (displayMessage.isScrollFullscreen) { tempMessageOffset.y = 0f; }
|
|||
|
displayMessage.scrollOffsetX = 0f;
|
|||
|
displayMessage.scrollOffsetY -= deltaY;
|
|||
|
|
|||
|
if (displayMessage.scrollOffsetY < -scrollHeight) { displayMessage.scrollOffsetY = scrollHeight; }
|
|||
|
}
|
|||
|
|
|||
|
Transform dmTrfm = displayMessage.CachedMessagePanel.transform;
|
|||
|
|
|||
|
tempMessageOffset.x += displayMessage.scrollOffsetX;
|
|||
|
tempMessageOffset.y += displayMessage.scrollOffsetY;
|
|||
|
tempMessageOffset.z = dmTrfm.localPosition.z;
|
|||
|
dmTrfm.localPosition = tempMessageOffset;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Private or Internal Methods - Targets
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL USE ONLY]
|
|||
|
/// Create a new Target RectTransform under the HUD in the hierarchy for the give slot
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayTarget"></param>
|
|||
|
/// <param name="slotIndex"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public RectTransform CreateTargetPanel(DisplayTarget displayTarget, int slotIndex)
|
|||
|
{
|
|||
|
RectTransform targetPanel = null;
|
|||
|
|
|||
|
if (targetsRectTfrm == null) { targetsRectTfrm = GetTargetsPanel(); }
|
|||
|
|
|||
|
if (displayTarget != null && targetsRectTfrm != null)
|
|||
|
{
|
|||
|
if (slotIndex >= 0 && slotIndex < DisplayTarget.MAX_DISPLAYTARGET_SLOTS)
|
|||
|
{
|
|||
|
// Convert into 0.0 to 1.0 value. The width/height values assume default 1920x1080.
|
|||
|
float panelWidth = displayTarget.width / refResolution.x;
|
|||
|
float panelHeight = displayTarget.height / refResolution.y;
|
|||
|
|
|||
|
//if (IsInitialised && slotIndex == 0) { numDisplayTargets++; }
|
|||
|
targetPanel = SSCUtils.GetOrCreateChildRectTransform(targetsRectTfrm, cvsResolutionFull, "Target_" + displayTarget.guidHash + "_" + slotIndex.ToString(), 0f, 0f,
|
|||
|
panelWidth, panelHeight, 0.5f, 0.5f, 0.5f, 0.5f);
|
|||
|
|
|||
|
if (targetPanel != null)
|
|||
|
{
|
|||
|
Image imgComponent = targetPanel.gameObject.AddComponent<Image>();
|
|||
|
if (imgComponent != null)
|
|||
|
{
|
|||
|
imgComponent.raycastTarget = false;
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.CreateTargetPanel() - could not add image to Target panel"); }
|
|||
|
#endif
|
|||
|
|
|||
|
if ((IsInitialised || editorMode) && !displayTarget.isInitialised) { InitialiseTarget(displayTarget); }
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.CreateTargetPanel() - could not create Target panel"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.CreateTargetPanel() - could not create Target panel. Slot number is outside the range 0 to " + DisplayTarget.MAX_DISPLAYTARGET_SLOTS.ToString()); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: ShipDisplayModule.CreateTargetPanel() - displayTarget is null or could not find or create " + targetsPanelName); }
|
|||
|
#endif
|
|||
|
|
|||
|
return targetPanel;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL USE ONLY]
|
|||
|
/// Find the Target RectTransform under the HUD in the hierarchy.
|
|||
|
/// If the parent targetsRectTfrm is null, it will attempt to find or create it.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
/// <param name="slotIndex"></param>
|
|||
|
/// <returns></returns>
|
|||
|
private RectTransform GetTargetPanel(int guidHash, int slotIndex)
|
|||
|
{
|
|||
|
if (targetsRectTfrm == null) { targetsRectTfrm = GetTargetsPanel(); }
|
|||
|
if (targetsRectTfrm != null)
|
|||
|
{
|
|||
|
return SSCUtils.GetChildRectTransform(targetsRectTfrm.transform, "Target_" + guidHash + "_" + slotIndex, this.name);
|
|||
|
}
|
|||
|
else { return null; }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// [INTERNAL ONLY]
|
|||
|
/// Used by the editor when moving DisplayTargets around in the list.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayTargetIndex"></param>
|
|||
|
public void RefreshDisplayTargetSlots()
|
|||
|
{
|
|||
|
numDisplayTargets = displayTargetList == null ? 0 : displayTargetList.Count;
|
|||
|
|
|||
|
for (int dtIdx = 0; dtIdx < numDisplayTargets; dtIdx++)
|
|||
|
{
|
|||
|
DisplayTarget displayTarget = displayTargetList[dtIdx];
|
|||
|
|
|||
|
// Initialise the Display Target slots
|
|||
|
displayTarget.displayTargetSlotList = new List<DisplayTargetSlot>(displayTarget.maxNumberOfTargets);
|
|||
|
|
|||
|
for (int slotIdx = 0; slotIdx < displayTarget.maxNumberOfTargets; slotIdx++)
|
|||
|
{
|
|||
|
DisplayTargetSlot displayTargetSlot = InitialiseTargetSlot(displayTarget, slotIdx);
|
|||
|
|
|||
|
displayTarget.displayTargetSlotList.Add(displayTargetSlot);
|
|||
|
}
|
|||
|
|
|||
|
// InitialiseTargetSlot will turn all the reticles off, so update the DisplayTarget property too
|
|||
|
displayTarget.showTarget = false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Initialise the display target
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayTarget"></param>
|
|||
|
/// <param name="hudRectTfrm"></param>
|
|||
|
private void InitialiseTarget(DisplayTarget displayTarget)
|
|||
|
{
|
|||
|
if (displayTarget.maxNumberOfTargets < 0) { displayTarget.maxNumberOfTargets = 1; }
|
|||
|
else if (displayTarget.maxNumberOfTargets > DisplayTarget.MAX_DISPLAYTARGET_SLOTS) { displayTarget.maxNumberOfTargets = DisplayTarget.MAX_DISPLAYTARGET_SLOTS; }
|
|||
|
|
|||
|
// Initialise the Display Target slots
|
|||
|
displayTarget.displayTargetSlotList = new List<DisplayTargetSlot>(displayTarget.maxNumberOfTargets);
|
|||
|
|
|||
|
for (int slotIdx = 0; slotIdx < displayTarget.maxNumberOfTargets; slotIdx++)
|
|||
|
{
|
|||
|
DisplayTargetSlot displayTargetSlot = InitialiseTargetSlot(displayTarget, slotIdx);
|
|||
|
|
|||
|
displayTarget.displayTargetSlotList.Add(displayTargetSlot);
|
|||
|
}
|
|||
|
|
|||
|
SetDisplayTargetSize(displayTarget, displayTarget.width, displayTarget.height);
|
|||
|
|
|||
|
// SetDisplayTargetReticleColour does not update the baseReticleColour if the reticleColour has not changed. So do it in here instead
|
|||
|
displayTarget.baseReticleColour.Set(displayTarget.reticleColour.r, displayTarget.reticleColour.g, displayTarget.reticleColour.b, displayTarget.reticleColour.a, true);
|
|||
|
SetDisplayTargetBrightness(displayTarget);
|
|||
|
|
|||
|
displayTarget.isInitialised = true;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Initialise a DisplayTarget Slot. This includes:
|
|||
|
/// 1. caching the panel and image component
|
|||
|
/// 2. Loading the reticle sprite
|
|||
|
/// 3. Setting the offset to 0,0
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayTarget"></param>
|
|||
|
/// <param name="slotIdx"></param>
|
|||
|
/// <returns></returns>
|
|||
|
private DisplayTargetSlot InitialiseTargetSlot(DisplayTarget displayTarget, int slotIdx)
|
|||
|
{
|
|||
|
DisplayTargetSlot displayTargetSlot = new DisplayTargetSlot();
|
|||
|
|
|||
|
displayTargetSlot.CachedTargetPanel = GetTargetPanel(displayTarget.guidHash, slotIdx);
|
|||
|
|
|||
|
if (displayTargetSlot.CachedTargetPanel != null)
|
|||
|
{
|
|||
|
displayTargetSlot.CachedImgComponent = displayTargetSlot.CachedTargetPanel.GetComponent<Image>();
|
|||
|
|
|||
|
// Add the Reticle sprite to the image for this Display Target
|
|||
|
if (displayTargetSlot.CachedImgComponent != null)
|
|||
|
{
|
|||
|
// TODO - consider getting the sprite only once per DisplayTarget
|
|||
|
displayTargetSlot.CachedImgComponent.sprite = GetDisplayReticleSprite(displayTarget.guidHashDisplayReticle);
|
|||
|
}
|
|||
|
|
|||
|
SetDisplayTargetOffset(displayTargetSlot, 0f, 0f);
|
|||
|
|
|||
|
// By default targets are initialised off. This is to prevent them suddenly appearing when first created.
|
|||
|
if (Application.isPlaying)
|
|||
|
{
|
|||
|
displayTargetSlot.showTargetSlot = false;
|
|||
|
displayTargetSlot.CachedTargetPanel.gameObject.SetActive(false);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return displayTargetSlot;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Initialise all the DisplayTargets by caching the RectTransforms.
|
|||
|
/// </summary>
|
|||
|
private void InitialiseTargets()
|
|||
|
{
|
|||
|
int _numDisplayTargets = GetNumberDisplayTargets;
|
|||
|
|
|||
|
if (_numDisplayTargets > 0)
|
|||
|
{
|
|||
|
if (targetsRectTfrm == null) { targetsRectTfrm = GetTargetsPanel(); }
|
|||
|
if (targetsRectTfrm != null)
|
|||
|
{
|
|||
|
CheckHUDResize(false);
|
|||
|
|
|||
|
for (int dmIdx = 0; dmIdx < _numDisplayTargets; dmIdx++)
|
|||
|
{
|
|||
|
InitialiseTarget(displayTargetList[dmIdx]);
|
|||
|
}
|
|||
|
|
|||
|
if (_numDisplayTargets > 0) { RefreshTargetsSortOrder(); }
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ShipDisplayModule.InitialiseTargets() - could not find " + targetsPanelName); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or Hide DisplayTarget slot on the HUD.
|
|||
|
/// By design, if the HUD is not shown, the Target slot will not be show.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayTargetSlot"></param>
|
|||
|
/// <param name="isShown"></param>
|
|||
|
private void ShowOrHideTargetSlot(DisplayTargetSlot displayTargetSlot, bool isShown)
|
|||
|
{
|
|||
|
if ((IsInitialised || editorMode) && displayTargetSlot != null && displayTargetSlot.CachedTargetPanel != null)
|
|||
|
{
|
|||
|
displayTargetSlot.showTargetSlot = isShown;
|
|||
|
displayTargetSlot.CachedTargetPanel.gameObject.SetActive(isShown);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or Hide all slots of a Display Target on the HUD.
|
|||
|
/// By design, if the HUD is not shown, the Targets will not be show.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayTarget"></param>
|
|||
|
/// <param name="isShown"></param>
|
|||
|
private void ShowOrHideTarget(DisplayTarget displayTarget, bool isShown)
|
|||
|
{
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
displayTarget.showTarget = isShown;
|
|||
|
|
|||
|
for (int sIdx = 0; sIdx < displayTarget.maxNumberOfTargets; sIdx++)
|
|||
|
{
|
|||
|
ShowOrHideTargetSlot(displayTarget.displayTargetSlotList[sIdx], isShown);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or hide all targets
|
|||
|
/// </summary>
|
|||
|
/// <param name="isShown"></param>
|
|||
|
private void ShowOrHideTargets(bool isShown)
|
|||
|
{
|
|||
|
if (IsInitialised)
|
|||
|
{
|
|||
|
for (int dmIdx = 0; dmIdx < numDisplayTargets; dmIdx++)
|
|||
|
{
|
|||
|
ShowOrHideTarget(displayTargetList[dmIdx], isShown);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or Hide all targets based on their current settings
|
|||
|
/// </summary>
|
|||
|
private void ShowOrHideTargets()
|
|||
|
{
|
|||
|
if (IsInitialised)
|
|||
|
{
|
|||
|
for (int dmIdx = 0; dmIdx < numDisplayTargets; dmIdx++)
|
|||
|
{
|
|||
|
DisplayTarget displayTarget = displayTargetList[dmIdx];
|
|||
|
ShowOrHideTarget(displayTarget, displayTarget.showTarget);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Update the position on the HUD for each of the Display Target slots
|
|||
|
/// that are shown.
|
|||
|
/// </summary>
|
|||
|
private void UpdateTargetPositions()
|
|||
|
{
|
|||
|
if (IsInitialised)
|
|||
|
{
|
|||
|
if (sscRadar == null) { sscRadar = SSCRadar.GetOrCreateRadar(); }
|
|||
|
|
|||
|
if (sscRadar != null)
|
|||
|
{
|
|||
|
// Loop through the display targets
|
|||
|
for (int dtgtIdx = 0; dtgtIdx < numDisplayTargets; dtgtIdx++)
|
|||
|
{
|
|||
|
DisplayTarget displayTarget = displayTargetList[dtgtIdx];
|
|||
|
|
|||
|
if (displayTarget.showTarget)
|
|||
|
{
|
|||
|
// Loop through the display target slots
|
|||
|
for (int slotIdx = 0; slotIdx < displayTarget.maxNumberOfTargets; slotIdx++)
|
|||
|
{
|
|||
|
DisplayTargetSlot displayTargetSlot = displayTarget.displayTargetSlotList[slotIdx];
|
|||
|
|
|||
|
if (displayTargetSlot.radarItemKey.radarItemIndex >= 0 && displayTargetSlot.showTargetSlot)
|
|||
|
{
|
|||
|
SSCRadarItem radarItem = sscRadar.GetRadarItem(displayTargetSlot.radarItemKey);
|
|||
|
|
|||
|
if (radarItem != null)
|
|||
|
{
|
|||
|
SetDisplayTargetPosition(displayTarget, slotIdx, radarItem.position);
|
|||
|
}
|
|||
|
//#if UNITY_EDITOR
|
|||
|
//else
|
|||
|
//{
|
|||
|
// // This could be a timing issue
|
|||
|
// Debug.LogWarning("ShipDisplayModule.UpdateTargetPositions - could not find radar item with index " + displayTargetSlot.radarItemKey.radarItemIndex + " for DisplayTarget " + (dtgtIdx+1).ToString("000") + " slot " + slotIdx);
|
|||
|
//}
|
|||
|
//#endif
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public API Methods - General
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Initialise the ShipDisplayModule. Either set initialiseOnStart to false and call this
|
|||
|
/// method in your code, or set initialiseOnStart to true in the inspector and don't call
|
|||
|
/// this method.
|
|||
|
/// </summary>
|
|||
|
public void Initialise()
|
|||
|
{
|
|||
|
// calling this method twice may incorrectly set the positions of the Altitude and speed panels.
|
|||
|
if (IsInitialised) { return; }
|
|||
|
|
|||
|
canvas = GetComponent<Canvas>();
|
|||
|
canvasScaler = GetComponent<CanvasScaler>();
|
|||
|
|
|||
|
hudRectTfrm = SSCUtils.GetChildRectTransform(transform, hudPanelName, this.name);
|
|||
|
|
|||
|
if (canvas != null && hudRectTfrm != null)
|
|||
|
{
|
|||
|
canvas.sortingOrder = canvasSortOrder;
|
|||
|
|
|||
|
// Get the reference resolution from the canvas scaler. If it hasn't been changed this should
|
|||
|
// always be 1920x1080 for SSC.
|
|||
|
//if (canvasScaler != null) { refResolutionFull = canvasScaler.referenceResolution; }
|
|||
|
//else { refResolutionFull.x = 1920f; refResolutionFull.y = 1080f; }
|
|||
|
|
|||
|
// use the scaled size rather than the original reference resolution size.
|
|||
|
CheckHUDResize(false);
|
|||
|
|
|||
|
GetHUDPanels();
|
|||
|
|
|||
|
if (reticlePanel != null && overlayPanel != null && altitudeTextRectTfrm != null && airspeedTextRectTfrm != null)
|
|||
|
{
|
|||
|
GetImgComponents();
|
|||
|
GetTextComponents();
|
|||
|
|
|||
|
// Store the starting position of the Altitude text
|
|||
|
altitudeInitPosition = altitudeTextRectTfrm.localPosition;
|
|||
|
altitudeCurrentPosition = altitudeInitPosition;
|
|||
|
// Initialise the string used to store the Altitude value and reduce GC.
|
|||
|
altitudeString = new SCSMString(6);
|
|||
|
altitudeString.SetMaxIntLength(6);
|
|||
|
|
|||
|
// Store the starting position of the Air speed text
|
|||
|
airspeedInitPosition = airspeedTextRectTfrm.localPosition;
|
|||
|
airspeedCurrentPosition = airspeedInitPosition;
|
|||
|
// Initialise the string used to store the Airspeed value and reduce GC.
|
|||
|
airspeedString = new SCSMString(6);
|
|||
|
airspeedString.SetMaxIntLength(6);
|
|||
|
|
|||
|
// Create an empty array of integers to use when processing
|
|||
|
tempIncludeFactionList = new List<int>(20);
|
|||
|
tempIncludeSquadronList = new List<int>(20);
|
|||
|
|
|||
|
InitialiseAttitude(true);
|
|||
|
InitialiseHeading(true);
|
|||
|
|
|||
|
ReinitialiseVariables();
|
|||
|
|
|||
|
hudRandom = new SSCRandom();
|
|||
|
// Set the seed to an arbitary prime number (but it could be anything really)
|
|||
|
if (hudRandom != null) { hudRandom.SetSeed(691); }
|
|||
|
flickerHistory = new Queue<float>(5);
|
|||
|
|
|||
|
#if UNITY_EDITOR
|
|||
|
if (!isMainCameraAssigned) { Debug.LogWarning("ShipDisplayModule could not find a camera with the MainCamera tag set"); }
|
|||
|
#endif
|
|||
|
|
|||
|
IsInitialised = displayReticleImg != null && isMainCameraAssigned;
|
|||
|
|
|||
|
RefreshHUD();
|
|||
|
|
|||
|
if (isShowHUDWithFlicker && isShowOnInitialise) { FlickerOn(flickerDefaultDuration); }
|
|||
|
else { ShowOrHideHUD(isShowOnInitialise); }
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: ShipDisplayModule.Initialise() could not find canvas HUDPanel. Did you start with the sample HUD prefab from Prefabs/Visuals folder?"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Check to see if the ship is the same as the sourceShip currently assigned to the HUD.
|
|||
|
/// If either are null, the method will return false.
|
|||
|
/// </summary>
|
|||
|
/// <param name="shipControlModule"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public bool IsSourceShip(ShipControlModule shipControlModule)
|
|||
|
{
|
|||
|
if (sourceShip == null || shipControlModule == null) { return false; }
|
|||
|
else { return shipControlModule.GetShipId == sourceShip.GetShipId; }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Check to see if the ship is the same as the soureShip currently assigned to the HUD.
|
|||
|
/// If either are null, the method will return false.
|
|||
|
/// </summary>
|
|||
|
/// <param name="ship"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public bool IsSourceShip(Ship ship)
|
|||
|
{
|
|||
|
if (sourceShip == null || ship == null) { return false; }
|
|||
|
else { return ship.shipId == sourceShip.GetShipId; }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Call this if you modify any of the following at runtime.
|
|||
|
/// 1) displayReticleList
|
|||
|
/// 2) The DisplayReticlePanel size
|
|||
|
/// 3) Add or remove the MainCamera tag from a camera
|
|||
|
/// 4) displayMessageList
|
|||
|
/// 5) displayTargetList
|
|||
|
/// </summary>
|
|||
|
public void ReinitialiseVariables()
|
|||
|
{
|
|||
|
ValidateReticleList();
|
|||
|
numDisplayReticles = displayReticleList == null ? 0 : displayReticleList.Count;
|
|||
|
|
|||
|
if (reticlePanel != null)
|
|||
|
{
|
|||
|
RectTransform reticleRectTransform = reticlePanel.GetComponent<RectTransform>();
|
|||
|
if (reticleRectTransform != null)
|
|||
|
{
|
|||
|
reticleWidth = reticleRectTransform.sizeDelta.x;
|
|||
|
reticleHeight = reticleRectTransform.sizeDelta.y;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// If the camera hasn't been assigned, attempt to use the first camera with the MainCamera tag.
|
|||
|
if (mainCamera == null && Camera.main != null) { mainCamera = Camera.main; }
|
|||
|
|
|||
|
isMainCameraAssigned = mainCamera != null;
|
|||
|
|
|||
|
ValidateGaugeList();
|
|||
|
numDisplayGauges = displayGaugeList == null ? 0 : displayGaugeList.Count;
|
|||
|
|
|||
|
ValidateMessageList();
|
|||
|
numDisplayMessages = displayMessageList == null ? 0 : displayMessageList.Count;
|
|||
|
|
|||
|
ValidateTargetList();
|
|||
|
numDisplayTargets = displayTargetList == null ? 0 : displayTargetList.Count;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Refresh all components of the HUD. Typically called after the screen has been resized.
|
|||
|
/// </summary>
|
|||
|
public void RefreshHUD()
|
|||
|
{
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
// Set the initial position
|
|||
|
SetDisplayReticleOffset(displayReticleOffsetX, displayReticleOffsetY);
|
|||
|
|
|||
|
SetHUDSize(displayWidth, displayHeight);
|
|||
|
SetHUDOffset(displayOffsetX, displayOffsetY);
|
|||
|
|
|||
|
// Show or Hide initial setup
|
|||
|
ShowOrHideReticle(showActiveDisplayReticle);
|
|||
|
ShowOrHideAltitude(showAltitude);
|
|||
|
SetPrimaryColour(primaryColour);
|
|||
|
SetDisplayReticleColour(activeDisplayReticleColour);
|
|||
|
SetAltitudeTextColour(altitudeTextColour);
|
|||
|
ShowOrHideAirSpeed(showAirspeed);
|
|||
|
SetAirSpeedTextColour(airspeedTextColour);
|
|||
|
ShowOrHideOverlay(showOverlay);
|
|||
|
InitialiseAttitude(false);
|
|||
|
ShowOrHideAttitude(showAttitude);
|
|||
|
InitialiseHeading(false);
|
|||
|
ShowOrHideHeading(showHeading);
|
|||
|
InitialiseMessages();
|
|||
|
ShowOrHideMessages();
|
|||
|
InitialiseTargets();
|
|||
|
ShowOrHideTargets();
|
|||
|
InitialiseGauges();
|
|||
|
ShowOrHideGauges();
|
|||
|
|
|||
|
// Set brightness after the colours have been set.
|
|||
|
InitialiseBrightness();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show the heads-up display. Has no effect if IsInitialised is false.
|
|||
|
/// </summary>
|
|||
|
public void ShowHUD()
|
|||
|
{
|
|||
|
// Prob makes sense to start in a non-flickering state.
|
|||
|
StopFlickering();
|
|||
|
|
|||
|
if (isShowHUDWithFlicker) { FlickerOn(flickerDefaultDuration); }
|
|||
|
else { ShowOrHideHUD(true); }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Hide the heads-up display. Has no effect if IsInitialised is false.
|
|||
|
/// </summary>
|
|||
|
public void HideHUD()
|
|||
|
{
|
|||
|
// Prob makes sense to start in a non-flickering state.
|
|||
|
StopFlickering();
|
|||
|
|
|||
|
if (isHideHUDWithFlicker) { FlickerOff(flickerDefaultDuration); }
|
|||
|
else { ShowOrHideHUD(false); }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show the Overlay image on the heads-up display. Has no effect if IsInitialised is false.
|
|||
|
/// </summary>
|
|||
|
public void ShowOverlay()
|
|||
|
{
|
|||
|
ShowOrHideOverlay(true);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Hide the Overlay image on the heads-up display. Has no effect if IsInitialised is false.
|
|||
|
/// </summary>
|
|||
|
public void HideOverlay()
|
|||
|
{
|
|||
|
ShowOrHideOverlay(false);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set or assign the main camera used by the heads-up display for calculations.
|
|||
|
/// </summary>
|
|||
|
/// <param name="camera"></param>
|
|||
|
public void SetCamera(Camera camera)
|
|||
|
{
|
|||
|
mainCamera = camera;
|
|||
|
isMainCameraAssigned = camera != null;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the HUD to use a particular display. Displays or monitors are numbered from 1 to 8.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayNumber">1 to 8</param>
|
|||
|
public void SetCanvasTargetDisplay (int displayNumber)
|
|||
|
{
|
|||
|
if (IsInitialised && SSCUtils.VerifyTargetDisplay(displayNumber, true))
|
|||
|
{
|
|||
|
Canvas _canvas = GetCanvas;
|
|||
|
|
|||
|
if (_canvas != null) { _canvas.targetDisplay = displayNumber - 1; }
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the offset (position) of the HUD.
|
|||
|
/// If the module has been initialised, this will also re-position the HUD.
|
|||
|
/// </summary>
|
|||
|
/// <param name="offsetX">Horizontal offset from centre. Range between -1 and 1</param>
|
|||
|
/// <param name="offsetY">Vertical offset from centre. Range between -1 and 1</param>
|
|||
|
public void SetHUDOffset(float offsetX, float offsetY)
|
|||
|
{
|
|||
|
// Clamp the x,y values -1 to 1.
|
|||
|
if (offsetX < -1f) { displayOffsetX = -1f; }
|
|||
|
else if (offsetX > 1f) { displayOffsetX = 1f; }
|
|||
|
else { if (offsetX != displayOffsetX) { displayOffsetX = offsetX; } }
|
|||
|
|
|||
|
if (offsetY < -1f) { displayOffsetY = -1f; }
|
|||
|
else if (offsetY > 1f) { displayOffsetY = 1f; }
|
|||
|
else { if (offsetY != displayOffsetY) { displayOffsetY = offsetY; } }
|
|||
|
|
|||
|
if (IsInitialised)
|
|||
|
{
|
|||
|
// Here we use the half original (reference) HUD size as it doesn't need to be scaled in any way.
|
|||
|
// The parent HUD canvas is correctly scaled and sized to the actual monitor or device display.
|
|||
|
overlayPanel.localPosition = new Vector3(offsetX * cvsResolutionFull.x, offsetY * cvsResolutionFull.y, overlayPanel.localPosition.z);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the size of the HUD overlay image and text.
|
|||
|
/// If the module has been initialised, this will also resize the HUD.
|
|||
|
/// The values are only updated if they are outside the range 0.0 to 1.0 or have changed.
|
|||
|
/// </summary>
|
|||
|
/// <param name="width"></param>
|
|||
|
/// <param name="height"></param>
|
|||
|
public void SetHUDSize(float width, float height)
|
|||
|
{
|
|||
|
// Clamp the x,y values 0.0 to 1.0
|
|||
|
if (width < 0f) { displayWidth = 0f; }
|
|||
|
else if (width > 1f) { displayWidth = 1f; }
|
|||
|
else if (width != displayWidth) { displayWidth = width; }
|
|||
|
|
|||
|
if (height < 0f) { displayHeight = 0f; }
|
|||
|
else if (height > 1f) { displayHeight = 1f; }
|
|||
|
else if (height != displayHeight) { displayHeight = height; }
|
|||
|
|
|||
|
if (IsInitialised)
|
|||
|
{
|
|||
|
// Here we use the original (reference) HUD size as it doesn't need to be scaled in any way.
|
|||
|
// The parent HUD canvas is correctly scaled and sized to the actual monitor or device display.
|
|||
|
overlayPanel.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, displayWidth * cvsResolutionFull.x);
|
|||
|
overlayPanel.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, displayHeight * cvsResolutionFull.y);
|
|||
|
|
|||
|
// altitudeInitPosition is in 1920x1080 sizing. Convert into canvas space with cvsResolutionFull.x / refResolution.x
|
|||
|
|
|||
|
// Move the altitude text relative to the resized overlay image
|
|||
|
altitudeCurrentPosition.x = altitudeInitPosition.x * displayWidth * cvsResolutionFull.x / refResolution.x;
|
|||
|
altitudeCurrentPosition.y = altitudeInitPosition.y * displayHeight * cvsResolutionFull.y / refResolution.y;
|
|||
|
altitudeTextRectTfrm.localPosition = altitudeCurrentPosition;
|
|||
|
|
|||
|
// Move the airspeed text relative to the resized overlay image
|
|||
|
airspeedCurrentPosition.x = airspeedInitPosition.x * displayWidth * cvsResolutionFull.x / refResolution.x;
|
|||
|
airspeedCurrentPosition.y = airspeedInitPosition.y * displayHeight * cvsResolutionFull.y / refResolution.y;
|
|||
|
airspeedTextRectTfrm.localPosition = airspeedCurrentPosition;
|
|||
|
|
|||
|
if (callbackOnSizeChange != null) { callbackOnSizeChange(displayWidth, displayHeight); }
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the primary colour of the heads-up display. Only update the colour if it has actually changed.
|
|||
|
/// If the module has been initialised, this will also re-colour the HUD with the appropriate brightness.
|
|||
|
/// </summary>
|
|||
|
/// <param name="newColour"></param>
|
|||
|
public void SetPrimaryColour(Color32 newColour)
|
|||
|
{
|
|||
|
SSCUtils.UpdateColour(ref newColour, ref primaryColour, ref baseOverlayColour, true);
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
if (primaryOverlayImg != null)
|
|||
|
{
|
|||
|
SetOverlayBrightness();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the primary colour of the heads-up display. Only update the colour if it has actually changed.
|
|||
|
/// If the module has been initialised, this will also re-colour the HUD with the appropriate brightness.
|
|||
|
/// </summary>
|
|||
|
/// <param name="newColour"></param>
|
|||
|
public void SetPrimaryColour(Color newColour)
|
|||
|
{
|
|||
|
SSCUtils.UpdateColour(ref newColour, ref primaryColour, ref baseOverlayColour, true);
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
if (primaryOverlayImg != null)
|
|||
|
{
|
|||
|
if (brightness == 1f) { primaryOverlayImg.color = newColour; }
|
|||
|
else { primaryOverlayImg.color = baseOverlayColour.GetColorWithBrightness(brightness); }
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the overall brightness of the HUD.
|
|||
|
/// </summary>
|
|||
|
/// <param name="newBrightness">Range 0.0 to 1.0</param>
|
|||
|
public void SetBrightness(float newBrightness)
|
|||
|
{
|
|||
|
// Clamp 0.0 to 1.0
|
|||
|
if (newBrightness < 0f) { brightness = 0f; }
|
|||
|
else if (newBrightness > 1f) { brightness = 1f; }
|
|||
|
|
|||
|
brightness = newBrightness;
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
SetOverlayBrightness();
|
|||
|
SetReticleBrightness();
|
|||
|
SetAltitudeTextBrightness();
|
|||
|
SetAirSpeedTextBrightness();
|
|||
|
SetAttitudeBrightness();
|
|||
|
SetHeadingBrightness();
|
|||
|
|
|||
|
int _numDisplayMessages = GetNumberDisplayMessages;
|
|||
|
|
|||
|
// Set the brightness of all the messages
|
|||
|
for (int dmIdx = 0; dmIdx < _numDisplayMessages; dmIdx++)
|
|||
|
{
|
|||
|
SetDisplayMessageBackgroundBrightness(displayMessageList[dmIdx]);
|
|||
|
SetDisplayMessageTextBrightness(displayMessageList[dmIdx]);
|
|||
|
}
|
|||
|
|
|||
|
int _numDisplayTargets = GetNumberDisplayTargets;
|
|||
|
|
|||
|
// Set the brightness for all the targets
|
|||
|
for (int dtgtIdx = 0; dtgtIdx < _numDisplayTargets; dtgtIdx++)
|
|||
|
{
|
|||
|
SetDisplayTargetBrightness(displayTargetList[dtgtIdx]);
|
|||
|
}
|
|||
|
|
|||
|
int _numDisplayGauges = GetNumberDisplayGauges;
|
|||
|
|
|||
|
// Set the brightness for all the gauges
|
|||
|
for (int dgIdx = 0; dgIdx < _numDisplayGauges; dgIdx++)
|
|||
|
{
|
|||
|
SetDisplayGaugeForegroundBrightness(displayGaugeList[dgIdx]);
|
|||
|
SetDisplayGaugeBackgroundBrightness(displayGaugeList[dgIdx]);
|
|||
|
SetDisplayGaugeTextBrightness(displayGaugeList[dgIdx]);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (callbackOnBrightnessChange != null) { callbackOnBrightnessChange(brightness); }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the sort order in the scene of the HUD. Higher values appear on top.
|
|||
|
/// </summary>
|
|||
|
/// <param name="newSortOrder"></param>
|
|||
|
public void SetCanvasSortOrder(int newSortOrder)
|
|||
|
{
|
|||
|
canvasSortOrder = newSortOrder;
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
Canvas _canvas = GetCanvas;
|
|||
|
if (_canvas != null) { _canvas.sortingOrder = newSortOrder; }
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Turn on or off the HUD. Has no effect if not initialised. See also ShowHUD() and HideHUD()
|
|||
|
/// </summary>
|
|||
|
public void ToggleHUD()
|
|||
|
{
|
|||
|
// Prob makes sense to start in a non-flickering state.
|
|||
|
StopFlickering();
|
|||
|
|
|||
|
IsHUDShown = !IsHUDShown;
|
|||
|
|
|||
|
if (isShowHUDWithFlicker && IsHUDShown) { FlickerOn(flickerDefaultDuration); }
|
|||
|
else if (isHideHUDWithFlicker && !IsHUDShown) { FlickerOff(flickerDefaultDuration); }
|
|||
|
else { ShowOrHideHUD(IsHUDShown); }
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public API Methods - Panels
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get the Attitude Panel
|
|||
|
/// Create it if it does not already exist
|
|||
|
/// </summary>
|
|||
|
/// <returns></returns>
|
|||
|
public RectTransform GetAttitudePanel()
|
|||
|
{
|
|||
|
if (hudRectTfrm == null) { hudRectTfrm = GetHUDPanel(); }
|
|||
|
|
|||
|
if (hudRectTfrm != null)
|
|||
|
{
|
|||
|
//if (cvsResolutionFull.x == 0f) { cvsResolutionFull = ReferenceResolution; }
|
|||
|
|
|||
|
// Centred panel (like messages)
|
|||
|
return SSCUtils.GetOrCreateChildRectTransform(hudRectTfrm, cvsResolutionFull, attitudePanelName, 0f, 0f, 1f, 1f, 0.5f, 0.5f, 0.5f, 0.5f);
|
|||
|
}
|
|||
|
else { return null; }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get the HUD RectTransform or panel
|
|||
|
/// </summary>
|
|||
|
/// <returns></returns>
|
|||
|
public RectTransform GetHUDPanel()
|
|||
|
{
|
|||
|
return SSCUtils.GetChildRectTransform(transform, hudPanelName, this.name);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get the Heading Panel
|
|||
|
/// Create it if it does not already exist
|
|||
|
/// </summary>
|
|||
|
/// <returns></returns>
|
|||
|
public RectTransform GetHeadingPanel()
|
|||
|
{
|
|||
|
if (hudRectTfrm == null) { hudRectTfrm = GetHUDPanel(); }
|
|||
|
|
|||
|
if (hudRectTfrm != null)
|
|||
|
{
|
|||
|
// Stretched panel
|
|||
|
//return SSCUtils.GetOrCreateChildRectTransform(hudRectTfrm, cvsResolutionFull, headingPanelName, 0f, 0f, 1f, 1f, 0f, 0f, 1f, 1f);
|
|||
|
// Centred panel (like messages)
|
|||
|
return SSCUtils.GetOrCreateChildRectTransform(hudRectTfrm, cvsResolutionFull, headingPanelName, 0f, 0f, 1f, 1f, 0.5f, 0.5f, 0.5f, 0.5f);
|
|||
|
}
|
|||
|
else { return null; }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get the parent panel for the Display Targets.
|
|||
|
/// Create it if it does not already exist
|
|||
|
/// </summary>
|
|||
|
/// <returns></returns>
|
|||
|
public RectTransform GetTargetsPanel()
|
|||
|
{
|
|||
|
if (hudRectTfrm == null) { hudRectTfrm = GetHUDPanel(); }
|
|||
|
|
|||
|
if (hudRectTfrm != null)
|
|||
|
{
|
|||
|
// Stretched panel
|
|||
|
return SSCUtils.GetOrCreateChildRectTransform(hudRectTfrm, cvsResolutionFull, targetsPanelName, 0f, 0f, 1f, 1f, 0f, 0f, 1f, 1f);
|
|||
|
}
|
|||
|
else { return null; }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get the parent panel for the Display Gauges.
|
|||
|
/// Create it if it does not already exist
|
|||
|
/// </summary>
|
|||
|
/// <returns></returns>
|
|||
|
public RectTransform GetGaugesPanel()
|
|||
|
{
|
|||
|
if (hudRectTfrm == null) { hudRectTfrm = GetHUDPanel(); }
|
|||
|
|
|||
|
if (hudRectTfrm != null)
|
|||
|
{
|
|||
|
// Stretched panel
|
|||
|
return SSCUtils.GetOrCreateChildRectTransform(hudRectTfrm, cvsResolutionFull, gaugesPanelName, 0f, 0f, 1f, 1f, 0f, 0f, 1f, 1f);
|
|||
|
}
|
|||
|
else { return null; }
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public API Methods - Cursor
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show the hardware (mouse) cursor.
|
|||
|
/// This also restarts the countdown auto-hide
|
|||
|
/// timer if that is enabled.
|
|||
|
/// </summary>
|
|||
|
public void ShowCursor()
|
|||
|
{
|
|||
|
ShowOrHideCursor(true);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Hide the hardware (mouse) cursor.
|
|||
|
/// NOTE: This will sometimes fail to turn off the cursor in the editor
|
|||
|
/// Game View when it doesn't have focus, but will work fine in a build.
|
|||
|
/// </summary>
|
|||
|
public void HideCursor()
|
|||
|
{
|
|||
|
ShowOrHideCursor(false);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Centre the hardware (mouse) cursor in the centre of the screen.
|
|||
|
/// WARNING: This will wait until the next frame before it returns.
|
|||
|
/// </summary>
|
|||
|
public void CentreCursor()
|
|||
|
{
|
|||
|
Cursor.lockState = CursorLockMode.Locked;
|
|||
|
StartCoroutine(UnlockCursor());
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Toggle the hardware (mouse) cursor on or off.
|
|||
|
/// NOTE: This will sometimes fail to turn off the cursor in the editor
|
|||
|
/// Game View when it doesn't have focus, but will work fine in a build.
|
|||
|
/// </summary>
|
|||
|
public void ToggleCursor()
|
|||
|
{
|
|||
|
ShowOrHideCursor(!Cursor.visible);
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public API Methods - Display Reticle
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Returns the guidHash of the Reticle in the list given the index or
|
|||
|
/// zero-based position in the list. Will return 0 if no matching Reticle
|
|||
|
/// is found.
|
|||
|
/// Will return 0 if the module hasn't been initialised.
|
|||
|
/// </summary>
|
|||
|
/// <param name="index"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public int GetDisplayReticleGuidHash(int index)
|
|||
|
{
|
|||
|
int guidHash = 0;
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
if (index >= 0 && index < GetNumberDisplayReticles)
|
|||
|
{
|
|||
|
if (displayReticleList[index] != null) { guidHash = displayReticleList[index].guidHash; }
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return guidHash;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Returns the guidHash of the Reticle in the list given the name of the sprite.
|
|||
|
/// Will return 0 if no matching Reticle is found.
|
|||
|
/// WARNING: This will increase GC. Use GetDisplayReticleGuidHash(int index) where possible.
|
|||
|
/// </summary>
|
|||
|
/// <param name="spriteName"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public int GetDisplayReticleGuidHash(string spriteName)
|
|||
|
{
|
|||
|
int guidHash = 0;
|
|||
|
DisplayReticle _tempDR = null;
|
|||
|
|
|||
|
if ((IsInitialised || editorMode) && !string.IsNullOrEmpty(spriteName))
|
|||
|
{
|
|||
|
int _numDisplayReticles = GetNumberDisplayReticles;
|
|||
|
string _spriteNameLowerCase = spriteName.ToLower();
|
|||
|
|
|||
|
for (int drIdx = 0; drIdx < _numDisplayReticles; drIdx++)
|
|||
|
{
|
|||
|
_tempDR = displayReticleList[drIdx];
|
|||
|
if (_tempDR != null && _tempDR.primarySprite != null && _tempDR.primarySprite.name.ToLower() == _spriteNameLowerCase)
|
|||
|
{
|
|||
|
guidHash = _tempDR.guidHash;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return guidHash;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get a DisplayReticle given its guidHash.
|
|||
|
/// See also GetDisplayReticleGuidHash(..).
|
|||
|
/// Will return null if guidHash parameter is 0, it cannot be found
|
|||
|
/// or the module has not been initialised.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public DisplayReticle GetDisplayReticle(int guidHash)
|
|||
|
{
|
|||
|
DisplayReticle displayReticle = null;
|
|||
|
DisplayReticle _tempDR = null;
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
int _numDisplayReticles = GetNumberDisplayReticles;
|
|||
|
|
|||
|
for (int drIdx = 0; drIdx < _numDisplayReticles; drIdx++)
|
|||
|
{
|
|||
|
_tempDR = displayReticleList[drIdx];
|
|||
|
if (_tempDR != null && _tempDR.guidHash == guidHash)
|
|||
|
{
|
|||
|
displayReticle = _tempDR;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return displayReticle;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get the UI sprite (image) for a DisplayReticle.
|
|||
|
/// See also GetDisplayReticleGuidHash(..).
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public Sprite GetDisplayReticleSprite(int guidHash)
|
|||
|
{
|
|||
|
Sprite sprite = null;
|
|||
|
DisplayReticle _tempDR = null;
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
int _numDisplayReticles = GetNumberDisplayReticles;
|
|||
|
|
|||
|
for (int drIdx = 0; drIdx < _numDisplayReticles; drIdx++)
|
|||
|
{
|
|||
|
_tempDR = displayReticleList[drIdx];
|
|||
|
if (_tempDR != null && _tempDR.guidHash == guidHash)
|
|||
|
{
|
|||
|
sprite = _tempDR.primarySprite;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return sprite;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Change the DiplayReticle sprite on the UI panel.
|
|||
|
/// See also GetDisplayReticleGuidHash(..).
|
|||
|
/// NOTE: The module must be initialised.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
public void ChangeDisplayReticle(int guidHash)
|
|||
|
{
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
guidHashActiveDisplayReticle = guidHash;
|
|||
|
currentDisplayReticle = GetDisplayReticle(guidHash);
|
|||
|
|
|||
|
LoadDisplayReticleSprite(currentDisplayReticle);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Hide or turn off the Display Reticle
|
|||
|
/// </summary>
|
|||
|
public void HideDisplayReticle()
|
|||
|
{
|
|||
|
ShowOrHideReticle(false);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the offset (position) of the Display Reticle on the HUD.
|
|||
|
/// If the module has been initialised, this will also re-position the Display Reticle.
|
|||
|
/// Same as SetDisplayReticleOffset(offset.x, offset.y)
|
|||
|
/// </summary>
|
|||
|
/// <param name="offset">Horizontal and Vertical offset from centre. Values should be between -1 and 1</param>
|
|||
|
public void SetDisplayReticleOffset(Vector2 offset)
|
|||
|
{
|
|||
|
SetDisplayReticleOffset(offset.x, offset.y);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the offset (position) of the Display Reticle on the HUD.
|
|||
|
/// If the module has been initialised, this will also re-position the Display Reticle.
|
|||
|
/// </summary>
|
|||
|
/// <param name="offsetX">Horizontal offset from centre. Range between -1 and 1</param>
|
|||
|
/// <param name="offsetY">Vertical offset from centre. Range between -1 and 1</param>
|
|||
|
public void SetDisplayReticleOffset(float offsetX, float offsetY)
|
|||
|
{
|
|||
|
// Verify the x,y values are within range -1 to 1.
|
|||
|
if (offsetX >= -1f && offsetX <= 1f)
|
|||
|
{
|
|||
|
displayReticleOffsetX = offsetX;
|
|||
|
}
|
|||
|
|
|||
|
if (offsetY >= -1f && offsetY <= 1f)
|
|||
|
{
|
|||
|
displayReticleOffsetY = offsetY;
|
|||
|
}
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
Vector2 halfHUDSize = GetHUDHalfSize(true);
|
|||
|
|
|||
|
if (lockDisplayReticleToCursor)
|
|||
|
{
|
|||
|
// Centre on mouse pointer more accurately (reticle can go half outside screen dimensions on edges)
|
|||
|
displayReticleImg.transform.localPosition = new Vector3(offsetX * halfHUDSize.x, offsetY * halfHUDSize.y, displayReticleImg.transform.localPosition.z);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// Original default behaviour - reticle remains within screen dimensions.
|
|||
|
displayReticleImg.transform.localPosition = new Vector3(offsetX * (halfHUDSize.x - (reticleWidth / 2f)), offsetY * (halfHUDSize.y - (reticleHeight / 2f)), displayReticleImg.transform.localPosition.z);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the active Display Reticle colour. Only update the colour if it has actually changed.
|
|||
|
/// If the module has been initialised, this will also re-colour the reticle with the appropriate brightness.
|
|||
|
/// </summary>
|
|||
|
/// <param name="newColour"></param>
|
|||
|
public void SetDisplayReticleColour(Color32 newColour)
|
|||
|
{
|
|||
|
SSCUtils.UpdateColour(ref newColour, ref activeDisplayReticleColour, ref baseReticleColour, true);
|
|||
|
|
|||
|
if (IsInitialised)
|
|||
|
{
|
|||
|
if (displayReticleImg != null)
|
|||
|
{
|
|||
|
SetReticleBrightness();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the active Display Reticle colour. Only update the colour if it has actually changed.
|
|||
|
/// If the module has been initialised, this will also re-colour the reticle with the appropriate brightness.
|
|||
|
/// </summary>
|
|||
|
/// <param name="newColour"></param>
|
|||
|
public void SetDisplayReticleColour(Color newColour)
|
|||
|
{
|
|||
|
SSCUtils.UpdateColour(ref newColour, ref activeDisplayReticleColour, ref baseReticleColour, true);
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
if (displayReticleImg != null)
|
|||
|
{
|
|||
|
if (brightness == 1f) { displayReticleImg.color = newColour; }
|
|||
|
else { displayReticleImg.color = baseReticleColour.GetColorWithBrightness(brightness); }
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show the Display Reticle on the HUD. The HUD will automatically be shown if it is not already visible.
|
|||
|
/// </summary>
|
|||
|
public void ShowDisplayReticle()
|
|||
|
{
|
|||
|
ShowOrHideReticle(true);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or Hide the Display Reticle on the HUD. The HUD will automatically be shown if required.
|
|||
|
/// </summary>
|
|||
|
public void ToggleDisplayReticle()
|
|||
|
{
|
|||
|
ShowOrHideReticle(!showActiveDisplayReticle);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Create a new list if required
|
|||
|
/// </summary>
|
|||
|
public void ValidateReticleList()
|
|||
|
{
|
|||
|
if (displayReticleList == null) { displayReticleList = new List<DisplayReticle>(1); }
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public API Methods - Altitude
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Attempt to show the Altitude indicator. Turn on HUD if required.
|
|||
|
/// </summary>
|
|||
|
public void ShowAltitude()
|
|||
|
{
|
|||
|
ShowOrHideAltitude(true);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Attempt to turn off the Altitude indicator
|
|||
|
/// </summary>
|
|||
|
public void HideAltitude()
|
|||
|
{
|
|||
|
ShowOrHideAltitude(false);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the altitude text colour on the heads-up display. Only update the colour if it has actually changed.
|
|||
|
/// If the module has been initialised, this will also re-colour the HUD with the appropriate brightness.
|
|||
|
/// </summary>
|
|||
|
/// <param name="newColour"></param>
|
|||
|
public void SetAltitudeTextColour(Color32 newColour)
|
|||
|
{
|
|||
|
SSCUtils.UpdateColour(ref newColour, ref altitudeTextColour, ref baseAltitudeTextColour, true);
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
if (altitudeText != null)
|
|||
|
{
|
|||
|
SetAltitudeTextBrightness();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the altitude text colour on the heads-up display. Only update the colour if it has actually changed.
|
|||
|
/// If the module has been initialised, this will also re-colour the HUD with the appropriate brightness.
|
|||
|
/// </summary>
|
|||
|
/// <param name="newColour"></param>
|
|||
|
public void SetAltitudeTextColour(Color newColour)
|
|||
|
{
|
|||
|
SSCUtils.UpdateColour(ref newColour, ref altitudeTextColour, ref baseAltitudeTextColour, true);
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
if (altitudeText != null)
|
|||
|
{
|
|||
|
if (brightness == 1f) { altitudeText.color = newColour; }
|
|||
|
else { altitudeText.color = baseAltitudeTextColour.GetColorWithBrightness(brightness); }
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public API Methods - Air Speed
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Attempt to show the Air speed indicator. Turn on HUD if required.
|
|||
|
/// </summary>
|
|||
|
public void ShowAirSpeed()
|
|||
|
{
|
|||
|
ShowOrHideAirSpeed(true);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Attempt to turn off the AirSpeed indicator
|
|||
|
/// </summary>
|
|||
|
public void HideAirSpeed()
|
|||
|
{
|
|||
|
ShowOrHideAirSpeed(false);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the airspeed text colour on the heads-up display. Only update the colour if it has actually changed.
|
|||
|
/// If the module has been initialised, this will also re-colour the HUD with the appropriate brightness.
|
|||
|
/// </summary>
|
|||
|
/// <param name="newColour"></param>
|
|||
|
public void SetAirSpeedTextColour(Color32 newColour)
|
|||
|
{
|
|||
|
SSCUtils.UpdateColour(ref newColour, ref airspeedTextColour, ref baseAirspeedTextColour, true);
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
if (airspeedText != null)
|
|||
|
{
|
|||
|
SetAirSpeedTextBrightness();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the airspeed text colour on the heads-up display. Only update the colour if it has actually changed.
|
|||
|
/// If the module has been initialised, this will also re-colour the HUD with the appropriate brightness.
|
|||
|
/// </summary>
|
|||
|
/// <param name="newColour"></param>
|
|||
|
public void SetAirSpeedTextColour(Color newColour)
|
|||
|
{
|
|||
|
SSCUtils.UpdateColour(ref newColour, ref airspeedTextColour, ref baseAirspeedTextColour, true);
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
if (airspeedText != null)
|
|||
|
{
|
|||
|
if (brightness == 1f) { airspeedText.color = newColour; }
|
|||
|
else { airspeedText.color = baseAirspeedTextColour.GetColorWithBrightness(brightness); }
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public API Methods - Attitude
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Attempt to turn off the Attitude display
|
|||
|
/// </summary>
|
|||
|
public void HideAttitude()
|
|||
|
{
|
|||
|
ShowOrHideAttitude(false);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the sprite that will mask the Display Attitude scrollable sprite
|
|||
|
/// </summary>
|
|||
|
/// <param name="newSprite"></param>
|
|||
|
public void SetDisplayAttitudeMaskSprite (Sprite newSprite)
|
|||
|
{
|
|||
|
attitudeMaskSprite = newSprite;
|
|||
|
|
|||
|
if (attitudeMaskImg != null)
|
|||
|
{
|
|||
|
attitudeMaskImg.sprite = attitudeMaskSprite;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// This is called when the HUD is resized or some elements of the Attitude control are modified
|
|||
|
/// </summary>
|
|||
|
public void RefreshAttitudeAfterResize()
|
|||
|
{
|
|||
|
// Recalculate the pixels per degree in the pitch ladder
|
|||
|
if (attitudeScrollImg != null && attitudeScrollImg.mainTexture != null)
|
|||
|
{
|
|||
|
// The attitude scroll img should be -90 to 90 deg. Ideally it should have a "border"
|
|||
|
// at the top and bottom of blank (transparent) space to prevent +-90 being right
|
|||
|
// at the top/bottom of the HUD.
|
|||
|
// The image is autoscaled to the full height of the default HUD screen size.
|
|||
|
|
|||
|
float imgHeight = attitudeScrollImg.mainTexture.height;
|
|||
|
|
|||
|
// If the image
|
|||
|
if (imgHeight < 10f) { imgHeight = 1024f; }
|
|||
|
|
|||
|
attitudePixelsPerDegree = cvsResolutionFull.y * ((imgHeight - attitudeScrollSpriteBorderWidth * 2f) / imgHeight) / 180f;
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else
|
|||
|
{
|
|||
|
Debug.LogWarning("RefreshAttitudeAfterResize - Attitude scroll sprite has no UI texture");
|
|||
|
}
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the Display Attitude primary colour. Only update the colour if it has actually changed.
|
|||
|
/// If the module has been initialised, this will also re-colour the attitude with the appropriate brightness.
|
|||
|
/// </summary>
|
|||
|
/// <param name="newColour"></param>
|
|||
|
public void SetDisplayAttitudePrimaryColour (Color newColour)
|
|||
|
{
|
|||
|
SSCUtils.UpdateColour(ref newColour, ref attitudePrimaryColour, ref baseAttitudePrimaryColour, true);
|
|||
|
|
|||
|
SetAttitudeBrightness();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the Display Attitude scroll sprite.
|
|||
|
/// </summary>
|
|||
|
/// <param name="newSprite"></param>
|
|||
|
public void SetDisplayAttitudeScrollSprite (Sprite newSprite)
|
|||
|
{
|
|||
|
attitudeScrollSprite = newSprite;
|
|||
|
|
|||
|
if (attitudeScrollImg != null)
|
|||
|
{
|
|||
|
attitudeScrollImg.sprite = attitudeScrollSprite;
|
|||
|
|
|||
|
// Recalculate the pixels per degree for scrolling.
|
|||
|
RefreshAttitudeAfterResize();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the normalised size of the scrollable Display Attitude.
|
|||
|
/// Currently width is always 1.0
|
|||
|
/// </summary>
|
|||
|
/// <param name="width"></param>
|
|||
|
/// <param name="height"></param>
|
|||
|
public void SetDisplayAttitudeSize (float width, float height)
|
|||
|
{
|
|||
|
// Verify the width,height values are within range 0.1 to 1.
|
|||
|
if (height >= 0.1f && height <= 1f)
|
|||
|
{
|
|||
|
attitudeHeight = height;
|
|||
|
}
|
|||
|
|
|||
|
attitudeWidth = 1f;
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
if (editorMode)
|
|||
|
{
|
|||
|
CheckHUDResize(false);
|
|||
|
UnityEditor.Undo.RecordObject(attitudeRectTfrm.transform, string.Empty);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
// Here we use the original (reference) HUD size as it doesn't need to be scaled in any way.
|
|||
|
// The parent HUD canvas is correctly scaled and sized to the actual monitor or device display.
|
|||
|
attitudeRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, attitudeWidth * cvsResolutionFull.x);
|
|||
|
attitudeRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, attitudeHeight * cvsResolutionFull.y);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the normalised offset (position) of the Display Attitude on the HUD.
|
|||
|
/// If the module has been initialised, this will also re-position the Display Attitude.
|
|||
|
/// </summary>
|
|||
|
/// <param name="offsetX">Horizontal offset from centre. Range between -1 and 1</param>
|
|||
|
/// <param name="offsetY">Vertical offset from centre. Range between -1 and 1</param>
|
|||
|
public void SetDisplayAttitudeOffset (float offsetX, float offsetY)
|
|||
|
{
|
|||
|
// Verify the x,y values are within range -1 to 1.
|
|||
|
if (offsetX >= -1f && offsetX <= 1f)
|
|||
|
{
|
|||
|
attitudeOffsetX = offsetX;
|
|||
|
}
|
|||
|
|
|||
|
if (offsetY >= -1f && offsetY <= 1f)
|
|||
|
{
|
|||
|
attitudeOffsetY = offsetY;
|
|||
|
}
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
Transform attTrfm = attitudeRectTfrm.transform;
|
|||
|
|
|||
|
#if UNITY_EDITOR
|
|||
|
if (editorMode)
|
|||
|
{
|
|||
|
CheckHUDResize(false);
|
|||
|
UnityEditor.Undo.RecordObject(attTrfm, string.Empty);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
// Use the scaled HUD size. This works in and out of play mode
|
|||
|
tempAttitudeOffset.x = attitudeOffsetX * cvsResolutionHalf.x;
|
|||
|
tempAttitudeOffset.y = attitudeOffsetY * cvsResolutionHalf.y;
|
|||
|
tempAttitudeOffset.z = attTrfm.localPosition.z;
|
|||
|
|
|||
|
attTrfm.localPosition = tempAttitudeOffset;
|
|||
|
|
|||
|
// Reset the position of the scrollable image
|
|||
|
if (attitudeScrollPanel != null)
|
|||
|
{
|
|||
|
attitudeScrollPanel.localPosition = Vector3.zero;
|
|||
|
attitudeInitPosition = attitudeScrollPanel.transform.position;
|
|||
|
|
|||
|
//if (showAttitudeIndicator && attitudeIndicatorPanel != null)
|
|||
|
//{
|
|||
|
// attitudeIndicatorPanel.localPosition = new Vector3(attitudeScrollPanel.localPosition.x, attitudeScrollPanel.localPosition.y - 20f, attitudeScrollPanel.localPosition.z);
|
|||
|
//}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the border width of the Scroll Sprite (texture) in pixels
|
|||
|
/// </summary>
|
|||
|
/// <param name="newBorderWidth"></param>
|
|||
|
public void SetDisplayAttitudeSpriteBorderWidth (float newBorderWidth)
|
|||
|
{
|
|||
|
if (newBorderWidth >= 0f)
|
|||
|
{
|
|||
|
attitudeScrollSpriteBorderWidth = newBorderWidth;
|
|||
|
|
|||
|
RefreshAttitudeAfterResize();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Attempt to show the scrollable Attitude. Turn on HUD if required.
|
|||
|
/// </summary>
|
|||
|
public void ShowAttitude()
|
|||
|
{
|
|||
|
ShowOrHideAttitude(true);
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public API Methods - Flickering
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Flicker the HUD on/off. Override the Flicker Default Duration.
|
|||
|
/// Show the HUD when flickering finishes.
|
|||
|
/// </summary>
|
|||
|
/// <param name="duration"></param>
|
|||
|
public void FlickerOn (float duration)
|
|||
|
{
|
|||
|
if (duration > 0f)
|
|||
|
{
|
|||
|
flickerDuration = duration;
|
|||
|
flickerDurationTimer = 0f;
|
|||
|
isFlickerWaiting = false;
|
|||
|
|
|||
|
isFlickeringEndStateOn = true;
|
|||
|
// If the HUD is flickering to the Shown state, it cannot also be flickering off.
|
|||
|
isFlickeringEndStateOff = false;
|
|||
|
|
|||
|
if (flickerHistory != null) { flickerHistory.Clear(); }
|
|||
|
|
|||
|
// Remember the current overall HUD brightness setting
|
|||
|
flickerStartIntensity = brightness;
|
|||
|
|
|||
|
if (!flickerVariableIntensity) { flickerIntensity = flickerStartIntensity; }
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Flicker the HUD on/off. Override the Flicker Default Duration.
|
|||
|
/// Hide the HUD when flickering finishers.
|
|||
|
/// </summary>
|
|||
|
/// <param name="duration"></param>
|
|||
|
public void FlickerOff (float duration)
|
|||
|
{
|
|||
|
if (duration > 0f)
|
|||
|
{
|
|||
|
flickerDuration = duration;
|
|||
|
flickerDurationTimer = 0f;
|
|||
|
isFlickerWaiting = false;
|
|||
|
|
|||
|
isFlickeringEndStateOff = true;
|
|||
|
// If the HUD is flickering to the Hidden state, it cannot also be flickering on.
|
|||
|
isFlickeringEndStateOn = false;
|
|||
|
|
|||
|
if (flickerHistory != null) { flickerHistory.Clear(); }
|
|||
|
|
|||
|
// Remember the current overall HUD brightness setting
|
|||
|
flickerStartIntensity = brightness;
|
|||
|
|
|||
|
if (!flickerVariableIntensity) { flickerIntensity = flickerStartIntensity; }
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
public void StopFlickering()
|
|||
|
{
|
|||
|
isFlickeringEndStateOn = false;
|
|||
|
isFlickeringEndStateOff = false;
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public API Methods - Gauges
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Add a new gauge to the HUD. By design, they are not visible at runtime when first added.
|
|||
|
/// </summary>
|
|||
|
/// <param name="gaugeName"></param>
|
|||
|
/// <param name="gaugeText"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public DisplayGauge AddGauge(string gaugeName, string gaugeText)
|
|||
|
{
|
|||
|
DisplayGauge displayGauge = null;
|
|||
|
|
|||
|
if (GetHUDPanel() == null)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
Debug.LogWarning("ERROR: ShipDisplayModule.AddGauge() - could not find HUDPanel for the HUD. Did you use the prefab from Prefabs/Visuals folder?");
|
|||
|
#endif
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
displayGauge = new DisplayGauge();
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
displayGauge.gaugeName = gaugeName;
|
|||
|
displayGauge.gaugeString = gaugeText;
|
|||
|
ValidateGaugeList();
|
|||
|
displayGaugeList.Add(displayGauge);
|
|||
|
|
|||
|
numDisplayGauges = displayGaugeList.Count;
|
|||
|
|
|||
|
RectTransform gaugePanel = CreateGaugePanel(displayGauge);
|
|||
|
if (gaugePanel != null)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
// Make sure we can rollback the creation of the new gauge panel for this slot
|
|||
|
UnityEditor.Undo.RegisterCreatedObjectUndo(gaugePanel.gameObject, string.Empty);
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return displayGauge;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Add a gauge to the HUD using a displayGauge instance. Typically, this is used
|
|||
|
/// with CopyDisplayGauge(..).
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
public void AddGauge(DisplayGauge displayGauge)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
if (GetHUDPanel() == null)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
Debug.LogWarning("ERROR: ShipDisplayModule.AddGauge() - could not find HUDPanel for the HUD. Did you use the prefab from Prefabs/Visuals folder?");
|
|||
|
#endif
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
ValidateGaugeList();
|
|||
|
displayGaugeList.Add(displayGauge);
|
|||
|
|
|||
|
numDisplayGauges = displayGaugeList.Count;
|
|||
|
|
|||
|
RectTransform gaugePanel = CreateGaugePanel(displayGauge);
|
|||
|
if (gaugePanel != null)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
// Make sure we can rollback the creation of the new gauge panel for this slot
|
|||
|
UnityEditor.Undo.RegisterCreatedObjectUndo(gaugePanel.gameObject, string.Empty);
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Delete a gauge from the HUD.
|
|||
|
/// NOTE: It is much cheaper to HideDisplayGauge(..) than completely remove it.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
public void DeleteGauge(int guidHash)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
bool isRecordUndo = !Application.isPlaying;
|
|||
|
int undoGroup=0;
|
|||
|
#else
|
|||
|
bool isRecordUndo = false;
|
|||
|
#endif
|
|||
|
|
|||
|
RectTransform gaugeRectTfrm = GetGaugePanel(guidHash);
|
|||
|
int _dgIndex = GetDisplayGaugeIndex(guidHash);
|
|||
|
|
|||
|
// Only record undo if in the editor AND is not playing AND something needs to be recorded
|
|||
|
isRecordUndo = isRecordUndo && (gaugeRectTfrm != null || _dgIndex >= 0);
|
|||
|
|
|||
|
#if UNITY_EDITOR
|
|||
|
if (isRecordUndo)
|
|||
|
{
|
|||
|
UnityEditor.Undo.SetCurrentGroupName("Delete Display Gauge " + (_dgIndex + 1).ToString());
|
|||
|
undoGroup = UnityEditor.Undo.GetCurrentGroup();
|
|||
|
|
|||
|
if (_dgIndex >= 0)
|
|||
|
{
|
|||
|
UnityEditor.Undo.RecordObject(this, string.Empty);
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
// Check that the gauge exists and it is within the list constraints
|
|||
|
// NOTE: The script element must be modified BEFORE the Undo.DestroyObjectImmediate is called
|
|||
|
// in order for Undo to correctly undo both the gauge change AND the destroy of the panel.
|
|||
|
if (_dgIndex >= 0 && _dgIndex < (displayGaugeList == null ? 0 : displayGaugeList.Count))
|
|||
|
{
|
|||
|
displayGaugeList.RemoveAt(_dgIndex);
|
|||
|
numDisplayGauges = displayGaugeList.Count;
|
|||
|
}
|
|||
|
|
|||
|
if (gaugeRectTfrm != null)
|
|||
|
{
|
|||
|
if (Application.isPlaying) { Destroy(gaugeRectTfrm.gameObject); }
|
|||
|
else
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
UnityEditor.Undo.DestroyObjectImmediate(gaugeRectTfrm.gameObject);
|
|||
|
#else
|
|||
|
DestroyImmediate(gaugeRectTfrm.gameObject);
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#if UNITY_EDITOR
|
|||
|
if (isRecordUndo)
|
|||
|
{
|
|||
|
UnityEditor.Undo.CollapseUndoOperations(undoGroup);
|
|||
|
}
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Create a copy of an existing DisplayGauge, and give it a new name.
|
|||
|
/// Call AddGauge(newDisplayGauge) to make it useable in the game.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
/// <param name="NameOfCopy"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public DisplayGauge CopyDisplayGauge(DisplayGauge displayGauge, string NameOfCopy)
|
|||
|
{
|
|||
|
DisplayGauge dgCopy = new DisplayGauge(displayGauge);
|
|||
|
|
|||
|
if (dgCopy != null)
|
|||
|
{
|
|||
|
// make it unique
|
|||
|
dgCopy.guidHash = SSCMath.GetHashCodeFromGuid();
|
|||
|
dgCopy.gaugeName = NameOfCopy;
|
|||
|
}
|
|||
|
return dgCopy;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Returns the guidHash of the Gauge in the list given the index or zero-based position in the list.
|
|||
|
/// Will return 0 if no matching Gauge is found.
|
|||
|
/// </summary>
|
|||
|
/// <param name="index"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public int GetDisplayGaugeGuidHash(int index)
|
|||
|
{
|
|||
|
int guidHash = 0;
|
|||
|
|
|||
|
if (index >= 0 && index < GetNumberDisplayGauges)
|
|||
|
{
|
|||
|
if (displayGaugeList[index] != null) { guidHash = displayGaugeList[index].guidHash; }
|
|||
|
}
|
|||
|
|
|||
|
return guidHash;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get the zero-based index of the Gauge in the list. Will return -1 if not found.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public int GetDisplayGaugeIndex(int guidHash)
|
|||
|
{
|
|||
|
int index = -1;
|
|||
|
|
|||
|
int _numDisplayGauges = GetNumberDisplayGauges;
|
|||
|
|
|||
|
for (int dgIdx = 0; dgIdx < _numDisplayGauges; dgIdx++)
|
|||
|
{
|
|||
|
if (displayGaugeList[dgIdx] != null && displayGaugeList[dgIdx].guidHash == guidHash) { index = dgIdx; break; }
|
|||
|
}
|
|||
|
|
|||
|
return index;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get a DisplayGauge given its guidHash.
|
|||
|
/// See also GetDisplayGaugeGuidHash(..).
|
|||
|
/// Will return null if guidHash parameter is 0, it cannot be found.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public DisplayGauge GetDisplayGauge(int guidHash)
|
|||
|
{
|
|||
|
DisplayGauge displayGauge = null;
|
|||
|
DisplayGauge _tempDG = null;
|
|||
|
|
|||
|
int _numDisplayGauges = GetNumberDisplayGauges;
|
|||
|
|
|||
|
for (int dgIdx = 0; dgIdx < _numDisplayGauges; dgIdx++)
|
|||
|
{
|
|||
|
_tempDG = displayGaugeList[dgIdx];
|
|||
|
if (_tempDG != null && _tempDG.guidHash == guidHash)
|
|||
|
{
|
|||
|
displayGauge = _tempDG;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return displayGauge;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get the display gauge give the description title of the gauge.
|
|||
|
/// WARNING: This will increase Garbage Collection (GC). Where possible
|
|||
|
/// use GetDisplayGauge(guidHash) and/or GetDisplayGaugeGuidHash(index)
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGaugeName"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public DisplayGauge GetDisplayGauge(string displayGaugeName)
|
|||
|
{
|
|||
|
DisplayGauge displayGauge = null;
|
|||
|
DisplayGauge _tempDG = null;
|
|||
|
|
|||
|
if (!string.IsNullOrEmpty(displayGaugeName))
|
|||
|
{
|
|||
|
int _numDisplayGauges = GetNumberDisplayGauges;
|
|||
|
|
|||
|
for (int dgIdx = 0; dgIdx < _numDisplayGauges; dgIdx++)
|
|||
|
{
|
|||
|
_tempDG = displayGaugeList[dgIdx];
|
|||
|
if (_tempDG != null && !string.IsNullOrEmpty(_tempDG.gaugeName))
|
|||
|
{
|
|||
|
if (_tempDG.gaugeName.ToLower() == displayGaugeName.ToLower())
|
|||
|
{
|
|||
|
displayGauge = _tempDG;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return displayGauge;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Hide or turn off the Display Gauge
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
public void HideDisplayGauge(int guidHash)
|
|||
|
{
|
|||
|
DisplayGauge displayGauge = GetDisplayGauge(guidHash);
|
|||
|
if (displayGauge != null) { ShowOrHideGauge(displayGauge, false); }
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("WARNING: ShowDisplayGauge - Could not find gauge with guidHash: " + guidHash); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Hide or turn off the Display Gauge
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
public void HideDisplayGauge(DisplayGauge displayGauge)
|
|||
|
{
|
|||
|
if (displayGauge != null) { ShowOrHideGauge(displayGauge, false); }
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("WARNING: ShowDisplayGauge - Could not find gauge - parameter was null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Hide or turn off all Display Gauges. ShipDisplayModule must be initialised.
|
|||
|
/// </summary>
|
|||
|
public void HideDisplayGauges()
|
|||
|
{
|
|||
|
ShowOrHideGauges(false);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// After adding or moving DisplayGauges, they may need to be sorted to
|
|||
|
/// have the correct z-order in on the HUD.
|
|||
|
/// </summary>
|
|||
|
public void RefreshGaugesSortOrder()
|
|||
|
{
|
|||
|
if (gaugesRectTfrm != null)
|
|||
|
{
|
|||
|
// Gauges should begin at index 0.
|
|||
|
int zIndex = -1;
|
|||
|
|
|||
|
// Update number of DisplayGauges. This can help issues in the Editor, like moving DislayGauges
|
|||
|
// up or down in the list while in play mode.
|
|||
|
numDisplayGauges = displayGaugeList == null ? 0 : displayGaugeList.Count;
|
|||
|
|
|||
|
for (int dtIdx = 0; dtIdx < numDisplayGauges; dtIdx++)
|
|||
|
{
|
|||
|
DisplayGauge displayGauge = displayGaugeList[dtIdx];
|
|||
|
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
RectTransform _rt = displayGauge.CachedGaugePanel;
|
|||
|
|
|||
|
if (_rt != null)
|
|||
|
{
|
|||
|
_rt.SetSiblingIndex(++zIndex);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Import a json file from disk and return as DisplayGauge
|
|||
|
/// </summary>
|
|||
|
/// <param name="folderPath"></param>
|
|||
|
/// <param name="fileName"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public DisplayGauge ImportGaugeFromJson (string folderPath, string fileName)
|
|||
|
{
|
|||
|
DisplayGauge displayGauge = null;
|
|||
|
|
|||
|
if (!string.IsNullOrEmpty(folderPath) && !string.IsNullOrEmpty(fileName))
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
string filePath = System.IO.Path.Combine(folderPath, fileName);
|
|||
|
if (System.IO.File.Exists(filePath))
|
|||
|
{
|
|||
|
string jsonText = System.IO.File.ReadAllText(filePath);
|
|||
|
|
|||
|
displayGauge = new DisplayGauge();
|
|||
|
int displayGaugeGuidHash = displayGauge.guidHash;
|
|||
|
|
|||
|
JsonUtility.FromJsonOverwrite(jsonText, displayGauge);
|
|||
|
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
// make hash code unique
|
|||
|
displayGauge.guidHash = displayGaugeGuidHash;
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else
|
|||
|
{
|
|||
|
Debug.LogWarning("ERROR: Import Gauge. Could not find file at " + filePath);
|
|||
|
}
|
|||
|
#endif
|
|||
|
}
|
|||
|
catch (System.Exception ex)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
Debug.LogWarning("ERROR: ShipDisplayModule - could not import gauge from: " + folderPath + " PLEASE REPORT - " + ex.Message);
|
|||
|
#else
|
|||
|
// Keep compiler happy
|
|||
|
if (ex != null) { }
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return displayGauge;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Save the Gauge to a json file on disk.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
/// <param name="filePath"></param>
|
|||
|
public bool SaveGaugeAsJson (DisplayGauge displayGauge, string filePath)
|
|||
|
{
|
|||
|
bool isSuccessful = false;
|
|||
|
|
|||
|
if (displayGauge != null && !string.IsNullOrEmpty(filePath))
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
string jsonGaugeData = JsonUtility.ToJson(displayGauge);
|
|||
|
|
|||
|
if (!string.IsNullOrEmpty(jsonGaugeData) && !string.IsNullOrEmpty(filePath))
|
|||
|
{
|
|||
|
System.IO.File.WriteAllText(filePath, jsonGaugeData);
|
|||
|
isSuccessful = true;
|
|||
|
}
|
|||
|
}
|
|||
|
catch (System.Exception ex)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
Debug.LogWarning("ERROR: ShipDisplayModule SaveGaugeAsJson - could not export: " + displayGauge.gaugeName + " PLEASE REPORT - " + ex.Message);
|
|||
|
#else
|
|||
|
// Keep compiler happy
|
|||
|
if (ex != null) { }
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return isSuccessful;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The foreground colour of the gauge will be determined by the gauge value and the low, medium and high colours.
|
|||
|
/// LowColour = value of 0, MediumColour when value is 0.5, and HighColour when value is 1.0
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
/// <param name="lowColour"></param>
|
|||
|
/// <param name="mediumColour"></param>
|
|||
|
/// <param name="highColour"></param>
|
|||
|
public void SetDisplayGaugeValueAffectsColourOn(DisplayGauge displayGauge, Color lowColour, Color mediumColour, Color highColour)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
SSCUtils.ColortoColorNoAlloc(ref lowColour, ref displayGauge.foregroundLowColour);
|
|||
|
SSCUtils.ColortoColorNoAlloc(ref mediumColour, ref displayGauge.foregroundMediumColour);
|
|||
|
SSCUtils.ColortoColorNoAlloc(ref highColour, ref displayGauge.foregroundHighColour);
|
|||
|
|
|||
|
displayGauge.isColourAffectByValue = true;
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
SetDisplayGaugeValue(displayGauge, displayGauge.gaugeValue);
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeValueAffectsColour - displayGauge is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The value of the gauge does not affect the foreground colour.
|
|||
|
/// When turning off this feature the new foreground colour would typically be the old foregroundHighColour.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
/// <param name="newForegroundColour"></param>
|
|||
|
public void SetDisplayGaugeValueAffectsColourOff(DisplayGauge displayGauge, Color newForegroundColour)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
displayGauge.isColourAffectByValue = false;
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
SetDisplayGaugeForegroundColour(displayGauge, newForegroundColour);
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeValueAffectsColour - displayGauge is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the gauge value at which the foreground medium colour should be set.
|
|||
|
/// The default value is 0.5.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
/// <param name="newValue"></param>
|
|||
|
public void SetDisplayGaugeMediumColourValue (DisplayGauge displayGauge, float newValue)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
if (newValue > 0f && newValue < 1f)
|
|||
|
{
|
|||
|
displayGauge.mediumColourValue = newValue;
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeMediumColourValue - displayGauge is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the offset (position) of the Display Gauge on the HUD.
|
|||
|
/// If the module has been initialised, this will also re-position the Display Gauge.
|
|||
|
/// </summary>
|
|||
|
/// <param name="offsetX">Horizontal offset from centre. Range between -1 and 1</param>
|
|||
|
/// <param name="offsetY">Vertical offset from centre. Range between -1 and 1</param>
|
|||
|
public void SetDisplayGaugeOffset(DisplayGauge displayGauge, float offsetX, float offsetY)
|
|||
|
{
|
|||
|
// Verify the x,y values are within range -1 to 1.
|
|||
|
if (offsetX >= -1f && offsetX <= 1f)
|
|||
|
{
|
|||
|
displayGauge.offsetX = offsetX;
|
|||
|
}
|
|||
|
|
|||
|
if (offsetY >= -1f && offsetY <= 1f)
|
|||
|
{
|
|||
|
displayGauge.offsetY = offsetY;
|
|||
|
}
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
Transform dgTrfm = displayGauge.CachedGaugePanel.transform;
|
|||
|
|
|||
|
#if UNITY_EDITOR
|
|||
|
if (editorMode)
|
|||
|
{
|
|||
|
CheckHUDResize(false);
|
|||
|
UnityEditor.Undo.RecordObject(dgTrfm, string.Empty);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
// Use the scaled HUD size. This works in and out of play mode
|
|||
|
tempGaugeOffset.x = displayGauge.offsetX * cvsResolutionHalf.x;
|
|||
|
tempGaugeOffset.y = displayGauge.offsetY * cvsResolutionHalf.y;
|
|||
|
tempGaugeOffset.z = dgTrfm.localPosition.z;
|
|||
|
|
|||
|
dgTrfm.localPosition = tempGaugeOffset;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the size of the Gauge Panel.
|
|||
|
/// If the module has been initialised, this will also resize the Gauge Panel.
|
|||
|
/// The values are only updated if they are outside the range 0.0 to 1.0 or have changed.
|
|||
|
/// Also updates the Text direction
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
/// <param name="width">Range between 0.0 and 1.0</param>
|
|||
|
/// <param name="height">Range between 0.0 and 1.0</param>
|
|||
|
public void SetDisplayGaugeSize(DisplayGauge displayGauge, float width, float height)
|
|||
|
{
|
|||
|
// Clamp the x,y values 0.0 to 1.0
|
|||
|
if (width < 0f) { displayGauge.displayWidth = 0f; }
|
|||
|
else if (width > 1f) { displayGauge.displayWidth = 1f; }
|
|||
|
else if (width != displayGauge.displayWidth) { displayGauge.displayWidth = width; }
|
|||
|
|
|||
|
if (height < 0f) { displayGauge.displayHeight = 0f; }
|
|||
|
else if (height > 1f) { displayGauge.displayHeight = 1f; }
|
|||
|
else if (height != displayGauge.displayHeight) { displayGauge.displayHeight = height; }
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
if (editorMode) { CheckHUDResize(false); }
|
|||
|
#endif
|
|||
|
|
|||
|
RectTransform dgRectTfrm = displayGauge.CachedGaugePanel;
|
|||
|
|
|||
|
float pixelWidth = displayGauge.displayWidth * cvsResolutionFull.x;
|
|||
|
float pixelHeight = displayGauge.displayHeight * cvsResolutionFull.y;
|
|||
|
|
|||
|
if (dgRectTfrm != null)
|
|||
|
{
|
|||
|
// Here we use the original (reference) HUD size as it doesn't need to be scaled in any way.
|
|||
|
// The parent HUD canvas is correctly scaled and sized to the actual monitor or device display.
|
|||
|
dgRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, pixelWidth);
|
|||
|
dgRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, pixelHeight);
|
|||
|
}
|
|||
|
|
|||
|
if (displayGauge.CachedFgImgComponent != null)
|
|||
|
{
|
|||
|
RectTransform dgFgImgRectTfrm = displayGauge.CachedFgImgComponent.rectTransform;
|
|||
|
|
|||
|
dgFgImgRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, pixelWidth);
|
|||
|
dgFgImgRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, pixelHeight);
|
|||
|
}
|
|||
|
|
|||
|
SetDisplayGaugeTextDirection(displayGauge, displayGauge.textDirection);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the type or style of the gauge.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
/// <param name="dgType"></param>
|
|||
|
public void SetDisplayGaugeType (DisplayGauge displayGauge, DisplayGauge.DGType dgType)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
displayGauge.gaugeType = dgType;
|
|||
|
|
|||
|
GetOrCreateOrRemoveGaugeLabel(displayGauge);
|
|||
|
|
|||
|
if (displayGauge.HasLabel)
|
|||
|
{
|
|||
|
// Refresh the label
|
|||
|
SetDisplayGaugeTextBrightness(displayGauge);
|
|||
|
|
|||
|
SetDisplayGaugeTextFontStyle(displayGauge, (UnityEngine.FontStyle)displayGauge.fontStyle);
|
|||
|
SetDisplayGaugeTextFontSize(displayGauge, displayGauge.isBestFit, displayGauge.fontMinSize, displayGauge.fontMaxSize);
|
|||
|
|
|||
|
SetDisplayGaugeLabelAlignment(displayGauge, displayGauge.labelAlignment);
|
|||
|
}
|
|||
|
|
|||
|
// Refresh the Text direction which also does the sizing for gauges with and without labels
|
|||
|
SetDisplayGaugeTextDirection(displayGauge, displayGauge.textDirection);
|
|||
|
|
|||
|
SetDisplayGaugeValue(displayGauge, displayGauge.gaugeValue);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Update the value or reading of the gauge. If Value Affects Colour (isColourAffectByValue)
|
|||
|
/// is enabled, the foreground colour of the gauge will also be updated.
|
|||
|
/// Values should be in range 0.0 to 1.0.
|
|||
|
/// NOTE: Numeric gauges can increase GC at runtime. Where possible, only call this method when
|
|||
|
/// the value changes.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
/// <param name="gaugeValue"></param>
|
|||
|
public void SetDisplayGaugeValue (DisplayGauge displayGauge, float gaugeValue)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
// Clamp 0.0 to 1.0
|
|||
|
float _gaugeValue = gaugeValue < 0f ? 0f : gaugeValue > 1f ? 1f : gaugeValue;
|
|||
|
|
|||
|
displayGauge.gaugeValue = _gaugeValue;
|
|||
|
UnityEngine.UI.Image fgImg = displayGauge.CachedFgImgComponent;
|
|||
|
|
|||
|
if (fgImg != null)
|
|||
|
{
|
|||
|
fgImg.fillAmount = displayGauge.isFillMethodNone ? 0f : _gaugeValue;
|
|||
|
|
|||
|
if (displayGauge.isColourAffectByValue)
|
|||
|
{
|
|||
|
if (_gaugeValue > displayGauge.mediumColourValue)
|
|||
|
{
|
|||
|
Color _newColour = Color.Lerp(displayGauge.foregroundMediumColour, displayGauge.foregroundHighColour, SSCMath.Normalise(_gaugeValue, displayGauge.mediumColourValue, 1f));
|
|||
|
|
|||
|
SSCUtils.UpdateColour(ref _newColour, ref displayGauge.foregroundColour, ref displayGauge.baseForegroundColour, false);
|
|||
|
SetDisplayGaugeForegroundBrightness(displayGauge);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Color _newColour = Color.Lerp(displayGauge.foregroundLowColour, displayGauge.foregroundMediumColour, SSCMath.Normalise(_gaugeValue, 0f, displayGauge.mediumColourValue));
|
|||
|
|
|||
|
SSCUtils.UpdateColour(ref _newColour, ref displayGauge.foregroundColour, ref displayGauge.baseForegroundColour, true);
|
|||
|
SetDisplayGaugeForegroundBrightness(displayGauge);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
int gaugeTypeInt = (int)displayGauge.gaugeType;
|
|||
|
|
|||
|
// If this is a numeric gauge, update the text with the numeric value
|
|||
|
if (gaugeTypeInt == DisplayGauge.DGTypeFilledNumber1Int || gaugeTypeInt == DisplayGauge.DGTypeNumberWithLabel1Int)
|
|||
|
{
|
|||
|
float _displayTxtValue = displayGauge.isNumericPercentage ? _gaugeValue * 100f : _gaugeValue * displayGauge.gaugeMaxValue;
|
|||
|
|
|||
|
displayGauge.gaugeString = SSCUtils.GetNumericString(_displayTxtValue, displayGauge.gaugeDecimalPlaces, displayGauge.isNumericPercentage);
|
|||
|
|
|||
|
// Update the text field for the gauge on the HUD UI
|
|||
|
Text uiText = displayGauge.CachedTextComponent;
|
|||
|
|
|||
|
if (uiText != null) { uiText.text = displayGauge.gaugeString; }
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeValue - displayGauge is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Update the text of the gauge label. This only applies to numeric gauges with labels.
|
|||
|
/// For non-numeric gauges see SetDisplayGaugeText(..).
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
/// <param name="gaugeLabel"></param>
|
|||
|
public void SetDisplayGaugeLabel (DisplayGauge displayGauge, string gaugeLabel)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
displayGauge.gaugeLabel = gaugeLabel;
|
|||
|
Text uiText = displayGauge.CachedLabelTextComponent;
|
|||
|
|
|||
|
if (uiText != null) { uiText.text = gaugeLabel; }
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeLabel - displayGauge is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Update the position of the label within the gauge panel.
|
|||
|
/// Only applies to numeric gauges with a label.
|
|||
|
/// See also SetDisplayGaugeTextAlignment(..)
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
/// <param name="textAlignment"></param>
|
|||
|
public void SetDisplayGaugeLabelAlignment (DisplayGauge displayGauge, TextAnchor textAlignment)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
if (!editorMode) { displayGauge.labelAlignment = textAlignment; }
|
|||
|
|
|||
|
// If this is not a numeric gauge with a label, this will return null.
|
|||
|
Text uiText = displayGauge.CachedLabelTextComponent;
|
|||
|
|
|||
|
if (uiText != null) { uiText.alignment = textAlignment; }
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeLabelAlignment - displayGauge is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Update the text of the gauge. For numeric gauges with labels, see
|
|||
|
/// SetDisplayGaugeLabel(..).
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
/// <param name="gaugeText"></param>
|
|||
|
public void SetDisplayGaugeText (DisplayGauge displayGauge, string gaugeText)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
displayGauge.gaugeString = gaugeText;
|
|||
|
Text uiText = displayGauge.CachedTextComponent;
|
|||
|
|
|||
|
if (uiText != null) { uiText.text = gaugeText; }
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeText - displayGauge is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Update the position of the text within the gauge panel
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
/// <param name="textAlignment"></param>
|
|||
|
public void SetDisplayGaugeTextAlignment(DisplayGauge displayGauge, TextAnchor textAlignment)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
if (!editorMode) { displayGauge.textAlignment = textAlignment; }
|
|||
|
|
|||
|
Text uiText = displayGauge.CachedTextComponent;
|
|||
|
|
|||
|
if (uiText != null) { uiText.alignment = textAlignment; }
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeTextAlignment - displayGauge is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the font of the DisplayGauge Text component
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
/// <param name="font"></param>
|
|||
|
public void SetDisplayGaugeTextFont(DisplayGauge displayGauge, Font font)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
Text uiText = displayGauge.CachedTextComponent;
|
|||
|
|
|||
|
if (uiText != null)
|
|||
|
{
|
|||
|
uiText.font = font;
|
|||
|
}
|
|||
|
|
|||
|
// If this is numeric gauge with a label, also set the label
|
|||
|
if (displayGauge.HasLabel && displayGauge.CachedLabelTextComponent != null)
|
|||
|
{
|
|||
|
displayGauge.CachedLabelTextComponent.font = font;
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeTextFont - displayGauge is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the font style of the DisplayGauge Text component
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
/// <param name="font"></param>
|
|||
|
public void SetDisplayGaugeTextFontStyle(DisplayGauge displayGauge, FontStyle fontStyle)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
displayGauge.fontStyle = (DisplayGauge.DGFontStyle)fontStyle;
|
|||
|
|
|||
|
Text uiText = displayGauge.CachedTextComponent;
|
|||
|
|
|||
|
if (uiText != null)
|
|||
|
{
|
|||
|
uiText.fontStyle = fontStyle;
|
|||
|
}
|
|||
|
|
|||
|
// If this is numeric gauge with a label, also set the label
|
|||
|
if (displayGauge.HasLabel && displayGauge.CachedLabelTextComponent != null)
|
|||
|
{
|
|||
|
displayGauge.CachedLabelTextComponent.fontStyle = fontStyle;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeTextFontStyle - displayGauge is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the font size of the display gauge text. If isBestFit is false, maxSize is the font size set.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
/// <param name="isBestFit"></param>
|
|||
|
/// <param name="minSize"></param>
|
|||
|
/// <param name="maxSize"></param>
|
|||
|
public void SetDisplayGaugeTextFontSize(DisplayGauge displayGauge, bool isBestFit, int minSize, int maxSize)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
if (!editorMode)
|
|||
|
{
|
|||
|
displayGauge.isBestFit = isBestFit;
|
|||
|
displayGauge.fontMinSize = minSize;
|
|||
|
displayGauge.fontMaxSize = maxSize;
|
|||
|
}
|
|||
|
|
|||
|
Text uiText = displayGauge.CachedTextComponent;
|
|||
|
|
|||
|
if (uiText != null)
|
|||
|
{
|
|||
|
uiText.resizeTextForBestFit = isBestFit;
|
|||
|
uiText.resizeTextMinSize = minSize;
|
|||
|
uiText.resizeTextMaxSize = maxSize;
|
|||
|
uiText.fontSize = maxSize;
|
|||
|
}
|
|||
|
|
|||
|
// If this is numeric gauge with a label, also set the label
|
|||
|
if (displayGauge.HasLabel && displayGauge.CachedLabelTextComponent != null)
|
|||
|
{
|
|||
|
Text uiLabelText = displayGauge.CachedLabelTextComponent;
|
|||
|
uiLabelText.resizeTextForBestFit = isBestFit;
|
|||
|
uiLabelText.resizeTextMinSize = minSize;
|
|||
|
uiLabelText.resizeTextMaxSize = maxSize;
|
|||
|
uiLabelText.fontSize = maxSize;
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeTextFontSize - displayGauge is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the Display Gauge text colour. Only update the colour if it has actually changed.
|
|||
|
/// If the module has been initialised, this will also re-colour the gauge text with the appropriate brightness.
|
|||
|
/// </summary>
|
|||
|
/// <param name="newColour"></param>
|
|||
|
public void SetDisplayGaugeTextColour(DisplayGauge displayGauge, Color newColour)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
SSCUtils.UpdateColour(ref newColour, ref displayGauge.textColour, ref displayGauge.baseTextColour, true);
|
|||
|
|
|||
|
SetDisplayGaugeTextBrightness(displayGauge);
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeTextColour - displayGauge is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Update the direction of the text within the gauge panel
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
/// <param name="textDirection"></param>
|
|||
|
public void SetDisplayGaugeTextDirection(DisplayGauge displayGauge, DisplayGauge.DGTextDirection textDirection)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
if (!editorMode) { displayGauge.textDirection = textDirection; }
|
|||
|
|
|||
|
Text uiText = displayGauge.CachedTextComponent;
|
|||
|
Text uiLabelText = displayGauge.CachedLabelTextComponent;
|
|||
|
|
|||
|
bool hasLabel = uiLabelText != null && displayGauge.HasLabel;
|
|||
|
|
|||
|
if (uiText != null)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
if (editorMode) { CheckHUDResize(false); }
|
|||
|
#endif
|
|||
|
|
|||
|
float pixelWidth = displayGauge.displayWidth * cvsResolutionFull.x;
|
|||
|
float pixelHeight = displayGauge.displayHeight * cvsResolutionFull.y;
|
|||
|
float textRotation = 0f;
|
|||
|
|
|||
|
RectTransform dgTextRectTfrm = displayGauge.CachedTextComponent.rectTransform;
|
|||
|
RectTransform dgLabelRectTfrm = hasLabel ? displayGauge.CachedLabelTextComponent.rectTransform : null;
|
|||
|
|
|||
|
if (textDirection == DisplayGauge.DGTextDirection.Horizontal)
|
|||
|
{
|
|||
|
if (hasLabel)
|
|||
|
{
|
|||
|
pixelHeight *= 0.5f;
|
|||
|
dgLabelRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, pixelWidth);
|
|||
|
dgLabelRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, pixelHeight);
|
|||
|
}
|
|||
|
|
|||
|
dgTextRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, pixelWidth);
|
|||
|
dgTextRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, pixelHeight);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (textDirection == DisplayGauge.DGTextDirection.BottomTop)
|
|||
|
{
|
|||
|
textRotation = 90f;
|
|||
|
}
|
|||
|
else { textRotation = 270f; }
|
|||
|
|
|||
|
if (hasLabel)
|
|||
|
{
|
|||
|
pixelWidth *= 0.5f;
|
|||
|
dgLabelRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, pixelHeight);
|
|||
|
dgLabelRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, pixelWidth);
|
|||
|
}
|
|||
|
|
|||
|
dgTextRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, pixelHeight);
|
|||
|
dgTextRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, pixelWidth);
|
|||
|
}
|
|||
|
|
|||
|
uiText.transform.localRotation = Quaternion.Euler(uiText.transform.localRotation.x, uiText.transform.localRotation.y, textRotation);
|
|||
|
|
|||
|
if (hasLabel)
|
|||
|
{
|
|||
|
uiLabelText.transform.localRotation = Quaternion.Euler(uiLabelText.transform.localRotation.x, uiLabelText.transform.localRotation.y, textRotation);
|
|||
|
|
|||
|
if (textDirection == DisplayGauge.DGTextDirection.Horizontal)
|
|||
|
{
|
|||
|
uiLabelText.transform.localPosition = new Vector3(0f, pixelHeight / 2f, 0f);
|
|||
|
uiText.transform.localPosition = new Vector3(0f, -pixelHeight / 2f, 0f);
|
|||
|
}
|
|||
|
else if (textDirection == DisplayGauge.DGTextDirection.BottomTop)
|
|||
|
{
|
|||
|
uiLabelText.transform.localPosition = new Vector3(-pixelWidth / 2f, 0f, 0f);
|
|||
|
uiText.transform.localPosition = new Vector3(pixelWidth / 2f, 0f, 0f);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
uiLabelText.transform.localPosition = new Vector3(pixelWidth / 2f, 0f, 0f);
|
|||
|
uiText.transform.localPosition = new Vector3(-pixelWidth / 2f, 0f, 0f);
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// This will correct the position if the dev has (incorrectly) moved the panel manually in the scene
|
|||
|
uiText.transform.localPosition = Vector3.zero;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeTextRotation - displayGauge is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the Display Gauge foreground colour. Only update the colour if it has actually changed.
|
|||
|
/// If the module has been initialised, this will also re-colour the gauge foreground with the appropriate brightness.
|
|||
|
/// </summary>
|
|||
|
/// <param name="newColour"></param>
|
|||
|
public void SetDisplayGaugeForegroundColour(DisplayGauge displayGauge, Color newColour)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
SSCUtils.UpdateColour(ref newColour, ref displayGauge.foregroundColour, ref displayGauge.baseForegroundColour, true);
|
|||
|
|
|||
|
SetDisplayGaugeForegroundBrightness(displayGauge);
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeForegroundColour - displayGauge is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the Display Gauge foreground sprite. This is used to render the gauge value by partially filling it.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
/// <param name="newSprite"></param>
|
|||
|
public void SetDisplayGaugeForegroundSprite(DisplayGauge displayGauge, Sprite newSprite)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
displayGauge.foregroundSprite = newSprite;
|
|||
|
|
|||
|
UnityEngine.UI.Image fgImg = displayGauge.CachedFgImgComponent;
|
|||
|
|
|||
|
if (fgImg != null)
|
|||
|
{
|
|||
|
fgImg.sprite = newSprite;
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeForegroundSprite - displayGauge is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the Display Gauge background colour. Only update the colour if it has actually changed.
|
|||
|
/// If the module has been initialised, this will also re-colour the gauge background with the appropriate brightness.
|
|||
|
/// </summary>
|
|||
|
/// <param name="newColour"></param>
|
|||
|
public void SetDisplayGaugeBackgroundColour(DisplayGauge displayGauge, Color newColour)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
SSCUtils.UpdateColour(ref newColour, ref displayGauge.backgroundColour, ref displayGauge.baseBackgroundColour, true);
|
|||
|
|
|||
|
SetDisplayGaugeBackgroundBrightness(displayGauge);
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeBackgroundColour - displayGauge is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the Display Gauge background sprite. This is used to render the background image of the gauge.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
/// <param name="newSprite"></param>
|
|||
|
public void SetDisplayGaugeBackgroundSprite(DisplayGauge displayGauge, Sprite newSprite)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
displayGauge.backgroundSprite = newSprite;
|
|||
|
|
|||
|
UnityEngine.UI.Image bgImg = displayGauge.CachedBgImgComponent;
|
|||
|
|
|||
|
if (bgImg != null)
|
|||
|
{
|
|||
|
bgImg.sprite = newSprite;
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeBackgroundSprite - displayGauge is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the Display Gauge fill method. This determines how the gauge is filled
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
/// <param name="fillMethod"></param>
|
|||
|
public void SetDisplayGaugeFillMethod(DisplayGauge displayGauge, DisplayGauge.DGFillMethod fillMethod)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
UnityEngine.UI.Image fgImg = displayGauge.CachedFgImgComponent;
|
|||
|
|
|||
|
if (fgImg != null)
|
|||
|
{
|
|||
|
displayGauge.isFillMethodNone = displayGauge.fillMethod == DisplayGauge.DGFillMethod.None;
|
|||
|
|
|||
|
fgImg.fillMethod = displayGauge.isFillMethodNone ? Image.FillMethod.Horizontal : (UnityEngine.UI.Image.FillMethod)fillMethod;
|
|||
|
|
|||
|
// Refresh the gauge if case changing from/to Fill Method None.
|
|||
|
SetDisplayGaugeValue(displayGauge, displayGauge.gaugeValue);
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeFillMethod - displayGauge is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Sets whether or not the foreground and background sprites keep their original texture aspect ratio.
|
|||
|
/// This can be useful when creating circular gauges.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
/// <param name="fillMethod"></param>
|
|||
|
public void SetDisplayGaugeKeepAspectRatio(DisplayGauge displayGauge, bool isKeepAspectRatio)
|
|||
|
{
|
|||
|
if (displayGauge != null)
|
|||
|
{
|
|||
|
UnityEngine.UI.Image fgImg = displayGauge.CachedFgImgComponent;
|
|||
|
UnityEngine.UI.Image bgImg = displayGauge.CachedBgImgComponent;
|
|||
|
|
|||
|
if (fgImg != null)
|
|||
|
{
|
|||
|
fgImg.preserveAspect = isKeepAspectRatio;
|
|||
|
}
|
|||
|
|
|||
|
if (bgImg != null)
|
|||
|
{
|
|||
|
bgImg.preserveAspect = isKeepAspectRatio;
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayGaugeKeepAspectRatio - displayGauge is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show the Display Gauge on the HUD. The HUD will automatically be shown if it is not already visible.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
public void ShowDisplayGauge(int guidHash)
|
|||
|
{
|
|||
|
DisplayGauge displayGauge = GetDisplayGauge(guidHash);
|
|||
|
if (displayGauge != null) { ShowOrHideGauge(displayGauge, true); }
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("WARNING: ShowDisplayGauge - Could not find gauge with guidHash: " + guidHash); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show the Display Gauge on the HUD. The HUD will automatically be shown if it is not already visible.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayGauge"></param>
|
|||
|
public void ShowDisplayGauge(DisplayGauge displayGauge)
|
|||
|
{
|
|||
|
if (displayGauge != null) { ShowOrHideGauge(displayGauge, true); }
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("WARNING: ShowDisplayGauge - Could not find gauge - parameter was null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or turn on all Display Gauges. ShipDisplayModule must be initialised.
|
|||
|
/// The HUD will automatically be shown if it is not already visible.
|
|||
|
/// </summary>
|
|||
|
public void ShowDisplayGauges()
|
|||
|
{
|
|||
|
ShowOrHideGauges(true);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Create a new list if required
|
|||
|
/// </summary>
|
|||
|
public void ValidateGaugeList()
|
|||
|
{
|
|||
|
if (displayGaugeList == null) { displayGaugeList = new List<DisplayGauge>(1); }
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public API Methods - Heading
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the small sprite that will indicate or point to the heading on the HUD
|
|||
|
/// </summary>
|
|||
|
/// <param name="newSprite"></param>
|
|||
|
public void SetDisplayHeadingIndicatorSprite (Sprite newSprite)
|
|||
|
{
|
|||
|
headingIndicatorSprite = newSprite;
|
|||
|
|
|||
|
if (headingIndicatorImg != null)
|
|||
|
{
|
|||
|
headingIndicatorImg.sprite = headingIndicatorSprite;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the sprite that will mask the Display Heading scrollable sprite
|
|||
|
/// </summary>
|
|||
|
/// <param name="newSprite"></param>
|
|||
|
public void SetDisplayHeadingMaskSprite (Sprite newSprite)
|
|||
|
{
|
|||
|
headingMaskSprite = newSprite;
|
|||
|
|
|||
|
if (headingMaskImg != null)
|
|||
|
{
|
|||
|
headingMaskImg.sprite = headingMaskSprite;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the Display Heading small indicator colour. Only update the colour if it has actually changed.
|
|||
|
/// If the module has been initialised, this will also re-colour the heading with the appropriate brightness.
|
|||
|
/// </summary>
|
|||
|
/// <param name="newColour"></param>
|
|||
|
public void SetDisplayHeadingIndicatorColour (Color newColour)
|
|||
|
{
|
|||
|
SSCUtils.UpdateColour(ref newColour, ref headingIndicatorColour, ref baseHeadingIndicatorColour, true);
|
|||
|
|
|||
|
SetHeadingBrightness();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the Display Heading primary colour. Only update the colour if it has actually changed.
|
|||
|
/// If the module has been initialised, this will also re-colour the heading with the appropriate brightness.
|
|||
|
/// </summary>
|
|||
|
/// <param name="newColour"></param>
|
|||
|
public void SetDisplayHeadingPrimaryColour (Color newColour)
|
|||
|
{
|
|||
|
SSCUtils.UpdateColour(ref newColour, ref headingPrimaryColour, ref baseHeadingPrimaryColour, true);
|
|||
|
|
|||
|
SetHeadingBrightness();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the Display Heading scroll sprite.
|
|||
|
/// </summary>
|
|||
|
/// <param name="newSprite"></param>
|
|||
|
public void SetDisplayHeadingScrollSprite (Sprite newSprite)
|
|||
|
{
|
|||
|
headingScrollSprite = newSprite;
|
|||
|
|
|||
|
if (headingScrollImg != null)
|
|||
|
{
|
|||
|
headingScrollImg.sprite = headingScrollSprite;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the normalised size of the scrollable Display Heading.
|
|||
|
/// Currently height is always 1.0
|
|||
|
/// </summary>
|
|||
|
/// <param name="width"></param>
|
|||
|
/// <param name="height"></param>
|
|||
|
public void SetDisplayHeadingSize (float width, float height)
|
|||
|
{
|
|||
|
// Verify the width,height values are within range 0.1 to 1.
|
|||
|
if (width >= 0.1f && width <= 1f)
|
|||
|
{
|
|||
|
headingWidth = width;
|
|||
|
}
|
|||
|
|
|||
|
headingHeight = 1f;
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
if (editorMode)
|
|||
|
{
|
|||
|
CheckHUDResize(false);
|
|||
|
UnityEditor.Undo.RecordObject(headingRectTfrm.transform, string.Empty);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
// Here we use the original (reference) HUD size as it doesn't need to be scaled in any way.
|
|||
|
// The parent HUD canvas is correctly scaled and sized to the actual monitor or device display.
|
|||
|
headingRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, headingWidth * cvsResolutionFull.x);
|
|||
|
headingRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, headingHeight * cvsResolutionFull.y);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the normalised offset (position) of the Display Heading on the HUD.
|
|||
|
/// If the module has been initialised, this will also re-position the Display Heading.
|
|||
|
/// </summary>
|
|||
|
/// <param name="offsetX">Horizontal offset from centre. Range between -1 and 1</param>
|
|||
|
/// <param name="offsetY">Vertical offset from centre. Range between -1 and 1</param>
|
|||
|
public void SetDisplayHeadingOffset (float offsetX, float offsetY)
|
|||
|
{
|
|||
|
// Verify the x,y values are within range -1 to 1.
|
|||
|
if (offsetX >= -1f && offsetX <= 1f)
|
|||
|
{
|
|||
|
headingOffsetX = offsetX;
|
|||
|
}
|
|||
|
|
|||
|
if (offsetY >= -1f && offsetY <= 1f)
|
|||
|
{
|
|||
|
headingOffsetY = offsetY;
|
|||
|
}
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
Transform hdgTrfm = headingRectTfrm.transform;
|
|||
|
|
|||
|
#if UNITY_EDITOR
|
|||
|
if (editorMode)
|
|||
|
{
|
|||
|
CheckHUDResize(false);
|
|||
|
UnityEditor.Undo.RecordObject(hdgTrfm, string.Empty);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
// Use the scaled HUD size. This works in and out of play mode
|
|||
|
tempHeadingOffset.x = headingOffsetX * cvsResolutionHalf.x;
|
|||
|
tempHeadingOffset.y = headingOffsetY * cvsResolutionHalf.y;
|
|||
|
tempHeadingOffset.z = hdgTrfm.localPosition.z;
|
|||
|
|
|||
|
hdgTrfm.localPosition = tempHeadingOffset;
|
|||
|
|
|||
|
// Reset the position of the scrollable image
|
|||
|
if (headingScrollPanel != null)
|
|||
|
{
|
|||
|
headingScrollPanel.localPosition = Vector3.zero;
|
|||
|
headingInitPosition = headingScrollPanel.transform.position;
|
|||
|
|
|||
|
if (showHeadingIndicator && headingIndicatorPanel != null)
|
|||
|
{
|
|||
|
headingIndicatorPanel.localPosition = new Vector3(headingScrollPanel.localPosition.x, headingScrollPanel.localPosition.y - 20f, headingScrollPanel.localPosition.z);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Attempt to turn off the scrollable Heading
|
|||
|
/// </summary>
|
|||
|
public void HideHeading()
|
|||
|
{
|
|||
|
ShowOrHideHeading(false);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Attempt to turn off the Heading indicator
|
|||
|
/// </summary>
|
|||
|
public void HideHeadingIndicator()
|
|||
|
{
|
|||
|
ShowOrHideHeadingIndicator(false);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Attempt to show the scrollable Heading. Turn on HUD if required.
|
|||
|
/// </summary>
|
|||
|
public void ShowHeading()
|
|||
|
{
|
|||
|
ShowOrHideHeading(true);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Attempt to turn on the Heading indicator
|
|||
|
/// </summary>
|
|||
|
public void ShowHeadingIndicator()
|
|||
|
{
|
|||
|
ShowOrHideHeadingIndicator(true);
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public API Methods - Messages
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Add a new message to the HUD. By design, they are not visible at runtime when first added.
|
|||
|
/// </summary>
|
|||
|
/// <param name="messageName"></param>
|
|||
|
/// <param name="messageText"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public DisplayMessage AddMessage(string messageName, string messageText)
|
|||
|
{
|
|||
|
DisplayMessage displayMessage = null;
|
|||
|
|
|||
|
Canvas canvas = GetCanvas;
|
|||
|
hudRectTfrm = GetHUDPanel();
|
|||
|
|
|||
|
if (canvas == null)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
Debug.LogWarning("ERROR: ShipDisplayModule.AddMessage() - could not find canvas for the HUD. Did you use the prefab from Prefabs/Visuals folder?");
|
|||
|
#endif
|
|||
|
}
|
|||
|
else if (hudRectTfrm == null)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
Debug.LogWarning("ERROR: ShipDisplayModule.AddMessage() - could not find HUDPanel for the HUD. Did you use the prefab from Prefabs/Visuals folder?");
|
|||
|
#endif
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
displayMessage = new DisplayMessage();
|
|||
|
if (displayMessage != null)
|
|||
|
{
|
|||
|
displayMessage.messageName = messageName;
|
|||
|
displayMessage.messageString = messageText;
|
|||
|
ValidateMessageList();
|
|||
|
displayMessageList.Add(displayMessage);
|
|||
|
|
|||
|
CreateMessagePanel(displayMessage, hudRectTfrm);
|
|||
|
|
|||
|
numDisplayMessages = displayMessageList.Count;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return displayMessage;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Add a message to the HUD using a displayMessage instance. Typically, this is used
|
|||
|
/// with CopyDisplayMessage(..).
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
public void AddMessage(DisplayMessage displayMessage)
|
|||
|
{
|
|||
|
if (displayMessage != null)
|
|||
|
{
|
|||
|
RectTransform hudRectTfrm = SSCUtils.GetChildRectTransform(transform, hudPanelName, this.name);
|
|||
|
|
|||
|
if (hudRectTfrm == null)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
Debug.LogWarning("ERROR: ShipDisplayModule.AddMessage() - could not find HUDPanel for the HUD. Did you use the prefab from Prefabs/Visuals folder?");
|
|||
|
#endif
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
ValidateMessageList();
|
|||
|
displayMessageList.Add(displayMessage);
|
|||
|
|
|||
|
CreateMessagePanel(displayMessage, hudRectTfrm);
|
|||
|
|
|||
|
numDisplayMessages = displayMessageList.Count;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Delete a message from the HUD.
|
|||
|
/// NOTE: It is much cheaper to HideDisplayMessage(..) than completely remove it.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
public void DeleteMessage(int guidHash)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
bool isRecordUndo = !Application.isPlaying;
|
|||
|
int undoGroup=0;
|
|||
|
#else
|
|||
|
bool isRecordUndo = false;
|
|||
|
#endif
|
|||
|
|
|||
|
RectTransform msgRectTfrm = GetMessagePanel(guidHash, null);
|
|||
|
int _msgIndex = GetDisplayMessageIndex(guidHash);
|
|||
|
|
|||
|
// Only record undo if in the editor AND is not playing AND something needs to be recorded
|
|||
|
isRecordUndo = isRecordUndo && (msgRectTfrm != null || _msgIndex >= 0);
|
|||
|
|
|||
|
#if UNITY_EDITOR
|
|||
|
if (isRecordUndo)
|
|||
|
{
|
|||
|
UnityEditor.Undo.SetCurrentGroupName("Delete Display Message " + (_msgIndex + 1).ToString());
|
|||
|
undoGroup = UnityEditor.Undo.GetCurrentGroup();
|
|||
|
|
|||
|
if (_msgIndex >= 0)
|
|||
|
{
|
|||
|
UnityEditor.Undo.RecordObject(this, string.Empty);
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
// Check that the message exists and it is within the list constraints
|
|||
|
// NOTE: The script element must be modified BEFORE the Undo.DestroyObjectImmediate is called
|
|||
|
// in order for Undo to correctly undo both the message change AND the destroy of the panel.
|
|||
|
if (_msgIndex >= 0 && _msgIndex < (displayMessageList == null ? 0 : displayMessageList.Count))
|
|||
|
{
|
|||
|
displayMessageList.RemoveAt(_msgIndex);
|
|||
|
numDisplayMessages = displayMessageList.Count;
|
|||
|
}
|
|||
|
|
|||
|
if (msgRectTfrm != null)
|
|||
|
{
|
|||
|
if (Application.isPlaying) { Destroy(msgRectTfrm.gameObject); }
|
|||
|
else
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
UnityEditor.Undo.DestroyObjectImmediate(msgRectTfrm.gameObject);
|
|||
|
#else
|
|||
|
DestroyImmediate(msgRectTfrm.gameObject);
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#if UNITY_EDITOR
|
|||
|
if (isRecordUndo)
|
|||
|
{
|
|||
|
UnityEditor.Undo.CollapseUndoOperations(undoGroup);
|
|||
|
}
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Create a copy of an existing DisplayMessage, and give it a new name.
|
|||
|
/// Call AddMessage(newDisplayMessage) to make it useable in the game.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
/// <param name="NameOfCopy"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public DisplayMessage CopyDisplayMessage(DisplayMessage displayMessage, string NameOfCopy)
|
|||
|
{
|
|||
|
DisplayMessage dmCopy = new DisplayMessage(displayMessage);
|
|||
|
|
|||
|
if (dmCopy != null)
|
|||
|
{
|
|||
|
// make it unique
|
|||
|
dmCopy.guidHash = SSCMath.GetHashCodeFromGuid();
|
|||
|
dmCopy.messageName = NameOfCopy;
|
|||
|
}
|
|||
|
return dmCopy;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Returns the guidHash of the Message in the list given the index or
|
|||
|
/// zero-based position in the list. Will return 0 if no matching Message
|
|||
|
/// is found.
|
|||
|
/// </summary>
|
|||
|
/// <param name="index"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public int GetDisplayMessageGuidHash(int index)
|
|||
|
{
|
|||
|
int guidHash = 0;
|
|||
|
|
|||
|
if (index >= 0 && index < GetNumberDisplayMessages)
|
|||
|
{
|
|||
|
if (displayMessageList[index] != null) { guidHash = displayMessageList[index].guidHash; }
|
|||
|
}
|
|||
|
|
|||
|
return guidHash;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get the zero-based index of the Message in the list. Will return -1 if not found.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public int GetDisplayMessageIndex(int guidHash)
|
|||
|
{
|
|||
|
int index = -1;
|
|||
|
|
|||
|
int _numDisplayMessages = GetNumberDisplayMessages;
|
|||
|
|
|||
|
for (int dmIdx = 0; dmIdx < _numDisplayMessages; dmIdx++)
|
|||
|
{
|
|||
|
if (displayMessageList[dmIdx] != null && displayMessageList[dmIdx].guidHash == guidHash) { index = dmIdx; break; }
|
|||
|
}
|
|||
|
|
|||
|
return index;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get a DisplayMessage given its guidHash.
|
|||
|
/// See also GetDisplayMessageGuidHash(..).
|
|||
|
/// Will return null if guidHash parameter is 0, it cannot be found.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public DisplayMessage GetDisplayMessage(int guidHash)
|
|||
|
{
|
|||
|
DisplayMessage displayMessage = null;
|
|||
|
DisplayMessage _tempDM = null;
|
|||
|
|
|||
|
int _numDisplayMessages = GetNumberDisplayMessages;
|
|||
|
|
|||
|
for (int dmIdx = 0; dmIdx < _numDisplayMessages; dmIdx++)
|
|||
|
{
|
|||
|
_tempDM = displayMessageList[dmIdx];
|
|||
|
if (_tempDM != null && _tempDM.guidHash == guidHash)
|
|||
|
{
|
|||
|
displayMessage = _tempDM;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return displayMessage;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get the display message give the description title of the message.
|
|||
|
/// WARNING: This will increase Garbage Collection (GC). Where possible
|
|||
|
/// use GetDisplayMessage(guidHash) and/or GetDisplayMessageGuidHash(index)
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessageName"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public DisplayMessage GetDisplayMessage(string displayMessageName)
|
|||
|
{
|
|||
|
DisplayMessage displayMessage = null;
|
|||
|
DisplayMessage _tempDM = null;
|
|||
|
|
|||
|
if (!string.IsNullOrEmpty(displayMessageName))
|
|||
|
{
|
|||
|
int _numDisplayMessages = GetNumberDisplayMessages;
|
|||
|
|
|||
|
for (int dmIdx = 0; dmIdx < _numDisplayMessages; dmIdx++)
|
|||
|
{
|
|||
|
_tempDM = displayMessageList[dmIdx];
|
|||
|
if (_tempDM != null && !string.IsNullOrEmpty(_tempDM.messageName))
|
|||
|
{
|
|||
|
if (_tempDM.messageName.ToLower() == displayMessageName.ToLower())
|
|||
|
{
|
|||
|
displayMessage = _tempDM;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return displayMessage;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Is the Display Message currently being shown on the HUD?
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public bool IsDisplayMessageShown (DisplayMessage displayMessage)
|
|||
|
{
|
|||
|
if (displayMessage != null)
|
|||
|
{
|
|||
|
return IsHUDShown && displayMessage.showMessage;
|
|||
|
}
|
|||
|
else { return false; }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// After adding or moving DisplayMessages, they may need to be sorted to
|
|||
|
/// have the correct z-order in on the HUD.
|
|||
|
/// </summary>
|
|||
|
public void RefreshMessagesSortOrder()
|
|||
|
{
|
|||
|
if (hudPanel != null)
|
|||
|
{
|
|||
|
// Messages should begin after index 1.
|
|||
|
int zIndex = 1;
|
|||
|
|
|||
|
// Start messages after Altitude in hierarchy.
|
|||
|
if (overlayPanel != null) { zIndex = overlayPanel.GetSiblingIndex(); }
|
|||
|
|
|||
|
int _numDisplayMessages = GetNumberDisplayMessages;
|
|||
|
|
|||
|
for (int dmIdx = 0; dmIdx < _numDisplayMessages; dmIdx++)
|
|||
|
{
|
|||
|
DisplayMessage displayMessage = displayMessageList[dmIdx];
|
|||
|
|
|||
|
if (displayMessage != null)
|
|||
|
{
|
|||
|
RectTransform _rt = displayMessage.CachedMessagePanel;
|
|||
|
|
|||
|
if (_rt != null)
|
|||
|
{
|
|||
|
_rt.SetSiblingIndex(++zIndex);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Import a json file from disk and return as DisplayMessage
|
|||
|
/// </summary>
|
|||
|
/// <param name="folderPath"></param>
|
|||
|
/// <param name="fileName"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public DisplayMessage ImportMessageFromJson (string folderPath, string fileName)
|
|||
|
{
|
|||
|
DisplayMessage displayMessage = null;
|
|||
|
|
|||
|
if (!string.IsNullOrEmpty(folderPath) && !string.IsNullOrEmpty(fileName))
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
string filePath = System.IO.Path.Combine(folderPath, fileName);
|
|||
|
if (System.IO.File.Exists(filePath))
|
|||
|
{
|
|||
|
string jsonText = System.IO.File.ReadAllText(filePath);
|
|||
|
|
|||
|
displayMessage = new DisplayMessage();
|
|||
|
int displayGaugeGuidHash = displayMessage.guidHash;
|
|||
|
|
|||
|
JsonUtility.FromJsonOverwrite(jsonText, displayMessage);
|
|||
|
|
|||
|
if (displayMessage != null)
|
|||
|
{
|
|||
|
// make hash code unique
|
|||
|
displayMessage.guidHash = displayGaugeGuidHash;
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else
|
|||
|
{
|
|||
|
Debug.LogWarning("ERROR: Import Message. Could not find file at " + filePath);
|
|||
|
}
|
|||
|
#endif
|
|||
|
}
|
|||
|
catch (System.Exception ex)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
Debug.LogWarning("ERROR: ShipDisplayModule - could not import message from: " + folderPath + " PLEASE REPORT - " + ex.Message);
|
|||
|
#else
|
|||
|
// Keep compiler happy
|
|||
|
if (ex != null) { }
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return displayMessage;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Save the Message to a json file on disk.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
/// <param name="filePath"></param>
|
|||
|
public bool SaveMessageAsJson (DisplayMessage displayMessage, string filePath)
|
|||
|
{
|
|||
|
bool isSuccessful = false;
|
|||
|
|
|||
|
if (displayMessage != null && !string.IsNullOrEmpty(filePath))
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
string jsonMessageData = JsonUtility.ToJson(displayMessage);
|
|||
|
|
|||
|
if (!string.IsNullOrEmpty(jsonMessageData) && !string.IsNullOrEmpty(filePath))
|
|||
|
{
|
|||
|
System.IO.File.WriteAllText(filePath, jsonMessageData);
|
|||
|
isSuccessful = true;
|
|||
|
}
|
|||
|
}
|
|||
|
catch (System.Exception ex)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
Debug.LogWarning("ERROR: ShipDisplayModule SaveMessageAsJson - could not export: " + displayMessage.messageName + " PLEASE REPORT - " + ex.Message);
|
|||
|
#else
|
|||
|
// Keep compiler happy
|
|||
|
if (ex != null) { }
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return isSuccessful;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the offset (position) of the Display Message on the HUD.
|
|||
|
/// If the module has been initialised, this will also re-position the Display Message.
|
|||
|
/// </summary>
|
|||
|
/// <param name="offsetX">Horizontal offset from centre. Range between -1 and 1</param>
|
|||
|
/// <param name="offsetY">Vertical offset from centre. Range between -1 and 1</param>
|
|||
|
public void SetDisplayMessageOffset(DisplayMessage displayMessage, float offsetX, float offsetY)
|
|||
|
{
|
|||
|
// Verify the x,y values are within range -1 to 1.
|
|||
|
if (offsetX >= -1f && offsetX <= 1f)
|
|||
|
{
|
|||
|
displayMessage.offsetX = offsetX;
|
|||
|
}
|
|||
|
|
|||
|
if (offsetY >= -1f && offsetY <= 1f)
|
|||
|
{
|
|||
|
displayMessage.offsetY = offsetY;
|
|||
|
}
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
Transform dmTrfm = displayMessage.CachedMessagePanel.transform;
|
|||
|
|
|||
|
#if UNITY_EDITOR
|
|||
|
if (editorMode)
|
|||
|
{
|
|||
|
CheckHUDResize(false);
|
|||
|
UnityEditor.Undo.RecordObject(dmTrfm, string.Empty);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
// Use original refResolution rather than the scaled size of the HUD. This works in and out of play mode
|
|||
|
//tempMessageOffset.x = displayMessage.offsetX * (refResolutionHalf.x - (displayMessage.displayWidth / 2f));
|
|||
|
//tempMessageOffset.y = displayMessage.offsetY * (refResolutionHalf.y - (displayMessage.displayHeight / 2f));
|
|||
|
|
|||
|
// Use the scaled HUD size. This works in and out of play mode
|
|||
|
tempMessageOffset.x = displayMessage.offsetX * cvsResolutionHalf.x;
|
|||
|
tempMessageOffset.y = displayMessage.offsetY * cvsResolutionHalf.y;
|
|||
|
tempMessageOffset.z = dmTrfm.localPosition.z;
|
|||
|
|
|||
|
dmTrfm.localPosition = tempMessageOffset;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the size of the Message Panel.
|
|||
|
/// If the module has been initialised, this will also resize the Message Panel.
|
|||
|
/// The values are only updated if they are outside the range 0.0 to 1.0 or have changed.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
/// <param name="width">Range between 0.0 and 1.0</param>
|
|||
|
/// <param name="height">Range between 0.0 and 1.0</param>
|
|||
|
public void SetDisplayMessageSize(DisplayMessage displayMessage, float width, float height)
|
|||
|
{
|
|||
|
// Clamp the x,y values 0.0 to 1.0
|
|||
|
if (width < 0f) { displayMessage.displayWidth = 0f; }
|
|||
|
else if (width > 1f) { displayMessage.displayWidth = 1f; }
|
|||
|
else if (width != displayMessage.displayWidth) { displayMessage.displayWidth = width; }
|
|||
|
|
|||
|
if (height < 0f) { displayMessage.displayHeight = 0f; }
|
|||
|
else if (height > 1f) { displayMessage.displayHeight = 1f; }
|
|||
|
else if (height != displayMessage.displayHeight) { displayMessage.displayHeight = height; }
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
if (editorMode) { CheckHUDResize(false); }
|
|||
|
#endif
|
|||
|
|
|||
|
RectTransform dmRectTfrm = displayMessage.CachedMessagePanel;
|
|||
|
|
|||
|
if (dmRectTfrm != null)
|
|||
|
{
|
|||
|
// Here we use the original (reference) HUD size as it doesn't need to be scaled in any way.
|
|||
|
// The parent HUD canvas is correctly scaled and sized to the actual monitor or device display.
|
|||
|
dmRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, displayMessage.displayWidth * cvsResolutionFull.x);
|
|||
|
dmRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, displayMessage.displayHeight * cvsResolutionFull.y);
|
|||
|
}
|
|||
|
|
|||
|
if (displayMessage.CachedTextComponent != null)
|
|||
|
{
|
|||
|
RectTransform dmTextRectTfrm = displayMessage.CachedTextComponent.rectTransform;
|
|||
|
|
|||
|
dmTextRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, displayMessage.displayWidth * cvsResolutionFull.x);
|
|||
|
dmTextRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, displayMessage.displayHeight * cvsResolutionFull.y);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Update the text of the message
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
/// <param name="messageText"></param>
|
|||
|
public void SetDisplayMessageText(DisplayMessage displayMessage, string messageText)
|
|||
|
{
|
|||
|
if (displayMessage != null)
|
|||
|
{
|
|||
|
displayMessage.messageString = messageText;
|
|||
|
Text uiText = displayMessage.CachedTextComponent;
|
|||
|
|
|||
|
if (uiText != null) { uiText.text = messageText; }
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayMessageText - displayMessage is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Update the position of the text within the message panel
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
/// <param name="textAlignment"></param>
|
|||
|
public void SetDisplayMessageTextAlignment(DisplayMessage displayMessage, TextAnchor textAlignment)
|
|||
|
{
|
|||
|
if (displayMessage != null)
|
|||
|
{
|
|||
|
if (!editorMode) { displayMessage.textAlignment = textAlignment; }
|
|||
|
|
|||
|
Text uiText = displayMessage.CachedTextComponent;
|
|||
|
|
|||
|
if (uiText != null) { uiText.alignment = textAlignment; }
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayMessageTextAlignment - displayMessage is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the font of the DisplayMessage Text component
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
/// <param name="font"></param>
|
|||
|
public void SetDisplayMessageTextFont(DisplayMessage displayMessage, Font font)
|
|||
|
{
|
|||
|
if (displayMessage != null)
|
|||
|
{
|
|||
|
Text uiText = displayMessage.CachedTextComponent;
|
|||
|
|
|||
|
if (uiText != null)
|
|||
|
{
|
|||
|
uiText.font = font;
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayMessageTextFont - displayMessage is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the font size of the display message text. If isBestFit is false, maxSize is the font size set.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
/// <param name="isBestFit"></param>
|
|||
|
/// <param name="minSize"></param>
|
|||
|
/// <param name="maxSize"></param>
|
|||
|
public void SetDisplayMessageTextFontSize(DisplayMessage displayMessage, bool isBestFit, int minSize, int maxSize)
|
|||
|
{
|
|||
|
if (displayMessage != null)
|
|||
|
{
|
|||
|
if (!editorMode)
|
|||
|
{
|
|||
|
displayMessage.isBestFit = isBestFit;
|
|||
|
displayMessage.fontMinSize = minSize;
|
|||
|
displayMessage.fontMaxSize = maxSize;
|
|||
|
}
|
|||
|
|
|||
|
Text uiText = displayMessage.CachedTextComponent;
|
|||
|
|
|||
|
if (uiText != null)
|
|||
|
{
|
|||
|
uiText.resizeTextForBestFit = isBestFit;
|
|||
|
uiText.resizeTextMinSize = minSize;
|
|||
|
uiText.resizeTextMaxSize = maxSize;
|
|||
|
uiText.fontSize = maxSize;
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayMessageTextFontSize - displayMessage is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the Display Message background colour. Only update the colour if it has actually changed.
|
|||
|
/// If the module has been initialised, this will also re-colour the message background with the appropriate brightness.
|
|||
|
/// </summary>
|
|||
|
/// <param name="newColour"></param>
|
|||
|
public void SetDisplayMessageBackgroundColour(DisplayMessage displayMessage, Color newColour)
|
|||
|
{
|
|||
|
if (displayMessage != null)
|
|||
|
{
|
|||
|
SSCUtils.UpdateColour(ref newColour, ref displayMessage.backgroundColour, ref displayMessage.baseBackgroundColour, true);
|
|||
|
|
|||
|
SetDisplayMessageBackgroundBrightness(displayMessage);
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayMessageBackgroundColour - displayMessage is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the Display Message scroll direction.
|
|||
|
/// USAGE: SetDisplayMessageScrollDirection(displayMessage, DisplayMessage.ScrollDirectionLR)
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
/// <param name="scrollDirection"></param>
|
|||
|
public void SetDisplayMessageScrollDirection(DisplayMessage displayMessage, int scrollDirection)
|
|||
|
{
|
|||
|
if (displayMessage != null)
|
|||
|
{
|
|||
|
if (scrollDirection >= 0 && scrollDirection < 5)
|
|||
|
{
|
|||
|
displayMessage.scrollDirectionInt = scrollDirection;
|
|||
|
displayMessage.scrollDirection = (DisplayMessage.ScrollDirection)scrollDirection;
|
|||
|
if (scrollDirection == DisplayMessage.ScrollDirectionNone)
|
|||
|
{
|
|||
|
displayMessage.scrollOffsetX = 0f;
|
|||
|
displayMessage.scrollOffsetY = 0f;
|
|||
|
SetDisplayMessageOffset(displayMessage, displayMessage.offsetX, displayMessage.offsetY);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayMessageScrollDirection - displayMessage is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the Display Message to scroll across or up/down the full screen regardless of the message width and height.
|
|||
|
/// Can also be set directly with displayMessage.isScrollFullscreen = true;
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
/// <param name="isScrollFullscreen"></param>
|
|||
|
public void SetDisplayMessageScrollFullscreen(DisplayMessage displayMessage, bool isScrollFullscreen)
|
|||
|
{
|
|||
|
if (displayMessage != null) { displayMessage.isScrollFullscreen = isScrollFullscreen; }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the Display Message scroll speed.
|
|||
|
/// Can also be set directly with displayMessage.scrollSpeed = scrollSpeed;
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
/// <param name="scrollSpeed"></param>
|
|||
|
public void SetDisplayMessageScrollSpeed(DisplayMessage displayMessage, float scrollSpeed)
|
|||
|
{
|
|||
|
if (displayMessage != null) { displayMessage.scrollSpeed = scrollSpeed; }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the Display Message text colour. Only update the colour if it has actually changed.
|
|||
|
/// If the module has been initialised, this will also re-colour the message text with the appropriate brightness.
|
|||
|
/// </summary>
|
|||
|
/// <param name="newColour"></param>
|
|||
|
public void SetDisplayMessageTextColour(DisplayMessage displayMessage, Color newColour)
|
|||
|
{
|
|||
|
if (displayMessage != null)
|
|||
|
{
|
|||
|
SSCUtils.UpdateColour(ref newColour, ref displayMessage.textColour, ref displayMessage.baseTextColour, true);
|
|||
|
|
|||
|
SetDisplayMessageTextBrightness(displayMessage);
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayMessageTextColour - displayMessage is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show the Display Message on the HUD. The HUD will automatically be shown if it is not already visible.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
public void ShowDisplayMessage (int guidHash)
|
|||
|
{
|
|||
|
DisplayMessage displayMessage = GetDisplayMessage(guidHash);
|
|||
|
if (displayMessage != null) { ShowOrHideMessage(displayMessage, true, false); }
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("WARNING: ShowDisplayMessage - Could not find message with guidHash: " + guidHash); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show the Display Message on the HUD. The HUD will automatically be shown if it is not already visible.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
public void ShowDisplayMessage (DisplayMessage displayMessage)
|
|||
|
{
|
|||
|
if (displayMessage != null) { ShowOrHideMessage(displayMessage, true, false); }
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("WARNING: ShowDisplayMessage - Could not find message - parameter was null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show the Display Message on the HUD instantly by ignoring fade settings. The HUD will automatically be shown if it is not already visible.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
public void ShowDisplayMessageInstant (int guidHash)
|
|||
|
{
|
|||
|
DisplayMessage displayMessage = GetDisplayMessage(guidHash);
|
|||
|
if (displayMessage != null) { ShowOrHideMessage(displayMessage, true, true); }
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("WARNING: ShowDisplayMessageInstant - Could not find message with guidHash: " + guidHash); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show the Display Message on the HUD instantly by ignoring fade settings. The HUD will automatically be shown if it is not already visible.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
public void ShowDisplayMessageInstant (DisplayMessage displayMessage)
|
|||
|
{
|
|||
|
if (displayMessage != null) { ShowOrHideMessage(displayMessage, true, true); }
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("WARNING: ShowDisplayMessageInstant - Could not find message - parameter was null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or turn on all Display Messages. ShipDisplayModule must be initialised.
|
|||
|
/// The HUD will automatically be shown if it is not already visible.
|
|||
|
/// </summary>
|
|||
|
public void ShowDisplayMessages()
|
|||
|
{
|
|||
|
ShowOrHideMessages(true, false);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show the Display Message background on the HUD. The display the actual message, you would
|
|||
|
/// need to call ShowDisplayMessage(..).
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
public void ShowDisplayMessageBackground(DisplayMessage displayMessage)
|
|||
|
{
|
|||
|
if (displayMessage != null) { ShowOrHideDisplayMessageBackground(displayMessage, true); }
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("WARNING: ShowDisplayMessageBackground - Could not find message - parameter was null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Hide or turn off the Display Message
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
public void HideDisplayMessage(int guidHash)
|
|||
|
{
|
|||
|
DisplayMessage displayMessage = GetDisplayMessage(guidHash);
|
|||
|
if (displayMessage != null) { ShowOrHideMessage(displayMessage, false, false); }
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("WARNING: ShowDisplayMessage - Could not find message with guidHash: " + guidHash); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Hide or turn off the Display Message
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
public void HideDisplayMessage (DisplayMessage displayMessage)
|
|||
|
{
|
|||
|
if (displayMessage != null) { ShowOrHideMessage(displayMessage, false, false); }
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("WARNING: ShowDisplayMessage - Could not find message - parameter was null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Hide or turn off the Display Message instantly and ignore any fade-out settings.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
public void HideDisplayMessageInstant (int guidHash)
|
|||
|
{
|
|||
|
DisplayMessage displayMessage = GetDisplayMessage(guidHash);
|
|||
|
if (displayMessage != null) { ShowOrHideMessage(displayMessage, false, true); }
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("WARNING: ShowDisplayMessageInstant - Could not find message with guidHash: " + guidHash); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Hide or turn off the Display Message instantly and ignore any fade-out settings.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
public void HideDisplayMessageInstant (DisplayMessage displayMessage)
|
|||
|
{
|
|||
|
if (displayMessage != null) { ShowOrHideMessage(displayMessage, false, true); }
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("WARNING: ShowDisplayMessageInstant - Could not find message - parameter was null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Hide or turn off all Display Messages.
|
|||
|
/// ShipDisplayModule must be initialised.
|
|||
|
/// </summary>
|
|||
|
public void HideDisplayMessages()
|
|||
|
{
|
|||
|
ShowOrHideMessages(false, false);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Hide the Display Message background on the HUD. The hide the actual message, you would
|
|||
|
/// need to call HideDisplayMessage(..).
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayMessage"></param>
|
|||
|
public void HideDisplayMessageBackground(DisplayMessage displayMessage)
|
|||
|
{
|
|||
|
if (displayMessage != null) { ShowOrHideDisplayMessageBackground(displayMessage, false); }
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("WARNING: HideDisplayMessageBackground - Could not find message - parameter was null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Create a new list if required
|
|||
|
/// </summary>
|
|||
|
public void ValidateMessageList()
|
|||
|
{
|
|||
|
if (displayMessageList == null) { displayMessageList = new List<DisplayMessage>(1); }
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Public API Methods - Targets
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Add a new Display Target to the HUD. By design, they are not visible at runtime when first added.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHashDisplayReticle"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public DisplayTarget AddTarget(int guidHashDisplayReticle)
|
|||
|
{
|
|||
|
DisplayTarget displayTarget = null;
|
|||
|
|
|||
|
if (GetHUDPanel() == null)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
Debug.LogWarning("ERROR: ShipDisplayModule.AddTarget() - could not find HUDPanel for the HUD. Did you use the prefab from Prefabs/Visuals folder?");
|
|||
|
#endif
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
displayTarget = new DisplayTarget();
|
|||
|
if (displayTarget != null)
|
|||
|
{
|
|||
|
displayTarget.guidHashDisplayReticle = guidHashDisplayReticle;
|
|||
|
|
|||
|
ValidateTargetList();
|
|||
|
displayTargetList.Add(displayTarget);
|
|||
|
|
|||
|
numDisplayTargets = displayTargetList.Count;
|
|||
|
|
|||
|
RectTransform targetSlotPanel = CreateTargetPanel(displayTarget, 0);
|
|||
|
if (targetSlotPanel != null)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
// Make sure we can rollback the creation of the new target panel for this slot
|
|||
|
UnityEditor.Undo.RegisterCreatedObjectUndo(targetSlotPanel.gameObject, string.Empty);
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return displayTarget;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Add another DisplayTarget slot to a DisplayTarget. This allows you to display another
|
|||
|
/// copy of the target on the HUD.
|
|||
|
/// If the DisplayTarget has not been initialised, the new slot panel will be added to the
|
|||
|
/// scene but this method will return null.
|
|||
|
/// This automatically updates displayTarget.maxNumberOfTargets.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayTarget"></param>
|
|||
|
/// <param name="numberToAdd"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public DisplayTargetSlot AddTargetSlots(DisplayTarget displayTarget, int numberToAdd)
|
|||
|
{
|
|||
|
DisplayTargetSlot displayTargetSlot = null;
|
|||
|
|
|||
|
if (displayTarget != null)
|
|||
|
{
|
|||
|
if (displayTarget.maxNumberOfTargets + numberToAdd <= DisplayTarget.MAX_DISPLAYTARGET_SLOTS)
|
|||
|
{
|
|||
|
int numberAdded = 0;
|
|||
|
|
|||
|
// slotIndex is zero-based so start to 1 beyond the end of the existing list
|
|||
|
for (int slotIndex = displayTarget.maxNumberOfTargets; slotIndex < displayTarget.maxNumberOfTargets + numberToAdd; slotIndex++)
|
|||
|
{
|
|||
|
RectTransform targetSlotPanel = CreateTargetPanel(displayTarget, slotIndex);
|
|||
|
|
|||
|
// If the DisplayTarget has already been initialised, this slot will need to be initialised
|
|||
|
if (targetSlotPanel != null)
|
|||
|
{
|
|||
|
numberAdded++;
|
|||
|
|
|||
|
#if UNITY_EDITOR
|
|||
|
// Make sure we can rollback the creation of the new target panel for this slot
|
|||
|
UnityEditor.Undo.RegisterCreatedObjectUndo(targetSlotPanel.gameObject, string.Empty);
|
|||
|
#endif
|
|||
|
|
|||
|
if (displayTarget.isInitialised)
|
|||
|
{
|
|||
|
displayTargetSlot = InitialiseTargetSlot(displayTarget, slotIndex);
|
|||
|
displayTarget.displayTargetSlotList.Add(displayTargetSlot);
|
|||
|
|
|||
|
// Refresh the size of the slot reticle panel
|
|||
|
#if UNITY_EDITOR
|
|||
|
if (editorMode) { CheckHUDResize(false); }
|
|||
|
#endif
|
|||
|
|
|||
|
RectTransform dtRectTfrm = displayTargetSlot.CachedTargetPanel;
|
|||
|
if (dtRectTfrm != null)
|
|||
|
{
|
|||
|
float pixelWidth = (float)displayTarget.width * screenResolution.x / refResolution.x;
|
|||
|
float pixelHeight = (float)displayTarget.height * screenResolution.y / refResolution.y;
|
|||
|
|
|||
|
// Target size is in pixels - this will result in non-square scaling.
|
|||
|
// (Future) provide an option to keep aspect ratio of original 64x64 reticle
|
|||
|
dtRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, pixelWidth);
|
|||
|
dtRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, pixelHeight);
|
|||
|
}
|
|||
|
|
|||
|
// Refresh brightness of this slot
|
|||
|
if (displayTargetSlot.CachedImgComponent != null)
|
|||
|
{
|
|||
|
if (brightness == 1f) { displayTargetSlot.CachedImgComponent.color = displayTarget.reticleColour; }
|
|||
|
else { displayTargetSlot.CachedImgComponent.color = displayTarget.baseReticleColour.GetColorWithBrightness(brightness); }
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
displayTarget.maxNumberOfTargets += numberAdded;
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("WARNING: shipDisplayModule.AddTargetSlot - not enough empty DisplayTarget slots"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.AddTargetSlot - displayTarget is null"); }
|
|||
|
#endif
|
|||
|
|
|||
|
return displayTargetSlot;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Delete a target from the HUD.
|
|||
|
/// NOTE: It is much cheaper to HideDisplayTarget(..) than completely remove it.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
public void DeleteTarget(int guidHash)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
bool isRecordUndo = !Application.isPlaying;
|
|||
|
int undoGroup=0;
|
|||
|
#else
|
|||
|
bool isRecordUndo = false;
|
|||
|
#endif
|
|||
|
|
|||
|
DisplayTarget displayTarget = GetDisplayTarget(guidHash);
|
|||
|
|
|||
|
List<RectTransform> tgtRectTfrmList = null;
|
|||
|
|
|||
|
// Get a list of DisplayTarget slot panels
|
|||
|
if (displayTarget != null)
|
|||
|
{
|
|||
|
tgtRectTfrmList = new List<RectTransform>(displayTarget.maxNumberOfTargets);
|
|||
|
for (int sIdx = 0; sIdx < displayTarget.maxNumberOfTargets; sIdx++)
|
|||
|
{
|
|||
|
RectTransform tgtRectTfrm = GetTargetPanel(guidHash, sIdx);
|
|||
|
if (tgtRectTfrm != null)
|
|||
|
{
|
|||
|
tgtRectTfrmList.Add(tgtRectTfrm);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
int _numPanels = tgtRectTfrmList == null ? 0 : tgtRectTfrmList.Count;
|
|||
|
int _tgtIndex = GetDisplayTargetIndex(guidHash);
|
|||
|
|
|||
|
// Only record undo if in the editor AND is not playing AND something needs to be recorded
|
|||
|
isRecordUndo = isRecordUndo && (_numPanels > 0 || _tgtIndex >= 0);
|
|||
|
|
|||
|
#if UNITY_EDITOR
|
|||
|
if (isRecordUndo)
|
|||
|
{
|
|||
|
UnityEditor.Undo.SetCurrentGroupName("Delete Display Target " + (_tgtIndex + 1).ToString());
|
|||
|
undoGroup = UnityEditor.Undo.GetCurrentGroup();
|
|||
|
|
|||
|
if (_tgtIndex >= 0)
|
|||
|
{
|
|||
|
UnityEditor.Undo.RecordObject(this, string.Empty);
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
// Check that the display target exists and it is within the list constraints
|
|||
|
// NOTE: The script element must be modified BEFORE the Undo.DestroyObjectImmediate is called
|
|||
|
// in order for Undo to correctly undo both the target change AND the destroy of the panels.
|
|||
|
if (_tgtIndex >= 0 && _tgtIndex < (displayTargetList == null ? 0 : displayTargetList.Count))
|
|||
|
{
|
|||
|
displayTargetList.RemoveAt(_tgtIndex);
|
|||
|
numDisplayTargets = displayTargetList.Count;
|
|||
|
}
|
|||
|
|
|||
|
if (_numPanels > 0)
|
|||
|
{
|
|||
|
if (Application.isPlaying)
|
|||
|
{
|
|||
|
// Destroy all the slot panels
|
|||
|
for (int sIdx = _numPanels - 1; sIdx >= 0; sIdx--)
|
|||
|
{
|
|||
|
Destroy(tgtRectTfrmList[sIdx].gameObject);
|
|||
|
tgtRectTfrmList.RemoveAt(sIdx);
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// Destroy all the slot panels
|
|||
|
for (int sIdx = _numPanels - 1; sIdx >= 0; sIdx--)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
UnityEditor.Undo.DestroyObjectImmediate(tgtRectTfrmList[sIdx].gameObject);
|
|||
|
#else
|
|||
|
DestroyImmediate(tgtRectTfrmList[sIdx].gameObject);
|
|||
|
#endif
|
|||
|
tgtRectTfrmList.RemoveAt(sIdx);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#if UNITY_EDITOR
|
|||
|
if (isRecordUndo)
|
|||
|
{
|
|||
|
UnityEditor.Undo.CollapseUndoOperations(undoGroup);
|
|||
|
}
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Delete or remove a DisplayTarget slot from the HUD. This is an expensive operation.
|
|||
|
/// It is much cheaper to HideDisplayTargetSlot(..) than completely remove it.
|
|||
|
/// Automatically updates displayTarget.maxNumberOfTargets.
|
|||
|
/// NOTE: You cannot remove slot 0.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash">guidHash of the DisplayTarget</param>
|
|||
|
/// <returns></returns>
|
|||
|
public void DeleteTargetSlots(int guidHash, int numberToDelete)
|
|||
|
{
|
|||
|
DisplayTarget displayTarget = GetDisplayTarget(guidHash);
|
|||
|
|
|||
|
if (displayTarget != null)
|
|||
|
{
|
|||
|
int remainingTargets = displayTarget.maxNumberOfTargets - numberToDelete;
|
|||
|
|
|||
|
if (remainingTargets > 0)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
bool isRecordUndo = !Application.isPlaying;
|
|||
|
int undoGroup=0;
|
|||
|
#else
|
|||
|
bool isRecordUndo = false;
|
|||
|
#endif
|
|||
|
|
|||
|
List<RectTransform> tgtRectTfrmList = null;
|
|||
|
|
|||
|
// Get a list of DisplayTarget slot panels to remove
|
|||
|
if (displayTarget != null)
|
|||
|
{
|
|||
|
tgtRectTfrmList = new List<RectTransform>(displayTarget.maxNumberOfTargets);
|
|||
|
for (int sIdx = remainingTargets; sIdx < displayTarget.maxNumberOfTargets; sIdx++)
|
|||
|
{
|
|||
|
RectTransform tgtRectTfrm = GetTargetPanel(guidHash, sIdx);
|
|||
|
if (tgtRectTfrm != null)
|
|||
|
{
|
|||
|
tgtRectTfrmList.Add(tgtRectTfrm);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
int _numPanels = tgtRectTfrmList == null ? 0 : tgtRectTfrmList.Count;
|
|||
|
int _tgtIndex = GetDisplayTargetIndex(guidHash);
|
|||
|
|
|||
|
// Only record undo if in the editor AND is not playing AND something needs to be recorded
|
|||
|
isRecordUndo = isRecordUndo && (_numPanels > 0 || _tgtIndex >= 0);
|
|||
|
|
|||
|
#if UNITY_EDITOR
|
|||
|
if (isRecordUndo)
|
|||
|
{
|
|||
|
UnityEditor.Undo.SetCurrentGroupName("Delete Display Target " + (_tgtIndex + 1).ToString() + " slots");
|
|||
|
undoGroup = UnityEditor.Undo.GetCurrentGroup();
|
|||
|
|
|||
|
if (_tgtIndex >= 0)
|
|||
|
{
|
|||
|
UnityEditor.Undo.RecordObject(this, string.Empty);
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
// NOTE: The script element must be modified BEFORE the Undo.DestroyObjectImmediate is called
|
|||
|
// in order for Undo to correctly undo both the target change AND the destroy of the panels.
|
|||
|
if (displayTarget.isInitialised)
|
|||
|
{
|
|||
|
for (int sIdx = displayTarget.maxNumberOfTargets - 1; sIdx >= remainingTargets; sIdx--)
|
|||
|
{
|
|||
|
if (sIdx < displayTarget.displayTargetSlotList.Count)
|
|||
|
{
|
|||
|
displayTarget.displayTargetSlotList[sIdx] = null;
|
|||
|
displayTarget.displayTargetSlotList.RemoveAt(sIdx);
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.DeleteTargetSlot - tried to remove initialised slot " + sIdx + " but only " + displayTarget.displayTargetSlotList.Count + " exist."); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
displayTarget.maxNumberOfTargets = remainingTargets;
|
|||
|
|
|||
|
if (_numPanels > 0)
|
|||
|
{
|
|||
|
if (Application.isPlaying)
|
|||
|
{
|
|||
|
// Destroy the slot panels
|
|||
|
for (int sIdx = _numPanels - 1; sIdx >= 0; sIdx--)
|
|||
|
{
|
|||
|
Destroy(tgtRectTfrmList[sIdx].gameObject);
|
|||
|
tgtRectTfrmList.RemoveAt(sIdx);
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// Destroy the slot panels
|
|||
|
for (int sIdx = _numPanels - 1; sIdx >= 0; sIdx--)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
UnityEditor.Undo.DestroyObjectImmediate(tgtRectTfrmList[sIdx].gameObject);
|
|||
|
#else
|
|||
|
DestroyImmediate(tgtRectTfrmList[sIdx].gameObject);
|
|||
|
#endif
|
|||
|
tgtRectTfrmList.RemoveAt(sIdx);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#if UNITY_EDITOR
|
|||
|
if (isRecordUndo)
|
|||
|
{
|
|||
|
UnityEditor.Undo.CollapseUndoOperations(undoGroup);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("WARNING: shipDisplayModule.DeleteTargetSlot - cannot delete that many DisplayTarget slots"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.DeleteTargetSlot - displayTarget cannot be found with guidHash: " + guidHash); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Assign a radar target to a DisplayTarget's slot.
|
|||
|
/// See also GetAssignedDisplayTarget(..)
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayTargetIndex"></param>
|
|||
|
/// <param name="instanceIndex"></param>
|
|||
|
/// <param name="radarItemIndex"></param>
|
|||
|
/// <param name="radarItemSequenceNumber"></param>
|
|||
|
public void AssignDisplayTargetSlot(int displayTargetIndex, int slotIndex, int radarItemIndex, uint radarItemSequenceNumber, bool isAutoShow)
|
|||
|
{
|
|||
|
if (displayTargetIndex >= 0 && displayTargetIndex < GetNumberDisplayTargets)
|
|||
|
{
|
|||
|
DisplayTarget displayTarget = displayTargetList[displayTargetIndex];
|
|||
|
if (displayTarget != null && slotIndex >= 0 && slotIndex < displayTarget.maxNumberOfTargets)
|
|||
|
{
|
|||
|
DisplayTargetSlot displayTargetSlot = displayTarget.displayTargetSlotList[slotIndex];
|
|||
|
|
|||
|
displayTargetSlot.radarItemKey.radarItemIndex = radarItemIndex;
|
|||
|
displayTargetSlot.radarItemKey.radarItemSequenceNumber = radarItemSequenceNumber;
|
|||
|
|
|||
|
if (isAutoShow)
|
|||
|
{
|
|||
|
// Should the DisplayTarget be shown?
|
|||
|
if (radarItemIndex >= 0)
|
|||
|
{
|
|||
|
// If not already shown, turn it on.
|
|||
|
if (!displayTargetSlot.showTargetSlot)
|
|||
|
{
|
|||
|
ShowOrHideTargetSlot(displayTargetSlot, true);
|
|||
|
// If one slot is on, mark the displayTarget as shown also.
|
|||
|
displayTarget.showTarget = true;
|
|||
|
}
|
|||
|
}
|
|||
|
// If should not be shown, but currently is, turn it off
|
|||
|
else if (displayTargetSlot.showTargetSlot) { ShowOrHideTargetSlot(displayTargetSlot, false); }
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get the radarItemKey for a DisplayTarget's slot.
|
|||
|
/// SSCRadarItemKey.radarItemIndex will be -1 if there is no target.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayTargetIndex"></param>
|
|||
|
/// <param name="slotIndex"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public SSCRadarItemKey GetAssignedDisplayTarget(int displayTargetIndex, int slotIndex)
|
|||
|
{
|
|||
|
if (displayTargetIndex >= 0 && displayTargetIndex < GetNumberDisplayTargets)
|
|||
|
{
|
|||
|
DisplayTarget displayTarget = displayTargetList[displayTargetIndex];
|
|||
|
if (displayTarget != null && slotIndex >= 0 && slotIndex < displayTarget.maxNumberOfTargets)
|
|||
|
{
|
|||
|
return displayTarget.displayTargetSlotList[slotIndex].radarItemKey;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return new SSCRadarItemKey() { radarItemIndex = -1, radarItemSequenceNumber = 0 };
|
|||
|
}
|
|||
|
}
|
|||
|
else { return new SSCRadarItemKey() { radarItemIndex = -1, radarItemSequenceNumber = 0 }; }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get the SSCRadarItem currently assigned to a DisplayTarget slot (instance).
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayTargetSlot"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public SSCRadarItem GetAssignedDisplayTargetRadarItem (DisplayTargetSlot displayTargetSlot)
|
|||
|
{
|
|||
|
if (displayTargetSlot != null && displayTargetSlot.radarItemKey.radarItemIndex >= 0 && sscRadar != null)
|
|||
|
{
|
|||
|
return sscRadar.GetRadarItem(displayTargetSlot.radarItemKey.radarItemIndex);
|
|||
|
}
|
|||
|
else { return null; }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Returns the guidHash of the Target in the list given the index or
|
|||
|
/// zero-based position in the list. Will return 0 if no matching Target
|
|||
|
/// is found.
|
|||
|
/// </summary>
|
|||
|
/// <param name="index"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public int GetDisplayTargetGuidHash(int index)
|
|||
|
{
|
|||
|
int guidHash = 0;
|
|||
|
|
|||
|
if (index >= 0 && index < GetNumberDisplayTargets)
|
|||
|
{
|
|||
|
if (displayTargetList[index] != null) { guidHash = displayTargetList[index].guidHash; }
|
|||
|
}
|
|||
|
|
|||
|
return guidHash;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get the zero-based index of the Target in the list. Will return -1 if not found.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public int GetDisplayTargetIndex(int guidHash)
|
|||
|
{
|
|||
|
int index = -1;
|
|||
|
|
|||
|
int _numDisplayTargets = GetNumberDisplayTargets;
|
|||
|
|
|||
|
for (int dmIdx = 0; dmIdx < _numDisplayTargets; dmIdx++)
|
|||
|
{
|
|||
|
if (displayTargetList[dmIdx] != null && displayTargetList[dmIdx].guidHash == guidHash) { index = dmIdx; break; }
|
|||
|
}
|
|||
|
|
|||
|
return index;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get a DisplayTarget given its guidHash.
|
|||
|
/// See also GetDisplayTargetGuidHash(..).
|
|||
|
/// Will return null if guidHash parameter is 0, it cannot be found.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public DisplayTarget GetDisplayTarget(int guidHash)
|
|||
|
{
|
|||
|
DisplayTarget displayTarget = null;
|
|||
|
DisplayTarget _tempDM = null;
|
|||
|
|
|||
|
int _numDisplayTargets = GetNumberDisplayTargets;
|
|||
|
|
|||
|
for (int dmIdx = 0; dmIdx < _numDisplayTargets; dmIdx++)
|
|||
|
{
|
|||
|
_tempDM = displayTargetList[dmIdx];
|
|||
|
if (_tempDM != null && _tempDM.guidHash == guidHash)
|
|||
|
{
|
|||
|
displayTarget = _tempDM;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return displayTarget;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get a DisplayTarget given a zero-based index in the list.
|
|||
|
/// </summary>
|
|||
|
/// <param name="index"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public DisplayTarget GetDisplayTargetByIndex(int index)
|
|||
|
{
|
|||
|
if (index >= 0 && index < GetNumberDisplayTargets)
|
|||
|
{
|
|||
|
return displayTargetList[index];
|
|||
|
}
|
|||
|
else { return null; }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get the (sprite) name of the DisplayTarget.
|
|||
|
/// WARNING: This will create GC, so not recommended to be called each frame.
|
|||
|
/// This is typically used for debugging purposes only.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayTarget"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public string GetDisplayTargetName(DisplayTarget displayTarget)
|
|||
|
{
|
|||
|
if (displayTarget != null && displayReticleList != null)
|
|||
|
{
|
|||
|
int _selectedIdx = displayReticleList.FindIndex(dr => dr.guidHash == displayTarget.guidHashDisplayReticle);
|
|||
|
|
|||
|
if (_selectedIdx >= 0)
|
|||
|
{
|
|||
|
string tempDisplayReticleName = displayReticleList[_selectedIdx].primarySprite == null ? "no texture in reticle" : displayReticleList[_selectedIdx].primarySprite.name;
|
|||
|
return string.IsNullOrEmpty(tempDisplayReticleName) ? "no texture name" : tempDisplayReticleName;
|
|||
|
}
|
|||
|
else { return "--"; }
|
|||
|
}
|
|||
|
else { return "--"; }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get the (sprite) name of the DisplayTarget.
|
|||
|
/// WARNING: This will create GC, so not recommended to be called each frame.
|
|||
|
/// This is typically used for debugging purposes only.
|
|||
|
/// </summary>
|
|||
|
/// <param name="index"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public string GetDisplayTargetName(int index)
|
|||
|
{
|
|||
|
return GetDisplayTargetName(GetDisplayTargetByIndex(index));
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Get a DisplayTargetSlot given the zero-based slot index. This is an instance of a DisplayTarget.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayTarget"></param>
|
|||
|
/// <param name="slotIndex"></param>
|
|||
|
/// <returns></returns>
|
|||
|
public DisplayTargetSlot GetDisplayTargetSlotByIndex (DisplayTarget displayTarget, int slotIndex)
|
|||
|
{
|
|||
|
if (IsInitialised && displayTarget != null && slotIndex > -1 && slotIndex < displayTarget.maxNumberOfTargets)
|
|||
|
{
|
|||
|
return displayTarget.displayTargetSlotList[slotIndex];
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return null;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show the Display Target slots on the HUD. By design, if the HUD is not shown, the Targets will not be show.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
public void ShowDisplayTarget(int guidHash)
|
|||
|
{
|
|||
|
DisplayTarget displayTarget = GetDisplayTarget(guidHash);
|
|||
|
if (displayTarget != null) { ShowOrHideTarget(displayTarget, true); }
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("WARNING: ShowDisplayTarget - Could not find displayTarget with guidHash: " + guidHash); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show the Display Target slots on the HUD. By design, if the HUD is not shown, the Targets will not be show.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayTarget"></param>
|
|||
|
public void ShowDisplayTarget(DisplayTarget displayTarget)
|
|||
|
{
|
|||
|
if (displayTarget != null) { ShowOrHideTarget(displayTarget, true); }
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("WARNING: ShowDisplayTarget - displayTarget parameter was null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show the Display Target slot on the HUD. By design, if the HUD is not shown, the Target in this slot will not be show.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayTargetSlot"></param>
|
|||
|
public void ShowDisplayTargetSlot(DisplayTargetSlot displayTargetSlot)
|
|||
|
{
|
|||
|
if (displayTargetSlot != null) { ShowOrHideTargetSlot(displayTargetSlot, true); }
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("WARNING: ShowDisplayTargetSlot - displayTargetSlot parameter was null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Show or turn on all Display Targets.
|
|||
|
/// ShipDisplayModule must be initialised.
|
|||
|
/// </summary>
|
|||
|
public void ShowDisplayTargets()
|
|||
|
{
|
|||
|
ShowOrHideTargets(true);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Hide or turn off all slots the Display Target
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
public void HideDisplayTarget(int guidHash)
|
|||
|
{
|
|||
|
DisplayTarget displayTarget = GetDisplayTarget(guidHash);
|
|||
|
if (displayTarget != null) { ShowOrHideTarget(displayTarget, false); }
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("WARNING: ShowDisplayTarget - Could not find message with guidHash: " + guidHash); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Hide or turn off all slots of the Display Target
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayTarget"></param>
|
|||
|
public void HideDisplayTarget(DisplayTarget displayTarget)
|
|||
|
{
|
|||
|
if (displayTarget != null) { ShowOrHideTarget(displayTarget, false); }
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("WARNING: ShowDisplayTarget - Could not find message - parameter was null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Hide the Display Target slot on the HUD. By design, if the HUD is not shown, the Target in this slot will not be show.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayTargetSlot"></param>
|
|||
|
public void HideDisplayTargetSlot(DisplayTargetSlot displayTargetSlot)
|
|||
|
{
|
|||
|
if (displayTargetSlot != null) { ShowOrHideTargetSlot(displayTargetSlot, false); }
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("WARNING: HideDisplayTargetSlot - displayTargetSlot parameter was null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Hide or turn off all all slots of all Display Targets.
|
|||
|
/// ShipDisplayModule must be initialised.
|
|||
|
/// </summary>
|
|||
|
public void HideDisplayTargets()
|
|||
|
{
|
|||
|
ShowOrHideTargets(false);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Given a radar query, add rules based on the current DisplayTargets.
|
|||
|
/// TODO - WARNING - NEED TO PERFORMANCE TEST THIS
|
|||
|
/// </summary>
|
|||
|
public void PopulateTargetingRadarQuery(SSCRadarQuery sscRadarQuery)
|
|||
|
{
|
|||
|
// Build a common list of factions and squadrons to include
|
|||
|
if (IsInitialised)
|
|||
|
{
|
|||
|
int _numDisplayTargets = GetNumberDisplayTargets;
|
|||
|
|
|||
|
if (_numDisplayTargets > 0)
|
|||
|
{
|
|||
|
tempIncludeFactionList.Clear();
|
|||
|
tempIncludeSquadronList.Clear();
|
|||
|
|
|||
|
for (int dtIdx = 0; dtIdx < _numDisplayTargets; dtIdx++)
|
|||
|
{
|
|||
|
DisplayTarget _tempDT = displayTargetList[dtIdx];
|
|||
|
|
|||
|
if (_tempDT != null)
|
|||
|
{
|
|||
|
int _numFactionsToInclude = _tempDT.factionsToInclude == null ? 0 : _tempDT.factionsToInclude.Length;
|
|||
|
int _numSquadronsToInclude = _tempDT.squadronsToInclude == null ? 0 : _tempDT.squadronsToInclude.Length;
|
|||
|
|
|||
|
// By default there is no exclude
|
|||
|
sscRadarQuery.factionsToExclude = null;
|
|||
|
sscRadarQuery.squadronsToExclude = null;
|
|||
|
|
|||
|
// Determine which Factions (if any) to include as a filter
|
|||
|
for (int fIdx = 0; fIdx < _numFactionsToInclude; fIdx++)
|
|||
|
{
|
|||
|
// If faction is not already in list add it.
|
|||
|
int _factionId = _tempDT.factionsToInclude[fIdx];
|
|||
|
if (tempIncludeFactionList.FindIndex(f => f == _factionId) < 0)
|
|||
|
{
|
|||
|
tempIncludeFactionList.Add(_factionId);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Determine which Squadrons (if any) to include as a filter
|
|||
|
for (int sqIdx = 0; sqIdx < _numSquadronsToInclude; sqIdx++)
|
|||
|
{
|
|||
|
// If squadron is not already in list add it.
|
|||
|
int _squadronId = _tempDT.squadronsToInclude[sqIdx];
|
|||
|
if (tempIncludeSquadronList.FindIndex(sq => sq == _squadronId) < 0)
|
|||
|
{
|
|||
|
tempIncludeSquadronList.Add(_squadronId);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (tempIncludeFactionList.Count > 0)
|
|||
|
{
|
|||
|
// Check if this generates work for GC
|
|||
|
sscRadarQuery.factionsToInclude = tempIncludeFactionList.ToArray();
|
|||
|
}
|
|||
|
else { sscRadarQuery.factionsToInclude = null; }
|
|||
|
|
|||
|
if (tempIncludeSquadronList.Count > 0)
|
|||
|
{
|
|||
|
// Check if this generates work for GC
|
|||
|
sscRadarQuery.squadronsToInclude = tempIncludeSquadronList.ToArray();
|
|||
|
}
|
|||
|
else { sscRadarQuery.squadronsToInclude = null; }
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
sscRadarQuery.range = targetingRange;
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: PopulateTargetingRadarQuery - shipDisplayModule is not initialised"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set or change the Reticle assigned to a DisplayTarget.
|
|||
|
/// The Reticle must belong to the list of available reticles for the HUD.
|
|||
|
/// </summary>
|
|||
|
/// <param name="guidHash"></param>
|
|||
|
/// <param name="guidHashDisplayReticle"></param>
|
|||
|
public void SetDisplayTargetReticle(int guidHash, int guidHashDisplayReticle)
|
|||
|
{
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
DisplayTarget displayTarget = GetDisplayTarget(guidHash);
|
|||
|
|
|||
|
if (displayTarget != null)
|
|||
|
{
|
|||
|
displayTarget.guidHashDisplayReticle = guidHashDisplayReticle;
|
|||
|
|
|||
|
DisplayReticle _displayReticle = GetDisplayReticle(guidHashDisplayReticle);
|
|||
|
|
|||
|
// Set the reticle for all slots of this DisplayTarget
|
|||
|
for (int sIdx = 0; sIdx < displayTarget.maxNumberOfTargets; sIdx++)
|
|||
|
{
|
|||
|
if (displayTarget.displayTargetSlotList[sIdx].CachedImgComponent != null)
|
|||
|
{
|
|||
|
displayTarget.displayTargetSlotList[sIdx].CachedImgComponent.sprite = _displayReticle == null ? null : _displayReticle.primarySprite;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the Display Target Reticle colour. Only update the colour if it has actually changed.
|
|||
|
/// If the module has been initialised, this will also re-colour the reticle with the appropriate brightness.
|
|||
|
/// </summary>
|
|||
|
/// <param name="newColour"></param>
|
|||
|
public void SetDisplayTargetReticleColour(DisplayTarget displayTarget, Color newColour)
|
|||
|
{
|
|||
|
if (displayTarget != null)
|
|||
|
{
|
|||
|
SSCUtils.UpdateColour(ref newColour, ref displayTarget.reticleColour, ref displayTarget.baseReticleColour, true);
|
|||
|
|
|||
|
SetDisplayTargetBrightness(displayTarget);
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayTargetReticleColour - displayTarget is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the offset (position) of the Display Target slot on the HUD.
|
|||
|
/// If the module has been initialised, this will also re-position the Display Target.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayTarget"></param>
|
|||
|
/// <param name="slotIndex"></param>
|
|||
|
/// <param name="offsetX"></param>
|
|||
|
/// <param name="offsetY"></param>
|
|||
|
public void SetDisplayTargetOffset(DisplayTarget displayTarget, int slotIndex, float offsetX, float offsetY)
|
|||
|
{
|
|||
|
if (displayTarget != null)
|
|||
|
{
|
|||
|
int numSlots = displayTarget.displayTargetSlotList == null ? 0 : displayTarget.displayTargetSlotList.Count;
|
|||
|
|
|||
|
if (slotIndex >= 0 & slotIndex < numSlots)
|
|||
|
{
|
|||
|
SetDisplayTargetOffset(displayTarget.displayTargetSlotList[slotIndex], offsetX, offsetY);
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayTargetOffset - the displayTarget slot is out-of-range (" + slotIndex + ")"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayTargetOffset - displayTarget is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the offset (position) of the Display Target slot on the HUD.
|
|||
|
/// If the module has been initialised, this will also re-position the Display Target.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayTargetSlot"></param>
|
|||
|
/// <param name="offsetX">Horizontal offset from centre. Range between -1 and 1</param>
|
|||
|
/// <param name="offsetY">Vertical offset from centre. Range between -1 and 1</param>
|
|||
|
public void SetDisplayTargetOffset(DisplayTargetSlot displayTargetSlot, float offsetX, float offsetY)
|
|||
|
{
|
|||
|
if (displayTargetSlot != null)
|
|||
|
{
|
|||
|
// Verify the x,y values are within range -1 to 1.
|
|||
|
if (offsetX < -1f) { displayTargetSlot.offsetX = -1f; }
|
|||
|
else if (offsetX > 1f) { displayTargetSlot.offsetX = 1f; }
|
|||
|
else
|
|||
|
{
|
|||
|
displayTargetSlot.offsetX = offsetX;
|
|||
|
}
|
|||
|
|
|||
|
if (offsetY < -1f) { displayTargetSlot.offsetY = -1f; }
|
|||
|
else if (offsetY > 1f) { displayTargetSlot.offsetY = 1f; }
|
|||
|
else
|
|||
|
{
|
|||
|
displayTargetSlot.offsetY = offsetY;
|
|||
|
}
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
Transform dtgtTrfm = displayTargetSlot.CachedTargetPanel.transform;
|
|||
|
|
|||
|
#if UNITY_EDITOR
|
|||
|
if (editorMode)
|
|||
|
{
|
|||
|
CheckHUDResize(false);
|
|||
|
UnityEditor.Undo.RecordObject(dtgtTrfm, string.Empty);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
// Use the scaled HUD size. This works in and out of play mode
|
|||
|
tempTargetOffset.x = displayTargetSlot.offsetX * cvsResolutionHalf.x;
|
|||
|
tempTargetOffset.y = displayTargetSlot.offsetY * cvsResolutionHalf.y;
|
|||
|
tempTargetOffset.z = dtgtTrfm.localPosition.z;
|
|||
|
|
|||
|
dtgtTrfm.localPosition = tempTargetOffset;
|
|||
|
}
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayTargetOffset - displayTargetSlot is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Move the DisplayTarget Slot to the correct 2D position on the HUD, based on a 3D world space position.
|
|||
|
/// If the camera has not been automatically or manually assigned, the DisplayTarget will not be moved.
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayTarget"></param>
|
|||
|
/// <param name="slotIndex"></param>
|
|||
|
/// <param name="wsPosition"></param>
|
|||
|
public void SetDisplayTargetPosition(DisplayTarget displayTarget, int slotIndex, Vector3 wsPosition)
|
|||
|
{
|
|||
|
if (isMainCameraAssigned)
|
|||
|
{
|
|||
|
if (displayTarget != null)
|
|||
|
{
|
|||
|
Vector3 screenPosition = mainCamera.WorldToScreenPoint(wsPosition);
|
|||
|
|
|||
|
// NOTE: cvsResolutionFull.x / cvsScaleFactor.x is NOT the same as Screen.width
|
|||
|
// x 2 and subtracting 1 moves it into our HUD -1 to 1 space.
|
|||
|
SetDisplayTargetOffset(displayTarget, slotIndex, 2f * screenPosition.x / cvsResolutionFull.x / cvsScaleFactor.x - 1f, 2f * screenPosition.y / cvsResolutionFull.y / cvsScaleFactor.y - 1f);
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: shipDisplayModule.SetDisplayTargetPosition - displayTarget is null"); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
#if UNITY_EDITOR
|
|||
|
else { Debug.LogWarning("ERROR: ShipDisplayModule.SetDisplayTargetPosition - Could not find mainCamera."); }
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Set the size of the Target Reticle in each slot.
|
|||
|
/// If the module has been initialised, this will also resize the Target Reticle.
|
|||
|
/// The values are only updated if they are outside the range 8 to 256 or have changed.
|
|||
|
/// The size is based on a screen resolution of 1920x1080
|
|||
|
/// </summary>
|
|||
|
/// <param name="displayTarget"></param>
|
|||
|
/// <param name="width">Range between 8 and 256</param>
|
|||
|
/// <param name="height">Range between 8 and 256</param>
|
|||
|
public void SetDisplayTargetSize(DisplayTarget displayTarget, int width, int height)
|
|||
|
{
|
|||
|
// Clamp the x,y values 8 to 256
|
|||
|
if (width < 8) { displayTarget.width = 8; }
|
|||
|
else if (width > 256) { displayTarget.width = 256; }
|
|||
|
else if (width != displayTarget.width) { displayTarget.width = width; }
|
|||
|
|
|||
|
if (height < 8) { displayTarget.height = 8; }
|
|||
|
else if (height > 256) { displayTarget.height = 256; }
|
|||
|
else if (height != displayTarget.height) { displayTarget.height = height; }
|
|||
|
|
|||
|
if (IsInitialised || editorMode)
|
|||
|
{
|
|||
|
#if UNITY_EDITOR
|
|||
|
if (editorMode) { CheckHUDResize(false); }
|
|||
|
#endif
|
|||
|
|
|||
|
float pixelWidth = (float)displayTarget.width * screenResolution.x / refResolution.x;
|
|||
|
float pixelHeight = (float)displayTarget.height * screenResolution.y / refResolution.y;
|
|||
|
|
|||
|
// Set the size of all the reticles in the DisplayTarget slots
|
|||
|
// There can be multiple copies or slots of the same DisplayTarget.
|
|||
|
for (int sIdx = 0; sIdx < displayTarget.maxNumberOfTargets; sIdx++)
|
|||
|
{
|
|||
|
RectTransform dtRectTfrm = displayTarget.displayTargetSlotList[sIdx].CachedTargetPanel;
|
|||
|
|
|||
|
if (dtRectTfrm != null)
|
|||
|
{
|
|||
|
// Target size is in pixels - this will result in non-square scaling.
|
|||
|
// (Future) provide an option to keep aspect ratio of original 64x64 reticle
|
|||
|
dtRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, pixelWidth);
|
|||
|
dtRectTfrm.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, pixelHeight);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Sets the clipped viewable area of the screen that DisplayTargets can be shown. When Targets
|
|||
|
/// are outside this area, they will be hidden.
|
|||
|
/// See also SetTargetsViewportOffset(..).
|
|||
|
/// </summary>
|
|||
|
/// <param name="width">Range between 0.1 and 1.0</param>
|
|||
|
/// <param name="height">Range between 0.1 and 1.0</param>
|
|||
|
public void SetTargetsViewportSize(float width, float height)
|
|||
|
{
|
|||
|
// Currently we just set the values after basic validation. This may change in future versions
|
|||
|
|
|||
|
// Perform basic validation
|
|||
|
if (width >= 0.1f && width <= 1.0f) { targetsViewWidth = width; }
|
|||
|
if (height >= 0.1f && height <= 1.0f) { targetsViewHeight = height; }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Sets the Targets viewport offset from the centre of the screen.
|
|||
|
/// Values can be between -1.0 and 1.0 with 0,0 depicting the centre of the screen.
|
|||
|
/// See also SetTargetsViewportSize(..).
|
|||
|
/// </summary>
|
|||
|
/// <param name="offsetX">Range between -1.0 and 1.0</param>
|
|||
|
/// <param name="offsetY">Range between -1.0 and 1.0</param>
|
|||
|
public void SetTargetsViewportOffset(float offsetX, float offsetY)
|
|||
|
{
|
|||
|
// Currently we just set the values after basic validation. This may change in future versions
|
|||
|
|
|||
|
if (offsetX >= -1f && offsetX <= 1.0f) { targetsViewOffsetX = offsetX; }
|
|||
|
if (offsetY >= -1f && offsetY <= 1.0f) { targetsViewOffsetY = offsetY; }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// After adding or moving DisplayTargets, they may need to be sorted to
|
|||
|
/// have the correct z-order in on the HUD.
|
|||
|
/// </summary>
|
|||
|
public void RefreshTargetsSortOrder()
|
|||
|
{
|
|||
|
if (targetsRectTfrm != null)
|
|||
|
{
|
|||
|
// Targets should begin at index 0.
|
|||
|
int zIndex = -1;
|
|||
|
|
|||
|
// Update number of DisplayTargets. This can help issues in the Editor, like moving DislayTargets
|
|||
|
// up or down in the list while in play mode.
|
|||
|
numDisplayTargets = displayTargetList == null ? 0 : displayTargetList.Count;
|
|||
|
|
|||
|
for (int dtIdx = 0; dtIdx < numDisplayTargets; dtIdx++)
|
|||
|
{
|
|||
|
DisplayTarget displayTarget = displayTargetList[dtIdx];
|
|||
|
|
|||
|
if (displayTarget != null)
|
|||
|
{
|
|||
|
//Debug.Log("[DEBUG] dt: " + dtIdx + " maxNum: " + displayTarget.maxNumberOfTargets + " actual: " + displayTarget.displayTargetSlotList.Count);
|
|||
|
|
|||
|
// Loop through all the slots for this DisplayTarget
|
|||
|
for (int sIdx = 0; sIdx < displayTarget.maxNumberOfTargets; sIdx++)
|
|||
|
{
|
|||
|
RectTransform _rt = displayTarget.displayTargetSlotList[sIdx].CachedTargetPanel;
|
|||
|
|
|||
|
if (_rt != null)
|
|||
|
{
|
|||
|
_rt.SetSiblingIndex(++zIndex);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Create a new list if required
|
|||
|
/// </summary>
|
|||
|
public void ValidateTargetList()
|
|||
|
{
|
|||
|
if (displayTargetList == null) { displayTargetList = new List<DisplayTarget>(1); }
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
}
|
|||
|
}
|