0111narwhalz Posted November 19, 2018 Share Posted November 19, 2018 8 hours ago, Hydrawx said: Hi, I'm trying to control my rover. I'm able to make it drive straight forward by modifying the wheelThrottleTrim and pitchTrim fields from Vessel.ctrlState. However, I couldn't get the rover to steer by modifying the wheelSteerTrim and yawTrim fields. void Update() { FlightCtrlState vesselCtrl = FlightGlobals.ActiveVessel.ctrlState; vesselCtrl.wheelThrottleTrim = this.Drive; vesselCtrl.pitchTrim = this.Drive; vesselCtrl.wheelSteerTrim = -1f*this.Steer; vesselCtrl.yawTrim = this.Steer; } The Steer property is modified by some button listeners, and gets the value -1f if steering left and 1f if steering right. The sign of wheelSteerTrim field is inverted, because the steer direction of my wheels are also set to inverted (this is the way it would be if I gave user input and observed the ctrlState object through a debugger). Also, here's a picture of a the rover I'm using to test my mod: [snip] So the problem is: I can't steer the wheels through an instance of the FlightCtrlState class. Am I missing something here? I think your problem might be that you've made a copy of ctrlState. I have code which modifies the ctrlState directly, without copying it to a new variable, which behaves itself. Quote Link to comment Share on other sites More sharing options...
Hydrawx Posted November 19, 2018 Share Posted November 19, 2018 (edited) 8 hours ago, 0111narwhalz said: I think your problem might be that you've made a copy of ctrlState. I have code which modifies the ctrlState directly, without copying it to a new variable, which behaves itself. Thank you for your answer! I thought C# only implicitly copied the reference to that object. Also the wheelThrottleTrim and pitchTrim do behave like expected, but if accessing the ctrlState directly through the vessel works for you, then I will try this as well later on. Edit: tried it, still doesn't work. As I thought, it's not the reference to the object that is the problem here, because I can observe it through a debugger and I can clearly see that the right object is modified. However, there is still something you're doing right which I am not. Does your code also handle the steering of the wheels? If so, could you show me the part of your code where you control the wheels? It would be greatly appreciated. Edit 2: Somehow wheelSteerTrim doesn't get registered and wheelThrottleTrim does: I made sure to use wheels that are steerable and I also checked if the steering was enabled for those wheels. Edited November 19, 2018 by Hydrawx Quote Link to comment Share on other sites More sharing options...
0111narwhalz Posted November 19, 2018 Share Posted November 19, 2018 9 hours ago, Hydrawx said: Does your code also handle the steering of the wheels? If so, could you show me the part of your code where you control the wheels? It would be greatly appreciated. It should be noted at this point that my code is a few KSP versions old by now, but this bit probably shouldn't have changed. public void Update(Vessel ves, NeuralNetwork nn) { ves.ctrlState.wheelSteer = nn.nodeValues[nn.nodeValues.Length - 1][0]; ves.ctrlState.wheelThrottle = nn.nodeValues[nn.nodeValues.Length - 1][1]; } The nn stuff just ends up being a float between -1 and 1. Quote Link to comment Share on other sites More sharing options...
Hydrawx Posted November 19, 2018 Share Posted November 19, 2018 Thanks, I appreciate it. Still no luck though.. odd.. Quote Link to comment Share on other sites More sharing options...
sarbian Posted November 20, 2018 Share Posted November 20, 2018 21 hours ago, Hydrawx said: Thanks, I appreciate it. Still no luck though.. odd.. You need to use the callbacks to control the vessel or you will fight with the stock code (and other mods). Somewhere in your OnStart public override void OnStart(PartModule.StartState state) { if (vessel != null) { vessel.OnFlyByWire += MyControlMethod; // or OnPreAutopilotUpdate / OnAutopilotUpdate / OnPostAutopilotUpdate depending on how soon/late you want to do it in the controls orders } } Make sure you have a OnDestroy void OnDestroy() { if (vessel != null) { vessel.OnFlyByWire -= MyControlMethod; } } And somewhere else private void MyControlMethod(FlightCtrlState s) { s.wheelSteer = 0.5 } Quote Link to comment Share on other sites More sharing options...
Hydrawx Posted November 20, 2018 Share Posted November 20, 2018 (edited) 12 minutes ago, sarbian said: You need to use the callbacks to control the vessel or you will fight with the stock code (and other mods). Excellent! That's exactly what I needed! Thank you! Edited November 20, 2018 by Hydrawx Quote Link to comment Share on other sites More sharing options...
NermNermNerm Posted December 23, 2018 Share Posted December 23, 2018 I'm new to KSP modding, and am trying to figure out what is the best way for one component to talk to another. Mainly I've been following the example from @RoverDude's mods, which look to be the most polished of the code I've seen (and as a result, easiest to follow). But even within his mods there's variance. Maybe there's a rhythm to it? Maybe it's just some is older/comes from different sources? Anyway, one method is this: public class LifeSupportScenario : ScenarioModule { public LifeSupportScenario() { Instance = this; } public static LifeSupportScenario Instance { get; private set; } And the other is public class LifeSupportManager : MonoBehaviour { // Static singleton instance private static LifeSupportManager instance; // Static singleton property public static LifeSupportManager Instance { get { return instance ?? (instance = new GameObject("LifeSupportManager").AddComponent<LifeSupportManager>()); } } (And if anybody cares, that implementation could be made a little nicer with .net's 'Lazy' class). Unity does a lot of reflecto-magic with classes, and I, at one point, thought that the static instance object got some of this love. I'm not finding any clear evidence of it in the Unity docs, but that could be because my search-fu on Unity stuff is not all it could be. Quote Link to comment Share on other sites More sharing options...
severedsolo Posted December 27, 2018 Share Posted December 27, 2018 On 12/23/2018 at 10:33 PM, NermNermNerm said: I'm new to KSP modding, and am trying to figure out what is the best way for one component to talk to another I don't know if this is the BEST way to do it, but this is the way I do it, because it's simple when writing the code. I make a static instance of the class I want to access, and assign it in Awake() (assuming the class I want to talk to is a MonoBehaviour) then from my ScenarioModule I can then reference it by <MyClass.Instance>. Example of this below, look at FlightTracker and Stripes Data https://github.com/severedsolo/EarnYourStripes/tree/master/EarnYourStripes Quote Link to comment Share on other sites More sharing options...
sarbian Posted December 28, 2018 Share Posted December 28, 2018 On 12/23/2018 at 11:33 PM, NermNermNerm said: public static LifeSupportManager Instance { get { return instance ?? (instance = new GameObject("LifeSupportManager").AddComponent<LifeSupportManager>()); } } KSP includes the KSPAddon annotation to do that and it provides far better control over the object life than this. Quote Link to comment Share on other sites More sharing options...
NermNermNerm Posted December 29, 2018 Share Posted December 29, 2018 5 hours ago, sarbian said: KSP includes the KSPAddon annotation to do that and it provides far better control over the object life than this. I'm not sure I understand what you mean here - [KSPAddOn]class foo does indeed control the lifetime of 'foo' - but what I'm asking for is how, if I'm in 'bar', can I get the correct instance of 'foo'. Quote Link to comment Share on other sites More sharing options...
DMagic Posted December 30, 2018 Share Posted December 30, 2018 (edited) 22 hours ago, NermNermNerm said: I'm not sure I understand what you mean here - [KSPAddOn]class foo does indeed control the lifetime of 'foo' - but what I'm asking for is how, if I'm in 'bar', can I get the correct instance of 'foo'. Use the method described by severedsolo, set the instance field in the Awake method (and remove it in OnDestroy, if needed). Then access it by using public property that only returns the instance. Sarbian was saying not to use AddComponent in the instance property as a method of creating the MonoBehaviour. Edited December 30, 2018 by DMagic Quote Link to comment Share on other sites More sharing options...
c4ooo Posted December 31, 2018 Share Posted December 31, 2018 Is there a good way to detect a "Revert to launch"? Neither the ActiveVessel.id nor the SceneManager.GetActiveScene().buildIndex seem to change. Quote Link to comment Share on other sites More sharing options...
NermNermNerm Posted January 3, 2019 Share Posted January 3, 2019 On 12/31/2018 at 1:01 PM, c4ooo said: Is there a good way to detect a "Revert to launch"? Neither the ActiveVessel.id nor the SceneManager.GetActiveScene().buildIndex seem to change. This probably isn't "the" way, but it's "a" way: you could look for a shift backwards in system time - Planetarium.GetUniversalTime() -- I suspect that might also pick up on loading quicksaves, however... But maybe that's a good thing for your scenario. Quote Link to comment Share on other sites More sharing options...
NermNermNerm Posted January 3, 2019 Share Posted January 3, 2019 I'm starting to get the hang of these PartModules - is there a stock part module that handles the notion that it takes a power-load to do its thing, and that the thing can be toggled on and off? I could go with a Resource Converter, with just "Electric Charge" as an input and no outputs. That seems like a good way to go, but it seems like this is probably a common need and there's something else out there like it. Quote Link to comment Share on other sites More sharing options...
Booots Posted January 3, 2019 Share Posted January 3, 2019 On 12/31/2018 at 4:01 PM, c4ooo said: Is there a good way to detect a "Revert to launch"? Neither the ActiveVessel.id nor the SceneManager.GetActiveScene().buildIndex seem to change. There’s a series of GameEvents that get fired when the scene loads. Maybe there’s a unique sequence or attached data for a revert? https://kerbalspaceprogram.com/api/class_game_events.htm Quote Link to comment Share on other sites More sharing options...
NermNermNerm Posted January 4, 2019 Share Posted January 4, 2019 I know that ScreenMessages.PostScreenMessage is a thing - but I'd like something fancier, like the tutorial messages - where it's a full-on dialog with a picture of Wernher Von Kerman in the corner. Anybody know how to do that? Quote Link to comment Share on other sites More sharing options...
c4ooo Posted January 5, 2019 Share Posted January 5, 2019 On 1/2/2019 at 11:21 PM, NermNermNerm said: This probably isn't "the" way, but it's "a" way: you could look for a shift backwards in system time - Planetarium.GetUniversalTime() -- I suspect that might also pick up on loading quicksaves, however... But maybe that's a good thing for your scenario. Ha well- simple solution but it works; thanks! Quote Link to comment Share on other sites More sharing options...
nightingale Posted January 6, 2019 Share Posted January 6, 2019 On 1/4/2019 at 12:18 PM, NermNermNerm said: I know that ScreenMessages.PostScreenMessage is a thing - but I'd like something fancier, like the tutorial messages - where it's a full-on dialog with a picture of Wernher Von Kerman in the corner. Anybody know how to do that? The short version is that you have to use the TutorialScenario (there are some very old examples if you search github). An alternative is to build your own dialog boxes using KerbalInstructor (that's what provides the picture). This is what Contract Configurator does, although it uses the old GUI system and is... overly complex. Quote Link to comment Share on other sites More sharing options...
Firex Posted January 8, 2019 Share Posted January 8, 2019 Hi all, apologies if this has been asked before, but is there some documentation/reference for KSP UI transforms? I want to make edits to certain panels but I feel like I'm fumbling around in the dark trying to guess what I need to be modifying. A couple of examples of what I want to learn more about can be found in Strategia and MKS. They both do it slightly differently though: MKS has the exact path to hand apparently, whereas Strategia searches for a transform with the right name. Any resources or help on this would be appreciated. Quote Link to comment Share on other sites More sharing options...
DMagic Posted January 8, 2019 Share Posted January 8, 2019 13 minutes ago, Firex said: Hi all, apologies if this has been asked before, but is there some documentation/reference for KSP UI transforms? I want to make edits to certain panels but I feel like I'm fumbling around in the dark trying to guess what I need to be modifying. A couple of examples of what I want to learn more about can be found in Strategia and MKS. They both do it slightly differently though: MKS has the exact path to hand apparently, whereas Strategia searches for a transform with the right name. Any resources or help on this would be appreciated. Accessing specific UI prefabs, or any other type of prefab, is different for each one. There isn't really one database of prefabs. There are references to them held in various different types of controller MonoBehaviours, but the real trouble is finding exactly where they are stored, and how to access those controllers. If all else fails when trying to get at a controller object you can use something like FindObjectOfType<ControllerType> to find any active instance of that type. You can see MKS is using FindObjectOfType, whereas the prefab Strategia is looking for has a more accessible prefab. In both cases the real problem is finding where that prefab is stored. Sometimes it can be obvious by the name, like the Tracking Station Widget prefab (the thing that shows each vessel in the list) is held in SpaceTracking. Or the staging group icon prefab is held in StageManager. You can use Debug Stuff in UI mode in some cases to help with this. A lot of the time the UI components are ultimately the child of whatever component is managing them, so that can help narrow it down. Quote Link to comment Share on other sites More sharing options...
Firex Posted January 9, 2019 Share Posted January 9, 2019 3 hours ago, DMagic said: Accessing specific UI prefabs, or any other type of prefab, is different for each one. There isn't really one database of prefabs. There are references to them held in various different types of controller MonoBehaviours, but the real trouble is finding exactly where they are stored, and how to access those controllers. If all else fails when trying to get at a controller object you can use something like FindObjectOfType<ControllerType> to find any active instance of that type. You can see MKS is using FindObjectOfType, whereas the prefab Strategia is looking for has a more accessible prefab. In both cases the real problem is finding where that prefab is stored. Sometimes it can be obvious by the name, like the Tracking Station Widget prefab (the thing that shows each vessel in the list) is held in SpaceTracking. Or the staging group icon prefab is held in StageManager. You can use Debug Stuff in UI mode in some cases to help with this. A lot of the time the UI components are ultimately the child of whatever component is managing them, so that can help narrow it down. Thanks for showing me this DebugStuff, it's helping a lot. I am still kind of stuck though, as sometimes DebugStuff will show an object with "(Clone)" after it's name and I'm unable to access these like other things. I thought this might be just the case in certain areas of the UI (with there being a "root" object somewhere), but even using FindObjectType doesn't work. I'm specifically trying to modify the currency widgets in the topbar of the SpaceCenter scene, and have so far successfully been able to remove the widget group as a whole, but I can't target each individual widget. Quote Link to comment Share on other sites More sharing options...
DMagic Posted January 9, 2019 Share Posted January 9, 2019 12 hours ago, Firex said: Thanks for showing me this DebugStuff, it's helping a lot. I am still kind of stuck though, as sometimes DebugStuff will show an object with "(Clone)" after it's name and I'm unable to access these like other things. I thought this might be just the case in certain areas of the UI (with there being a "root" object somewhere), but even using FindObjectType doesn't work. I'm specifically trying to modify the currency widgets in the topbar of the SpaceCenter scene, and have so far successfully been able to remove the widget group as a whole, but I can't target each individual widget. The "(Clone)" in the name just means that the game object was instantiated as a copy of another object, usually the prefab. This would affect trying to find objects by name, but not by component type, it's just a name that can be changed to basically anything. If you can access the parent object, then you can get to the child objects, one way or another. This could be by accessing the components through GetComponentsInChildren<Type>, or by going through the GameObject's transform, using transform.GetChild(index). For UI objects you would have to cast the Transform (which all Unity GameObjects have) to a RectTransform, which has more controls about the object's position in the UI. Quote Link to comment Share on other sites More sharing options...
Firex Posted January 9, 2019 Share Posted January 9, 2019 1 hour ago, DMagic said: The "(Clone)" in the name just means that the game object was instantiated as a copy of another object, usually the prefab. This would affect trying to find objects by name, but not by component type, it's just a name that can be changed to basically anything. If you can access the parent object, then you can get to the child objects, one way or another. This could be by accessing the components through GetComponentsInChildren<Type>, or by going through the GameObject's transform, using transform.GetChild(index). For UI objects you would have to cast the Transform (which all Unity GameObjects have) to a RectTransform, which has more controls about the object's position in the UI. Thanks so much for your help! Combined with this, I'm actually starting to get somewhere! Quote Link to comment Share on other sites More sharing options...
NermNermNerm Posted January 13, 2019 Share Posted January 13, 2019 On 1/6/2019 at 9:20 AM, nightingale said: The short version is that you have to use the TutorialScenario (there are some very old examples if you search github). An alternative is to build your own dialog boxes using KerbalInstructor (that's what provides the picture). This is what Contract Configurator does, although it uses the old GUI system and is... overly complex. Took me a while, but I managed to figure out how to use the KerbalInstructor technique in the new dialog framework: https://github.com/SteveBenz/ColonizationByNerm/blob/master/src/PopupMessageWithKerbal.cs That's a class that will display a quick modal dialog with a message in it. Quote Link to comment Share on other sites More sharing options...
DeltaDizzy Posted January 14, 2019 Share Posted January 14, 2019 Does anyone know of a way to get an ExperienceTrait from the name of a trait? 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.