コード例 #1
0
        IEnumerable push_and_spin_launched_vessel(Vector3 dV)
        {
            FlightCameraOverride.UpdateDurationSeconds(1);
            var startP   = part.Rigidbody.worldCenterOfMass;
            var startAV  = part.Rigidbody.angularVelocity;
            var startAVm = startAV.sqrMagnitude;
            var vel      = (Vector3d)part.Rigidbody.velocity;

            vel += Vector3d.Cross(startAV, launched_vessel.CoM - startP);
            if (!dV.IsZero())
            {
                //conserve momentum
                var hM   = vessel.GetTotalMass();
                var lM   = launched_vessel.GetTotalMass();
                var lvel = dV * hM / (hM + lM);
                vel += lvel;
                part.Rigidbody.AddForce(-lvel * lM, ForceMode.Impulse);
            }
            launched_vessel.SetWorldVelocity(vel);
            for (int i = 0; i < 10; i++)
            {
                //this is a hack for incorrect VelocityChange mode (or whatever causing this);
                //if the startAV is applied once, the resulting vessel.angularVelocity is 2-3 times bigger
                var deltaAV  = startAV - launched_vessel.transform.rotation * launched_vessel.angularVelocity;
                var deltaAVm = deltaAV.sqrMagnitude;
                if (deltaAVm < 1e-5)
                {
                    break;
                }
                var av = deltaAVm > startAVm?deltaAV.ClampMagnitudeH(startAVm *Mathf.Sqrt(1 / deltaAVm)) : deltaAV / 3;

                var CoM = launched_vessel.CoM;
                foreach (Part p in launched_vessel.Parts)
                {
                    if (p.Rigidbody != null)
                    {
                        p.Rigidbody.AddTorque(av, ForceMode.VelocityChange);
                        p.Rigidbody.AddForce(Vector3.Cross(av, p.Rigidbody.worldCenterOfMass - CoM), ForceMode.VelocityChange);
                    }
                }
                FlightCameraOverride.UpdateDurationSeconds(1);
                yield return(null);

                FlightCameraOverride.UpdateDurationSeconds(1);
                yield return(null);
            }
        }
コード例 #2
0
 public IEnumerator <YieldInstruction> SpawnShipConstructToGround(ShipConstruct construct,
                                                                  Transform spawn_transform,
                                                                  Vector3 spawn_offset,
                                                                  Callback <Vessel> on_vessel_positioned = null,
                                                                  Callback <Vessel> on_vessel_loaded     = null,
                                                                  Callback <Vessel> on_vessel_off_rails  = null,
                                                                  Callback <Vessel> on_vessel_launched   = null,
                                                                  int easing_frames = 0)
 {
     begin_launch(spawn_transform);
     PutShipToGround(construct, spawn_transform, spawn_offset);
     ShipConstruction.AssembleForLaunch(construct,
                                        vessel.landedAt, vessel.displaylandedAt, part.flagURL,
                                        FlightDriver.FlightStateCache,
                                        new VesselCrewManifest());
     launched_vessel = FlightGlobals.Vessels[FlightGlobals.Vessels.Count - 1];
     on_vessel_positioned?.Invoke(launched_vessel);
     while (!launched_vessel.loaded)
     {
         FlightCameraOverride.UpdateDurationSeconds(1);
         yield return(new WaitForFixedUpdate());
     }
     on_vessel_loaded?.Invoke(launched_vessel);
     while (launched_vessel.packed)
     {
         launched_vessel.precalc.isEasingGravity = true;
         launched_vessel.situation = Vessel.Situations.PRELAUNCH;
         stabilize_launched_vessel(0);
         FlightCameraOverride.UpdateDurationSeconds(1);
         yield return(new WaitForFixedUpdate());
     }
     on_vessel_off_rails?.Invoke(launched_vessel);
     if (easing_frames > 0)
     {
         foreach (var n in stabilize_launched_vessel(easing_frames))
         {
             FlightCameraOverride.UpdateDurationSeconds(1);
             yield return(new WaitForFixedUpdate());
         }
     }
     on_vessel_launched?.Invoke(launched_vessel);
     StageManager.BeginFlight();
     end_launch();
 }
コード例 #3
0
        IEnumerable <YieldInstruction> launch_moving_vessel(Transform spawn_transform,
                                                            Vector3 spawn_offset,
                                                            Quaternion spawn_rot_offset,
                                                            Vector3 dV,
                                                            Callback <Vessel> on_vessel_loaded,
                                                            Callback <Vessel> on_vessel_off_rails,
                                                            Callback <Vessel> on_vessel_launched)
        {
            var vsl_colliders = new List <Collider>();

            disable_vsl_colliders(launched_vessel, vsl_colliders);
            FlightCameraOverride.UpdateDurationSeconds(1);
            if (vessel.LandedOrSplashed)
            {
                while (launched_vessel.packed)
                {
                    if (launched_vessel == null)
                    {
                        goto end;
                    }
                    launched_vessel.situation = Vessel.Situations.PRELAUNCH;
                    run_on_vessel_loaded(on_vessel_loaded);
                    FlightCameraOverride.UpdateDurationSeconds(1);
                    try
                    {
                        launched_vessel.SetPosition(spawn_transform.TransformPointUnscaled(spawn_offset));
                        launched_vessel.SetRotation(spawn_transform.rotation * spawn_rot_offset);
                    }
                    catch (Exception e)
                    { Utils.Log("Exception occured during launched_vessel.SetPosition/Rotation call. Ignoring it:\n{}", e.StackTrace); }
                    launched_vessel.GoOffRails();
                    yield return(new WaitForFixedUpdate());
                }
                if (launched_vessel == null)
                {
                    goto end;
                }
                launched_vessel.SetPosition(spawn_transform.TransformPointUnscaled(spawn_offset));
                launched_vessel.SetRotation(spawn_transform.rotation * spawn_rot_offset);
            }
            else
            {
                //hold the vessel inside the hangar until unpacked
                while (launched_vessel.packed)
                {
                    if (launched_vessel == null)
                    {
                        goto end;
                    }
                    run_on_vessel_loaded(on_vessel_loaded);
                    FlightCameraOverride.UpdateDurationSeconds(1);
                    try
                    {
                        launched_vessel.SetPosition(spawn_transform.TransformPointUnscaled(spawn_offset));
                        launched_vessel.SetRotation(spawn_transform.rotation * spawn_rot_offset);
                    }
                    catch (Exception e)
                    { Utils.Log("Exception occured during launched_vessel.SetPosition/Rotation call. Ignoring it:\n{}", e.StackTrace); }
                    yield return(new WaitForFixedUpdate());
                }
                if (launched_vessel == null)
                {
                    goto end;
                }
                launched_vessel.SetPosition(spawn_transform.TransformPointUnscaled(spawn_offset));
                launched_vessel.SetRotation(spawn_transform.rotation * spawn_rot_offset);
            }
            launched_vessel.situation = vessel.situation;
            FlightGlobals.ForceSetActiveVessel(launched_vessel);
            on_vessel_off_rails?.Invoke(launched_vessel);
            enable_vsl_colliders(vsl_colliders);
            launched_vessel.IgnoreGForces(10);
            foreach (var _ in push_and_spin_launched_vessel(spawn_transform.TransformDirection(dV)))
            {
                yield return(null);

                launched_vessel.IgnoreGForces(10);
            }
            on_vessel_launched?.Invoke(launched_vessel);
end:
            {
                enable_vsl_colliders(vsl_colliders);
                yield break;
            }
        }