sarbian Posted June 19, 2017 Share Posted June 19, 2017 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; Quote Link to comment Share on other sites More sharing options...
Bonus Eventus Posted June 19, 2017 Share Posted June 19, 2017 (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 June 21, 2017 by Bonus Eventus Quote Link to comment Share on other sites More sharing options...
Dozed12 Posted June 30, 2017 Share Posted June 30, 2017 (edited) What's the best way to get the distance from the active vessel to a specific CelestialBody? Edited June 30, 2017 by Dozed12 Quote Link to comment Share on other sites More sharing options...
gomker Posted July 3, 2017 Share Posted July 3, 2017 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. Quote Link to comment Share on other sites More sharing options...
Benjamin Kerman Posted July 4, 2017 Share Posted July 4, 2017 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. Quote Link to comment Share on other sites More sharing options...
0111narwhalz Posted July 4, 2017 Share Posted July 4, 2017 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. Quote Link to comment Share on other sites More sharing options...
amankd Posted July 6, 2017 Share Posted July 6, 2017 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 Quote Link to comment Share on other sites More sharing options...
klond Posted July 7, 2017 Share Posted July 7, 2017 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); } } Quote Link to comment Share on other sites More sharing options...
HebaruSan Posted July 7, 2017 Share Posted July 7, 2017 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. Quote Link to comment Share on other sites More sharing options...
Next_Star_Industries Posted July 7, 2017 Share Posted July 7, 2017 (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 July 7, 2017 by Next_Star_Industries Quote Link to comment Share on other sites More sharing options...
0111narwhalz Posted July 7, 2017 Share Posted July 7, 2017 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. Quote Link to comment Share on other sites More sharing options...
Li0n Posted July 7, 2017 Share Posted July 7, 2017 (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 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 July 7, 2017 by Li0n Quote Link to comment Share on other sites More sharing options...
hab136 Posted July 8, 2017 Share Posted July 8, 2017 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. Quote Link to comment Share on other sites More sharing options...
0111narwhalz Posted July 8, 2017 Share Posted July 8, 2017 (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 July 8, 2017 by 0111narwhalz Quote Link to comment Share on other sites More sharing options...
sarbian Posted July 9, 2017 Share Posted July 9, 2017 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. Quote Link to comment Share on other sites More sharing options...
Kobymaru Posted July 25, 2017 Share Posted July 25, 2017 Hi, how do I retrieve the physical time step length (in in-game time)? I know that there's a setting for "max physics delta-time per frame" and that there's Planetarium.fixedDeltaTime, but those seem to be fixed settings, whereas the physics update time depends on system performance. I calculated my own value from the difference between Planetarium.GetUniversalTime() values in every FixedUpdate(), but I'm not sure that this is correct (or is it?) Also, this value needs to stay accurate for Physics-timewarp, where the time step gets bigger if I'm not mistaken. Quote Link to comment Share on other sites More sharing options...
sarbian Posted July 25, 2017 Share Posted July 25, 2017 2 hours ago, Kobymaru said: Hi, how do I retrieve the physical time step length (in in-game time)? I know that there's a setting for "max physics delta-time per frame" and that there's Planetarium.fixedDeltaTime, but those seem to be fixed settings, whereas the physics update time depends on system performance The KSP way is TimeWarp.fixedDeltaTime (and some other in TimeWarp). You can also check Unity native method since KSP use them outside of high time warp : Time Quote Link to comment Share on other sites More sharing options...
severedsolo Posted July 25, 2017 Share Posted July 25, 2017 (edited) I feel like I am doing something stupid, so I will post here rather than make an entire thread. This method is basically supposed to just create a list of KSPFields and KSPEvents attached to a part, sort them by name, and then cache it for later: private void Start() { List<BaseField> myFieldList = new List<BaseField>(); List<BaseEvent> myEventList = new List<BaseEvent>(); foreach (BaseEvent e in part.Events) { myEventList.Add(e); } foreach (BaseField bf in part.Fields) { myFieldList.Add(bf); } if (part.Modules.Count > 0) { foreach (PartModule pm in part.Modules) { if (pm.Fields.Count > 0) { foreach (BaseField bf in pm.Fields) { myFieldList.Add(bf); } } if (pm.Events.Count() > 0) { foreach (BaseEvent e in pm.Events) { myEventList.Add(e); } } } sortedFields = myFieldList.OrderBy(baseField => baseField.guiName).ToList(); sortedEvents = myEventList.OrderBy(baseEvent => baseEvent.guiName).ToList(); } } It works great, until I get to this bit: if (pm.Events.Count() > 0) { foreach (BaseEvent e in pm.Events) { myEventList.Add(e); } } For some reason, the act of adding a BaseEvent from a Part Module to a List causes KSP to duplicate all the buttons in the PAW. I can put anything else in the foreach loop, and the buttons are fine, but the moment I try and add them to a list, everything gets duplicated. I've commented out each line of code one by one, and thats the only line that causes the issue. I can also interact with the Fields in exactly the same way, with no duplication. It doesn't make any sense to me, I am not interacting with the Events in any way, except examining the list. So, my questions then: Am I missing something obvious, and if not, can I get around this somehow? I've already tried: - Turning the List<BaseEvent> into a BaseEventList - Using AddRange to try to bypass examining the individual events - Adding the PartModules and Events to a separate list, and examining that so I'm not interacting directly with PartModule.Events. Edited July 25, 2017 by severedsolo Quote Link to comment Share on other sites More sharing options...
linuxgurugamer Posted July 25, 2017 Share Posted July 25, 2017 5 minutes ago, severedsolo said: PAW Ok, I'm dense. What is this? Quote Link to comment Share on other sites More sharing options...
severedsolo Posted July 25, 2017 Share Posted July 25, 2017 1 minute ago, linuxgurugamer said: Ok, I'm dense. What is this? Part Action Window - the right click menu on a part. Quote Link to comment Share on other sites More sharing options...
linuxgurugamer Posted July 25, 2017 Share Posted July 25, 2017 It is very strange. I wonder if the Add is somehow calling the init/start of the event, so it gets added to the PAW (see, i can learn :-) ) Have you tried removing the extra button from the PAW? Quote Link to comment Share on other sites More sharing options...
DMagic Posted July 25, 2017 Share Posted July 25, 2017 KSP uses reflection to grab all of the events, so maybe it's catching your cached event list somehow. See what happens if you move the process out of start and instead wait a few frames or seconds. Maybe the base part's event loading process occurs after the part module process. Quote Link to comment Share on other sites More sharing options...
linuxgurugamer Posted July 25, 2017 Share Posted July 25, 2017 2 minutes ago, DMagic said: KSP uses reflection to grab all of the events, so maybe it's catching your cached event list somehow. See what happens if you move the process out of start and instead wait a few frames or seconds. Maybe the base part's event loading process occurs after the part module process. I would suggest waiting at least 20 tics (ie: 1/3 sec) if you do, I've had issues with delayed actions and found that in some cases, it took this long before things got settled down Quote Link to comment Share on other sites More sharing options...
severedsolo Posted July 25, 2017 Share Posted July 25, 2017 (edited) 17 minutes ago, linuxgurugamer said: Have you tried removing the extra button from the PAW? I have (I assume you mean by changing guiActive to false, unless there is another way to do this) - this just removes both buttons, so they seem to be linked to the same Event. 16 minutes ago, DMagic said: KSP uses reflection to grab all of the events, so maybe it's catching your cached event list somehow. See what happens if you move the process out of start and instead wait a few frames or seconds. Maybe the base part's event loading process occurs after the part module process. I did originally move it to FixedUpdate but that was probably not waiting long enough. I actually just figured out a solution (as you always do just after you post for help!) foreach (BaseEvent e in pm.Events) { int id = e.id; myEventList.Add(pm.Events[id]); } Adding the Event by ID seems to bypass whatever the issue is. Probably what @DMagic said though, as my list would be referencing the original event, which would explain why both buttons disappear when removed. Edited July 25, 2017 by severedsolo Quote Link to comment Share on other sites More sharing options...
TaxiService Posted July 29, 2017 Share Posted July 29, 2017 (edited) Hi, I am trying to find out if KSP has a GameEvent or some kind of notification on part deployment (can be antenna, solar panel, landing gear etc) and ActionGroup (eg toggle antenna extend/retract). The closest one I can find is `GameEvents.onPartActionUIDismiss` which is almost suitable for me. But I am not finding an easy way to hook to ActionGroup activation. The reason for this is to run some update codes on demand, rather than FixedUpdate() pulse to check and run if change is detected. Thanks! Edited July 29, 2017 by TaxiService Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.