Cephei

The official unoffical "help a fellow plugin developer" thread

Recommended Posts

Is there any "official" way on how to get the different vectors from the navball (Pro/Retrograde, radialIn/Out, Anti/Normal etc)? I have found some old forum posts (one and two) but the github links that are there are dead. I have also found this code on github, which seems to get the NavBall class through GameObject.Find(""); but when I try the same method, I get a null object. Do I have to manually calculate the vectors, or is there a way to somehow read them from somewhere? 

 

Edit: I want the navball vectors because I want to render a navball in a separate desktop application. I already have the navball pitch/yaw/roll rotation correctly rendered, now I just need the vectors.

Edited by c4ooo

Share this post


Link to post
Share on other sites

@c4ooo You can use the similarly brute force GameObject.FindObjectsOfType<NavBall>() to get the NavBall instance (it might not be active or present immediately after a scene loads, so you may have to wait a bit to do this). But I don't know about how accessible or not the target vectors are.

Edited by DMagic

Share this post


Link to post
Share on other sites

@DMagic well, for the target vectors I suppose I could just subtract the target position from the vessel position. I just don't know how to "orient" this resulting vector so that I can sensibly draw it on my external navball.

 

Edit:

Well, it took me all morning but I figured out how to calculate the Pitch and Heading (relative to the surface/navball) of the prograde vector given the vessel's velocity vector (which is in world space). Once I got it though, it seemed easier then I expected. In the code bellow, AV is the active vessel:

Spoiler


 
            Vector3d CoM, north, up, east;
            Quaternion rotationSurface;
            CoM = AV.CoM;
            up = (CoM - AV.mainBody.position).normalized;
            north = Vector3d.Exclude(up, (AV.mainBody.position + AV.mainBody.transform.up * (float)AV.mainBody.Radius) - CoM).normalized;
           east = Vector3d.Cross(up, north);
 
            Vector3d prograde = AV.srf_velocity.normalized;
            ProgradsVectorPitch = (float)-((Vector3d.Angle(up, prograde)) - 90.0f);
 
            Vector3d progradeFlat = Vector3d.Exclude(up, prograde); 
            float NAngle = (float)Vector3d.Angle(north, progradeFlat);
            float EAngle = (float)Vector3d.Angle(east, progradeFlat);
 
            if (EAngle < 90) {
                ProgradeVectorHeading = NAngle;
            } else  {
                ProgradeVectorHeading = -NAngle + 360;
            }

 

Edited by c4ooo

Share this post


Link to post
Share on other sites
On 7/25/2018 at 6:15 AM, DMagic said:

@Doxel For unloaded vessels you have to check the protovessel situation: vessel.protovessel.situation, or something like that.

It should give the correct value, though I'm not sure if it gives the correct value for a loaded vessel, so you might need to check if the vessel is loaded before checking its situation.

Giving me a second type of situation to query adds another bit to the puzzle, although it is still not working entirely right. Both vessel.situation and protovessel.situation work if you are asking about the currently active vessel, but I am still getting wonky results with unloaded target vessels.

Protovessel.situation seems to always be able to detect if an unloaded vessel is landed or splashed, but it calls orbiting, sub-orbital, and escaping all just "orbiting". Regular vessel.situation seems to be always able to detect landed or splashed too, but it calls everything else "flying" until I switch to, view, or otherwise load a second craft of any kind. Rather confusing.

So the same exact vessel that is currently escaping Kerbin's SOI would show up like this initially:

targetObject.GetVessel().loaded == FALSE
targetObject.GetVessel().situation == Vessel.Situations.FLYING
targetObject.GetVessel().protoVessel.situation == Vessel.Situations.ORBITING

...and then like this once a second vessel of any kind loads:

targetObject.GetVessel().loaded == FALSE
targetObject.GetVessel().situation == Vessel.Situations.ESCAPING
targetObject.GetVessel().protoVessel.situation == Vessel.Situations.ORBITING

The vessel situation system continues to elude my understanding.

Edited by Doxel
Edited because I forgot to set it to C# syntax hilighting for my code snippets and it was botherin' me.

Share this post


Link to post
Share on other sites

Can anyone point me to the proper size for AppLauncher buttons? I've got them at 38x38 pixels, which I thought was the right size, but they're blurry still like they're being resized.

Or does it have something to do with getting them via GameDatabase.Instance.GetTexture() ? I think I remember seeing some discussion that that only works for power-of-two sized images, but I don't know how else to load a button texture.

Edit:

I found the answer. It is 38x38, but the reason it was blurry is because of the method used to get the texture.

Instead, use the method here:

Edited by Booots

Share this post


Link to post
Share on other sites

