Jump to content

NaN Orbit when using custom PartModule


Recommended Posts

Whenver I try to use a custom PartModule, physics doesnt load and the DebugLog keeps spitting out errors saying that my orbit is NaN.


//KSPFields
public class ModuleUFO : PartModule
{
[KSPField]
public float GravitationalConstant;
[KSPField]
public string resourceName;
[KSPField]
public string electricResourceName;
[KSPField]
public double kerbalConsuption;
[KSPField]
public float maxThrust;
[KSPField]
public float translationMaxThrust;
[KSPField]
public float afterBurnerThrustMultiplier;
[KSPField]
public float afterBurnerResourceMultiplier;
[KSPField]
public int powerPerAbduction;


//KSPField GUI crappers
[KSPField(guiName = "Hovering: ")]
public bool hovering = false;
[KSPField(guiName = "After-Burner active: ")]
public bool afterBurner = false;
[KSPField(guiName = "Flight Mode: ")]
public string flightMode = "Surface";


//Regular fields
LineRenderer deathRenderer = null;

public override void OnStart(StartState state)
{
base.OnStart(state);


if(part.gameObject.transform.FindChild("Light").gameObject.GetComponent<LineRenderer>() != null)
{
deathRenderer = part.gameObject.transform.FindChild("Light").gameObject.AddComponent<LineRenderer>();
}
else
deathRenderer = part.gameObject.transform.FindChild("Light").gameObject.GetComponent<LineRenderer>();


deathRenderer.renderer.enabled = false;
maxThrust *= 1000;
translationMaxThrust *= 1000;
}
public override void OnFixedUpdate()
{
base.OnFixedUpdate();

float throttle = vessel.ctrlState.mainThrottle;
double resourceRequest = kerbalConsuption;
Vector3 thrustDirection = new Vector3(0f, 1f, 0f);

//hovering stuff
if(hovering)
{
float vesselmass = vessel.GetTotalMass();
float gravity = (float)vessel.mainBody.GeeASL;
float thrust = vesselmass * gravity * GravitationalConstant;
float realThrust = Mathf.Clamp(thrust, 0f, maxThrust);
throttle = realThrust / maxThrust;
resourceRequest *= throttle;
}
//space mode stuff
if(flightMode == "Space")
{
thrustDirection = new Vector3(1f, 0f, 0f);
resourceRequest *= throttle;
}
if(flightMode == "Surface")
{
var axisX = GameSettings.AXIS_TRANSLATE_X;
var axisZ = GameSettings.AXIS_TRANSLATE_Z;
var axisY = GameSettings.AXIS_TRANSLATE_Y;
float directionX = axisX.GetAxis();
float directionZ = axisZ.GetAxis();
float directionY = axisY.GetAxis();
float multiplier = 1f;
float abMultiplier = 1f;
if(afterBurner)
{
multiplier = afterBurnerThrustMultiplier;
abMultiplier = afterBurnerResourceMultiplier;
}
resourceRequest += 0.125 * directionX * kerbalConsuption * abMultiplier;
resourceRequest += 0.125 * directionZ * kerbalConsuption * abMultiplier;
resourceRequest += 0.125 * directionY * kerbalConsuption * abMultiplier;
part.rigidbody.AddRelativeForce(new Vector3(directionX * multiplier, directionY, directionZ * multiplier));
}


part.RequestResource(resourceName, resourceRequest * Time.deltaTime);
part.RequestResource(electricResourceName, -0.1 * Time.deltaTime);
part.rigidbody.AddRelativeForce(thrustDirection * maxThrust * throttle);
}


[KSPEvent(guiName = "Toggle Afterburner")]
public void ToggleAfterburner()
{
afterBurner = !afterBurner;
}
[KSPEvent(guiName = "Toggle Hover")]
public void ToggleHover()
{
hovering = !hovering;
}
[KSPEvent(guiName = "Toggle Flight Mode")]
public void ToggleFlightMode()
{
if(flightMode == "Surface")
flightMode = "Space";
else
flightMode = "Surface";
}
[KSPEvent(guiName = "Abduct")]
public void Abduct()
{
LineRenderer deathRenderer = part.gameObject.transform.FindChild("Light").gameObject.GetComponent<LineRenderer>();
Color abductColor = new Color(0f, 0.859f, 0.27f, 1f);
Vector3 AbductPos = part.gameObject.transform.FindChild("Light").position;
var Objs = Physics.OverlapSphere(AbductPos, 50);
KerbalEVA victim = null;


foreach(Collider c in Objs)
{
if(c.gameObject.GetComponent<KerbalEVA>() != null)
{
victim = c.gameObject.GetComponent<KerbalEVA>();
break;
}
}
if(victim == null)
{
ScreenMessages.PostScreenMessage(new ScreenMessage("No victims found in the vicinity", 4f, ScreenMessageStyle.UPPER_CENTER), false);
return;
}


part.RequestResource(electricResourceName, (double)powerPerAbduction);
deathRenderer.renderer.enabled = true;
deathRenderer.SetWidth(6f, 10f);
deathRenderer.SetColors(abductColor, abductColor);
deathRenderer.SetPosition(0, AbductPos);
deathRenderer.SetPosition(1, victim.gameObject.transform.position);
Invoke("killAbductee", 0.5f);
Invoke("cancelRay", 0.3f);
}
public void killAbductee(KerbalEVA victim)
{
victim.part.explosionPotential = 100;
victim.part.explode();


foreach(var crew in victim.part.protoModuleCrew)
{
crew.Die();
crew.rosterStatus = ProtoCrewMember.RosterStatus.MISSING;
crew.StartRespawnPeriod(7200);
part.RequestResource(resourceName, -1);
}
}
public void cancelRay()
{
deathRenderer.renderer.enabled = false;
}
}

:(

Link to comment
Share on other sites

I don't know for sure why you're getting NaN for the orbit, but there are a few things in that code that don't look right at a casual glance based on this code in isolation (since I don't know what part you're attaching the module to, or what's in the config file):

You're not verifying that the "Light" transform exists in your part.

You are dereferencing a null object in OnStart if the GetComponent call returns null.

You don't have defaults for any of the KSPField values, and you don't set them anywhere, so they could be 0 for all I know (which can lead to a divide by zero in at least one spot I see).

It also looks like you're querying the deathRenderer in Abduct, even though you notionally got it already in OnStart.

Have you printed out the values you're actually adding in part.rigidbody.AddRelativeForce during OnFixedUpdate to see if they're reasonable?

Link to comment
Share on other sites

            if(part.gameObject.transform.FindChild("Light").gameObject.GetComponent<LineRenderer>() != null)
{
deathRenderer = part.gameObject.transform.FindChild("Light").gameObject.AddComponent<LineRenderer>();
}
else
deathRenderer = part.gameObject.transform.FindChild("Light").gameObject.GetComponent<LineRenderer>();

Lets transform that to pseudo code:

 if Part has non null LineRenderer
Add LineRenderer to Part
else
Get LineRenderer in Part

I think the problem just became obvious.

Also: you don't need to go through gameObject to get the part transform. this.part.transform.FindChild("Light") will do just alright.

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