zero3growlithe

FlightProgressController.cs

Sep 2nd, 2015
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.33 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. public class FlightProgressController : MonoBehaviour {
  6.  
  7. //*** ATTRIBUTES ***//
  8.  
  9. //*** PROPERTIES ***//
  10.     public float CurrentProgress {get; private set;}
  11.     public int Laps {
  12.         get {return GetFixedCurrentLapIndex();}
  13.     }
  14.  
  15.     public int CurrentSubPathIndex {
  16.         get;
  17.         private set;
  18.     }
  19.     public bool IsOnSubPath {
  20.         get {return
  21.                 GetNodeProperties(CurrentNode - 1).IsSplitRoadNode ||
  22.                 GetNodeProperties(CurrentNode).IsSplitRoadNode;
  23.         }
  24.     }
  25.  
  26.     // REFERENCES
  27.     private TrackSetupManager TrackSetup {
  28.         get {return TrackSetupManager.Instance;}
  29.     }
  30.  
  31.     // REFERENCE DATA
  32.     private int NodeCount {
  33.         get {return TrackSetup != null ? TrackSetup.OrientedTrackNodes.Length : 0;}
  34.     }
  35.     private TrackNodeProperties[] Nodes {
  36.         get {return TrackSetup != null ? TrackSetup.OrientedTrackNodes : new TrackNodeProperties[0];}
  37.     }
  38.  
  39.     // PROGRESS TRACKING
  40.     public int CurrentNode {get; private set;}
  41.     public int ReachedNodesCount {get; private set;}
  42.  
  43.     private int ProgressNode {get; set;}
  44.     private int[] CurrentSubIndexes {get; set;}
  45.  
  46.     // NODE TRACKING
  47.     private float PreviousNodeDistance {get; set;}
  48.     private float CurrentNodeDistance {get; set;}
  49.     private float NextNodeDistance {get; set;}
  50.  
  51.     private float NextNodePathLength {get; set;}
  52.     private float PreviousNodePathLength {get; set;}
  53.  
  54.     // CONSTANTS
  55.     private const int ProgressNodeSwitchThreshold = 2;
  56.     private const float ProgressUpdateSpeed = 30f;
  57.     private const int LapCountNodeOffset = 5;
  58.  
  59. //*** METHODS - PUBLIC ***//
  60.     public TrackNodeProperties GetCurrentNodeProperties (){
  61.         TrackNodeProperties nodeProperties = Nodes[CurrentNode];
  62.  
  63.         if (IsOnSubPath == true){
  64.             nodeProperties = GetCurrentSubPaths()[CurrentSubPathIndex].Nodes[CurrentSubIndexes[CurrentSubPathIndex]];
  65.         }
  66.  
  67.         return nodeProperties;
  68.     }
  69.  
  70.     public TrackNodeProperties[] GetNodesByCount (int count){
  71.         List<TrackNodeProperties> nodes = new List<TrackNodeProperties>();
  72.  
  73.         for (int i = 0; i <= count; i++){
  74.             nodes.Add(GetNodeProperties(CurrentNode + i));
  75.         }
  76.  
  77.         return nodes.ToArray();
  78.     }
  79.  
  80.     public TrackNodeProperties[] GetNodesWithSubPathByCount (int count, int startOffset = 0, int path = 0){
  81.         List<TrackNodeProperties> nodes = new List<TrackNodeProperties>();
  82.  
  83.         for (int i = startOffset; i <= count; i++){
  84.             TrackNodeProperties nextNode = GetNodeProperties(GetRealCurrentNode() + i);
  85.  
  86.             if (nextNode.IsSplitRoadNode == true){
  87.                 TrackNodeProperties[] subNodes = new TrackNodeProperties[0];
  88.                 TrackNodeProperties.SubPath[] subPaths = nextNode.NodeSubPaths;
  89.  
  90.                 CurrentSubPathIndex = Mathf.Clamp(path, 0, subPaths.Length - 1);
  91.  
  92.                 if (IsOnSubPath == true){
  93.                     subNodes = GetSubPathNodesByCount(nextNode, CurrentSubPathIndex, CurrentSubIndexes[CurrentSubPathIndex], count - i);
  94.                 } else {
  95.                     subNodes = GetSubPathNodesByCount(nextNode, CurrentSubPathIndex, 0, count - i);
  96.                 }
  97.  
  98.                 nodes.AddRange(new List<TrackNodeProperties>(subNodes));
  99.                 i += subNodes.Length;
  100.  
  101.                 continue;
  102.             }
  103.  
  104.             nodes.Add(nextNode);
  105.         }
  106.  
  107.         return nodes.ToArray();
  108.     }
  109.  
  110. //*** METHODS - PROTECTED ***//
  111.     protected virtual void Awake (){
  112.        
  113.     }
  114.  
  115.     protected virtual void Start (){
  116.        
  117.     }
  118.    
  119.     protected virtual void Update (){
  120.         if (Nodes == null || NodeCount == 0){
  121.             return;
  122.         }
  123.  
  124.         ControlBasePathNodesProgress();
  125.  
  126.         if (IsOnSubPath == false){
  127.             ResetSubPathProgress();
  128.             UpdateProgressValue(ReachedNodesCount + GetFractionPathProgress(
  129.                 GetNode(CurrentNode - 1),
  130.                 GetNode(CurrentNode),
  131.                 GetNode(CurrentNode + 1)));
  132.         } else {
  133.             ControlSubPathNodesProgress();
  134.         }
  135.     }
  136.  
  137.     protected void OnDrawGizmos (){
  138.         if (Nodes == null || NodeCount == 0){
  139.             return;
  140.         }
  141.  
  142.         Gizmos.color = Color.cyan;
  143.  
  144.         // draw main path tracking debug lines
  145.         Gizmos.DrawLine(transform.position, GetNode(CurrentNode - 1).position);
  146.         Gizmos.DrawLine(transform.position, GetNode(CurrentNode).position);
  147.         Gizmos.DrawLine(transform.position, GetNode(CurrentNode + 1).position);
  148.  
  149.         Gizmos.color = Color.red;
  150.  
  151.         // draw path for next 5 nodes
  152.         TrackNodeProperties[] leftPath = GetNodesWithSubPathByCount(5, 0, 0);
  153.         TrackNodeProperties[] rightPath = GetNodesWithSubPathByCount(5, 0, 1);
  154.  
  155.         for (int i = 0; i < leftPath.Length - 1; i++){
  156.             Gizmos.DrawLine(leftPath[i].transform.position, leftPath[i + 1].transform.position);
  157.         }
  158.  
  159.         for (int i = 0; i < rightPath.Length - 1; i++){
  160.             Gizmos.DrawLine(rightPath[i].transform.position, rightPath[i + 1].transform.position);
  161.         }
  162.     }
  163.  
  164. //*** METHODS - PRIVATE ***//
  165.     private void ResetSubPathProgress (){
  166.         CurrentSubIndexes = new int[0];
  167.         CurrentSubPathIndex = 0;
  168.     }
  169.  
  170.     private void UpdateProgressValue (float value){
  171.         if (Mathf.Abs(CurrentProgress - value) > ProgressNodeSwitchThreshold){
  172.             CurrentProgress = value;
  173.         } else {
  174.             CurrentProgress = Mathf.Lerp(CurrentProgress, value, ProgressUpdateSpeed * Time.unscaledDeltaTime);
  175.         }
  176.     }
  177.  
  178.     private void ControlBasePathNodesProgress (){
  179.         int nodeProgressCount = CheckTrackerProgressDirection(
  180.             GetNode(CurrentNode - 1),
  181.             GetNode(CurrentNode),
  182.             GetNode(CurrentNode + 1));
  183.  
  184.         CurrentNode = (CurrentNode + nodeProgressCount).Warp(0, NodeCount);
  185.         ReachedNodesCount += nodeProgressCount;
  186.  
  187.         // recursively get to the actual node in case of low framerate
  188.         if (nodeProgressCount != 0){
  189.             ControlBasePathNodesProgress();
  190.         }
  191.     }
  192.  
  193.     private void ControlSubPathNodesProgress (){
  194.         TrackNodeProperties.SubPath[] subPaths = GetCurrentSubPaths();
  195.  
  196.         if (CurrentSubIndexes == null || CurrentSubIndexes.Length != subPaths.Length){
  197.             CurrentSubIndexes = new int[subPaths.Length];
  198.         }
  199.  
  200.         // check which sub path are we currently on
  201.         float closestPathDistance = Mathf.Infinity;
  202.         int currentPathIndex = 0;
  203.  
  204.         for (int i = 0; i < CurrentSubIndexes.Length; i++){
  205.             CurrentSubIndexes[i] = Mathf.Clamp(CurrentSubIndexes[i], 1, subPaths[i].Nodes.Length - 2);
  206.  
  207.             float currentDistance = Vector3.Distance(
  208.                 transform.position,
  209.                 subPaths[i].Nodes[CurrentSubIndexes[i]].transform.position);
  210.  
  211.             if (currentDistance < closestPathDistance){
  212.                 closestPathDistance = currentDistance;
  213.                 currentPathIndex = i;
  214.             }
  215.         }
  216.  
  217.         // get current sub path progress
  218.         float actualPathProgress = 0;
  219.  
  220.         for (int i = 0; i < subPaths.Length; i++){
  221.             int nodeProgressCount = CheckTrackerProgressDirection(
  222.                 subPaths[i].Nodes[CurrentSubIndexes[i] - 1].transform,
  223.                 subPaths[i].Nodes[CurrentSubIndexes[i]].transform,
  224.                 subPaths[i].Nodes[CurrentSubIndexes[i] + 1].transform);
  225.            
  226.             CurrentSubIndexes[i] = Mathf.Clamp(CurrentSubIndexes[i] + nodeProgressCount, 1, subPaths[i].Nodes.Length - 2);
  227.  
  228.             if (i != currentPathIndex){
  229.                 continue;
  230.             }
  231.  
  232.             // get progress in percentages to fit in 01 range between main path nodes
  233.             float fractionProgress = CurrentSubIndexes[i] + GetFractionPathProgress(
  234.                 subPaths[i].Nodes[CurrentSubIndexes[i] - 1].transform,
  235.                 subPaths[i].Nodes[CurrentSubIndexes[i]].transform,
  236.                 subPaths[i].Nodes[CurrentSubIndexes[i] + 1].transform);
  237.  
  238.             actualPathProgress = fractionProgress / subPaths[i].Nodes.Length;
  239.         }
  240.  
  241.         UpdateProgressValue(GetRealReachedNodesCount() + actualPathProgress);
  242.     }
  243.  
  244.     private int CheckTrackerProgressDirection (Transform previousNode, Transform currentNode, Transform nextNode){
  245.         // check distances to the nodes
  246.         PreviousNodeDistance = Vector3.Distance(transform.position, previousNode.position);
  247.         CurrentNodeDistance = Vector3.Distance(transform.position, currentNode.position);
  248.         NextNodeDistance = Vector3.Distance(transform.position, nextNode.position);
  249.  
  250.         // check which one is closer and switch to the closer one
  251.         if (CurrentNodeDistance < PreviousNodeDistance && CurrentNodeDistance < NextNodeDistance){
  252.             return 0;
  253.         }
  254.  
  255.         int progressCount = (NextNodeDistance < CurrentNodeDistance) ? 1 : -1;
  256.  
  257.         return progressCount;
  258.     }
  259.  
  260.     private float GetFractionPathProgress (Transform previousNode, Transform currentNode, Transform nextNode){
  261.         // update node paths lengths for percentage calculation
  262.         NextNodePathLength = Vector3.Distance(currentNode.position, nextNode.position);
  263.         PreviousNodePathLength = Vector3.Distance(previousNode.position, currentNode.position);
  264.  
  265.         float nodePathFraction = 0;
  266.         float flightProgressToAdd = 0;
  267.  
  268.         // update flight progress as ReachedNodesCount + fractional value like 455.1f
  269.         if (NextNodeDistance < PreviousNodeDistance){
  270.             nodePathFraction = 1.0f - (NextNodeDistance / NextNodePathLength);
  271.             flightProgressToAdd = nodePathFraction;
  272.         } else {
  273.             nodePathFraction = PreviousNodeDistance / PreviousNodePathLength;
  274.             flightProgressToAdd = nodePathFraction - 1.0f;
  275.         }
  276.  
  277.         return flightProgressToAdd;
  278.     }
  279.  
  280.     private TrackNodeProperties.SubPath[] GetCurrentSubPaths (){
  281.         for (int i = -1; i <= 1; i++){
  282.             TrackNodeProperties node = GetNodeProperties(CurrentNode + i);
  283.  
  284.             if (node.IsSplitRoadNode == true){
  285.                 return node.NodeSubPaths;
  286.             }
  287.         }
  288.  
  289.         return null;
  290.     }
  291.  
  292.     private int GetRealCurrentNode (){
  293.         for (int i = -1; i <= 0; i++){
  294.             if (GetNodeProperties(CurrentNode + i).IsSplitRoadNode == true){
  295.                 return CurrentNode + i;
  296.             }
  297.         }
  298.  
  299.         return CurrentNode;
  300.     }
  301.  
  302.     private int GetRealReachedNodesCount (){
  303.         for (int i = -2; i <= 0; i++){
  304.             if (GetNodeProperties(CurrentNode + i).IsSplitRoadNode == true){
  305.                 return ReachedNodesCount + i;
  306.             }
  307.         }
  308.  
  309.         return ReachedNodesCount;
  310.     }
  311.  
  312.     private TrackNodeProperties[] GetSubPathNodesByCount (TrackNodeProperties node, int path, int startIndex, int count){
  313.         List<TrackNodeProperties> nodes = new List<TrackNodeProperties>();
  314.  
  315.         if (node.IsSplitRoadNode == false || path < 0 || path >= node.NodeSubPaths.Length){
  316.             return nodes.ToArray();
  317.         }
  318.  
  319.         TrackNodeProperties[] subPathNodes = node.NodeSubPaths[path].Nodes;
  320.  
  321.         for (int i = 0; i <= count; i++){
  322.             if (startIndex + i >= subPathNodes.Length){
  323.                 break;
  324.             }
  325.  
  326.             nodes.Add(subPathNodes[startIndex + i]);
  327.         }
  328.  
  329.         return nodes.ToArray();
  330.     }
  331.  
  332.     private int GetFixedCurrentLapIndex (){
  333.         int progressLaps = (int)Mathf.Floor(CurrentProgress / NodeCount);
  334.  
  335.         if (CurrentProgress < 0){
  336.             return 0;
  337.         }
  338.  
  339.         if (CurrentNode > NodeCount - LapCountNodeOffset){
  340.             return progressLaps + 1;
  341.         }
  342.  
  343.         return progressLaps;
  344.     }
  345.  
  346.     private Transform GetNode (int index){
  347.         return Nodes[index.Warp(0, NodeCount)].transform;
  348.     }
  349.  
  350.     private TrackNodeProperties GetNodeProperties (int index){
  351.         return Nodes[index.Warp(0, NodeCount)];
  352.     }
  353. }
Advertisement
Add Comment
Please, Sign In to add comment