Hi, I'm struggling to fix a bug in my BetterLoadSaveGame mod, when trying to load games using the GamePersistence.LoadGame function. The problem is that when trying to load games that were saved at the space center, it just seems to load the "persistent" save instead. Loading games that are saved in flight seems to work fine. Does anyone know if there's something I'm missing?

I'm using this code:

var game = GamePersistence.LoadGame(name, HighLogic.SaveFolder, true, false);
game.Start();

Things I've tried that still have the same problem:

Documentation for the LoadGame function (https://kerbalspaceprogram.com/api/class_game_persistence.html#aa98f7b6bca2e6d3cca42ac2c25e66522) says to use Game.Start or Game.Load function to apply the game to the scene. I'm using Game.Start, because the Game.Load function says it doesn't wipe the scene first.

One thing I have tried that works is (in code) copying the save files to be loaded over the top of the "persistent" one, then loading that. This works, but I doubt people want this behaviour :)

Share this post


Link to post
Share on other sites
On 8/5/2018 at 4:20 AM, jefftimlin said:

Hi, I'm struggling to fix a bug in my BetterLoadSaveGame mod, when trying to load games using the GamePersistence.LoadGame function. The problem is that when trying to load games that were saved at the space center, it just seems to load the "persistent" save instead. Loading games that are saved in flight seems to work fine. Does anyone know if there's something I'm missing?

I forgot how complex it is to do simple stuff in this game sometimes.

Did you try something like this ?

ConfigNode configNode = GamePersistence.LoadSFSFile(saveName, HighLogic.SaveFolder);
HighLogic.CurrentGame = GamePersistence.LoadGameCfg(configNode, saveName, true, false);
HighLogic.CurrentGame.Start();

I guess KSPUpgradePipeline should be used somewhere too. It seems loading a game is not as simple as it was...

Share this post


Link to post
Share on other sites
43 minutes ago, sarbian said:

I forgot how complex it is to do simple stuff in this game sometimes.

Did you try something like this ?


ConfigNode configNode = GamePersistence.LoadSFSFile(saveName, HighLogic.SaveFolder);
HighLogic.CurrentGame = GamePersistence.LoadGameCfg(configNode, saveName, true, false);
HighLogic.CurrentGame.Start();

I guess KSPUpgradePipeline should be used somewhere too. It seems loading a game is not as simple as it was...

Thanks for the reply. Unfortunately yes I've tried that, and it doesn't seem to work when loading a game that was saved at the space center, it just loads the persistent save. I was hoping I was just missing something simple, but maybe not. For now, I've gone with the workaround of copying the game to load over the persistent one first, which actually seems to be similar to what happens with the stock load game dialog. It just seems like a terrible hack :)

Share this post


Link to post
Share on other sites

I am writing a plugin that will track vessel's movement along the orbit. I need to see when it's made a full circle relative to its main body. Neither orbital period nor true anomaly (or any other anomalies) help here because the period and periapsis can change during movement.

Basically, I'm looking for some sort of non-rotating longitude value. Orbit class has loads of various fields and methods, but it's poorly documented and I'm not sure which one suits my needs. Any suggestions?

Share this post


Link to post
Share on other sites
33 minutes ago, garwel said:

I am writing a plugin that will track vessel's movement along the orbit. I need to see when it's made a full circle relative to its main body. Neither orbital period nor true anomaly (or any other anomalies) help here because the period and periapsis can change during movement.

Basically, I'm looking for some sort of non-rotating longitude value. Orbit class has loads of various fields and methods, but it's poorly documented and I'm not sure which one suits my needs. Any suggestions?

I defined a function "AbsolutePhaseAngle" that might do what you need, basically a sum of LAN, AOP, and TA:

https://github.com/HebaruSan/Astrogator/blob/master/src/PhysicsTools.cs#L135-L164

Orbit1.svg

Share this post


Link to post
Share on other sites

I'm having trouble loading a png texture into my application launcher button.

What I have now is

void Start()
        {
            Debug.Log("LFO Balancer Initialized");
            
            InitializeButton();

            GameEvents.onVesselWasModified.Add(UpdateBalancerList);
            GameEvents.onVesselChange.Add(UpdateBalancerList);
        }
}

and

private void InitializeButton()
{
  _button = ApplicationLauncher.Instance.AddModApplication(
    OnTrue,
    OnFalse,
    null,
    null,
    null,
    null,
    ApplicationLauncher.AppScenes.FLIGHT,
    GameDatabase.Instance.GetTexture("LFOBalancer/Icons/toolbar_enabled_38", false) // using placeholder texture from DOE
  );
}

but all that shows up in my applauncher button is a white square, which was the same as when I had the texture set to null from before. Is there a better way to load in png files as textures?

