Jump to content

Noob Needing Help WIth First Plug In


Recommended Posts

Hi Guys, 

I'm trying to make my first plug in, i'm completely new to all this so please be gentle.

I've followed a tutorial and have so far managed to set up a working environment, build a plug in and load it in game but i'm throwing some errors that I'm struggling to work out.

It's one of the first steps in the tutorial and it's just supposed to be creating a window but i'm getting the following error.

Module CareerManager threw during OnStart: System.NullReferenceException: Object reference not set to an instance of an object

  at RenderingManager.AddToPostDrawQueue (Int32 queueSpot, .Callback drawFunction) [0x00000] in <filename unknown>:0 

  at CareerManager.CareerManager.OnStart (StartState state) [0x00000] in <filename unknown>:0 

  at Part.ModulesOnStart () [0x00000] in <filename unknown>:0 

This is the code I've got so far that is throwing the error.

using UnityEngine;

namespace CareerManager
{
    public class CareerManager : PartModule
    {

        private Rect _windowPosition = new Rect();


        public override void OnStart(StartState state)
        {
            if (state != StartState.Editor)
                RenderingManager.AddToPostDrawQueue(5, OnDraw);
        }

        private void OnDraw()
        {
            if (vessel == FlightGlobals.ActiveVessel)
                _windowPosition = GUILayout.Window(10, _windowPosition, OnWindow, "This is a title");
        }

        private void OnWindow(int windowId)
        {
            GUILayout.BeginHorizontal(GUILayout.Width(250f));
            GUILayout.Label("THis is a label");
            GUILayout.EndHorizontal();

            GUI.DragWindow();
        }
    }
}

I've searched through the documentation i can find but i can't work out what is wrong. I guess something has changed since the tutorial was wrote? Or i'm missing something simple? Any help will be appreciated.

Cheers 

Link to comment
Share on other sites

I've found sarbians notes on  RenderingManager  and it being removed but I don't understand how to implement the below into my code.

Quote

RenderingManager

That class is still here but should not be used anymore. The object is not present anymore and even adding it manually create problems (corruption of RenderingTexture). So you will have to replace your code. Unfortunately it means that many tutorial are now obsolete.


void Start() // or an other similar mtehod
{
	RenderingManager.AddToPostDrawQueue(3, new Callback(drawGUI));
	RenderingManager.AddToPreDrawQueue(3, new Callback(myPreDrawQueue));
}

void myPreDrawQueue()
{
  // my preDrawQueue code
}

void drawGUI()
{
  // my GUI code
}

Need to be replaced with 


private void OnGUI()
{
    if (Event.current.type == EventType.Repaint || Event.current.isMouse)
    {
        myPreDrawQueue(); // Your current on preDrawQueue code
    }
    drawGUI(); // Your current on postDrawQueue code
}

void myPreDrawQueue()
{
  // my preDrawQueue code
}

void drawGUI()
{
  // my GUI code
}

 

So for most mods it will mean adding OnGUI and calling your current UI code from it.

 

Link to comment
Share on other sites

RenderingManager cannot be used... it is a defunc KSP class.
You need to use the Unity OnGUI which will be called by Unity automatically if your class inherits from MonoBehaviour.
Add this to your CareerManager class:

private void OnGUI()
{    
    onDraw(); 
}

Or better yet just change your onDraw method to be called OnGUI

This might help:
http://docs.unity3d.com/Manual/ExecutionOrder.html

Link to comment
Share on other sites

57 minutes ago, JPLRepo said:

RenderingManager cannot be used... it is a defunc KSP class.
You need to use the Unity OnGUI which will be called by Unity automatically if your class inherits from MonoBehaviour.
Add this to your CareerManager class:


private void OnGUI()
{    
    onDraw(); 
}

Or better yet just change your onDraw method to be called OnGUI

This might help:
http://docs.unity3d.com/Manual/ExecutionOrder.html

Hi, 

Thanks for helping. I'm struggling to understand what that means.

How would i change what i have now to use OnGUI instead? do i just add what you put above into my code?

The link looks useful but i don't actually know how to use any of it.

After a lot of fiddling and rebuilding i finally got it working!!!

Cheers, i really appreciate the help.

Edited by dboi88
Link to comment
Share on other sites

4 minutes ago, JPLRepo said:

Glad you got it working. Don't give Up! and read that unity3d page. and lots of other unity pages. Might help if you read up on the basics of unity.

Thanks.

The trouble with the documentation is i do understand it in so much as what can be achieved with each the events and classes and how evrything ties together from a conceptual point of view, it's actually implementing them into a working code that i'm struggling with, I've never coded in C# before.

It's quite frustrating because i can clearly see i can do everything i want to do but it's going to take me a while to work out how to put things together!

I'm enjoying it though!

Link to comment
Share on other sites

Hi guys, tonight's stumbling block. . . 

I had to replace

public override void OnStart(StartState state)
        {
            if (state != StartState.Editor)
                RenderingManager.AddToPostDrawQueue(5, OnDraw);
        }

with 

private void OnGUI()
        {
            ///checks if styles have been initated and skips if they have not
            if (!_hasInitStyles) InitStyles();
            {
            /// calls OnDraw method to draw GUI
            OnDraw();
            }
        }

To get around 'RenderingManager' no longer being in use. But i've now lost the Start.State check. I'm really struggling to work out how i can work that check back into the OnGUI method.

Can someone explain the different ways i can call and check against the current scene?

Cheers for the help :)

Link to comment
Share on other sites

You can do it using negative logic or positive logic. If you don't want the GUI in the editor but every other scene then:
 

private void OnGUI()
        {
            if (HighLogic.LoadedScene == GameScenes.EDITOR)
		{
			return;
		}
			///checks if styles have been initated and skips if they have not
            if (!_hasInitStyles) InitStyles();
            {
            /// calls OnDraw method to draw GUI
            OnDraw();
            }
        }

 

Edited by JPLRepo
correct my postive negative logic
Link to comment
Share on other sites

17 minutes ago, JPLRepo said:

You can do it using negative logic or positive logic. If you don't want the GUI in the editor but every other scene then:
 


private void OnGUI()
        {
            if (HighLogic.LoadedScene == GameScenes.EDITOR)
		{
			return;
		}
			///checks if styles have been initated and skips if they have not
            if (!_hasInitStyles) InitStyles();
            {
            /// calls OnDraw method to draw GUI
            OnDraw();
            }
        }

 

Cheers, that is working and following looking at the other HighLogic functions this opens a lot of possibilites.

I'm struggling to understand why this makes the GUI not show in the editor though? in the editor wouldn't HighLogic.LoadedScene return EDITOR and if EDITOR == EDITOR wouldn't this return true?

Link to comment
Share on other sites

ok now i'm really confused because it was behaving as first stated. I have this

 private void OnGUI()
        {
            if (HighLogic.LoadedScene == GameScenes.EDITOR)
            {
                return;
            }
            ///checks if styles have been initated and skips if they have not
            if (!_hasInitStyles) InitStyles();
            {
            /// calls OnDraw method to draw GUI
            OnDraw();
            }
        }

and this does not show in the editor, it does show in flight . . .

Link to comment
Share on other sites

oh man... yeah told you pre-coffee... I was right the first time.
It is checking if the current game scene is EDITOR and if it IS then it returns - ie doesn't execute the rest of the method so OnDraw is not called.

Link to comment
Share on other sites

1 hour ago, JPLRepo said:

oh man... yeah told you pre-coffee... I was right the first time.
It is checking if the current game scene is EDITOR and if it IS then it returns - ie doesn't execute the rest of the method so OnDraw is not called.

Thanks so much for your help. I understand it now. I managed to play around and get different set ups working so i know how to control which scenes it shows in now. I also managed to convert my whole class to Monobehaviour by following the unity documentation and searching through the KAC source files. So it's not attached to a part module anymore! 

Now to start working out buttons and lists.

Edited by dboi88
Link to comment
Share on other sites

OK my next problem is saving settings to a file.

I did have this working previously.

	public void OnSave(ConfigNode node)
        {
            PluginConfiguration config = PluginConfiguration.CreateForType<CareerManager>();

            config.SetValue("Main Window Position", _mainwindowPosition);
            config.save();
        }

        public void OnLoad(ConfigNode node)
        {
            PluginConfiguration config = PluginConfiguration.CreateForType<CareerManager>();

            config.load();
            _mainwindowPosition = config.GetValue<Rect>("Main Window Position");
        }

but this no longer works. I think it stopped working when i switched from :PartModule to :monobehaviour.

Can anyone confirm if that is why? and what the preferred method for saving things like window settings.

Also do you know how i can call a list of all active contracts? I can only find calls for when a contract is changed/added/completed ect. I just want a list of all accepted contracts that are currently live in game.

Cheers

Link to comment
Share on other sites

Because OnSave and OnLoad are part of PartModule - which is a KSP class/construct. It is not part of MonoBehaviour.
You can move you save and load to Awake and OnDestroy methods... or you could use KSPScenario module behaviour.
What you are missing here is knowledge on how Unity MonoBehaviour works and how KSP has extended that. First go back to the link I provided the other day on how Unity executes then:
Two good guides that might help you understand:

 

List of contracts can be found in:
ContractSystem.Instance.Contracts

Link to comment
Share on other sites

11 minutes ago, JPLRepo said:

What you are missing here is knowledge

Nail, head.

I've been furiously playing around with what I've learnt so far but I've definitely hit a barrier on what i can achieve next.

I'm going to take a few days to have a good read through the first link you gave me again. I'll be back if there's anything i can't get my head around.

This is what I've got so far

3WWevDK.png

Link to comment
Share on other sites

I've used the Unity Scripting API documents and TriggerAU's framework loads to get to where i am now but i didn't really understand why things were placed where they were. btw the code examples in the unity API docs are terrible!! that's why i used TriggerAU's files for references on working examples.

So all of my code so far is just where it landed with no rhyme nor reason other than it worked. So my plan is.

Read the Unity MANUAL instead of just the Scripting API, and hopefully understand it.

Revist TriggerAU's Frameworks and hopefully they'll then make a lot more sense.

Plan out and build a framework for my own plugin that i actually understand in before moving forwards with any more code.

Link to comment
Share on other sites

Hi again,

I've had a good read through the unity manual and i'm understanding a lot more now and feel i could get on with a lot more coding.

but

I've also had a good read through the blog from TriggerAU and looked through the examples but i'm struggling in understanding how to actual use his framework. There is lots of information about what he has made his framework do, but i can't understand how to actually use what he's made. There isn't any direction.

Are his frameworks supposed to be used as actual templates or are are they acting like library's where we can call complicated functions with simpler methods?

I'm struggling with the fact that the none of the example projects are commented. The blog only outlines his process for creating the framework and doesn't really touch on how it should be used. There is certainly no list of what functions the framework supplies.

This has me worried that i haven't actually learnt anything . . 

Link to comment
Share on other sites


I'm new too, I didn't want to create a new topic.

So I want to use the new unity UI system with prefabs instead of OnGUI. Does anybody know how do I do it with the Asset Bundles? A tutorial would be even better.

 

Thanks

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