示例#1
0
        public override void update(float dt, double update_time)
        {
            var player = Player.Instance;
            var diff   = player.rigidbody_.transform_.position_ - rigidbody_.transform_.position_;
            var dir    = new Vector3(0f, 0f, diff.magnitude * 0.5f);
            var lookat = player.rigidbody_.transform_.transformPosition(ref dir);

            diff = lookat - rigidbody_.transform_.position_;
            rigidbody_.transform_.rotation_ = (Quaternion.LookRotation(diff) *
                                               Quaternion.Euler((Mathf.PerlinNoise((float)update_time * 0.4f, 0f) - 0.5f) * 10f,
                                                                (Mathf.PerlinNoise((float)update_time * 0.4f, 0.3f) - 0.5f) * 10f,
                                                                (Mathf.PerlinNoise((float)update_time * 0.4f, 0.6f) - 0.5f) * 10f));
            var phase  = update_time * 4f;
            var mag    = 3f;
            var point  = new Vector3((float)System.Math.Sin(phase) * mag, 2f, (float)System.Math.Cos(phase) * mag);
            var target = player.rigidbody_.transform_.transformPosition(ref point);

            if (MyRandom.Probability(0.005f))
            {
                spring_ratio_idx_ = MyRandom.Range(0, spring_ratio_table_.Length);
            }
            float spring_ratio = spring_ratio_table_[spring_ratio_idx_];

            rigidbody_.addSpringForce(ref target, spring_ratio);
            rigidbody_.addRelativeForceX(relative_force_table_[spring_ratio_idx_]);
            rigidbody_.update(dt);
            rigidbody_.solveForGround(1f, dt);
        }
示例#2
0
        private void init(ref Vector3 position, ref Quaternion rotation, LockTarget lock_target)
        {
            // var rotation = Quaternion.identity;
            base.init(ref position, ref rotation);
            rigidbody_.init();
            rigidbody_.transform_.position_ = position;
            float theta;

            if (MyRandom.Probability(0.5f))
            {
                theta = (MyRandom.Range(-1f, 1f) * Mathf.PI * 0.125f) * Mathf.Rad2Deg;
            }
            else
            {
                theta = (MyRandom.Range(-1f, 1f) * Mathf.PI * 0.125f + Mathf.PI) * Mathf.Rad2Deg;
            }
            var rot = Quaternion.Euler(0f, 0f, theta) * rotation;
            var v   = rot * new Vector3(20f, 0f, 0f);

            rigidbody_.setVelocity(ref v);
            lock_target_   = lock_target;
            trail_locator_ = new Vector3(0, 0, -1);
            // var col = new Color(0.1f, 1f, 0.5f);
            var pos = rigidbody_.transform_.transformPosition(ref trail_locator_);

            trail_id_ = Trail.Instance.spawn(ref pos,
                                             0.2f /* width */,
                                             Trail.Type.Missile);
            arrival_time_  = MyRandom.Range(1.0f, 1.5f);
            destroy_start_ = 0f;
        }
 private void alpha_normal_act(float dt, double update_time)
 {
     if (target_fighter_ == null || MyRandom.Probability(0.025f, dt))
     {
         target_fighter_ = Fighter.searchFarest(fighter_id_, ref rigidbody_.transform_.position_);
     }
     if (target_fighter_ != null)
     {
         rigidbody_.addSpringTorqueCalcUp(ref target_fighter_.rigidbody_.transform_.position_,
                                          2f /* torque_level */);
         rigidbody_.addSpringTorqueCalcUp(ref CV.Vector3Zero,
                                          0.1f /* torque_level */);
         rigidbody_.addRelativeForceZ(250f);
         var roti = rigidbody_.transform_.getInverseRotation();
         var rvec = roti * rigidbody_.r_velocity_;
         rigidbody_.addRelativeTorqueZ(rvec.y * 2f);
         if (MyRandom.Probability(3.5f / 6f, dt))
         {
             var offset = new Vector3(0f, -0.3f, 0f);
             var lpos   = rigidbody_.transform_.transformPosition(ref offset);
             var num    = MyRandom.Range(6, 8);
             for (var i = 0; i < num; ++i)
             {
                 MissileManager.Instance.spawn(ref lpos,
                                               ref rigidbody_.transform_.rotation_,
                                               target_fighter_.target_id_, update_time);
             }
             Spark.Instance.spawn(ref lpos, Spark.Type.Bullet, update_time);
         }
         if (MyRandom.Probability(0.2f, dt))
         {
             rigidbody_.addRelativeTorqueX(MyRandom.Probability(0.5f) ? 20f : -20f);
         }
     }
 }
示例#4
0
        public override void update(float dt, double update_time)
        {
            bool refresh_target = false;

            if (current_target_ == null)
            {
                refresh_target = true;
            }
            else
            {
                var probability = current_target_.getHitElapsed(update_time) < 1f ? 1f : 0.01f;
                if (MyRandom.Probability(probability, dt))
                {
                    refresh_target = true;
                }
            }
            if (refresh_target)
            {
                Fighter closest_fighter = Fighter.searchClosest(ref rigidbody_.transform_.position_, current_target_);
                if (closest_fighter != null)
                {
                    current_target_ = closest_fighter;
                }
            }
            if (current_target_ != null)
            {
                switch (phase_)
                {
                case 0:
                {
                    var target = current_target_.rigidbody_.transform_.transformPositionZ(16f);
                    rigidbody_.addSpringForce(ref target, 4f /* spring ratio */);
                    if (time_ < update_time)
                    {
                        phase_ = 1;
                        time_  = (float)update_time + MyRandom.Range(5f, 28f);
                    }
                }
                break;

                case 1:
                {
                    var target = current_target_.rigidbody_.transform_.transformPositionZ(-2f);
                    rigidbody_.addSpringForce(ref target, 2f /* spring ratio */);
                    if (time_ < update_time)
                    {
                        phase_ = 0;
                        time_  = (float)update_time + MyRandom.Range(5f, 28f);
                    }
                }
                break;
                }
                rigidbody_.addSpringTorqueCalcUp(ref current_target_.rigidbody_.transform_.position_, 40f /* torque_level */);
                rigidbody_.update(dt);
            }
        }
示例#5
0
        private void dragon_update(float dt)
        {
            if (MyCollider.getHitOpponentForEnemy(collider_) != MyCollider.Type.None)
            {
                float p = 100f;
                rigidbody_.addTorque(MyRandom.Range(-p, p),
                                     MyRandom.Range(-p, p),
                                     MyRandom.Range(-p, p));
                life_ -= 20f;
            }
            if (life_ <= 0f && phase_ == Phase.Alive)
            {
                MyCollider.disableForEnemy(collider_);
                phase_ = Phase.Dying;
            }

            rigidbody_.update(dt);
            MyCollider.updateEnemy(collider_, ref rigidbody_.transform_.position_);
            MyCollider.updateEnemyHoming(collider_homing_, ref rigidbody_.transform_.position_);
            // var head_transform = rigidbody_.transform_.add(ref HEAD_OFFSET);
            dragon_.update(dt, update_time_, ref rigidbody_);

            if (MyRandom.Probability(0.01f))
            {
                var head_pos = new Vector3(0f, 0f, 2f);
                var pos      = rigidbody_.transform_.transformPosition(ref head_pos);
                if (pos.y > 0f)
                {
                    EnemyLaser.create(ref pos, ref rigidbody_.transform_.rotation_, 40f /* speed */, update_time_);
                    SystemManager.Instance.registSound(DrawBuffer.SE.Laser);
                }
            }

            if (MyRandom.Probability(0.1f))
            {
                var pos = rigidbody_.transform_.position_;
                pos.x += MyRandom.Range(-1f, 1f);
                pos.z += MyRandom.Range(-1f, 1f);
                WaterSplash.Instance.spawn(ref pos,
                                           ref CV.Vector3Zero, update_time_ - 0.2f);
            }

            if (-1f < rigidbody_.transform_.position_.y && rigidbody_.transform_.position_.y < 1f)
            {
                WaterSurface.Instance.makeBump(ref rigidbody_.transform_.position_, -0.1f /* value */, 1f /* size */);
                if (MyRandom.Probability(0.1f))
                {
                    var wpos = rigidbody_.transform_.position_;
                    wpos.y = -2f;
                    var vel = new Vector3(0f, MyRandom.Range(5f, 8f), 0f);
                    WaterSplash.Instance.spawn(ref wpos, ref vel, update_time_);
                }
            }
        }
        private IEnumerator act()
        {
            const float RANGE = 300f;

            for (var i = 0; i < 100; ++i)
            {
                var position = new Vector3(MyRandom.Probability(0.5f) ? -RANGE : RANGE,
                                           MyRandom.Range(-RANGE, RANGE),
                                           MyRandom.Range(-RANGE, RANGE));
                var rotation = Quaternion.LookRotation(MyRandom.onSphere(1f));
                Fighter.create(Fighter.Type.Alpha, ref position, ref rotation, update_time_);
            }
            for (;;)
            {
                yield return(null);
            }
        }
