Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using UnityEngine;
- using System.Collections;
- using System.Collections.Generic;
- public class FlightProgressController : MonoBehaviour {
- //*** ATTRIBUTES ***//
- //*** PROPERTIES ***//
- public float CurrentProgress {get; private set;}
- public int Laps {
- get {return GetFixedCurrentLapIndex();}
- }
- public int CurrentSubPathIndex {
- get;
- private set;
- }
- public bool IsOnSubPath {
- get {return
- GetNodeProperties(CurrentNode - 1).IsSplitRoadNode ||
- GetNodeProperties(CurrentNode).IsSplitRoadNode;
- }
- }
- // REFERENCES
- private TrackSetupManager TrackSetup {
- get {return TrackSetupManager.Instance;}
- }
- // REFERENCE DATA
- private int NodeCount {
- get {return TrackSetup != null ? TrackSetup.OrientedTrackNodes.Length : 0;}
- }
- private TrackNodeProperties[] Nodes {
- get {return TrackSetup != null ? TrackSetup.OrientedTrackNodes : new TrackNodeProperties[0];}
- }
- // PROGRESS TRACKING
- public int CurrentNode {get; private set;}
- public int ReachedNodesCount {get; private set;}
- private int ProgressNode {get; set;}
- private int[] CurrentSubIndexes {get; set;}
- // NODE TRACKING
- private float PreviousNodeDistance {get; set;}
- private float CurrentNodeDistance {get; set;}
- private float NextNodeDistance {get; set;}
- private float NextNodePathLength {get; set;}
- private float PreviousNodePathLength {get; set;}
- // CONSTANTS
- private const int ProgressNodeSwitchThreshold = 2;
- private const float ProgressUpdateSpeed = 30f;
- private const int LapCountNodeOffset = 5;
- //*** METHODS - PUBLIC ***//
- public TrackNodeProperties GetCurrentNodeProperties (){
- TrackNodeProperties nodeProperties = Nodes[CurrentNode];
- if (IsOnSubPath == true){
- nodeProperties = GetCurrentSubPaths()[CurrentSubPathIndex].Nodes[CurrentSubIndexes[CurrentSubPathIndex]];
- }
- return nodeProperties;
- }
- public TrackNodeProperties[] GetNodesByCount (int count){
- List<TrackNodeProperties> nodes = new List<TrackNodeProperties>();
- for (int i = 0; i <= count; i++){
- nodes.Add(GetNodeProperties(CurrentNode + i));
- }
- return nodes.ToArray();
- }
- public TrackNodeProperties[] GetNodesWithSubPathByCount (int count, int startOffset = 0, int path = 0){
- List<TrackNodeProperties> nodes = new List<TrackNodeProperties>();
- for (int i = startOffset; i <= count; i++){
- TrackNodeProperties nextNode = GetNodeProperties(GetRealCurrentNode() + i);
- if (nextNode.IsSplitRoadNode == true){
- TrackNodeProperties[] subNodes = new TrackNodeProperties[0];
- TrackNodeProperties.SubPath[] subPaths = nextNode.NodeSubPaths;
- CurrentSubPathIndex = Mathf.Clamp(path, 0, subPaths.Length - 1);
- if (IsOnSubPath == true){
- subNodes = GetSubPathNodesByCount(nextNode, CurrentSubPathIndex, CurrentSubIndexes[CurrentSubPathIndex], count - i);
- } else {
- subNodes = GetSubPathNodesByCount(nextNode, CurrentSubPathIndex, 0, count - i);
- }
- nodes.AddRange(new List<TrackNodeProperties>(subNodes));
- i += subNodes.Length;
- continue;
- }
- nodes.Add(nextNode);
- }
- return nodes.ToArray();
- }
- //*** METHODS - PROTECTED ***//
- protected virtual void Awake (){
- }
- protected virtual void Start (){
- }
- protected virtual void Update (){
- if (Nodes == null || NodeCount == 0){
- return;
- }
- ControlBasePathNodesProgress();
- if (IsOnSubPath == false){
- ResetSubPathProgress();
- UpdateProgressValue(ReachedNodesCount + GetFractionPathProgress(
- GetNode(CurrentNode - 1),
- GetNode(CurrentNode),
- GetNode(CurrentNode + 1)));
- } else {
- ControlSubPathNodesProgress();
- }
- }
- protected void OnDrawGizmos (){
- if (Nodes == null || NodeCount == 0){
- return;
- }
- Gizmos.color = Color.cyan;
- // draw main path tracking debug lines
- Gizmos.DrawLine(transform.position, GetNode(CurrentNode - 1).position);
- Gizmos.DrawLine(transform.position, GetNode(CurrentNode).position);
- Gizmos.DrawLine(transform.position, GetNode(CurrentNode + 1).position);
- Gizmos.color = Color.red;
- // draw path for next 5 nodes
- TrackNodeProperties[] leftPath = GetNodesWithSubPathByCount(5, 0, 0);
- TrackNodeProperties[] rightPath = GetNodesWithSubPathByCount(5, 0, 1);
- for (int i = 0; i < leftPath.Length - 1; i++){
- Gizmos.DrawLine(leftPath[i].transform.position, leftPath[i + 1].transform.position);
- }
- for (int i = 0; i < rightPath.Length - 1; i++){
- Gizmos.DrawLine(rightPath[i].transform.position, rightPath[i + 1].transform.position);
- }
- }
- //*** METHODS - PRIVATE ***//
- private void ResetSubPathProgress (){
- CurrentSubIndexes = new int[0];
- CurrentSubPathIndex = 0;
- }
- private void UpdateProgressValue (float value){
- if (Mathf.Abs(CurrentProgress - value) > ProgressNodeSwitchThreshold){
- CurrentProgress = value;
- } else {
- CurrentProgress = Mathf.Lerp(CurrentProgress, value, ProgressUpdateSpeed * Time.unscaledDeltaTime);
- }
- }
- private void ControlBasePathNodesProgress (){
- int nodeProgressCount = CheckTrackerProgressDirection(
- GetNode(CurrentNode - 1),
- GetNode(CurrentNode),
- GetNode(CurrentNode + 1));
- CurrentNode = (CurrentNode + nodeProgressCount).Warp(0, NodeCount);
- ReachedNodesCount += nodeProgressCount;
- // recursively get to the actual node in case of low framerate
- if (nodeProgressCount != 0){
- ControlBasePathNodesProgress();
- }
- }
- private void ControlSubPathNodesProgress (){
- TrackNodeProperties.SubPath[] subPaths = GetCurrentSubPaths();
- if (CurrentSubIndexes == null || CurrentSubIndexes.Length != subPaths.Length){
- CurrentSubIndexes = new int[subPaths.Length];
- }
- // check which sub path are we currently on
- float closestPathDistance = Mathf.Infinity;
- int currentPathIndex = 0;
- for (int i = 0; i < CurrentSubIndexes.Length; i++){
- CurrentSubIndexes[i] = Mathf.Clamp(CurrentSubIndexes[i], 1, subPaths[i].Nodes.Length - 2);
- float currentDistance = Vector3.Distance(
- transform.position,
- subPaths[i].Nodes[CurrentSubIndexes[i]].transform.position);
- if (currentDistance < closestPathDistance){
- closestPathDistance = currentDistance;
- currentPathIndex = i;
- }
- }
- // get current sub path progress
- float actualPathProgress = 0;
- for (int i = 0; i < subPaths.Length; i++){
- int nodeProgressCount = CheckTrackerProgressDirection(
- subPaths[i].Nodes[CurrentSubIndexes[i] - 1].transform,
- subPaths[i].Nodes[CurrentSubIndexes[i]].transform,
- subPaths[i].Nodes[CurrentSubIndexes[i] + 1].transform);
- CurrentSubIndexes[i] = Mathf.Clamp(CurrentSubIndexes[i] + nodeProgressCount, 1, subPaths[i].Nodes.Length - 2);
- if (i != currentPathIndex){
- continue;
- }
- // get progress in percentages to fit in 01 range between main path nodes
- float fractionProgress = CurrentSubIndexes[i] + GetFractionPathProgress(
- subPaths[i].Nodes[CurrentSubIndexes[i] - 1].transform,
- subPaths[i].Nodes[CurrentSubIndexes[i]].transform,
- subPaths[i].Nodes[CurrentSubIndexes[i] + 1].transform);
- actualPathProgress = fractionProgress / subPaths[i].Nodes.Length;
- }
- UpdateProgressValue(GetRealReachedNodesCount() + actualPathProgress);
- }
- private int CheckTrackerProgressDirection (Transform previousNode, Transform currentNode, Transform nextNode){
- // check distances to the nodes
- PreviousNodeDistance = Vector3.Distance(transform.position, previousNode.position);
- CurrentNodeDistance = Vector3.Distance(transform.position, currentNode.position);
- NextNodeDistance = Vector3.Distance(transform.position, nextNode.position);
- // check which one is closer and switch to the closer one
- if (CurrentNodeDistance < PreviousNodeDistance && CurrentNodeDistance < NextNodeDistance){
- return 0;
- }
- int progressCount = (NextNodeDistance < CurrentNodeDistance) ? 1 : -1;
- return progressCount;
- }
- private float GetFractionPathProgress (Transform previousNode, Transform currentNode, Transform nextNode){
- // update node paths lengths for percentage calculation
- NextNodePathLength = Vector3.Distance(currentNode.position, nextNode.position);
- PreviousNodePathLength = Vector3.Distance(previousNode.position, currentNode.position);
- float nodePathFraction = 0;
- float flightProgressToAdd = 0;
- // update flight progress as ReachedNodesCount + fractional value like 455.1f
- if (NextNodeDistance < PreviousNodeDistance){
- nodePathFraction = 1.0f - (NextNodeDistance / NextNodePathLength);
- flightProgressToAdd = nodePathFraction;
- } else {
- nodePathFraction = PreviousNodeDistance / PreviousNodePathLength;
- flightProgressToAdd = nodePathFraction - 1.0f;
- }
- return flightProgressToAdd;
- }
- private TrackNodeProperties.SubPath[] GetCurrentSubPaths (){
- for (int i = -1; i <= 1; i++){
- TrackNodeProperties node = GetNodeProperties(CurrentNode + i);
- if (node.IsSplitRoadNode == true){
- return node.NodeSubPaths;
- }
- }
- return null;
- }
- private int GetRealCurrentNode (){
- for (int i = -1; i <= 0; i++){
- if (GetNodeProperties(CurrentNode + i).IsSplitRoadNode == true){
- return CurrentNode + i;
- }
- }
- return CurrentNode;
- }
- private int GetRealReachedNodesCount (){
- for (int i = -2; i <= 0; i++){
- if (GetNodeProperties(CurrentNode + i).IsSplitRoadNode == true){
- return ReachedNodesCount + i;
- }
- }
- return ReachedNodesCount;
- }
- private TrackNodeProperties[] GetSubPathNodesByCount (TrackNodeProperties node, int path, int startIndex, int count){
- List<TrackNodeProperties> nodes = new List<TrackNodeProperties>();
- if (node.IsSplitRoadNode == false || path < 0 || path >= node.NodeSubPaths.Length){
- return nodes.ToArray();
- }
- TrackNodeProperties[] subPathNodes = node.NodeSubPaths[path].Nodes;
- for (int i = 0; i <= count; i++){
- if (startIndex + i >= subPathNodes.Length){
- break;
- }
- nodes.Add(subPathNodes[startIndex + i]);
- }
- return nodes.ToArray();
- }
- private int GetFixedCurrentLapIndex (){
- int progressLaps = (int)Mathf.Floor(CurrentProgress / NodeCount);
- if (CurrentProgress < 0){
- return 0;
- }
- if (CurrentNode > NodeCount - LapCountNodeOffset){
- return progressLaps + 1;
- }
- return progressLaps;
- }
- private Transform GetNode (int index){
- return Nodes[index.Warp(0, NodeCount)].transform;
- }
- private TrackNodeProperties GetNodeProperties (int index){
- return Nodes[index.Warp(0, NodeCount)];
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment