Jump to content

OnStart Is Giving Me Conniptions


Recommended Posts

I have a two parts with a single .DLL file. One part class (orbitscanner) is derived from another part (landscanner). For testing and reporting purposes, I reduced everything to their basics. Each part is a simple Cube with a collider mesh.

The problem: when I install a part using the orbitscanner part, it attaches correctly. When I attempt to attach the landscanner part (which is the base part), it refuses to attach; in fact, after that, nothing will attach. You will note in the source code that although orbit scanner is derived from and extends landscanner, it contains no code. It's a class about nothing (sounds like a Seinfeld episode).

using System;

using System.Collections;

using UnityEngine;

namespace MissionControllerEC

{

public class landscanner : PartModule

{

[KSPField(isPersistant = true, guiActive = false)]

private bool boolDeployed = false;

[KSPField(isPersistant = true, guiActive = false)]

private bool isScanning = false;

[KSPField(isPersistant = true, guiActive = false)]

private Animation anim;

public const string scannerType = "ground";

public const string modelType = "egbs";

public const string modelName = "Enhanced Ground-based Scanner";

public bool isDeployed // the deployment property

{

get

{

return boolDeployed;

}

}

public override void OnStart(PartModule.StartState state)

{

anim = part.FindModelAnimators("Scene")[0];

Deploy(boolDeployed); //restore deployment & scanning states

base.OnStart(state);

}

[KSPEvent(active = true, guiActive = true, guiActiveEditor = false, guiName = "Deploy")]

public void ToggleDeploy()

{

Deploy(!boolDeployed);

return;

}

public void Deploy(bool deployThis)

{

boolDeployed = deployThis;

if (boolDeployed) // deploy, start scanning

{

anim.Rewind();

anim["Deploy"].speed = 1f;

anim["Deploy"].normalizedTime = 0f;

anim.Play("Deploy");

isScanning = true;

}

else // stop scanning, retract

{

isScanning = false;

anim.Stop();

anim.Rewind();

anim["Deploy"].speed = -1f;

anim["Deploy"].normalizedTime = 1f;

anim.Play("Deploy");

}

Events["ToggleDeploy"].guiName = (boolDeployed ? "Retract" : "Deploy");

return;

}

// to test OnFixedUpdate, you MUST have at least one stage and Launch!!!

public override void OnFixedUpdate()

{

// Debug.Log("onFixedUpdate: deployed= " + boolDeployed + ", scanning= " + isScanning + ", playing= " + anim.isPlaying);

if (isScanning && !anim.isPlaying) // start scanner

{

anim.Rewind();

anim["Scan"].speed = 1f;

anim["Scan"].normalizedTime = 0f;

anim.Play("Scan");

}

base.OnFixedUpdate();

}

}

public class orbitscanner : landscanner

{

}

}

The models are the exact same file: landscanner.mu. Same for the texture file, UVscanner.mbm. The CFG files for the two parts are exactly the same with three exceptions: 1) part name (required by KSP); 2) part title (so you can see which is which in VAB); 3) module name (to determine which class).

Why do I think OnStart is the culprit? When I comment-out the line "anim = part.FindModelAnimators("Scene")[0];", then I can attach the landscanner part. Of course, there are no animations as a result. The FBX and MU files contain one baked animation (Scene), plus two clips (Deploy, Scan).

Note: this all used to work correctly. That is, I could attach both parts and the animations played. What changed? Nothing. When things started to fail, I actually simplified the code. I changed nothing in OnStart.

Why does landscanner fail and orbitscanner succeed when they are the same code? Note that I'm using no other mods. There are only two folders in my GameData directory: Squad and RocketWorks (my part folder).

I've included the GameData, source code, Blender, FBX, and texture (PNG) files.

ZIP file

Edited by Apollo13
Link to comment
Share on other sites

Can you throw a Print statement in there to get a timestamp in the log to see when your OnState is running?

This is only tangentially related, but I had issues trying to use OnStart myself recently.

Now, it was not the PartModule OnStart, but the KSPAddon.Flight OnStart, but it was running a lot earlier then I thought it did.

Notably, it would run while the monitor was still displaying the black screen with the "Loading" indicator in the bottom right and while it looks like objects existed at that point, the load was not finished and things went wonky when I tried to do anything to the vessel.

I would think that simply finding animation clips would not be affected by running early as you are not interacting with the vessel or other objects, but maybe the animations are not initialized yet because you are still looking at at loading screen?

A bit of a reach, I know.

The other test you could do it to put it in the Update frame and run it on the first frame where Vessel.holdPhysics goes false. At that point everything is finished loading and everything is good to go. This would not work as a permanent solution I don't think as switching vessels without loading would mess it up, but it is a way to run your code as a test after everything else is finished loading to prove it is in fact OnStart causing the issue.

D.

Link to comment
Share on other sites

I would put this in fixedUpdate



if(anim = null)
{
anim = part.FindModelAnimators("Scene")[0];
}

this will throw some errors until the part is loaded, then it runs once

to prevent the NREs you can wrap it in try-catch

I call that "pragmatic init" - it tryes until it works..

no more headache.. - just keep all following dependent code in an "if != null" thingy..

Link to comment
Share on other sites

The problem: when I install a part using the orbitscanner part, it attaches correctly. When I attempt to attach the landscanner part (which is the base part), it refuses to attach; in fact, after that, nothing will attach. You will note in the source code that although orbit scanner is derived from and extends landscanner, it contains no code. It's a class about nothing (sounds like a Seinfeld episode).

First, make sure you're building for 3.5. I think I saw an attribute on the DLL that said it was targeting .NET 4.5 and you don't want that.

There are some clues in the debug log. If you attach the landscanner and look in the log (note: enable VERBOSE_DEBUG_OUTPUT in settings.cfg to show the full stack trace like this):

fee57f5ed3.png

So, something is wrong when the PartModule is saving and it has something to do with a field's type. That means the problem is here:

        [KSPField(isPersistant = true, guiActive = false)]
private bool boolDeployed = false;
[KSPField(isPersistant = true, guiActive = false)]
private bool isScanning = false;
[KSPField(isPersistant = true, guiActive = false)]
private Animation anim;

Persistent KSPFields are sadly simple and only support a relatively limited set of types -- int, float, string, Vector2, Vector3, Quaternion and bool if I recall correctly -- so your attribute on anim is causing an exception.

The reason your derived type works is that anim is hidden from it (being a private member of the base class) and so KSP doesn't try to stuff it through this BaseFieldList.Save method it chokes on earlier

Link to comment
Share on other sites

First, make sure you're building for 3.5. I think I saw an attribute on the DLL that said it was targeting .NET 4.5 and you don't want that.

There are some clues in the debug log. If you attach the landscanner and look in the log (note: enable VERBOSE_DEBUG_OUTPUT in settings.cfg to show the full stack trace like this):

http://puu.sh/dlAti/fee57f5ed3.png

So, something is wrong when the PartModule is saving and it has something to do with a field's type. That means the problem is here:

        [KSPField(isPersistant = true, guiActive = false)]
private bool boolDeployed = false;
[KSPField(isPersistant = true, guiActive = false)]
private bool isScanning = false;
[KSPField(isPersistant = true, guiActive = false)]
private Animation anim;

Persistent KSPFields are sadly simple and only support a relatively limited set of types -- int, float, string, Vector2, Vector3, Quaternion and bool if I recall correctly -- so your attribute on anim is causing an exception.

The reason your derived type works is that anim is hidden from it (being a private member of the base class) and so KSP doesn't try to stuff it through this BaseFieldList.Save method it chokes on earlier

Vector2 doesn't work for me, and color is supported as well. Any classes that are added with the persistent tag and have persistent members are converted to a config item.

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