Jump to content

The official unoffical "help a fellow plugin developer" thread


Recommended Posts

4 hours ago, DeltaDizzy said:

1)    How do I export an assetbundle from unity? I'm following this tutorial:

 

Is this part from the tutorial not working?

Exporting the Asset Bundle:

To load anything into KSP we’ll need to actually export all of our prefabs as an AssetBundle using the Asset Compiler from the KSP Part Tools. The method for this is similar to that described in the KSPedia tutorial, just without the KSPedia Database steps.

  • Drag any prefabs into the Assets folder in your Project Window
  • Set the AssetBundle name in the Properties Panel in the lower right
  • Then open or go to the Asset Compiler window -> Create (for your bundle) -> Update -> Build
  • This will export a file into the AssetBundles folder in your Unity Project, it should have the .ksp file extension

Like I said, there is more detail in the KSPedia tutorial linked at the top, but it's pretty simple for basic assets, as long as the Part Tools are properly installed. 

I actually don't bother with Part Tools most of the time, since I usually use Unity 5.4 (there are Part Tools for that version, but I've heard there are some problems and I've never bothered with them). You can just add a simple script to your Unity project to build an asset bundle. I don't have said script on hand, but it's simple enough to figure out if Part Tools aren't working for some reason.

 

Link to comment
Share on other sites

2 hours ago, DMagic said:

 

Is this part from the tutorial not working?

Like I said, there is more detail in the KSPedia tutorial linked at the top, but it's pretty simple for basic assets, as long as the Part Tools are properly installed. 

I actually don't bother with Part Tools most of the time, since I usually use Unity 5.4 (there are Part Tools for that version, but I've heard there are some problems and I've never bothered with them). You can just add a simple script to your Unity project to build an asset bundle. I don't have said script on hand, but it's simple enough to figure out if Part Tools aren't working for some reason.

 

There's no update option. Also I 'm not sure how to transfer it into a prefab.

Link to comment
Share on other sites

On 8/11/2017 at 10:13 AM, Benjamin Kerman said:

In what unit does Planetarium.GetUniversalTime return? Is it seconds? 

I want to have something update 2 seconds after an event. 

It appears that both Planetarium.time and Planetarium.GetUniversalTime() return the time in seconds, and both are the same in accuracy. One is a method, and the other is an instance, so you have to use Planetarium.fetch to get the time. 

Link to comment
Share on other sites

Hi all, I've just started modding and am following this tutorial on getting started:

I'm at the first step (IDE setup) and have installed Visual Studio 2017. I've followed all in instructions for this hello world program:

using System;
using UnityEngine;

namespace HelloWorld
{
    [KSPAddon(KSPAddon.Startup.MainMenu, false)]
    public class Hello : MonoBehaviour
    {
        public void Update()
        {
            Debug.Log("Hello world! " + Time.realtimeSinceStartup);
        }
    }
}

 

I made sure iI was compiling into a .NET 3.5 lib and that the necessary .dlls are referenced.

I compiled into a .dll, put it into my GameData folder, but instead of Hello world I get a string of FileNotFoundexceptions:

HhfsQKK.png

 

It works just fine if I get rid of "Time.realtimeSinceStartup," and I get the same error if I try to use "Time.time," etc.

The exception is also common when I tried to follow this tutorial

 

 

It looks like the HelloWorld.dll is loading, but it breaks when Update is called. Any help would be appreciated! 

Link to comment
Share on other sites

8 hours ago, deltavee said:

I made sure iI was compiling into a .NET 3.5 lib and that the necessary .dlls are referenced.

It tries to load v4 of System so I would say it is most likely compiled as a .NET 4 dll. Could you put your .csproj file somewhere ?

Link to comment
Share on other sites

Your project is setup for "Microsoft.NETCore.UniversalWindowsPlatform". It may be that your VS does not have the proper workloads installed. I think I had the same problem when I installed 2017.

You should have a "Visual Studio Installer" in your start menu. Launch it and select the icon next to launch under VS 2017, and select modify in the menu. IN the next Window you should have at least that checked. The important one is the ".NET desktop development" (center) and the ".NET Framework 3.5 development tools" (right side)eUeJYwL.png

 

And when you create the project select "Class Library (.NET Framework)" then open the project properties and set it to ".NET Framework 3.5"

 

Link to comment
Share on other sites

Where can i get the information if the Brakes are currently activated in a vessel? Have been looking through the code for multiple hours.
Its not in vessel.ctrlState nor vessel.Autopilot and neither in any other classes i looked in.

