/// <summary> /// Изменяем значение скоростей самолётов, чтобы они смогли выравнить растояние между друг другом /// </summary> /// <param name="increaseSpeedPlane"></param> /// <param name="reduceSpeedPlane"></param> /// <param name="overallSpeedOfChange"></param> private void ChangeSpeedPlanes(PlaneMovementLogical increaseSpeedPlane, PlaneMovementLogical reduceSpeedPlane, float overallSpeedOfChange) { float speedReserveIncreaseSpeedPlane = increaseSpeedPlane.GetMaxSpeed - increaseSpeedPlane.CurrentSpeed; //запас увеличения скорости float speedReserveReduceSpeedPlane = reduceSpeedPlane.CurrentSpeed - reduceSpeedPlane.GetMinSpeed; //запас уменьшения скорости //коэффициент запаса скорости у первого самолёта. На основе его будет будет добавлена скорость или вычтена //Значение от 0 до 1 float speedCoefficientReserveFirstPlane; if (speedReserveIncreaseSpeedPlane != 0) { speedCoefficientReserveFirstPlane = speedReserveIncreaseSpeedPlane / (speedReserveIncreaseSpeedPlane + speedReserveReduceSpeedPlane); } else { speedCoefficientReserveFirstPlane = 0; } float speedChangeIncreaseSpeedPlane = overallSpeedOfChange * speedCoefficientReserveFirstPlane; float speedChangeReduceSpeedPlane = -overallSpeedOfChange * (1 - speedCoefficientReserveFirstPlane); // "-" т.к. замедляем float timeBetveansCountFrame = Time.time / Time.frameCount * _countFrameСalculatingNextPosition; increaseSpeedPlane.UpdatingSpeedPlaneForWhile(speedChangeIncreaseSpeedPlane, timeBetveansCountFrame, true); reduceSpeedPlane.UpdatingSpeedPlaneForWhile(speedChangeReduceSpeedPlane, timeBetveansCountFrame, true); }
/// <summary> /// Удалить самолёт из списока контроля /// </summary> /// <param name="plane"></param> public static void RemovePlaneInList(PlaneMovementLogical plane) { CheckCorrectListPlanes(); _listPlanes.Remove(plane); if (_dictionaryLastFrameUpdateSpeedPlane.ContainsKey(plane)) { _dictionaryLastFrameUpdateSpeedPlane.Remove(plane); } else { Debug.LogError($"Project({nameof(AirTrafficController)}, _dictionaryLastFrameUpdateSpeedPlane): объект уже был удалён из списка. Такого быть не должно..."); } }
/// <summary> /// Добавить самолёт в список контроля /// </summary> /// <param name="plane"></param> public static void AddPlaneInList(PlaneMovementLogical plane) { CheckCorrectListPlanes(); _listPlanes.Add(plane); if (!_dictionaryLastFrameUpdateSpeedPlane.ContainsKey(plane)) { _dictionaryLastFrameUpdateSpeedPlane.Add(plane, -1); //-1 т.к. обновления ещё не выполнялись } else { Debug.LogError($"Project({nameof(AirTrafficController)}, _dictionaryLastFrameUpdateSpeedPlane): объект уже существует в списке. Такого быть не должно... Где-то не почистил ссылку"); } }
/// <summary> /// Проверить вызов события запуска самолёта /// </summary> private void CheckLaunchPlan() { if (Input.GetButtonDown("LaunchPlane")) { if (Time.time - _lastTimeLaunchPlane > _cooldownLaunchPlane && _currentPlaneInAir < _maxPlaneInAir) { _lastTimeLaunchPlane = Time.time; PoolObject plane = PoolManager.Get(_indexPlaneInPoll); plane.transform.position = transform.position; plane.transform.rotation = transform.rotation; PlaneMovementLogical planeMovementLogical = plane.GetComponent <PlaneMovementLogical>(); AirTrafficController.AddPlaneInList(planeMovementLogical); planeMovementLogical.EventAfterFinishFly.AddListener(PlaneFinishFly); _currentPlaneInAir++; planeMovementLogical.Init(transform); } } }
private void ControlDistancePlanes(PlaneMovementLogical firstPlane, PlaneMovementLogical secondPlane, float maxNeedDistance) { //Проверяем когда последний раз, для данного самолёта обновлялся кадр. Если меньше чем число предсказания, // то пропускаем итераци. //+1 сделано для того, чтобы скорость не успела сброситься в PlaneMovementLogical. Тем самым сохранялась плавность int numCurrentFrame = Time.frameCount; if ((numCurrentFrame - _dictionaryLastFrameUpdateSpeedPlane[firstPlane] + 1 < _countFrameСalculatingNextPosition) && (numCurrentFrame - _dictionaryLastFrameUpdateSpeedPlane[secondPlane] + 1 < _countFrameСalculatingNextPosition)) { return; } Vector3 nextPosAfterNumberFrame_firstPlane = firstPlane.NextPositionAfterNumbersFrames; Vector3 nextPosAfterNumberFrame_secondPlane = secondPlane.NextPositionAfterNumbersFrames; float distanceFirstPlaneAndNextPointSecondPlane = Vector3.Distance(firstPlane.transform.position, nextPosAfterNumberFrame_secondPlane); float distanceSecondPlaneAndNextPointFirstPlane = Vector3.Distance(secondPlane.transform.position, nextPosAfterNumberFrame_firstPlane); float distancePlane = Vector3.Distance(nextPosAfterNumberFrame_firstPlane, nextPosAfterNumberFrame_secondPlane); float differenceDistansPlanes = maxNeedDistance - distancePlane; float overallSpeedOfChange = differenceDistansPlanes / _countFrameСalculatingNextPosition; if (distanceFirstPlaneAndNextPointSecondPlane < distanceSecondPlaneAndNextPointFirstPlane) { //firstPlane впереди , secondPlane позади ChangeSpeedPlanes(firstPlane, secondPlane, overallSpeedOfChange); } else { //secondPlane впереди, firstPlane позади ChangeSpeedPlanes(secondPlane, firstPlane, overallSpeedOfChange); } _dictionaryLastFrameUpdateSpeedPlane[firstPlane] = Time.frameCount; _dictionaryLastFrameUpdateSpeedPlane[secondPlane] = Time.frameCount; }