Jump to content

Need help getting started


Recommended Posts

I've got Visual Studio set up and I've looked through all the "tutorials" and getting started material, but I still have can't figure out what should be a relatively simple task. I also looked through other people's source code, but given that I'm completely new to C# I'm not sure what I should be looking for. Could anyone post some example code of making a GUI window appear whenever at the space center or whenever at the RnD building?

Link to comment
Share on other sites

To get something started in the space center, you're looking at a KSP Addon type plugin (rather than a Part Module). This means inheriting from Monobehaviour and having the class tagged with the KSPAddon attribute.

[KSPAddon (KSPAddon.Startup.SpaceCentre, false)]
public class YourClass : MonoBehaviour
{}

This gives you a class for which the methods Awake, Start, Update, FixedUpdate (NOTE: not particularly useful outside the Flight scene), OnGUI and OnDestroy. There are (a lot) more, but those are the ones you will use the most.

To draw a window, you want OnGUI


public void OnGUI()
{
GUI.Window(/*some number*/, new Rect(300,500,300,300), windowFunc, "This is a window Title"); // draws a 300x300 window 300 in and 500 down from the top left of the screen.
// You have a choice of GUI or GUILayout for most UI objects. GUI you specify the size explictly using a Rect for each object, GUILayout you have formatting functions to shape your layout. Both work, what you use is up to you.
}

void windowFunc(int id)
{
// the contents of your window go here.
// NOTE: if using GUI functions, the (x,y) coordinates are relative to the top left of the window, not the screen (ie. (0,0) in this function is the top left corner of the window)
}

The R&D window is an overlay on the space center scene so if you want a window in both there is no special considerations (although you will have to block it for the other buildings that aren't the VAB/SPH if you don't want them showing up). To detect entry to these facilities, we add callbacks to functions for various "OnEnter" and "OnLeaving" events

public void Start()
{
GameEvents.onGUIRnDComplexSpawn.Add(RnDEnteredFunc);
GameEvents.onGUIRnDComplexDespawn.Add(RnDLeavingFunc);
}
public void OnDestroy() //You don't want to leave event subscriptions lying around
{
GameEvents.onGUIRnDComplexSpawn.Remove(RnDEnteredFunc);
GameEvents.onGUIRnDComplexDespawn.Remove(RnDLeavingFunc);
}

void RnDEnteredFunc()
{}

void RnDLeavingFunc()
{}

set a boolean value in those callbacks and gate your OnGUI code behind that check if you only want to show in the RnD complex


bool bRnDOverlayVisible = false;
void OnGUI()
{
if (!bRnDOverlayVisible)
return; // I prefer return statements for gating as it reduces the level of nesting but you can also wrap everything inside the if statement. Whatever works for you
}

Edited by Crzyrndm
Link to comment
Share on other sites

How would I make the window drag-able? I tried the following code, but it doesn't seem to do anything. Also one thing I don't understand about the code is why "int id" is needed for the "windowFunc" method. If I remove it, then Visual Studio shows an error with "GUI.Window"

namespace Testing
{
[KSPAddon(KSPAddon.Startup.SpaceCentre, false)]

public class Testing : MonoBehaviour
{
public void OnGUI()
{
GUI.Window(1, new Rect(10, 10, 300, 700), windowFunc, "Title");
}

void windowFunc(int id)
{
GUI.DragWindow();
}
}
}

Link to comment
Share on other sites

To make it draggable, you need a persistent Rect instead of creating one each time.

namespace Testing
{
[KSPAddon(KSPAddon.Startup.SpaceCentre, false)]

public class Testing : MonoBehaviour
{
Rect windowRect = new Rect(10,10,300,700);
public void OnGUI()
{
windowRect = GUI.Window(1, windowRect, windowFunc, "Title");
}

void windowFunc(int id)
{
GUI.DragWindow();
}
}
}

The window id I don't understand too well myself, expect that two windows with the same id cannot both be drawn at the same time (you can draw one or the other, but not both). I just give them a large arbitrary random number

Link to comment
Share on other sites

I'm asking a lot of questions so I'll just put them all in this thread instead of making new ones.

I'm trying to get information on the node that is currently clicked such as it's name and the parts assigned to it. I found the class "RDNode" which has a "OnNodeSelected()" method, but I can't figure out how to use it. Looking at the old Treeloader source, it makes use of the "ConfigNode" class. I'm not really sure how to use either or what I should be looking for to get the info of the clicked node.

Link to comment
Share on other sites

ConfigNode is the class which KSP uses to read/write/store the majority of data in .cfg files (eg. PART { ... } is initially read into a ConfigNode)

This is probably the one you want

RDController.Instance.node_selected

Link to comment
Share on other sites

What does the template parameter do for file IO commands? I'm trying to check that a file exists, but I'm not sure what to put for "T". Also, does the directory for the file not need specified?

KSP.IO.File.Exists<T>("filename")

Link to comment
Share on other sites

It's used by KSP to define the patch where you file is stored. Say you mod is in GameData/myMod/myMod.dll and it contains a class called MyModule.

KSP.IO.File.Exists<MyModule>("filename") will check for a file relative to the position of the dll that contains MyModule. From memory it should be GameData/myMod/pluginData/myMod/filename.cfg

The path are quite long since it was designed when all the plugins lived in the same dir.

Link to comment
Share on other sites

I'm not sure if this is doing what I think it's doing. There's probably a better way to do this. I'm trying to load the tech tree data using ConfigNode. Is this the correct way to do it?

ConfigNode allNodes = GameDatabase.Instance.GetConfigNode("RDNode");

If it is, for some reason my plugin stops working when I try to get the RnD node position data.

string[] allNodePos = allNodes.GetValues("pos");

What am I doing wrong?

Also, does the GetConfigNode method get sub structures in the config files? So will it get the Parent structures within the RDNode structure?

Link to comment
Share on other sites

You probably want something like

string[] allNodePos = new string[allNodes.Length];
for (int i = 0; i < allNodes.Length; i++)
allNodePos[i] = allNodes[i].GetValue("pos");

or even

string[][] allNodePos = new string[allNodes.Length][];
for (int i = 0; i < allNodes.Length; i++)
allNodePos[i] = allNodes[i].GetValue("pos").Split(',');

which will give you each of the pos numbers in individual cells (eg. allNodePos[0][0] is the first number in the first node)

Edited by Crzyrndm
Link to comment
Share on other sites

I'm still having trouble with this part

[COLOR=#333333]ConfigNode allNodes = GameDatabase.Instance.GetConfigNodes("RDNode");[/COLOR]

This produces a list of length zero. And if I replace "RDNode" with "TechTree" it produces a list of length two. Neither are results I would have expected.

Link to comment
Share on other sites

if the root node is techTree, that's the one you need to check GameDatabase for. You can then get the RDNodes using techTreeNode.GetNodes("RDNode").

As for why there is two, I don't know. print them both to the log and see what they look like (the node.toString method will show values just as they would appear in a .cfg)

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...