My only idea was to use an actiongroup to get the information like that:

        [KSPField(isPersistant = true)]
        bool brakesEnabled = false;

        /// <summary>
        /// Action to set the breakes
        /// </summary>
        [KSPAction(actionGroup = KSPActionGroup.Brakes)]
        public void ToggleBrakes(KSPActionParam param)
        {
            brakesEnabled = (param.type == KSPActionType.Activate);
        }

This solution works but seems to be a bit cumbersome for such a seemingliy simple task. Is there a more elegant solution?

Edited by Nils277
Link to comment
Share on other sites

5 minutes ago, TheRagingIrishman said:

Maybe, the problem is that i do not use wheels. And as i see it, this class can only be accessed from ModuleWheelBase. 

Link to comment
Share on other sites

Anyone got an idea how to get a list of keys (or key-value pairs) in a ConfigNode? I have only found lists of sub-nodes and of values. I want to basically convert ConfigNode contents into a Dictionary without knowing in advance what keys it has.

Link to comment
Share on other sites

 

On 8/27/2017 at 7:29 PM, sarbian said:

Uh, if you have the values list then what else do you need? 

Well, I need the respective keys too. In my case I wanted to read a node into a Dictionary, but I don't know what keys it will have in advance (they can change and in general be user-defined).

For instance, I wanted this:

NODE {
    time = 2342
    vessel = Probe 1
    mass = 3.4
}

to become a Dictionary with keys { "time", "vessel", "mass" } and respective values of { "2342", "Probe 1", "3.4" }. I can get the latter by calling GetValues, but there's no way to get the former part. I had to create a subnode for every value that looked like this:

NODE {
    SUBNODE {
        key = time
        value = 2342
    }
    ...
}

It looks a bit too complex, but I couldn't think of anything better.

Edited by garwel
Link to comment
Share on other sites

24 minutes ago, garwel said:

 

Well, I need the respective keys too. In my case I wanted to read a node into a Dictionary, but I don't know what keys it will have in advance (they can change and in general be user-defined).

For instance, I wanted this:


NODE {
    time = 2342
    vessel = Probe 1
    mass = 3.4
}

to become a Dictionary with keys { "time", "vessel", "mass" } and respective values of { "2342", "Probe 1", "3.4" }. I can get the latter by calling GetValues, but there's no way to get the former part. I had to create a subnode for every value that looked like this:


NODE {
    SUBNODE {
        key = time
        value = 2342
    }
    ...
}

It looks a bit too complex, but I couldn't think of anything better.

You do have access to the keys :huh:

Dictionary<string, string> dict = new Dictionary<string, string>();

for (int i = 0; i < node.values.Count; i++)
{
  ConfigNode.Value value = node.values[i];
  dict[value.name] = value.value;
}
Link to comment
Share on other sites

2 hours ago, blowfish said:

You do have access to the keys :huh:


Dictionary<string, string> dict = new Dictionary<string, string>();

for (int i = 0; i < node.values.Count; i++)
{
  ConfigNode.Value value = node.values[i];
  dict[value.name] = value.value;
}

Thank you! Somehow, it didn't occur to me to use the values property. Or maybe I thought it would contain only values, without the keys.

Edited by garwel
Link to comment
Share on other sites

On 8/23/2017 at 5:49 AM, Nils277 said:

Where can i get the information if the Brakes are currently activated in a vessel? Have been looking through the code for multiple hours.
Its not in vessel.ctrlState nor vessel.Autopilot and neither in any other classes i looked in.

My only idea was to use an actiongroup to get the information like that:


        [KSPField(isPersistant = true)]
        bool brakesEnabled = false;

        /// <summary>
        /// Action to set the breakes
        /// </summary>
        [KSPAction(actionGroup = KSPActionGroup.Brakes)]
        public void ToggleBrakes(KSPActionParam param)
        {
            brakesEnabled = (param.type == KSPActionType.Activate);
        }

This solution works but seems to be a bit cumbersome for such a seemingliy simple task. Is there a more elegant solution?

There is no one field storing the value of the brakes key per-se.
However, how it works is when the player hits the brakes key a KSPActionGroup is fired called KSPActionGroup.Brakes.
The ModuleWheelBrakes implements this attribute on the method BrakeAction. Which turns wheel brakes on or off, and it's state is stored in ModuleWheelBrakes as public float brakeInput.
So you are completely on the right track.  If you want to do your own brake actions for your module you need to have the attribute as above and store your own status in your module.

Link to comment
Share on other sites

