I saw that CH47HelicopterAIController In the method hoverHeight The method of using altitudeProtection can disable altitude maintenance,My idea is to generate CH47 in the sky and then land it on the ground,But the plane will be forcibly fixed at a distance of 30 meters from the ground, without attempting to call up the hover Height setting to 0, but it has no effect,How do I need to modify it to make the CH47 aircraft land?π
private void CreateHelicopter()
{
MonumentInfo monument = GetAirportMonument();
if (monument == null) return;
Vector3 position = monument.transform.TransformPoint(new Vector3(-36f, 0.4f, -43.6f));
Vector3 finalTankHeliPos = new Vector3(position.x + 100f, position.y + 300f, position.z);
CH47HelicopterAIController entity = GameManager.server.CreateEntity(CH47Prefab, finalTankHeliPos)?.GetComponent<CH47HelicopterAIController>();
if (entity == null)return;
entity.EnableSaving(false);
entity.Spawn();
entity.InitializeHealth(99999999, 9999999);
entity.OwnerID = 123456;
entity.CancelInvoke(entity.GetPrivateAction("CheckSpawnScientists"));
SimpleCH47System militaryHeli = entity.gameObject.AddComponent<SimpleCH47System>();
ShipEntity.Add(entity);
militaryHeli.InitializeForCrateDrop(monument);
Effect.server.Run(StringPool.Get(2278592883), entity, 0, Vector3.zero, Vector3.zero, null, true);
entity.SendNetworkUpdate();
militaryHeli.SetCurrentDropPoint(position);
ServerMgr.Instance.StartCoroutine(HelicopterDropRoutine(militaryHeli));
}
private IEnumerator HelicopterDropRoutine(SimpleCH47System heli)
{
yield return new WaitUntil(() => heli.IsInDropPosition());
heli.EnterWaitingMode();
yield return new WaitUntil(() => heli.CurrentState != SimpleCH47System.HelicopterState.Waiting);
heli.InitiateExit();
yield return new WaitUntil(() => heli.CurrentState == SimpleCH47System.HelicopterState.Exited);
}
Β
public class SimpleCH47System : MonoBehaviour
{
public MonumentInfo Monument { get; private set; }
private CH47HelicopterAIController _aiController;
private Vector3 _exitPosition;
private Vector3 _currentDropTarget;
private const float ExitHeight = 300f;
private const float ExitDistance = 1000f;
public HelicopterState CurrentState { get; private set; } = HelicopterState.Flying;
private HeightState _heightState = HeightState.Cruising;
public enum HelicopterState
{
Flying,Β Β Β
Waiting,Β Β
Exiting,Β Β Β
ExitedΒ Β Β
}
Β
private enum HeightState
{
Cruising,Β Β
Approaching,
DroppingΒ Β
}
Β
public void InitializeForCrateDrop(MonumentInfo monument)
{
_aiController = GetComponent<CH47HelicopterAIController>();
Monument = monument;
}
public void SetCurrentDropPoint(Vector3 point)
{
_currentDropTarget = point;
_aiController.SetLandingTarget(point);
}
public void EnterWaitingMode()
{
CurrentState = HelicopterState.Waiting;
_aiController.SetMoveTarget(transform.position);
}
Β
public void ExitWaitingMode()
{
if (CurrentState == HelicopterState.Waiting)
{
CurrentState = HelicopterState.Flying;
}
}
Β
public void TriggerExit()
{
ExitWaitingMode();
}
Β
public void InitiateExit()
{
if (CurrentState == HelicopterState.Exiting || CurrentState == HelicopterState.Exited)return;
CurrentState = HelicopterState.Exiting;
_aiController.SetMinHoverHeight(ExitHeight);
Vector3 exitDirection = (transform.position - Monument.transform.position).normalized;
exitDirection.y = 0;
_exitPosition = transform.position + exitDirection * ExitDistance;
_exitPosition.y = Mathf.Max(
TerrainMeta.HeightMap.GetHeight(_exitPosition),
TerrainMeta.WaterMap.GetHeight(_exitPosition)
) + ExitHeight;
_aiController.SetMoveTarget(_exitPosition);
Invoke(nameof(DesHelicopter), 300f);
}
public bool HasExited()
{
return CurrentState == HelicopterState.Exited;
}
private void DesHelicopter()
{
if (this == null || gameObject == null) return;
CurrentState = HelicopterState.Exited;
_aiController.Die(new HitInfo(_aiController, _aiController, DamageType.Explosion, 999999999999f));
}
private void Update()
{
if (CurrentState == HelicopterState.Exiting)Β
{
_aiController.SetMoveTarget(_exitPosition);
if (HasExited()) DesHelicopter();
return;
}
if (CurrentState == HelicopterState.Waiting)
{
Vector3 currentPosition = transform.position;
_aiController.SetMoveTarget(currentPosition);
return;
}
if (CurrentState == HelicopterState.Flying)
{
switch (_heightState)
{
case HeightState.Cruising:
float distanceToTarget = Vector3.Distance(
new Vector3(transform.position.x, 0, transform.position.z),
new Vector3(_currentDropTarget.x, 0, _currentDropTarget.z)
);
if (distanceToTarget < 200f)Β
{
_heightState = HeightState.Approaching;
}
break;
}
}
}
public bool IsInDropPosition()
{
if (_aiController == null || CurrentState == HelicopterState.Exiting || CurrentState == HelicopterState.Exited || _currentDropTarget == Vector3.zero) {return false;}
bool isExactPosition =Β
transform.position.x == _currentDropTarget.x &&
transform.position.y == _currentDropTarget.y &&
transform.position.z == _currentDropTarget.z;
return isExactPosition;
}
private void OnDestroy()
{
CancelInvoke(nameof(DesHelicopter));
StopAllCoroutines();
}
}