Jump to content

Waiting for ground contact to resume physics


Recommended Posts

On 10/14/2017 at 8:52 PM, Fengist said:

Anyone know how to bypass this?  If my hovercraft get quick-saved while still hovering, they end up falling through the terrain on reload.

If you have custom part-modules, there is a method you can override to tell the game the ground-height-offset to use when placing the craft 'on the ground'.  I use it in KSPWheel to prevent KSP from spawning the wheel-equipped-craft squashed onto the ground.

You can see an example of its use here:  https://github.com/shadowmage45/KSPWheel/blob/master/VSProject/KSPWheel/PartModules/KSPWheelBase.cs#L689-L694

Link to comment
Share on other sites

On 10/16/2017 at 10:58 AM, Shadowmage said:

If you have custom part-modules, there is a method you can override to tell the game the ground-height-offset to use when placing the craft 'on the ground'.  I use it in KSPWheel to prevent KSP from spawning the wheel-equipped-craft squashed onto the ground.

You can see an example of its use here:  https://github.com/shadowmage45/KSPWheel/blob/master/VSProject/KSPWheel/PartModules/KSPWheelBase.cs#L689-L694

Ok, I do have one partmodule that is a 'lift engine.'  Without it, the vessel won't hover so that sounded like a good place to put this.

        public void OnPutToGround(PartHeightQuery phq)
        {          
            float pos = part.transform.position.y;
            phq.lowestOnParts[part] = Mathf.Min(phq.lowestOnParts[part], pos);
            phq.lowestPoint = Mathf.Min(phq.lowestPoint, phq.lowestOnParts[part]);
            Debug.Log("[MPHover] Putting on ground. "+phq.lowestPoint);
        }

I put a vessel on the runway, quicksaved, reloaded, checked the log and... that log entry doesn't show up,  From what I've gathered that's an undocumented function.  Do I need to call it from somewhere or is it called automatically by Unity?

One issue that may make a difference is this:

[LOG 18:09:23.370] Active Vessel is in atmosphere. Cannot save.

Whenever the ship is hovering, it's considered to be flying even though it's a lot less than 10m.

Link to comment
Share on other sites

36 minutes ago, Fengist said:

Ok, I do have one partmodule that is a 'lift engine.'  Without it, the vessel won't hover so that sounded like a good place to put this.


        public void OnPutToGround(PartHeightQuery phq)
        {          
            float pos = part.transform.position.y;
            phq.lowestOnParts[part] = Mathf.Min(phq.lowestOnParts[part], pos);
            phq.lowestPoint = Mathf.Min(phq.lowestPoint, phq.lowestOnParts[part]);
            Debug.Log("[MPHover] Putting on ground. "+phq.lowestPoint);
        }

I put a vessel on the runway, quicksaved, reloaded, checked the log and... that log entry doesn't show up,  From what I've gathered that's an undocumented function.  Do I need to call it from somewhere or is it called automatically by Unity?

One issue that may make a difference is this:

[LOG 18:09:23.370] Active Vessel is in atmosphere. Cannot save.

Whenever the ship is hovering, it's considered to be flying even though it's a lot less than 10m.

Hmm.. it is supposed to be called automatically by KSP code (through GameObject.SendMessage I believe).

However it is likely not being called because your craft is not 'landed' during the game loading operation, and that code is specifically intended to handle vessels in the 'landed' state.  Apologies, didn't really think that bit of it through when I put together my initial post (the function being for landed vessels).

Is it called properly when your craft is initialized / launched from the editor into a regular landed state?

Link to comment
Share on other sites

5 minutes ago, Shadowmage said:

Hmm.. it is supposed to be called automatically by KSP code (through GameObject.SendMessage I believe).

However it is likely not being called because your craft is not 'landed' during the game loading operation, and that code is specifically intended to handle vessels in the 'landed' state.  Apologies, didn't really think that bit of it through when I put together my initial post (the function being for landed vessels).

Is it called properly when your craft is initialized / launched from the editor into a regular landed state?