示例#7
0
        public IEnumerator zako_act()
        {
            rigidbody_.setDamper(2f);
            rigidbody_.setRotateDamper(4f);
            yield return(null);

            for (var i = new Utility.WaitForSeconds(0.8f, update_time_); !i.end(update_time_);)
            {
                rigidbody_.addSpringTorque(ref Player.Instance.rigidbody_.transform_.position_, 3f);
                rigidbody_.addSpringForceY(4f /* target_y */, 4f /* ratio */);
                yield return(null);
            }
            WaterSurface.Instance.makeBump(ref rigidbody_.transform_.position_, 1f /* value */, 1f /* size */);
            for (var i = new Utility.WaitForSeconds(1f, update_time_); !i.end(update_time_);)
            {
                rigidbody_.addSpringTorque(ref Player.Instance.rigidbody_.transform_.position_, 3f);
                rigidbody_.addSpringForceY(4f /* target_y */, 4f /* ratio */);
                if (MyRandom.Probability(0.1f))
                {
                    WaterSplash.Instance.spawn(ref rigidbody_.transform_.position_,
                                               ref CV.Vector3Zero, update_time_ - 0.2f);
                }
                yield return(null);
            }
            for (var i = new Utility.WaitForSeconds(10f, update_time_); !i.end(update_time_);)
            {
                var pos = Player.Instance.rigidbody_.transform_.position_;
                // pos.y -= 1f;
                rigidbody_.addSpringTorque(ref pos, 8f);
                rigidbody_.addSpringForceY(4f /* target_y */, 4f /* ratio */);
                if (MyRandom.Probability(0.04f))
                {
                    EnemyBullet.create(ref rigidbody_.transform_.position_,
                                       ref rigidbody_.transform_.rotation_,
                                       60f /* speed */, update_time_);
                }
                yield return(null);
            }
            for (var i = new Utility.WaitForSeconds(3f, update_time_); !i.end(update_time_);)
            {
                rigidbody_.addHorizontalStableTorque(8f /* torque_level */);
                rigidbody_.addRelativeForceZ(80f);
                yield return(null);
            }
            destroy();
        }
