Cephei

The official unoffical "help a fellow plugin developer" thread

2717 posts in this topic

2 minutes ago, saabstory88 said:

Quick question. I want to setup a UI_FloatEdit with values from the config file. What is the proper way to make this work?

I think you would need to set those values at run time in your module's Start().

	BaseField field = Fields["MyField"];
	UI_FloatEdit edit = (UI_FloatEdit)field.uiControlEditor;
	if (edit != null) {
		edit.minValue = 0f;
	}

 

1 person likes this

Share this post


Link to post
Share on other sites

Works like a charm, thanks!

1 person likes this

Share this post


Link to post
Share on other sites
On 6/18/2017 at 4:36 AM, Bonus Eventus said:

I did a simple test with an internal module I've been tinkering with, and caused all kinds of mayhem. The module is simple. It finds a prop transform for a screen model and an empty gameObject, then adds a camera component to the empty gameObject and adds a renderTexture to the screen model. The camera then has its targetTexture assigned to the renderTexture. That's it. 

The game loads fine but when I load the IVA on the pad the main cam is rotated 90 degrees on the x axis or sometimes is flung into deep space before the game crashes. I'm guessing it has something to do with layers and tags. I'm sure there's some camera voodoo I'm unaware of. @linuxgurugamer would probably know what the best practices are.

hum. I don't see where you create an empty GameObject. You search for a transform in a model, add a Camera component to it. Then search for the Camera Component you just added (???) and change the parent to itself. The last part, as many years of SF about time travel taught us, will not end well.

What you want may be closer to this. But know that you need more than 1 camera to show the scene so you would have to create one for each of FlightCamera.fetch.cameras[x] (2 in currently). See JPLRepo post for the details

				
displayTexture = new RenderTexture(dPixelWidth, dPixelHeight, 24, RenderTextureFormat.ARGB32);
displayTexture.Create(); // not sure if mandatory
displayMaterial = internalProp.FindModelTransform(dTransform).GetComponent<Renderer>().material;

cameraParentTransform = internalProp.internalModel.FindModelTransform(cameraName);				

GameObject cameraGameObject = new GameObject("MyNewCamera");				
cameraGameObject.transform.parent = cameraParentTransform;
cameraGameObject.transform.localPosition = Vector3.zero;
cameraGameObject.transform.localRotation = Quaternion.identity;							

Camera cameraFeed = cameraGameObject.AddComponent<Camera>();
cameraFeed.CopyFrom(FlightCamera.fetch.mainCamera);
cameraFeed.fieldOfView = 110;				

UtilisTools.Log(this, "Camera created");				
displayMaterial.mainTexture = displayTexture;

 

Share this post


Link to post
Share on other sites

Posted (edited)

On 6/19/2017 at 5:30 AM, sarbian said:

hum. I don't see where you create an empty GameObject. You search for a transform in a model, add a Camera component to it. Then search for the Camera Component you just added (???) and change the parent to itself. The last part, as many years of SF about time travel taught us, will not end well.

What you want may be closer to this. But know that you need more than 1 camera to show the scene so you would have to create one for each of FlightCamera.fetch.cameras[x] (2 in currently). See JPLRepo post for the details


				
displayTexture = new RenderTexture(dPixelWidth, dPixelHeight, 24, RenderTextureFormat.ARGB32);
displayTexture.Create(); // not sure if mandatory
displayMaterial = internalProp.FindModelTransform(dTransform).GetComponent<Renderer>().material;

cameraParentTransform = internalProp.internalModel.FindModelTransform(cameraName);				

GameObject cameraGameObject = new GameObject("MyNewCamera");				
cameraGameObject.transform.parent = cameraParentTransform;
cameraGameObject.transform.localPosition = Vector3.zero;
cameraGameObject.transform.localRotation = Quaternion.identity;							

Camera cameraFeed = cameraGameObject.AddComponent<Camera>();
cameraFeed.CopyFrom(FlightCamera.fetch.mainCamera);
cameraFeed.fieldOfView = 110;				

UtilisTools.Log(this, "Camera created");				
displayMaterial.mainTexture = displayTexture;

 

Thank you @sarbian, haha, that line adding the component to itself as parent shouldn't have been in there to begin with, it was old code.That JPLRepo post helped a lot. I was confused though about whether I needed to duplicate both the near and far camera or could use one camera at a higher depth. I've since revised the code. This is where I got last night.

using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

namespace Utilis
{
	public class UtilisDisplay : InternalModule
	{
		[KSPField]
		public string cameraName = "utilisCamera";

		[KSPField]
		public int width = 512;

		[KSPField]
		public int height = 256;

		public Camera camera;

		public RenderTexture renderTexture;

		private Material material;

