public void OnUpdate()
        {
            m_direction = -this.GameObj.Transform.Pos;
            this.GameObj.Transform.Angle = m_direction.Xy.Angle + MathF.RadAngle180;

            Vector3         moveDelta       = Time.TimeMult * m_direction * m_speed;
            LevelController levelController = this.GameObj.ParentScene.FindComponent <LevelController>();

            // Hovering animation
            {
                SpriteRenderer sprite = this.GameObj.GetComponent <SpriteRenderer>();
                if (this.initialSpriteRect == Rect.Empty)
                {
                    this.initialSpriteRect = sprite.Rect;
                }
                float hoverTimeOffset = (float)(this.GameObj.Id.GetHashCode() % 1000) / 1000.0f;
                sprite.Rect = new Rect(
                    this.initialSpriteRect.X,
                    this.initialSpriteRect.Y + 10.0f * (1.0f + MathF.Sin(2.0f * (float)Time.GameTimer.TotalSeconds + hoverTimeOffset)),
                    this.initialSpriteRect.W,
                    this.initialSpriteRect.H);
            }

            switch (m_shipState)
            {
            case ShipState.MoveToTarget:
                this.GameObj.Transform.MoveBy(moveDelta);
                if (IsInShootingRange())
                {
                    StartScanning();
                }
                break;

            case ShipState.ScanTarget:
                //Log.Game.Write("countdownTime: {0}, lastDelta: {1}", m_countdownToAttack, Time.LastDelta);
                if (m_beamSoundInstance == null || m_beamSoundInstance.Disposed)
                {
                    m_beamSoundInstance        = DualityApp.Sound.PlaySound(m_beamSound);
                    m_beamSoundInstance.Looped = true;
                    m_beamSoundInstance.Pitch  = MathF.Rnd.NextFloat(0.8f, 1.25f);
                }
                m_countdownToAttack -= Time.LastDelta / 1000;
                if (levelController == null || levelController.IsGameOver)
                {
                    m_beamSoundInstance.Volume = 0.1f + 0.1f * MathF.Clamp(1.0f - ((float)m_countdownToAttack / (float)m_scanDuration), 0.0f, 1.0f);
                }
                else
                {
                    m_beamSoundInstance.Volume = 0.5f + 0.5f * MathF.Clamp(1.0f - ((float)m_countdownToAttack / (float)m_scanDuration), 0.0f, 1.0f);
                }

                UpdateLineRenderer(false);
                if (m_countdownToAttack <= 0)
                {
                    //Log.Game.Write("distance: {0}", this.GameObj.Transform.Pos.LengthSquared);
                    Vector2 hitPos;
                    if (ScanPlanet(out hitPos))
                    {
                        m_hitPosition = new Vector3(hitPos.X, hitPos.Y, 0);
                        StartShooting();
                    }
                    else
                    {
                        StartLeaving();
                    }
                    m_beamSoundInstance.FadeOut(0.1f);
                }
                break;

            case ShipState.ShootTarget:
                if (m_target != null)
                {
                    if (levelController != null && !levelController.IsGameOver)
                    {
                        DualityApp.Sound.PlaySound(m_lockAcquiredSound);
                    }

                    Planet planetComp = m_target.GetComponent <Planet>();
                    if (planetComp != null)
                    {
                        planetComp.IncreaseDetectionCounter();
                    }
                }
                SpawnParticle();
                m_shipState = ShipState.LockPosition;
                break;

            case ShipState.LeaveTarget:
                this.GameObj.Transform.MoveBy(-moveDelta);
                if (IsOutsideRange())
                {
                    StartWaiting();
                }
                break;

            case ShipState.Waiting:
                m_countdownToAttack -= Time.LastDelta / 1000;
                if (m_countdownToAttack <= 0)
                {
                    StartMovingToTarget();
                }
                break;

            case ShipState.LockPosition:
                // occasionally spawn particles pulled towards the ship
                m_countdownToAttack -= Time.LastDelta / 1000;
                if (m_countdownToAttack <= 0)
                {
                    SpawnParticle();
                }
                break;

            default:
                break;
            }
        }
 private void Awake()
 {
     levelController = Harmony.Finder.LevelController;
     gridController  = Harmony.Finder.GridController;
 }