示例#8
0
        public override void update(float dt, double update_time)
        {
            var controller = Controller.Instance.getLatest();

            muscle_motion_.setTarget(posture_apose_);
            if (controller.isLeftButtonUp())
            {
                throwing_cnt_l_ = (int)(0.5f / dt);
            }
            if (controller.isRightButtonUp())
            {
                throwing_cnt_r_ = (int)(0.5f / dt);
            }
            if (throwing_cnt_l_ > 0)
            {
                muscle_motion_.setTarget(posture_throw_l_arm_);
                // muscle_motion_.addTorqueY(MuscleMotion.Parts.Ribs2, 8000f);
                // muscle_motion_.addTorqueY(MuscleMotion.Parts.Hip, 8000f);
                // muscle_motion_.addTorqueX(MuscleMotion.Parts.L_Thigh, 8000f);
                // muscle_motion_.addTorqueX(MuscleMotion.Parts.L_Knee, 8000f);
                if (throwing_cnt_l_ < (int)(0.45f / dt))
                {
                    fire_left(update_time);
                }
                --throwing_cnt_l_;
            }
            if (throwing_cnt_r_ > 0)
            {
                muscle_motion_.setTarget(posture_throw_r_arm_);
                // muscle_motion_.addTorqueY(MuscleMotion.Parts.Ribs2, -8000f);
                // muscle_motion_.addTorqueY(MuscleMotion.Parts.Hip, -8000f);
                // muscle_motion_.addTorqueX(MuscleMotion.Parts.R_Thigh, 8000f);
                // muscle_motion_.addTorqueX(MuscleMotion.Parts.R_Knee, 8000f);
                if (throwing_cnt_r_ < (int)(0.45f / dt))
                {
                    fire_right(update_time);
                }
                --throwing_cnt_r_;
            }
            if (controller.isLeftButtonDown())
            {
                MuscleMotion.Node node = muscle_motion_.getNode(MuscleMotion.Parts.L_Wrist);
                fire_left(update_time);
                left_held_bullet_ = Bullet.create(ref node.rigidbody_.transform_.position_,
                                                  ref CV.QuaternionIdentity);
            }
            if (controller.isRightButtonDown())
            {
                MuscleMotion.Node node = muscle_motion_.getNode(MuscleMotion.Parts.R_Wrist);
                fire_right(update_time);
                right_held_bullet_ = Bullet.create(ref node.rigidbody_.transform_.position_,
                                                   ref CV.QuaternionIdentity);
            }
            if (controller.isLeftButton())
            {
                throwing_cnt_l_  = 0;
                throwing_cnt_r_ -= (int)(0.25f / dt);
                muscle_motion_.setTarget(posture_pre_throw_l_arm_);
                bullet_tame_left_ += dt;
            }
            if (controller.isRightButton())
            {
                throwing_cnt_l_ -= (int)(0.25f / dt);
                throwing_cnt_r_  = 0;
                muscle_motion_.setTarget(posture_pre_throw_r_arm_);
                bullet_tame_right_ += dt;
            }
            if (left_held_bullet_ != null)
            {
                MuscleMotion.Node node = muscle_motion_.getNode(MuscleMotion.Parts.L_Wrist);
                left_held_bullet_.setPosition(ref node.rigidbody_.transform_.position_);
                left_held_bullet_.setPower(Mathf.Clamp(bullet_tame_left_, 0.25f, 2f));
            }
            if (right_held_bullet_ != null)
            {
                MuscleMotion.Node node = muscle_motion_.getNode(MuscleMotion.Parts.R_Wrist);
                right_held_bullet_.setPosition(ref node.rigidbody_.transform_.position_);
                right_held_bullet_.setPower(Mathf.Clamp(bullet_tame_right_, 0.25f, 2f));
            }

            if (controller.isJumpButton() && on_ground_)
            {
                muscle_motion_.getRootNode().rigidbody_.addRelativeTorqueX(1000f);
                muscle_motion_.setTarget(posture_pre_jump_,
                                         MuscleMotion.PartsBit.LowerBody |
                                         MuscleMotion.PartsBit.Ribs |
                                         MuscleMotion.PartsBit.Ribs2 |
                                         MuscleMotion.PartsBit.Ribs3);
                jump_tame_duration_ += dt;
            }

            if (controller.isJumpButtonUp())
            {
                if (jump_tame_duration_ > 0.5f)
                {
                    jump_propel_remain_ = Mathf.Min((jump_tame_duration_ - 0.5f) + 0.5f, 1f) * 2f;
                    rigidbody_.addForceY(1000f);
                    WaterSurface.Instance.makeBump(ref rigidbody_.transform_.position_,
                                                   -1f /* value */, 1f /* size */);
                    on_ground_time_ = 0f;
                    somersault_     = MyRandom.Probability(0.25f);
                }
                jump_tame_duration_ = 0f;
            }

            float hori          = controller.getHorizontal();
            float ground_height = 1.25f;

            if (hori != 0f)
            {
                ground_height = 1f;
            }

            if (jump_propel_remain_ > 0f)
            {
                rigidbody_.addForceY(100f);
                jump_propel_remain_ -= dt;
            }
            on_ground_ = (rigidbody_.transform_.position_.y <= 1f);

            rigidbody_.addTargetTorque(ref look_at_, 500f /* torque_level */, -1f /* max_level */);
            rigidbody_.addRelativeForceX(hori * 64f);
            if (hori != 0f)
            {
                rigidbody_.addRelativeForceZ(10f);
            }
            rigidbody_.addForceY(-9.8f * 5f);   // gravity
            if (rigidbody_.transform_.position_.y < ground_height)
            {
                rigidbody_.addSpringForceY(ground_height, 100f);
            }
            rigidbody_.solveForGround(0.0f /* ground_height */, dt);
            rigidbody_.addRelativeTorqueZ(-hori * 100f);
            {
                var forward = rigidbody_.transform_.rotation_ * CV.Vector3Forward;
                var q       = Quaternion.LookRotation(forward);
                rigidbody_.addSpringTorque(ref q, 10000f);
            }
            rigidbody_.update(dt);

            if (rigidbody_.transform_.position_.y < 5f)
            {
                WaterSurface.Instance.makeBump(ref rigidbody_.transform_.position_, -0.05f /* value */, 0.6f /* size */);
                var pos = rigidbody_.transform_.position_;
                pos.y = -2f;
                float vel_y;
                if (hori != 0f)
                {
                    vel_y = MyRandom.Range(7f, 9f);
                }
                else
                {
                    vel_y = MyRandom.Range(5f, 7f);
                }
                var vel = new Vector3(0f,
                                      vel_y,
                                      0f);
                if (MyRandom.Probability(0.2f))
                {
                    WaterSplash.Instance.spawn(ref pos, ref vel, update_time);
                }
            }

            var root_node = muscle_motion_.getRootNode();

            root_node.rigidbody_.transform_.position_ =
                rigidbody_.transform_.position_ + new Vector3((Mathf.PerlinNoise((float)update_time * 4f, 0.0f) - 0.5f) * 0.04f,
                                                              (Mathf.PerlinNoise((float)update_time * 4f, 0.5f) - 0.5f) * 0.04f,
                                                              (Mathf.PerlinNoise((float)update_time * 4f, 1.0f) - 0.5f) * 0.04f);

            if (somersault_ && on_ground_time_ < 0.25f)
            {
                root_node.rigidbody_.addRelativeTorqueX(-3000f);
                muscle_motion_.getNode(MuscleMotion.Parts.Ribs).rigidbody_.addRelativeTorqueX(-3000f);
                muscle_motion_.getNode(MuscleMotion.Parts.Ribs2).rigidbody_.addRelativeTorqueX(-3000f);
                muscle_motion_.getNode(MuscleMotion.Parts.Ribs3).rigidbody_.addRelativeTorqueX(-3000f);
                muscle_motion_.getNode(MuscleMotion.Parts.Hip).rigidbody_.addRelativeTorqueX(-3000f);
            }
            else
            {
                root_node.rigidbody_.addTorqueY(hori * 1000f);
                root_node.rigidbody_.addRelativeTorqueZ(-hori * 1000f);
                root_node.rigidbody_.addSpringTorque(ref rigidbody_.transform_.rotation_, 4000f);
            }

            muscle_motion_.addTorqueX(MuscleMotion.Parts.L_Tale1, MyRandom.Range(500f, 1200f));
            muscle_motion_.addTorqueX(MuscleMotion.Parts.L_Tale4, MyRandom.Range(-4000f, 4000f));
            muscle_motion_.addTorqueX(MuscleMotion.Parts.R_Tale1, MyRandom.Range(500f, 1200f));
            muscle_motion_.addTorqueX(MuscleMotion.Parts.R_Tale4, MyRandom.Range(-4000f, 4000f));
            muscle_motion_.addTorqueX(MuscleMotion.Parts.L_SusoBack, MyRandom.Range(300f, 600f));
            muscle_motion_.addTorqueX(MuscleMotion.Parts.L_SusoFront, MyRandom.Range(-600f, -300f));
            muscle_motion_.addTorqueX(MuscleMotion.Parts.R_SusoBack, MyRandom.Range(300f, 600f));
            muscle_motion_.addTorqueX(MuscleMotion.Parts.R_SusoFront, MyRandom.Range(-600f, -300f));

            Vector3 e_pos;

            if (jump_tame_duration_ > 0.75f || on_ground_time_ < 1f)
            {
                var node = muscle_motion_.getNode(MuscleMotion.Parts.Head);
                node.rigidbody_.addRelativeTorqueX(-4000f);
            }
            else if (MyCollider.getNearestEnemyPosition(out e_pos))
            {
                muscle_motion_.getNode(MuscleMotion.Parts.Head).rigidbody_.addSpringTorque(ref e_pos, 4000f);
            }

            {
                var intersect_point = CV.Vector3Zero;
                if (MyCollider.getHitOpponentForPlayer(collider_, ref intersect_point) == MyCollider.Type.EnemyBullet)
                {
                    var node   = muscle_motion_.getNode(MuscleMotion.Parts.Ribs3);
                    var torque = MyRandom.onSphere(1f) * 5000f;
                    node.rigidbody_.addTorque(ref torque);
                    Shield.Instance.spawn(ref intersect_point,
                                          ref rigidbody_.transform_.position_,
                                          update_time,
                                          Shield.Type.Green);
                    SystemManager.Instance.registSound(DrawBuffer.SE.Shield);
                    // hit_time_ = (float)update_time;
                    // hit_position_ = intersect_point;
                }
                MyCollider.updatePlayer(collider_, ref rigidbody_.transform_.position_);
            }

            muscle_motion_.update(dt);
            on_ground_time_ += dt;
        }