		public override void OnAwake()
		{
			if(!HighLogic.LoadedSceneIsFlight) return;

			renderTexture = new RenderTexture(height,width,24,RenderTextureFormat.RGB565);

			renderTexture.anisoLevel = 0;

			renderTexture.antiAliasing = 4;

			renderTexture.filterMode = FilterMode.Trilinear;

			renderTexture.isPowerOfTwo = true;

			renderTexture.Create();

			while (!renderTexture.IsCreated()) ;

			material = gameObject.GetChild("model").GetComponent<Renderer>().material;

			camera = internalModel.FindModelTransform(cameraName).gameObject.AddComponent<Camera>();

			camera.fieldOfView = 100;

			camera.cullingMask = (1 << 0) | (1 << 1) | (1 << 4) | (1 << 9) | (1 << 10) | (1 << 15) | (1 << 18) | (1 << 20) | (1 << 23);

			camera.nearClipPlane = 0.001f;

			camera.farClipPlane = 1000000000f;

			camera.targetTexture = renderTexture;

			Camera[] fCameras = FlightCamera.fetch.cameras;

			foreach(Camera c in fCameras)
			{
				if(c.name == "Camera00")
				{
					camera.depth = c.depth + 1;
				}
			}

			camera.enabled = false;

			camera.Render();

			material.mainTexture = renderTexture;
		}
	}
}

The problem of the main camera flipping out was caused by a null reference I missed in the log. I didn't understand that dTransform was not where the renderer was located, because when I compiled the .mu file I added the part tools component directly. dTransform has no renderer or mesh, what I needed was the "model" transform. 

As of this moment the problem I'm still having is that the render texture appears completely black. At first I thought it was a depth problem. I thought maybe one of the gui cameras at the lowest layer renders a black screen. But that turned out to be wrong, because I switched the depth order and nothing changed. I was thinking I would add the second camera after I confirmed I can render texture was working. 

BTW, I too am confused about RenderTexture.create( ), the docs are a bit ambiguous: "RenderTexture constructor does not actually create the hardware texture; by default the texture is created the first time it is set active. Calling Create lets you create it up front. Create does nothing if the texture is already created."

Edited by Bonus Eventus

Share this post


Link to post
Share on other sites

Posted (edited)

What's the best way to get the distance from the active vessel to a specific CelestialBody?

Edited by Dozed12
1 person likes this

Share this post


Link to post
Share on other sites

Found an odd issue working on a problem with Submarines. It looks like anything that is Splashed / Underwater is considered "VesselType.Debris" . Has anyone else confirmed this, its a problem as I am trying to implement Sonar and I would like to exclude Debris from targeting but be able to keep a list of underwater vessels.

Share this post


Link to post
Share on other sites
On 6/30/2017 at 1:11 PM, Dozed12 said:

What's the best way to get the distance from the active vessel to a specific CelestialBody?

If you can hook into the altimeter, that might be an option. 

 

Share this post


Link to post
Share on other sites
On 6/30/2017 at 1:11 PM, Dozed12 said:

What's the best way to get the distance from the active vessel to a specific CelestialBody?

Found two things of note: CelestialBody.position and Vessel.GetWorldPos3d(). With these, you could do a little Pythagoras and arrive at a distance.

Alternatively, you could do CelestialBody.GetAltitude(Vessel.GetWorldPos3d()), which would give you distance to nearest sea level. I'm not sure if that works out of the SoI of a given planet, though.

Share this post


Link to post
Share on other sites

hey guys this is my first forrey into plugin development having been a part modder for many years but im wanting to look at pushing VRTK and the vive compatablity into ksp, anyone have any ideas o where to start to start rebuilding the UI for vr, a good start would be the ability to walk and teleport around the SPH 

Share this post


Link to post
Share on other sites

 Hello fellow potential helpers.

 I used to write tiny games in BASIC on Apple IIe in the 90's.  So, after a few decades hiatus I now have a Learning C# book and have several tabs open to docs.unity3d.com  I installed MS Visual C# 2010, added the KSP Unity references, and after a few days of googling debugging errors I have lines written that will build.  Feeling ok.

 But the code doesn't do what I expect.  Since I don't yet know how to display text on the screen I thought I'd test by bombarding the log just to see what would happen, but nada.  The KSP log shows nothing, but I think it should be adding a single digit floating point number every phyics step.  You folks see anything?

using UnityEngine;
public class spin : MonoBehaviour
{
    public Rigidbody rb;
    void start()
    {
        object rb = GetComponent<Rigidbody>();
    }
        void fixedupdate()
    {
        float rads = rb.angularVelocity.magnitude;
        Debug.Log(rads);
    }
}

 

Share this post


Link to post
Share on other sites
4 minutes ago, klond said:

I used to write tiny games in BASIC on Apple IIe in the 90's.  So, after a few decades hiatus I now have a Learning C# book and have several tabs open to docs.unity3d.com  I installed MS Visual C# 2010, added the KSP Unity references, and after a few days of googling debugging errors I have lines written that will build.  Feeling ok.

Cool, welcome back! I've found that C# has inverted my attitude towards compiler errors. Formerly I thought of it as a bad thing when I got a compiler error, but now if I write some new code and get a compiler error, I feel grateful that my latest error was caught by the compiler, whereas otherwise I feel regret that it will take actual testing to find. :)

4 minutes ago, klond said:

You folks see anything?

You need to tell it when to run your module with the KSPAddon attribute. Try tagging your MonoBehaviour class with this to load it at the KSC:

[KSPAddon(KSPAddon.Startup.SpaceCentre, false)]

Also, function names are case sensitive; use Start and FixedUpdate instead. And your GetComponent call will probably return null, because a freshly created MonoBehaviour won't have any components in it by default. Try AddComponent, or get a reference to an object that already has a Rigidbody.

1 person likes this

Share this post


Link to post
Share on other sites

Posted (edited)

36 minutes ago, klond said:

 


using UnityEngine;
public class spin : MonoBehaviour
{
    public Rigidbody rb;
    void start()
    {
        object rb = GetComponent<Rigidbody>();
    }
        void fixedupdate()
    {
        float rads = rb.angularVelocity.magnitude;
        Debug.Log(rads);
    }
}

 

using UnityEngine;
public class spin : MonoBehaviour
{
    public Rigidbody rb;
    void FixedUpdate()
    {
        float rads = rb.angularVelocity.magnitude;
        Debug.Log(rads);
    }
}

I believe this is what your wanting.

 

Send message to screen with:

ScreenMessages.PostScreenMessage(meassage, duration, ScreenMessageStyle style);

Edited by Next_Star_Industries
1 person likes this

Share this post


Link to post
Share on other sites

I may have asked this already, but…

How might I load a save? I see the class QuickSaveLoad, but it appears to lack a Load() method. Classes with Load() seem to use it in an entirely different context.

Share this post


Link to post
Share on other sites

Posted (edited)

On 30/06/2017 at 10:11 PM, Dozed12 said:

What's the best way to get the distance from the active vessel to a specific CelestialBody?

There is a built-in method for this : Vector3d.Distance (Vector3d a, Vector3d b). It will return the distance in meter (as a double).

KSP uses different referential, I think you need to use : FlightGlobals.ship_orbit.pos (for your ship) and body.orbit.pos (where body is a CelestialBody). Not 100% sure about those so test it :wink:

 

 

13 hours ago, amankd said:

hey guys this is my first forrey into plugin development having been a part modder for many years but im wanting to look at pushing VRTK and the vive compatablity into ksp, anyone have any ideas o where to start to start rebuilding the UI for vr, a good start would be the ability to walk and teleport around the SPH 

I love to see a VR mod for KSP, there were one for KSP 1.1.2 but the author had trouble getting it to work with newer version, check their github : https://github.com/Vivero/Kerbal-VR

Edited by Li0n
1 person likes this

Share this post


Link to post
Share on other sites
22 hours ago, 0111narwhalz said:

I may have asked this already, but…

How might I load a save? I see the class QuickSaveLoad, but it appears to lack a Load() method. Classes with Load() seem to use it in an entirely different context.

 

HighLogic.CurrentGame = GamePersistence.LoadGame()

HighLogic.CurrentGame.Start();

 

Two mods that use this to load a game on startup:

https://github.com/sirkut/DevHelper/blob/master/DevHelper/DevHelper.cs#L81-L110

https://github.com/malahx/QuickMods/blob/master/QuickStart/QS_MainMenu.cs#L81-L89

 

Links are provided for reference; straight out copying of the code requires respecting the license (All Rights Reserved for DevHelper and GPL3 for QuickStart).

The only difference between quicksaves and regular saves is that quicksaves return you to a particular ship, whereas regular saves return you to the main menu.  You can load a quicksave as a regular save; not sure about the reverse.

 

Share this post


Link to post
Share on other sites

Posted (edited)

Thanks.

Is there some issue with PartModule.vessel and/or PartModule.part.vessel? Use of it seems to yield only NREs.

If so, how should I go about acquiring a vessel reference?

Edited by 0111narwhalz

Share this post


Link to post
Share on other sites
On 7/8/2017 at 9:48 AM, 0111narwhalz said:

Thanks.

Is there some issue with PartModule.vessel and/or PartModule.part.vessel? Use of it seems to yield only NREs.

If so, how should I go about acquiring a vessel reference?

Those 2 are the basics of mods so if you get NRE something else is wrong. You should post a short version of your code.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now