Edited by peachoftree

Share this post


Link to post
Share on other sites

You have to manually load the texture (in your case a .png) and store it in a Texture2D (methods exist in the Unity code for this). I'm on mobile right now, but I can give you a link to some code that I wrote…

https://repo.nothuman.online/KerbaeAdAstra/KerbalFuture/blob/BK-FSDDev/KerbalFuture/KFGUI/KFGUI.cs#L644

That region deals with the toolbar button. 

Share this post


Link to post
Share on other sites

No you don't. Png in GameData are loaded by the game. 

Your code looks like what I use in MechJeb. The difference I see is that I make sure that ApplicationLauncher.Ready is true before creating the button. 

Share this post


Link to post
Share on other sites

@sarbian my apologies, I was following what @Aerospike had said worked for him here: 

i was also personally having problems getting GameDatabase to work in my own testing, for some reason, and this is what finally did it for me. 

Share this post


Link to post
Share on other sites

Ok :)

My guess is that you could find an error message in the loading log that tells you why the image did not load. (power of two size or something alike)

Share this post


Link to post
Share on other sites
23 hours ago, peachoftree said:

Thank you @sarbian and @Benjamin Kerman for all your help, I managed to get it working using the method in the thread linked!

If you're talking about my reply:

I'm now using that for all of my mods and it seems to work beautifully.  The method for loading the .png using WWW should work for most any application.  

Share this post


Link to post
Share on other sites
23 hours ago, Fengist said:

If you're talking about my reply:

I'm now using that for all of my mods and it seems to work beautifully.  The method for loading the .png using WWW should work for most any application.  

I'm actually using the method posted by Aerospike in that thread and it's working fine. If I run into issues with this method in some other context I'll definitely give your method a try!

Share this post


Link to post
Share on other sites

Are there any good sources from which to learn how to add buttons to a part's (in my case, an EVA'd kerbal) right click menu?

I've been searching and digging through other mods for the past few hours and cannot make sense of it. 

Share this post


Link to post
Share on other sites
Just now, nubeees said:

Are there any good sources from which to learn how to add buttons to a part's (in my case, an EVA'd kerbal) right click menu?

I've been searching and digging through other mods for the past few hours and cannot make sense of it. 

I believe you're looking for a KSPField, though I'm not sure how to add it to a kerbal.

Share this post


Link to post
Share on other sites
15 hours ago, nubeees said:

Are there any good sources from which to learn how to add buttons to a part's (in my case, an EVA'd kerbal) right click menu?

I've been searching and digging through other mods for the past few hours and cannot make sense of it. 

You need to create a PartModule that defines the button (you should be able to find plenty of examples of this).  Then create a ModuleManager patch that adds that module to the two kerbal EVA parts

Share this post


Link to post
Share on other sites

How would I go about doing some autopilot stuff?

I've got a part module with this code but nothing seems to happen, do i need to enable fly by wire or something else?

public void Fly(FlightCtrlState s)
{
  s.mainThrottle = 0.2f;
}

public override void OnActive()
{
  vessel.OnFlyByWire += new FlightInputCallback(Fly);
  base.OnActive();
}

Thanks in advance

 

Edit:

Also functions like OnPartStart() don't seem to be part of the PartModule so I cant override those, is there something i'm doing wrong?

Edited by BillBodkin

Share this post


Link to post
Share on other sites
3 hours ago, BillBodkin said:

How would I go about doing some autopilot stuff?

I've got a part module with this code but nothing seems to happen, do i need to enable fly by wire or something else?


public void Fly(FlightCtrlState s)
{
  s.mainThrottle = 0.2f;
}

public override void OnActive()
{
  vessel.OnFlyByWire += new FlightInputCallback(Fly);
  base.OnActive();
}

Thanks in advance

 

Edit:

Also functions like OnPartStart() don't seem to be part of the PartModule so I cant override those, is there something i'm doing wrong?

Are you putting this in a VesselModule or a PartModule? If it's the latter, are you adding your PartModule to any parts?

Share this post


Link to post
Share on other sites
17 hours ago, 0111narwhalz said:

Are you putting this in a VesselModule or a PartModule? If it's the latter, are you adding your PartModule to any parts?

It is a part module and it is indeed attached, I managed to get it to work in the end, all I did was move the 

vessel.OnFlyByWire += new FlightInputCallback(Fly);

to my OnUpdate loop and replace the += with just an = so i dont have it run loads per frame, seems to do the trick hovever I gues this means it will mess up if i attach multiple modules, I havt tested yet but i guess i can just iteriate though all the parts on spawn and see if there are other parts  already running the module and only enable self if no others?

Share this post


Link to post
Share on other sites

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.