[LOG 18:59:17.022] Untitled Space Craft loaded!
[LOG 18:59:18.976] [FS Hover] Putting on ground. 9.595714
[LOG 18:59:18.978] putting ship to ground: 9.595714

Yep.... launching from the SPH it seems to do what is intended.  Doing a quicksave and a load with it hovering, it does not.  I attempted to deactivate the hovering during OnSave and it does drop to the ground, but apparently not fast enough to actually make ground contact before the save is complete.

Actually, it's only running that code after launch.  It doesn't run it when loading a quicksave.

Link to comment
Share on other sites

So, I thot I'd get smart.  I took this basic idea of OnPutToGround and perform it duing the OnLoad.  Well, that didn't work.  It tried to put it to a negative height.  So, I tried it in every other event I could think of.  Those that didn't produce a kraken gave the same net result. The events seem to be firing after it passes through the terrain.

So... I thot I'd get smarter.  I went through every rigidbody on the vessel and tried setting isKinematic to false.  Didn't work.  So, I tried setting every rigidbody to to useGravity = false.  And that didn't work either.

Is there some other way to turn the effects of KSP gravity off?  I was hoping I could turn it off during OnLoad and put it back on at a later event.

Edited by Fengist
Link to comment
Share on other sites

Hmm.. you might be able to hook into the physics easing stuff.  Other than that... I'm not really sure.

 

One thing that might work for you that I used on the repulsors in KSPWheel (basically a hovercraft type thing), was to add in code to manually set the craft to 'landed' state whenever it was supported by the repulsors.  However as they were essentially wheels with invisible tire and suspension, it was a reasonable workaround.  In the case of something that is supported by thrust alone (the typical hovercraft), that might not work as well.  You might be able to still do something like that though; anytime the craft is within X meters of the ground and the hover-engines are enabled, set the part/craft to landed state.

The reason this works is because when a craft is reloaded, and it was saved in a 'landed' state, it is placed into the same position it was previously.  So if it was previously 5 meters above the ground, that is where it will be when reloaded (the wheel physics then kick in and start supporting it again).

I'm not sure how that all relates to your exact problem.  Does the 'hover engine' have some sort of spool-up time, or does it start outputting thrust the moment the craft is realoded?  Or what method are you using to achieve the hovering effect?  (more info on what is going on might let me offer better suggestions as to solutions).

Link to comment
Share on other sites

1 hour ago, Shadowmage said:

Hmm.. you might be able to hook into the physics easing stuff.  Other than that... I'm not really sure.

 

One thing that might work for you that I used on the repulsors in KSPWheel (basically a hovercraft type thing), was to add in code to manually set the craft to 'landed' state whenever it was supported by the repulsors.  However as they were essentially wheels with invisible tire and suspension, it was a reasonable workaround.  In the case of something that is supported by thrust alone (the typical hovercraft), that might not work as well.  You might be able to still do something like that though; anytime the craft is within X meters of the ground and the hover-engines are enabled, set the part/craft to landed state.

The reason this works is because when a craft is reloaded, and it was saved in a 'landed' state, it is placed into the same position it was previously.  So if it was previously 5 meters above the ground, that is where it will be when reloaded (the wheel physics then kick in and start supporting it again).

I'm not sure how that all relates to your exact problem.  Does the 'hover engine' have some sort of spool-up time, or does it start outputting thrust the moment the craft is realoded?  Or what method are you using to achieve the hovering effect?  (more info on what is going on might let me offer better suggestions as to solutions).

