Jump to content

Mouseless Keyboardless MechJeb, or Directly Control Ship


Keith Young

Recommended Posts

I'm new to C#, and I'm finding the lack of KSP API documentation crippling.

I want to find a way to call for certain MechJeb actions without using a mouse. I currently have a system that can recognize when I want something to happen. What I don't know is how to ask my ship to do something, or ask MechJeb.


Declare Secret Way To Talk To MechJeb //This probably requires multiple lines of stuff, and even likely settings in Visual Studio
I_Want_To_Kill_Rot = true
if (I_Want_To_Kill_Rot)

MechJeb.secretThing.greek.KillRot()

So what do I need to substitute for "Declare Secret Way To Talk To MechJeb" and "MechJeb.secretThing.greek.KillRot()"?

Or, is there a way to just directly tell the ship what I want? I already know how to do SAS on my own, so let's say I want the ship to point in a direction and burn.

ship.magic.pointindirection(vectorthing)
while vel < 2000
ship.magic.full_throttle
ship.magic.cut_throttle
darnIt.prepare.rescue.Jeb.AGAIN(location, velocity, float facepalm)

Sorry if this question seems really basic. I've Googled to no avail, and trying to decipher the thousands of lines of MechJeb to find answers is proving to be very difficult.

Thanks for any help!

Link to comment
Share on other sites

Unfortunately, none of what you are asking is really easy or straight forward.

1) To reference MechJeb from code, you need to find the reference. You can either do so via a hard dependancy where you add MechJeb.dll as a reference and add the Using MechJeb; line to the start of your code. The downside to this method is that if MechJeb is not present, your mod will not load. The upside is you can just call MechJeb's stuff the same way you do Part or Vessel.

If you want your mod to load regardless of if MechJeb is installed or not, you need to use reflection. I use reflection here in my mod to talk to RemoteTech. You'll have to find the correct values for MechJeb to use it for your purposes.

2) If you want to point the vessel in a specific direction, the easiest way is to put the SAS system in hold mode, then override the hold vector. This is dealing with quaternions though so it gets confusing fast. Here's the actual command to do this, you will have to backtrack up my code to see how I get the values I plug into said command.

3) Throttle is the easy part of all this, if you are working with the currently focused vessel, it is FlightInputHandle.fetch.mainThrottle

Hope that helps,

D.

Link to comment
Share on other sites

Without taking a proper look, I would just about guarantee SetFlightCtrlState is what controls the ship (One I can guarantee completely is the control [URL="https://github.com/Crzyrndm/Pilot-Assistant/blob/master/PilotAssistant/FlightModules/PilotAssistant.cs#L711"]function[/URL] from Pilot Assistant. [URL="https://github.com/Crzyrndm/Pilot-Assistant/blob/master/PilotAssistant/FlightModules/PilotAssistant.cs#L745-L746"]Yaw/Roll[/URL], [URL="https://github.com/Crzyrndm/Pilot-Assistant/blob/master/PilotAssistant/FlightModules/PilotAssistant.cs#L764"]Pitch[/URL], [URL="https://github.com/Crzyrndm/Pilot-Assistant/blob/master/PilotAssistant/FlightModules/PilotAssistant.cs#L780"]Throttle[/URL]). All that's done for the actual turning is feeding the FlightCtrlState the percent (0 -> +/-1) deflection on each axis. KSP handles updating each of the relevant parts (RCS, control surfaces, gimbals, reaction wheels)

EDIT

