Diazo Posted August 6, 2015 Share Posted August 6, 2015 It depends on if you are declaring a new object or not, but that's a basic C# question, not a KSP question.If you are asking questions of that level I would look at finding some C# tutorials online that would get you started. Modding KSP is all done in C#, just through the KSP API, so learning C# is learning to mod KSP.D. Quote Link to comment Share on other sites More sharing options...
blowfish Posted August 7, 2015 Share Posted August 7, 2015 Alright thanks a lot! MonoDevelop doesn't seem to complain but just to be sure should I define it as 'ModuleEngines x = part.FindMo...;'? I'm very new to this you see That's correct (if you're just looking for the first one - otherwise you would want a list). But as Diazo mentioned, C# tutorials might be a good place to start with this stuff. Quote Link to comment Share on other sites More sharing options...
*Aqua* Posted August 7, 2015 Share Posted August 7, 2015 During a collision I get the collider which I'm colliding with.For example:public void OnCollisionStay(Collision c){ if (isActive) { collidingObject = c.collider.gameObject; collisionPoint = c.contacts[0]; }}Now I want to find the part this collider belongs to.I came up with this method but it won't find the part:public Part GetPartByGameObject(GameObject gameObject){ Part foundPart = null; FlightGlobals.Vessels.ForEach(vessel => { foundPart = vessel.Parts.Find(part => { if (gameObject.Equals(part.gameObject)) return true; return false; }); }); return foundPart;}IMO this should work but it always returns null. What did I do wrong? Quote Link to comment Share on other sites More sharing options...
xEvilReeperx Posted August 7, 2015 Share Posted August 7, 2015 (edited) You're making the assumption that the collider is on the same GameObject as a Part, but that's never the case. Instead, Parts are made up of a hierarchy of GameObjects. The top-level one contains logic (ex: PartModules) and rigidbody, then another as a child called model, then beneath that as children are GameObjects with Renderers, Animations, Colliders--all the other things that make up a Part and come from cloned instances of models from GameDatabase.databaseModelJust look upwards in the hierarchy: private Part GetPartFromCollider(Collider c) { return c.gameObject.GetComponentInParent<Part>(); } Edited August 7, 2015 by xEvilReeperx Quote Link to comment Share on other sites More sharing options...
*Aqua* Posted August 7, 2015 Share Posted August 7, 2015 Thank you very much! I didn't know that the transform hierarchy works like that. Quote Link to comment Share on other sites More sharing options...
Albert VDS Posted August 8, 2015 Share Posted August 8, 2015 (edited) Does anyone know the event when a packed part is remove from the scene?At the moment I've got this: public void OnPartPack() { LeaveCamera (); }This works but it kicks in at about 500m(?). OnDestroy doesn't work.Edit: Fixed it. Just needed to add this to the OnDestroy();if (sCurrentCamera.vessel != FlightGlobals.ActiveVessel){RestoreMainCamera();}Edit2: Actually that didn't work, well it did but it didn't correctly restore the main camera.So to fix it I added this to update: if (sCurrentCamera != null) { // Is the current camera a hullcam if (sCurrentCamera.vessel != FlightGlobals.ActiveVessel) { // Is it not on the active vessel Vector3d activeVesselPos = FlightGlobals.ActiveVessel.orbit.getRelativePositionAtUT (Planetarium.GetUniversalTime ()) + FlightGlobals.ActiveVessel.orbit.referenceBody.position; // Calculate active vessel position Vector3d cameraVesselPos = sCurrentCamera.vessel.orbit.getRelativePositionAtUT (Planetarium.GetUniversalTime ()) + sCurrentCamera.vessel.orbit.referenceBody.position; // Calculate current camera position sCameraDistance = (activeVesselPos - cameraVesselPos).magnitude; // Calculate the distance between them if (sCameraDistance >= 2480) { // If distance between them is larger than 2480 then leave the current camera. LeaveCamera (); } } }It works perfectly, but maybe someone has an easier way of doing it? Edited August 8, 2015 by Albert VDS Quote Link to comment Share on other sites More sharing options...
ObiVanDamme Posted August 14, 2015 Share Posted August 14, 2015 Can someone please tell me how I can get a List of all parts, that have been researched (science mode) and that are purchased (career mode). Here is what I have now:foreach (var loadedPart in PartLoader.LoadedPartsList) { try { if (ResearchAndDevelopment.PartModelPurchased(loadedPart)) { items.Add(loadedPart); } } catch (Exception) { Debug.Log("[OSE] - Part " + loadedPart.name + " could not be added to available parts list"); } }I logged the length of the LoadedPartsList and the newly created list called items and they both have the same length no matter how far I am in the tech tree. Quote Link to comment Share on other sites More sharing options...
hab136 Posted August 15, 2015 Share Posted August 15, 2015 Can someone please tell me how I can get a List of all parts, that have been researched (science mode) and that are purchased (career mode). I was literally testing such a function just now private static bool partResearched(AvailablePart ap){ if (ResearchAndDevelopment.Instance == null) { print ("no ResearchAndDevelopment.Instance, must be sandbox mode"); return true; } if (!ResearchAndDevelopment.PartTechAvailable(ap)) { print (ap.name+".PartTechAvailable()==false"); return false; } if (!ResearchAndDevelopment.PartModelPurchased (ap)) { print (ap.name + ".PartModelPurchased()==false"); return false; } return true;}This works in sandbox, science, and career. In Sandbox, always returns true. In science, returns true if PartTechAvailable(), since PartModelPurchased() is always true in Science mode. In career, both PartModelPurchased() and PartTechAvailable() have to be true.HOWEVER!!! ResearchAndDevelopment.Instance doesn't exist on .Start() or .Awake(). I had to move all the part detection stuff to my onTrue (when someone clicks the GUI button). It's inefficient to re-check all the parts every time the GUI is shown, but it works. Quote Link to comment Share on other sites More sharing options...
ObiVanDamme Posted August 17, 2015 Share Posted August 17, 2015 (edited) I was literally testing such a function just now private static bool partResearched(AvailablePart ap){ if (ResearchAndDevelopment.Instance == null) { print ("no ResearchAndDevelopment.Instance, must be sandbox mode"); return true; } if (!ResearchAndDevelopment.PartTechAvailable(ap)) { print (ap.name+".PartTechAvailable()==false"); return false; } if (!ResearchAndDevelopment.PartModelPurchased (ap)) { print (ap.name + ".PartModelPurchased()==false"); return false; } return true;}This works in sandbox, science, and career. In Sandbox, always returns true. In science, returns true if PartTechAvailable(), since PartModelPurchased() is always true in Science mode. In career, both PartModelPurchased() and PartTechAvailable() have to be true.HOWEVER!!! ResearchAndDevelopment.Instance doesn't exist on .Start() or .Awake(). I had to move all the part detection stuff to my onTrue (when someone clicks the GUI button). It's inefficient to re-check all the parts every time the GUI is shown, but it works.Thank you very much, I will try that out. The code currently is in the onStart Method, so it needs to be moved, but I think it can go to the context menu action, that opens the GUI. This might even be better than OnStart, because the list will be loaded only when needed.Edit: I tried that out now and the problem really is, that you cannot run that detection in OnStart. I moved the detection to the GUI initialization and now it seems to work. You can reduce the code you posted to a one liner if you do not need the logging private bool PartResearched(AvailablePart p) { return ResearchAndDevelopment.PartTechAvailable(p) && ResearchAndDevelopment.PartModelPurchased(p); }I only tested this in Sandbox and Career mode without part unlock, but so far it does what it should do. Edited August 17, 2015 by ObiVanDamme Quote Link to comment Share on other sites More sharing options...
Ydoow Posted August 18, 2015 Share Posted August 18, 2015 I'm getting this error, and not sure what to do about it.As far as I can tell, it's making my plugin not work at all.Code is here, if it needs looking at: https://github.com/Ydoow/KSP_KonsoleNon platform assembly: /home/clark/Code/Mono/KSP_Konsole/KSP_Konsole/bin/Debug/KSP_Konsole.dll (this message is harmless)AssemblyLoader: Exception loading 'KSP_Konsole': System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded. at (wrapper managed-to-native) System.Reflection.Assembly:GetTypes (bool) at System.Reflection.Assembly.GetTypes () [0x00000] in <filename unknown>:0 at AssemblyLoader.LoadAssemblies () [0x00000] in <filename unknown>:0Additional information about this exception: System.TypeLoadException: Could not load type 'Kerbalish.Parser' from assembly 'KSP_Konsole, Version=1.0.5707.36052, Culture=neutral, PublicKeyToken=null'. System.TypeLoadException: Could not load type 'Kerbalish.Lexer' from assembly 'KSP_Konsole, Version=1.0.5707.36052, Culture=neutral, PublicKeyToken=null' Quote Link to comment Share on other sites More sharing options...
Diazo Posted August 18, 2015 Share Posted August 18, 2015 My first suspicion would be that you are not compiling against Net 3.5 which is what KSP runs on.Failing that, I'm not sure, at a quick glance everything looks correct code wise.If you are compiling against Net 3.5 already, I'll take a closer look but that is the first thing to check.D. Quote Link to comment Share on other sites More sharing options...
JPLRepo Posted August 18, 2015 Share Posted August 18, 2015 I'm getting this error, and not sure what to do about it.As far as I can tell, it's making my plugin not work at all.Code is here, if it needs looking at: https://github.com/Ydoow/KSP_KonsoleNon platform assembly: /home/clark/Code/Mono/KSP_Konsole/KSP_Konsole/bin/Debug/KSP_Konsole.dll (this message is harmless)AssemblyLoader: Exception loading 'KSP_Konsole': System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.at (wrapper managed-to-native) System.Reflection.Assembly:GetTypes (bool)at System.Reflection.Assembly.GetTypes () [0x00000] in <filename unknown>:0at AssemblyLoader.LoadAssemblies () [0x00000] in <filename unknown>:0Additional information about this exception:System.TypeLoadException: Could not load type 'Kerbalish.Parser' from assembly 'KSP_Konsole, Version=1.0.5707.36052, Culture=neutral, PublicKeyToken=null'.System.TypeLoadException: Could not load type 'Kerbalish.Lexer' from assembly 'KSP_Konsole, Version=1.0.5707.36052, Culture=neutral, PublicKeyToken=null'My first suspicion would be that you are not compiling against Net 3.5 which is what KSP runs on.Failing that, I'm not sure, at a quick glance everything looks correct code wise.If you are compiling against Net 3.5 already, I'll take a closer look but that is the first thing to check.D.As Diazo said. Your project file is compiling against .NET 4.5 Quote Link to comment Share on other sites More sharing options...
Ydoow Posted August 18, 2015 Share Posted August 18, 2015 Yeah that was the problem. I figured out how to check/switch the compiler and it's now compiling against 3.5, which solved it. Dunno how it was working before, but oh well.Thanks Quote Link to comment Share on other sites More sharing options...
Svm420 Posted August 19, 2015 Share Posted August 19, 2015 I am trying to modify some code I found. It is adding an EVA parachute MODULE to kerbals. Within the parachute MODULE, ModuleKrKerbalParachute, there is a float value called deployeddrag. I want to set this to a value when I add this MODULE to the KerbalEVA part I want to set the value to 10. I am not sure how to write the code to set the value when adding the MODULE. Thank you! namespace EVAParachutes {[KSPAddon(KSPAddon.Startup.MainMenu, true)]public class initKerbalEVA : UnityEngine.MonoBehaviour { public void Awake() { ConfigNode EVA = new ConfigNode("MODULE"); EVA.AddValue("name", "ModuleKrKerbalParachute"); try { PartLoader.getPartInfoByName("kerbalEVA").partPrefab.AddModule(EVA); } catch{} EVA = new ConfigNode("MODULE"); EVA.AddValue("name", "ModuleKrKerbalParachute"); try { PartLoader.getPartInfoByName("kerbalEVAfemale").partPrefab.AddModule(EVA); } catch{} }}} Quote Link to comment Share on other sites More sharing options...
blowfish Posted August 19, 2015 Share Posted August 19, 2015 Just add it to the ConfigNode the same way the name value is added:public const float evaChuteDeployedDrag = 10f;... EVA.AddValue("name", "ModuleKrKerbalParachute"); EVA.AddValue("deployedDrag", evaChuteDeployedDrag.ToString()); Quote Link to comment Share on other sites More sharing options...
royals Posted August 22, 2015 Share Posted August 22, 2015 Is it possible to read and write module info of the parent part? Like if I have a custom module on part A which is attached to part B, can I retrieve/edit the info of a module on part B from the module on part A? Quote Link to comment Share on other sites More sharing options...
Diazo Posted August 22, 2015 Share Posted August 22, 2015 royals: You certainly can, the only trick is getting the reference to the correct part.Inside a part module: this.vessel.Parts is a list of all parts on the vessel your partModule is attached to.There is also two other potential commands unfortunately I can't remember them exactly.Look for something like this.part.GetParentParts() which will return a list of parts between your current part and the root part, and this.partGetChildren() which will return a list of all parts that use this part to reach the root part.If you always want a part you are connected to, you could also look at the attachement nodes and see if there is some way to pull attached parts that way.Not a part of KSP I've dealt with much, but hopefully this at least points you in the right direction.D. Quote Link to comment Share on other sites More sharing options...
royals Posted August 22, 2015 Share Posted August 22, 2015 royals: You certainly can, the only trick is getting the reference to the correct part.Inside a part module: this.vessel.Parts is a list of all parts on the vessel your partModule is attached to.There is also two other potential commands unfortunately I can't remember them exactly.Look for something like this.part.GetParentParts() which will return a list of parts between your current part and the root part, and this.partGetChildren() which will return a list of all parts that use this part to reach the root part.If you always want a part you are connected to, you could also look at the attachement nodes and see if there is some way to pull attached parts that way.Not a part of KSP I've dealt with much, but hopefully this at least points you in the right direction.D.Alright thanks but I figured it out, used x = part.parent and then x.FindModuleImplementing<>();What I'm now curious about is how about editing custom modules? UnityEngine doesn't include my class Foobar, so if I want to reference something in another module which I've made myself, how does that work? For example with engines I can say 'ModuleEngines x = blah blah' but I can't say 'Foobar x = ...' since neither System nor UnityEngine has that class. Must I add a "using x;" or how would I go about that? Quote Link to comment Share on other sites More sharing options...
Diazo Posted August 22, 2015 Share Posted August 22, 2015 You will want to tag the values you want to edit with KSPField, they will then show in the partModule.Fields list and you can access them by name.int val1 = (int)otherPartModule.Fields["Value1"]; //gets value of an Int from another partModuleotherPartModule.Fields["Value2"] = 5f; //set's Value2 (of type float) in the other partModule to 5You can reference the other partModule as a PartModule type, you don't need to reference it as your custom type.D. Quote Link to comment Share on other sites More sharing options...
royals Posted August 22, 2015 Share Posted August 22, 2015 You will want to tag the values you want to edit with KSPField, they will then show in the partModule.Fields list and you can access them by name.int val1 = (int)otherPartModule.Fields["Value1"]; //gets value of an Int from another partModuleotherPartModule.Fields["Value2"] = 5f; //set's Value2 (of type float) in the other partModule to 5You can reference the other partModule as a PartModule type, you don't need to reference it as your custom type.D.Great thanks a bunch! Exactly what I need, much appreciated! But how do I see if my part actually has that module? I don't know how to use PartModuleList (part.Modules) but I assume it's that or something like it that I should use? Quote Link to comment Share on other sites More sharing options...
blowfish Posted August 22, 2015 Share Posted August 22, 2015 part.FindModulesImplementing<SomePartModuleClass>() or part.Modules["SomePartModuleClass"] will just return an empty list or null if the module does not exist. There might also be part.Modules.Contains("SomePartModuleClass") but I don't remember for sure. Quote Link to comment Share on other sites More sharing options...
Crzyrndm Posted August 22, 2015 Share Posted August 22, 2015 part.FindModulesImplementing<SomePartModuleClass>() or part.Modules["SomePartModuleClass"] will just return an empty list or null if the module does not exist. There might also be part.Modules.Contains("SomePartModuleClass") but I don't remember for sure.Contains exists, but has the limitation of being an exact match (Contains("ModuleEngines") won't find ModuleEnginesFX or other derivatives but FindModulesImplementing<ModuleEngines>() will) Quote Link to comment Share on other sites More sharing options...
blowfish Posted August 22, 2015 Share Posted August 22, 2015 Right. It's worth asking whether you want an exact match or any modules deriving from a particular class. Quote Link to comment Share on other sites More sharing options...
Diazo Posted August 22, 2015 Share Posted August 22, 2015 The catch being that you can only use FindModulesImplementing on classes you know are loaded, so stock classes and the ones in your mod.That is sufficient most of the time, just be aware you have to use .Contains for referencing another mod.D. Quote Link to comment Share on other sites More sharing options...
mrsolarsail Posted August 25, 2015 Share Posted August 25, 2015 Has anyone developed mods to with deployable trusses or tethers? I see that Infernal Robotics allows you to link parts of a spacecraft together with rotating parts. I'm looking for something with connecting parts that expand. 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.