I am investigating making a part like NASA's https://en.wikipedia.org/wiki/Robonaut. Ideally, the Kerbal Robonaut will have the ability to repair wheels, run experiments and collect their data, and repack chutes. Many functions in KSP, such as ModuleScienceExperiment.DeployExperimentExternal() and ModuleParachute.Repack(), check for the presence of a kerbal with the required skill. I know how to programmatically generate a kerbal and add it to a part, but what I can't figure out is how to flag Vessel.isEVA = true, because Vessel.isEVA is read only.

I tried adding a KerbalEVA part module to the prototype Robonaut part but that didn't help. I'm wondering if a dev like @JPLRepo is able to shed some light on how the game determines if the vessel is a kerbal on EVA, or ideally, if there is a way to bypass the skill check required to pack chutes and such. Calling ModuleScienceExperiment.ResetExperiment on a vessel that isn't the active vessel gives me an error, something to the effect that the event requires a powered vessel to accomplish. A similar error does not occur when calling ModuleWheelDamage.SetDamaged(false), so at least I can have the Robonaut change tires. :)

The only thing that comes to mind would be to disable crew experience, but I don't think that disables crew skill.

Any ideas?

Thanks for your help! :)

Edited by Angel-125
Link to comment
Share on other sites

On 9/5/2017 at 10:57 AM, Angel-125 said:

I am investigating making a part like NASA's https://en.wikipedia.org/wiki/Robonaut. Ideally, the Kerbal Robonaut will have the ability to repair wheels, run experiments and collect their data, and repack chutes. Many functions in KSP, such as ModuleScienceExperiment.DeployExperimentExternal() and ModuleParachute.Repack(), check for the presence of a kerbal with the required skill. I know how to programmatically generate a kerbal and add it to a part, but what I can't figure out is how to flag Vessel.isEVA = true, because Vessel.isEVA is read only.

I tried adding a KerbalEVA part module to the prototype Robonaut part but that didn't help. I'm wondering if a dev like @JPLRepo is able to shed some light on how the game determines if the vessel is a kerbal on EVA, or ideally, if there is a way to bypass the skill check required to pack chutes and such. Calling ModuleScienceExperiment.ResetExperiment on a vessel that isn't the active vessel gives me an error, something to the effect that the event requires a powered vessel to accomplish. A similar error does not occur when calling ModuleWheelDamage.SetDamaged(false), so at least I can have the Robonaut change tires. :)

The only thing that comes to mind would be to disable crew experience, but I don't think that disables crew skill.

Any ideas?

Thanks for your help! :)

The external science functions do expect the vessel to be EVA and they do check Vessel.isEVA. This is a read only because it is simply returning if the value of Vessel.vesselType is VesselType.EVA.
So you could trick it by setting that before calling the methods you need. I wouldn't permanently have it set, because that will probably cause issues with other functionality etc  in the game.
and yeah, you can't call ResetExperiment on a vessel that isn't the active vessel. That's the way it has been designed. That those things are  only available on the active vessel.
But you know, all you really want to do there in that case is dump the data. ModuleScienceExperiment.DumpData method (of course you'd have to GetData first).
As for bypassing skill checks etc.. most of them check first if the game parameter KerbalExperienceEnabled is active or not and applying those checks if it is active. So you could disable that while you do your thing and then turn it back on ( look at HighLogic.CurrentGame.Parameters.CustomParams<GameParameters.AdvancedParams>().EnableKerbalExperience).
 

Link to comment
Share on other sites

11 minutes ago, JPLRepo said:

The external science functions do expect the vessel to be EVA and they do check Vessel.isEVA. This is a read only because it is simply returning if the value of Vessel.vesselType is VesselType.EVA.
So you could trick it by setting that before calling the methods you need. I wouldn't permanently have it set, because that will probably cause issues with other functionality etc  in the game.
and yeah, you can't call ResetExperiment on a vessel that isn't the active vessel. That's the way it has been designed. That those things are  only available on the active vessel.
But you know, all you really want to do there in that case is dump the data. ModuleScienceExperiment.DumpData method (of course you'd have to GetData first).
As for bypassing skill checks etc.. most of them check first if the game parameter KerbalExperienceEnabled is active or not and applying those checks if it is active. So you could disable that while you do your thing and then turn it back on ( look at HighLogic.CurrentGame.Parameters.CustomParams<GameParameters.AdvancedParams>().EnableKerbalExperience).
 

OOOOO That is some really great stuff, thanks! :) I think I have enough info to dig around more and see what I can come up with. Thank you much! :)

Link to comment
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.

×
×
  • Create New...