A simpler [URL="https://github.com/Crzyrndm/Analog-Control/blob/master/Analog%20Control/AnalogControl.cs#L299"]example[/URL] (NOTE: since FlightCtrlState is a class (passed by reference) I really don't need to be returning the output here...) Edited by Crzyrndm
Link to comment
Share on other sites

Thanks Crzyrndm! I ended up getting that to work.

So my main class uses Monobehaviour. I'm trying to call a method that is in another class (in another cs file in the same project using the same namespace).

I can't get my code to call it. The main way I'd see it working is:


[CODE]

namespace same
{
public class mainclass : MonoBehaviour
{
public otherclass oc;
void Update()
{
do some other stuff //--------this stuff works
oc.justworkforchristssake();
do more stuff //-------------this stuff never works
}
}
}


//-----------------OTHER CS FILE-----------------------

namespace same
{
public class otherclass
{
public void justworkforchristssake()
{
Debug.Log("IT FINALLY WORKED TIME TO SWEEP UP ALL MY HAIR I'VE PULLED OUT"); //----this never get in to the log
}
}
}

[/CODE]

I've tried static, override, I've been all over StackFlow and haven't found anything that works yet.

Can someone please help me just manage to call a method from another class? I really don't want it all in a single cs file and get thousands of lines of code when I can just have a new class in a new cs file.

Thanks for any help!
Link to comment
Share on other sites

You need to reference the other file at run time somehow, either by initializing an instance of it, or declaring it static so that only a single instance of it can exist.

Until you do this, the other class doesn't actually exist, it is just a template used to make instances. The static keyword cheats and initialized a single copy of the class on launch for you so you don't have to do it yourself for static objects.

[code]namespace same
{
public class mainclass : MonoBehaviour
{
public otherclass oc;
void Update()
{
do some other stuff //--------this stuff works
[U][COLOR="#FF0000"]othercalss oc = new otherclass();[/COLOR][/U] <- initialize a new instance of your class
oc.justworkforchristssake();
do more stuff //-------------this stuff never works
}
}
}


//-----------------OTHER CS FILE-----------------------

namespace same
{
public class otherclass
{
public void justworkforchristssake()
{
Debug.Log("IT FINALLY WORKED TIME TO SWEEP UP ALL MY HAIR I'VE PULLED OUT"); //----this never get in to the log
}
}
}[/code]

or

[code]namespace same
{
public class mainclass : MonoBehaviour
{
public otherclass oc;
void Update()
{
do some other stuff //--------this stuff works
[COLOR="#FF0000"][U] otherclass[/U][/COLOR].justworkforchristssake(); //static is directly referenced
do more stuff //-------------this stuff never works
}
}
}


//-----------------OTHER CS FILE-----------------------

namespace same
{
public [COLOR="#FF0000"][U]static[/U][/COLOR] class otherclass //the static keyword tells the program this is the only instance of this class that will ever exist, so you don't need to initialise it
{
public void justworkforchristssake()
{
Debug.Log("IT FINALLY WORKED TIME TO SWEEP UP ALL MY HAIR I'VE PULLED OUT"); //----this never get in to the log
}
}
}[/code]

These concepts are part of the basic core that you need to know in order to work with C#. I'd recommend googling C# tutorials, you are going to keep banging your head against the wall on basic stuff like this until you do.

D. Edited by Diazo
Link to comment
Share on other sites

You either need an instance of otherclass to call the method on, or both otherclass and its methods need to be static.

To get an instance of otherclass, you either need to create it or find it somehow. Creating an instance is very easy:
[code]// instance of otherclass
public void Start()
{
oc = new OtherClass(); // calls the constructor for OtherClass
}
// Update() as per above[/code]

If you want to go the static method, you don't use your instance variable, oc, at all
[code]public static class OtherClass
{
public static void JustWork...();
}

// In Update
OtherClass.JustWork...() <= Note using the class name, not an instance variable. [/code]

This stuff is some fairly basic C#. You would be better served running yourself through a general C# tutorial at the moment I think Edited by Crzyrndm
Link to comment
Share on other sites

There we go. I was saying otherclass oc = new otherclass(); in the class, and not inside void Update().

Thanks Diazo.

I've looked at tutorials but seeing where to find this without watching 40 hours of video is tough. I don't know where I would have found that I have to create the "instance?" inside the method itself rather than just in the class.

I am going through tutorials as I develop this, but there are a lot of specific problems I'm running in to which are hard to find without already knowing the specific terminology etc.

Thanks again Diazo!
Link to comment
Share on other sites

[quote name='Keith Young']There we go. I was saying otherclass oc = new otherclass(); in the class, and not inside void Update().[/QUOTE]

Yikes, careful here.

You are creating (and then destroying) a instance of the otherclass every update here. That's bad form as it exert a lot of extra overhead on the CPU in terms of load. It also does not persist data across Update frames.

All objects created inside a method are destroyed when that method finishes running, so you need to create the instance elsewhere.

In this case, I would use the class constructor. (Google "c# class constructor") Short form is that the constructor method is a method that automatically runs once when the class is created. So:

[code]namespace same
{
public class mainclass : MonoBehaviour
{
public otherclass oc;

[U][COLOR="#FF0000"]publc mainclass() //constructor class that runs once when this instance of mainclass is created. Check the exact syntax with google, I'm on my mobile.
{
oc = new otherclass();
} [/COLOR][/U]

void Update()
{
do some other stuff //--------this stuff works
oc.justworkforchristssake(); [COLOR="#FF0000"][U]this is now valid since the constructor has initialized the oc object.[/U][/COLOR]
do more stuff //-------------this stuff never works
}
}
}[/code]

This way, the oc object will stay in existence as long as this instance of mainclass exists and you aren't wasting processing power destroying and recreating it every Update() frame and any data changes made to the oc object will persist across Update frames.

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