Well, you were right.  While digging around last night I also stumbled upon the vessel situation and decided to play around with that today.  While this isn't a perfect solution, it does work.  And I'm sure I'll have to add in some code to handle splashed as well.

        public override void OnLoad(ConfigNode node)
        {
            Debug.Log("[FS Hover] Load");
            if (HighLogic.LoadedSceneIsFlight)
            {
                HEngineDeactivate();
                var partHeightQuery = new PartHeightQuery(float.MaxValue);
                int count = this.vessel.parts.Count;
                for (int i = 0; i < count; i++)
                {
                    var p = this.vessel[i];
                    partHeightQuery.lowestOnParts.Add(p, float.MaxValue);
                    Collider[] componentsInChildren = p.GetComponentsInChildren<Collider>();
                    int num = componentsInChildren.Length;
                    for (int j = 0; j < num; j++)
                    {
                        Collider collider = componentsInChildren[j];
                        if (collider.enabled && collider.gameObject.layer != 21)
                        {
                            partHeightQuery.lowestPoint = Mathf.Min(partHeightQuery.lowestPoint, collider.bounds.min.y);
                            partHeightQuery.lowestOnParts[p] = Mathf.Min(partHeightQuery.lowestOnParts[p], collider.bounds.min.y);
                        }
                    }
                }
                count = this.vessel.parts.Count;
                for (int k = 0; k < count; k++)
                    this.vessel[k].SendMessage("OnPutToGround", partHeightQuery, SendMessageOptions.DontRequireReceiver);
                this.vessel.situation = Vessel.Situations.LANDED;
                base.vessel.Landed = true;
                base.vessel.landedAt = "";
            }
        }

The part of this that doesn't work as well as hoped is that it still falls through the terrain... for a second or two.  Without this code, it falls through the terrain and then, it's put about 50 meters above it and falls back down again, usually ending in a minor disaster.  With this code, it still initially falls through the terrain but then, it magically appears where it should.  And, if saved in a hovering state, it's still hovering.

To answer your question I have 2 partmodules, one for skirt sections and one for the engine, and one monobehavour. The monobehaviour is where all the lifting actually takes place. The engine itself does no lifting but is required in order to run the monobehaviour.  The skirts define a part where the monobehaviour looks for thrust transforms.  The actual lifting is all done via raycasting from the transforms and adding or subtracting an impulse force based on the height returned.  The lift engines also have a thrust rating so that it's entirely possible to overload the hovercraft to the point it won't get off the ground.  It also looks to see if FlightGlobals.currentMainBody.ocean is true and cheats by creating a new "Plane" under the craft to raycast off of.

Either way, thanks much SM!  While not exactly the elegant solution I was hoping for, it does work.  And in modding KSP, sometimes, that's the best you can hope for.

Link to comment
Share on other sites

Lol, but now I have an entirely different problem.

If the vessel is hovering, it's not considered a vessel!??!

If I change the scene to say the tracking station while it's hovering... it vanishes.

And even if it's landed and I switch to the tracking station, I can't select fly.  And... if it exit out of the tracking station again... it vanishes.

Edited by Fengist
Link to comment
Share on other sites

5 hours ago, Fengist said:

Lol, but now I have an entirely different problem.

If the vessel is hovering, it's not considered a vessel!??!

If I change the scene to say the tracking station while it's hovering... it vanishes.

And even if it's landed and I switch to the tracking station, I can't select fly.  And... if it exit out of the tracking station again... it vanishes.

The code involving setting the landed state is... touchy.  It took me a few days to get it working on KSPWheel, and I never could get it working for flying over the ocean.  You can take a look at that code if you would like, though its a bit convoluted due to all the features it has to support -- https://github.com/shadowmage45/KSPWheel/blob/master/VSProject/KSPWheel/PartModules/KSPWheelBase.cs#L940-L1067

I also figured out how to do the ocean raycast handing analytically (no plane/collider needed) -- https://github.com/shadowmage45/KSPWheel/blob/master/VSProject/KSPWheel/PartModules/KSPWheelRepulsor.cs#L198-L277 .  Might be of some use to you if you wanted to go that route; feel free to re-use / adapt any of that code if you want.  The actual magic that does it is this function -- https://github.com/shadowmage45/KSPWheel/blob/master/VSProject/KSPWheel/PartModules/Utils.cs#L342-L359  rayPlaneIntersect(...).  Allows you to define a ray, and it will tell you where it intersects with an arbitrary plane that you also define (through surface normal and point on the plane), and return the point hit by the ray, if any.

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...