sarbian Posted August 19, 2016 Share Posted August 19, 2016 8 minutes ago, Malah said: Hello, Is there a way to keep a coroutine active when the game is paused (with something like FlightDriver.setPause(True,True) or in the RnD building) ? Yep, use WaitForSecondsRealtime Quote Link to comment Share on other sites More sharing options...
Malah Posted August 19, 2016 Share Posted August 19, 2016 (edited) 18 minutes ago, sarbian said: Yep, use WaitForSecondsRealtime As easy as this, thanks Edit1: I know why I haven't found it ... it seems to be in Unity 5.4 ... I need to wait KSP 1.2 Edit2: After some research, I will use this in KSP 1.1: IEnumerator test() { int i = 0; while (true) { Debug.Log ("wait ... " + i); i++; float pauseEndTime = Time.realtimeSinceStartup + 1; while (Time.realtimeSinceStartup < pauseEndTime) { yield return 0; } } } Edited August 19, 2016 by Malah Quote Link to comment Share on other sites More sharing options...
nightingale Posted August 19, 2016 Share Posted August 19, 2016 (edited) 19 minutes ago, Malah said: As easy as this, thanks Edit1: I know why I haven't found it ... it seems to be in Unity 5.4 ... I need to wait KSP 1.2 Edit2: After some research, I will use: IEnumerator test() { int i = 0; while (true) { Debug.Log ("wait ... " + i); i++; float pauseEndTime = Time.realtimeSinceStartup + 1; while (Time.realtimeSinceStartup < pauseEndTime) { yield return 0; } } } Or you can use WaitForSeconds (which exists in 5.2) and multiply by Time.timeScale. Edited August 19, 2016 by nightingale Quote Link to comment Share on other sites More sharing options...
sarbian Posted August 19, 2016 Share Posted August 19, 2016 The scale is 0 when in pause Quote Link to comment Share on other sites More sharing options...
nightingale Posted August 19, 2016 Share Posted August 19, 2016 2 hours ago, sarbian said: The scale is 0 when in pause Yup, that would make sense. Quote Link to comment Share on other sites More sharing options...
Galileo Posted August 21, 2016 Share Posted August 21, 2016 Ok I didn't want to post in here as the thread name states "help a fellow plugin developer" which I am definitely not. I just really want to know if a plugin is possible for what I have in mind. I am more than willing to do the work and learn, I just need to be pointed in the right direction. I have never made a plugin for ksp but I have a love for coding and programing just not in c# or unity so this is going to be a test run for me. I love to learn so any help and guidance will be greatly appreciated. If you think this wouldn't be worth my time that's cool too. ill definitely be here with an open ear. HERE is my proposal. i haven't fully fleshed out the details but I think it has potential. check it out! Quote Link to comment Share on other sites More sharing options...
hab136 Posted August 24, 2016 Share Posted August 24, 2016 On 8/21/2016 at 6:44 AM, Galileo said: Ok I didn't want to post in here as the thread name states "help a fellow plugin developer" which I am definitely not. I just really want to know if a plugin is possible for what I have in mind. I am more than willing to do the work and learn, I just need to be pointed in the right direction. I have never made a plugin for ksp but I have a love for coding and programing just not in c# or unity so this is going to be a test run for me. I love to learn so any help and guidance will be greatly appreciated. If you think this wouldn't be worth my time that's cool too. ill definitely be here with an open ear. HERE is my proposal. i haven't fully fleshed out the details but I think it has potential. check it out! Yes, it's possible. See Multi-tasking Kerbals for a small intro to the trait system (reproduced below since the download link is broken) and making Kerbals do different things. Also check out Roster Manager which seems to do many of the same things you want to accomplish. While you can modify the three classes (Pilot, Scientist, Engineer) to have different attributes, I have no idea if you can add additional classes. EXPERIENCE_TRAIT { name = Pilot title = Astronaut desc = One Kerbal for One Job! EFFECT { name = AutopilotSkill } EFFECT { name = RepairSkill } EFFECT { name = VesselScienceReturn modifiers = 1.05, 1.1, 1.15, 1.2, 1.25 } EFFECT { name = PartScienceReturn modifiers = 1.05, 1.1, 1.15, 1.2, 1.25 } EFFECT { name = ScienceSkill } } EXPERIENCE_TRAIT { name = Engineer title = Astronaut desc = One Kerbal for One Job! EFFECT { name = AutopilotSkill } EFFECT { name = RepairSkill } EFFECT { name = VesselScienceReturn modifiers = 1.05, 1.1, 1.15, 1.2, 1.25 } EFFECT { name = PartScienceReturn modifiers = 1.05, 1.1, 1.15, 1.2, 1.25 } EFFECT { name = ScienceSkill } } EXPERIENCE_TRAIT { name = Scientist title = Astronaut desc = One Kerbal for One Job! EFFECT { name = AutopilotSkill } EFFECT { name = RepairSkill } EFFECT { name = VesselScienceReturn modifiers = 1.05, 1.1, 1.15, 1.2, 1.25 } EFFECT { name = PartScienceReturn modifiers = 1.05, 1.1, 1.15, 1.2, 1.25 } EFFECT { name = ScienceSkill } } Quote Link to comment Share on other sites More sharing options...
0111narwhalz Posted August 29, 2016 Share Posted August 29, 2016 I'd like clarification on a couple of things. First: Could someone direct me to a flowchart of how the Unity process goes? I get that there's something to do with Start(), Update(), et cetera, but I don't know exactly when all these methods are called. Second: How does one trigger action groups? E.g. toggling the Gear action group, or trigger the Stage one. Third: How do I use coroutines? Quote Link to comment Share on other sites More sharing options...
blowfish Posted August 29, 2016 Share Posted August 29, 2016 28 minutes ago, 0111narwhalz said: I'd like clarification on a couple of things. First: Could someone direct me to a flowchart of how the Unity process goes? I get that there's something to do with Start(), Update(), et cetera, but I don't know exactly when all these methods are called. Second: How does one trigger action groups? E.g. toggling the Gear action group, or trigger the Stage one. Third: How do I use coroutines? This topic may shed some light. It's specific to PartModules but a lot of the same stuff applies to other MonoBehaviours Something like FlightGlobals.ActiveVessel.ActionGroups.ToggleGroup(KSPActionGroup.Gear); If you're interested in a specific vessel rather than just the active vessel then you can substitute something there Have you read the Unity documentation on them? (if yes, then you'll know that it's a bit confusing but I just want to know how much you already know before I try to start explaining things) Quote Link to comment Share on other sites More sharing options...
ShotgunNinja Posted August 29, 2016 Share Posted August 29, 2016 I was wondering if somebody know how to extend the maximum zoom allowed in tracking view and map mode. Quote Link to comment Share on other sites More sharing options...
0111narwhalz Posted August 29, 2016 Share Posted August 29, 2016 57 minutes ago, blowfish said: Have you read the Unity documentation on them? (if yes, then you'll know that it's a bit confusing but I just want to know how much you already know before I try to start explaining things) Many thanks. I read it, but it's still a little unclear. I'm trying to make a sort of autopilot, so I need it to wait a physics frame between loops (because it makes no sense to change control inputs any more frequently than that). So should I make OnUpdate() call into the coroutine, and then yield at the end of each loop? And then when I call it again, it starts at the line after yield return null;, right? As for the lifecycle, this is my understanding: Load() -> OnStart() -> Start() -> OnFixedUpdate() -> FixedUpdate() ^_________________/ Is this representative of reality? Quote Link to comment Share on other sites More sharing options...
blowfish Posted August 29, 2016 Share Posted August 29, 2016 32 minutes ago, 0111narwhalz said: Many thanks. I read it, but it's still a little unclear. I'm trying to make a sort of autopilot, so I need it to wait a physics frame between loops (because it makes no sense to change control inputs any more frequently than that). So should I make OnUpdate() call into the coroutine, and then yield at the end of each loop? And then when I call it again, it starts at the line after yield return null;, right? That's generally correct. yield return null will defer the rest of the coroutine to the next frame. I think this might not be quite what you want however. If you start the coroutine every frame, then it will run the whole coroutine, just part of it will be a frame after it was started. 47 minutes ago, 0111narwhalz said: Load() -> OnStart() -> Start() -> OnFixedUpdate() -> FixedUpdate() ^_________________/ Is this representative of reality? That looks correct for those methods (there are other update methods that are run on a different schedule). Quote Link to comment Share on other sites More sharing options...
RocketSquid Posted August 29, 2016 Share Posted August 29, 2016 How do I set up node_stack_top, node_stack_bottom, and node_attach? Quote Link to comment Share on other sites More sharing options...
blowfish Posted August 29, 2016 Share Posted August 29, 2016 2 hours ago, RocketSquid said: How do I set up node_stack_top, node_stack_bottom, and node_attach? I think this is the wrong thread for this, part configs aren't the same as plugins. But anyway, the first three numbers are the node's position (relative to the part's origin), and the next 3 are the node's normal (i.e. what direction does it point in). The last one is optional and defines the size (this must be an integer). node_attach is special because it defines the actual attach node, stack nodes are anything starting with node_stack_ Quote Link to comment Share on other sites More sharing options...
JPLRepo Posted August 29, 2016 Share Posted August 29, 2016 9 hours ago, ShotgunNinja said: I was wondering if somebody know how to extend the maximum zoom allowed in tracking view and map mode. You could try CameraManager.GetCurrentCamera() and manipulate the near/far clipping panes and the field of view. Quote Link to comment Share on other sites More sharing options...
0111narwhalz Posted August 30, 2016 Share Posted August 30, 2016 12 hours ago, blowfish said: That's generally correct. yield return null will defer the rest of the coroutine to the next frame. I think this might not be quite what you want however. If you start the coroutine every frame, then it will run the whole coroutine, just part of it will be a frame after it was started. How would you suggest I achieve the goal of running a loop once per physframe while keeping a (rather large) set of variables alive between iterations? Quote Link to comment Share on other sites More sharing options...
blowfish Posted August 30, 2016 Share Posted August 30, 2016 11 minutes ago, 0111narwhalz said: How would you suggest I achieve the goal of running a loop once per physframe while keeping a (rather large) set of variables alive between iterations? I'm confused. Before it sounded like you wanted it to run every other physics frame. When exactly do you want this to run? Quote Link to comment Share on other sites More sharing options...
Crzyrndm Posted August 30, 2016 Share Posted August 30, 2016 (edited) 38 minutes ago, 0111narwhalz said: How would you suggest I achieve the goal of running a loop once per physframe while keeping a (rather large) set of variables alive between iterations? Normally I'd go with a wrapper class/struct and a function called from fixed update (function in the class, or just another function for a struct). I prefer to use coroutines for periodic checks (NOT every frame) or as a sort of psuedo-thread for responding to an event over a finite number of frames. Using them to generate additional infinite loops just fragments code that's running on the same events (ie. I like being able to trace all functions that run every frame back to (fixed) update). I'd say that's just my personal style guidelines though. Running an infinite loop in a coroutine is not going to have major downsides so if that works for you, why not. Edited August 30, 2016 by Crzyrndm Quote Link to comment Share on other sites More sharing options...
0111narwhalz Posted August 30, 2016 Share Posted August 30, 2016 1 hour ago, blowfish said: I'm confused. Before it sounded like you wanted it to run every other physics frame. When exactly do you want this to run? Did I? Sorry, I want it to run each physics frame. 1:1 physframe : iteration. 45 minutes ago, Crzyrndm said: Normally I'd go with a wrapper class/struct and a function called from fixed update (function in the class, or just another function for a struct). So something like this? class Autopilot { //Various variables public void OnFixedUpdate() { Iterate(Object); } void Iterate(Object) { //Do autopilot-y things } } Would this preserve the "various variables" between calls of OnFixedUpdate()? Finally, what's the functional difference between OnFixedUpdate() and FixedUpdate()? Quote Link to comment Share on other sites More sharing options...
blowfish Posted August 30, 2016 Share Posted August 30, 2016 15 minutes ago, 0111narwhalz said: Did I? Sorry, I want it to run each physics frame. 1:1 physframe : iteration. So something like this? class Autopilot { //Various variables public void OnFixedUpdate() { Iterate(Object); } void Iterate(Object) { //Do autopilot-y things } } Would this preserve the "various variables" between calls of OnFixedUpdate()? Finally, what's the functional difference between OnFixedUpdate() and FixedUpdate()? FixedUpdate and OnFixedUpdate are just instance methods, whatever you do to the instance variables will be kept. OnFixedUpdate on a PartModule is called by the part's FixedUpdate method. It is only run if the part has been staged. FixedUpdate is called by Unity on the PartModule (or any other Behaviour). Quote Link to comment Share on other sites More sharing options...
0111narwhalz Posted August 30, 2016 Share Posted August 30, 2016 10 minutes ago, blowfish said: FixedUpdate and OnFixedUpdate are just instance methods, whatever you do to the instance variables will be kept. So I don't need a separate Iterate() method? I probably will anyway, because I need some other methods to run at appropriate times, but it's not necessary? 11 minutes ago, blowfish said: OnFixedUpdate on a PartModule is called by the part's FixedUpdate method. It is only run if the part has been staged. FixedUpdate is called by Unity on the PartModule (or any other Behaviour). So in this case (partless), I should use FixedUpdate() instead of OnFixedUpdate()? Quote Link to comment Share on other sites More sharing options...
Crzyrndm Posted August 30, 2016 Share Posted August 30, 2016 (edited) Correct, On* methods will not work when inheriting from a module that doesn't implement them for you (including direct from MonoBehaviour (general partless mod)). and no Fixed update will not store variables for you. You just need to declare them outside the method (loose globals, global wrapper struct instance, global wrapper class instance) int global var = 0; // increments with every call to Update class wrapperClass { // wrapper vars int var1; // wrapper functions void AutoPilotStuff() { ++var1; } } wrapperClass dataClass = new wrapperClass(); // persistent across method invocations and groups variables nicely struct wrapperStruct { // wrapper vars int var1; // wrapper functions void AutoPilotStuff() { ++var1; } } wrapperStruct dataStruct = new dataStruct(); void FixedUpdate() { // not persistent int i = 100; // will be lost when FixedUpdate completes for that frame // persistent ++var; // increase by 1 every physics frame dataStruct.AutoPilotStuff(); // increase by 1 every physics frame dataClass.AutoPilotStuff(); // bundle function and vars for the function together } Only variables declared inside the method are lost upon completion of each invocation (If you're new at this, I would avoid using the struct implementation. There are a few gotchas with it) Edited August 30, 2016 by Crzyrndm Quote Link to comment Share on other sites More sharing options...
severedsolo Posted August 30, 2016 Share Posted August 30, 2016 (edited) So, I'm writing my first mod, and my C# knowledge is.. shaky to say the least, so bear with me. What I am basically trying to do, is set it so that when a player returns to the Space Centre, if it detects more Dead crew members than it did last time, it takes some rep away from the player. I know I could set up an Event Handler in the flight scene for this, but so far, everything it needs to do happens in the space centre, so I'd like to keep it that way if at all possible. I know the code works, because when I load up to the Space Centre from the main menu, the rep is deducted properly. However, when returning to the Space Centre, the rep isn't deducted but the number of dead Kerbals is updated (and outputted to the text file where I'm storing this stuff at the moment). I'm guessing what is happening is that the game is calling the first Update() before it's loaded the crew list, so it's not finding them. What's weird though is the number of dead Kerbals is being updated properly (which I wouldn't expect to happen if it hadn't finished loading, and it would pick it up on the next pass). Thinking this was my problem, I tried using WaitForSeconds to make sure everything had loaded, but no joy. This is the relevant bits of my code (apologies for the terrible forum formatting) - I've pruned some bits from Budget() which are working fine, and not relevant to the problem: Quote void Update() { Wait(); Budget(); } private void Budget() { IEnumerable<ProtoCrewMember> DeadCrew = HighLogic.CurrentGame.CrewRoster.Crew.Where(k => k.rosterStatus == ProtoCrewMember.RosterStatus.Dead || k.rosterStatus == ProtoCrewMember.RosterStatus.Missing); if (DeadCrew.Count() > DeadCount) { Reputation.Instance.AddReputation(-100, TransactionReasons.None); DeadCount = DeadCrew.Count(); } } IEnumerator Wait() { yield return new WaitForSeconds(10); } So I guess I have two questions: 1) What am I doing wrong? Why is it only doing it on a new save load and not a scene change? It's probably a really obvious rookie mistake. 2) Is there a better way of doing this? Edited August 30, 2016 by severedsolo Quote Link to comment Share on other sites More sharing options...
JPLRepo Posted August 30, 2016 Share Posted August 30, 2016 (edited) 11 minutes ago, severedsolo said: So, I'm writing my first mod, and my C# knowledge is.. shaky to say the least, so bear with me. What I am basically trying to do, is set it so that when a player returns to the Space Centre, if it detects more Dead crew members than it did last time, it takes some rep away from the player. I know I could set up an Event Handler in the flight scene for this, but so far, everything it needs to do happens in the space centre, so I'd like to keep it that way if at all possible. I know the code works, because when I load up to the Space Centre from the main menu, the rep is deducted properly. However, when returning to the Space Centre, the rep isn't deducted but the number of dead Kerbals is updated (and outputted to the text file where I'm storing this stuff at the moment). I'm guessing what is happening is that the game is calling the first Update() before it's loaded the crew list, so it's not finding them. What's weird though is the number of dead Kerbals is being updated properly (which I wouldn't expect to happen if it hadn't finished loading, and it would pick it up on the next pass). Thinking this was my problem, I tried using WaitForSeconds to make sure everything had loaded, but no joy. This is the relevant bits of my code (apologies for the terrible forum formatting) - I've pruned some bits from Budget() which are working fine, and not relevant to the problem: So I guess I have two questions: 1) What am I doing wrong? Why is it only doing it on a new save load and not a scene change? It's probably a really obvious rookie mistake. 2) Is there a better way of doing this? Bit hard to tell with just that snippit. But you seem to be over-doing it. And I think a GameEvent is exactly what you want. All you need is a MonoBehaviour class using KSPAddOn to have it start at MainMenu (or SpaceCenter) scene. Tell Unity not to destroy it between scenes. Register for the GameEvent.onCrewKilled and then put your code in that method. so it would look something like this: [KSPAddon(KSPAddon.Startup.SpaceCentre, true)] public class DeadKerbalPenaliser : MonoBehaviour { public void Awake() { DontDestroyOnLoad(this); GameEvents.onCrewKilled.Add(onCrewKilled); } public void OnDestroy() { GameEvents.onCrewKilled.Remove(onCrewKilled); } public void onCrewKilled(EventData<EventReport> evtdata) { // Put your code in here. // evtdata.sender will contain the Name of the kerbal that just died. } } Edited August 30, 2016 by JPLRepo Quote Link to comment Share on other sites More sharing options...
sarbian Posted August 30, 2016 Share Posted August 30, 2016 Since some variable need to be saved/loaded with the save I would use a KSPScenario instead but it works that same. 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.