示例#9
0
 private IEnumerator fetch_auto()
 {
     for (;;)
     {
         for (var w = new Utility.WaitForSeconds(MyRandom.Range(2f, 4f), update_time_);
              !w.end(update_time_);)
         {
             if (latest_.horizontal_ < 0f)
             {
                 for (var w0 = new Utility.WaitForSeconds(MyRandom.Range(0.1f, 1f), update_time_);
                      !w0.end(update_time_);)
                 {
                     latest_.left_button_ = true;
                     yield return(null);
                 }
             }
             else
             {
                 for (var w0 = new Utility.WaitForSeconds(MyRandom.Range(0.1f, 1f), update_time_);
                      !w0.end(update_time_);)
                 {
                     latest_.right_button_ = true;
                     yield return(null);
                 }
             }
             for (var w0 = new Utility.WaitForSeconds(MyRandom.Range(0.1f, 0.6f), update_time_);
                  !w0.end(update_time_);)
             {
                 yield return(null);
             }
             yield return(null);
         }
         if (MyRandom.Probability(0.5f))
         {
             for (var w = new Utility.WaitForSeconds(MyRandom.Range(0.8f, 1.2f), update_time_);
                  !w.end(update_time_);)
             {
                 latest_.jump_button_ = true;
                 yield return(null);
             }
         }
         if (MyRandom.Probability(0.1f))
         {
             for (var w = new Utility.WaitForSeconds(MyRandom.Range(3f, 4f), update_time_);
                  !w.end(update_time_);)
             {
                 for (var w0 = new Utility.WaitForSeconds(MyRandom.Range(0.2f, 0.4f), update_time_);
                      !w0.end(update_time_);)
                 {
                     latest_.left_button_ = true;
                     yield return(null);
                 }
                 for (var w0 = new Utility.WaitForSeconds(MyRandom.Range(0.2f, 0.4f), update_time_);
                      !w0.end(update_time_);)
                 {
                     latest_.right_button_ = true;
                     yield return(null);
                 }
                 yield return(null);
             }
         }
         for (var w = new Utility.WaitForSeconds(MyRandom.Range(0.2f, 0.8f), update_time_);
              !w.end(update_time_);)
         {
             yield return(null);
         }
         yield return(null);
     }
 }
示例#10
0
        public void update(float dt,
                           double update_time,
                           ref RigidbodyTransform grand_parent_rigidbody,
                           ref RigidbodyTransform parent_rigidbody,
                           ref RigidbodyTransform child_rigidbody,
                           bool head,
                           bool tail)
        {
#if false
            if (MyCollider.getHitOpponentForEnemy(collider_) != MyCollider.Type.None)
            {
                rigidbody_.addTorque(MyRandom.Range(-20f, 20f),
                                     MyRandom.Range(-20f, 20f),
                                     MyRandom.Range(-20f, 20f));
            }
            rigidbody_.addSpringTorque(ref parent_transform.rotation_, 10f /* torque_level */);
            rigidbody_.transform_.position_ = parent_transform.transformPosition(ref locator_);
            rigidbody_.update(dt);
#else
            if (head)
            {
                rigidbody_.updateVerlet(dt, 0.8f /* damper */);
            }
            else
            {
                rigidbody_.updateVerlet(dt, 0.8f /* damper */);
            }
            if (head)
            {
                var head_offset = new Vector3(0f, 0f, -3f);
                var pos         = parent_rigidbody.transform_.transformPosition(ref head_offset);
                rigidbody_.restrictPositionVerletFixed(ref pos, 0f /* length */);
            }
            else
            {
                rigidbody_.restrictPositionVerlet(ref grand_parent_rigidbody,
                                                  ref parent_rigidbody,
                                                  3f /* length */, 60f /* max_degree */);
            }
            if (!tail)
            {
                rigidbody_.solveRotationVerlet(ref parent_rigidbody, ref child_rigidbody);
            }
#endif
            MyCollider.updateEnemy(collider_, ref rigidbody_.transform_.position_);
            MyCollider.updateEnemyHoming(collider_homing_, ref rigidbody_.transform_.position_);

            if (-2f < rigidbody_.transform_.position_.y && rigidbody_.transform_.position_.y < 2f)
            {
                WaterSurface.Instance.makeBump(ref rigidbody_.transform_.position_, -0.025f /* value */, 1f /* size */);
                var wpos = rigidbody_.transform_.position_;
                wpos.y = -1.5f;
                var th  = MyRandom.Range(0f, Mathf.PI * 2f);
                var cos = Mathf.Cos(th);
                var sin = Mathf.Sin(th);
                wpos.x += cos * 1.25f;
                wpos.z += sin * 1.25f;
                var vel = new Vector3(cos * 0.8f,
                                      MyRandom.Range(5f, 8f),
                                      sin * 0.8f);
                WaterSplash.Instance.spawn(ref wpos, ref vel, update_time);
            }
            if (MyRandom.Probability(0.1f))
            {
                var pos = rigidbody_.transform_.position_;
                pos.x += MyRandom.Range(-1f, 1f);
                pos.z += MyRandom.Range(-1f, 1f);
                WaterSplash.Instance.spawn(ref pos,
                                           ref CV.Vector3Zero, update_time - 0.2f);
            }
        }