

fatcargo
Members-
Posts
400 -
Joined
-
Last visited
Content Type
Profiles
Forums
Developer Articles
KSP2 Release Notes
Everything posted by fatcargo
-
[1.8.x] DMagic's Modlets - Most KSP 1.8 Updates [10-29-2019]
fatcargo replied to DMagic's topic in KSP1 Mod Releases
Hi ! I was amazed that "wiggly" ports could event exist. To me, these are the holy grail for anyone trying to do resource transfers on surface. Prior to this (a looong time actually) i was experimenting with KAS winches and ports (yes i know those were a big no-no, but there weren't any alternatives at the time). I have an issue with vertically aligned ports on SPH runway launch: - built a simple rover out of stock parts, added down-facing flex port jr -launched it on runway -watch phantom forces immediately make it rotate crazy Same for upward facing port. Only when in horizontal orientation it works. I tried to flip rover so that port faces down to ground and similar behavior repeated. This is with modded instal. I'll try later with clean KSP too. Small update : for testing purposes only -added single IR rotatron and a small girder with flex port jr. -launched in horizontal position -nothing happened I then tried to : -attach port again without rotatron and facing down -noticed everything went well until i gave rover command to turn, then madness started again One more test : -same rover as before -added IR rotatron, small girder and flex port jr. starting position facing down. -launch on SPH runway -add small forward velocity -begin rover turn -noted loss of control, uncontrolled rotation in horizontal plane -begin turn of IR rotatron, port now turning parallel to ground -port started to rotate like crazy inside girder -after rotation neared horizontal plane, port started to wobble like compass needle, then stabilized -control over rover regained Last test gave a glimpse of what might have gone wrong. It looks like some kind of IK solver was confused by having all port's joints line up right below it's up-vector (used to resolve positions etc, don't ask how it works), causing flex port to rotate around that axis without successfully finding a stable position. I wouldn't recognize this without learning about IK's for my animation/rigging of part models tests for KSP. I've seen a few tutorials that show how to fix up-vector item/object to one of points, far enough so none of them ever cross over up-axis, and the whole rig follows IK target without flipping over. Hope this helps. -
Ok here we go @xEvilReeperx : yes i already had that hard-code-then-hide idea, and it is very likely to end up in code. @blowfish : as far as animations go, i'm trying to make my module as flexible as possible, which means i'll take it as far as i can. @Diazo : yes i found posts about ModuleAnimationGroup and it aaalmost got it with triggering all modules that have IAnimatedModule (see here) but it still has limit of two different animations with fixed "roles", to keep things reasonably simple. @ All : Guys, thanks you made my day As i was exploring the subject of animations in KSP and Unity, i became aware of more and more options, and variations. Thus my apetite for module complexity has grown and has reached a saturation limit which i may cross after first release, when things settle down and people start responding (which is a whole different can of worms every modder opens when posting his/hers work ).
- 16 replies
-
- kspfield
- kspapiextensions
-
(and 1 more)
Tagged with:
-
I thought of multiple modules for animations using existing plugins as well, but there is no control over their ordering to fire animations in desired sequence and no binding to same part right-click menu button (same event) to fire that sequence. Note that there may be any number of sequences with arbitrary ordering of animations. Here is a piece of part.cfg i consider to be a central part of entire plugin, i hope this explains enough : MODULE { name = ChainedAnimationsModule CHAIN { name = Open Gate 1 repeat = 0 chainSequence = animation=GateShieldAnimation, command=once, speed=1, wait=1 chainSequence = animation=Gate1Animation, command=once, speed=1 } CHAIN { name = Open Gate Shield repeat = 0 chainSequence = animation=GateShieldAnimation, command=once, speed=1, wait=1 } } In above sample, a part has animations which need to be executed in certain order because they depend on each other. There are two actions a player can execute on that part. Both actions have their own sequence of animations. A first action "Open Gate 1" has two animations because GateShieldAnimation needs to happen before Gate1Animation, otherwise the part will have collisions between its components and will be mechanically inconsistent. A second action "Open Gate Shield" has only one animation in sequence because no other components of that part will collide if its animation runs, it does not depend on any other animation to run without apparent collisions. Oh, and as a bonus you can see i have added "named arguments" that can be put inside as values giving extra control over how a particular animation gets executed within a sequence.
- 16 replies
-
- kspfield
- kspapiextensions
-
(and 1 more)
Tagged with:
-
I'll try to explain. To me, the overall topic is quite complicated : i'm trying to build fully configurable module that enables part creators to put multiple animation sequences in part.cfg in any combination they want with parameters. So far, i have made most of code to run this and have tested snippets in separate steps. It all passed. Now i wanted to add ability for multi-animated part creators to allow end users (the actual players) to control how much of each animation is to be played. Example : remember that player can tweak how much the ramps on cargo fuselages can open ? Well, its ok and simple because there is a predefined animation that has known amount of tweak paramaters (in this case only one). With my module, i do not know how many animations a part creator will make, so i don't know how many tweakables there will be. And it would be nice to have control of how much frames of each animation is going to play out in those multi-animated combos. Again, thanks for spending time to help me, i really appreciate it. I'll be back here tomorrow.
- 16 replies
-
- kspfield
- kspapiextensions
-
(and 1 more)
Tagged with:
-
OK i'll give this one more try : is there a way to add interactive controls to part right-click menu that are not bound to fields and can display values ? I ask because creating a special window just to manage tweakable values would break VAB/SPH immersion/workflow.
- 16 replies
-
- kspfield
- kspapiextensions
-
(and 1 more)
Tagged with:
-
Thanks for the heads up ! I'm still trying to bypass compile-time-only KSPField and try to go for runtime version With the above info now i look differently at ModularFuelTanks - having a separate window both saves on complications of jamming everyting in part context menu and provides better logic/UI for its intended purpose. Right now i'm stuck/fiddling with BaseField as constructor ie var bfi = new BaseField(KSPField, FieldInfo, object) and i'm clueless on the last "object" part. FieldInfo i do understand to some degree, though i'm not sure entirely how it connect to actual Field and how to create that at runtime (if needed) . One more thing though : if i want to dump a variable with KSPField attribute (" attribute " is a proper c# naming ?) to a file or string, how do i do it ? Could i use this serialized data to make my own FieldInfo ? I could drop the whole ksp field thing, but my module will then loose support for tweakables. Not fatal for functioning, just annoying.
- 16 replies
-
- kspfield
- kspapiextensions
-
(and 1 more)
Tagged with:
-
Thanks for the reply, i too suspected something along the lines of reausable KSPField (via getter/setter). What did surprise me is that i found examples KSPEvents added at runtime (ModuleFuelTanks.cs @ github has one) and have myself confirmed it works, maybe it was just a typo on your part ? Anyways, the only reason i did not test this is my module is grown too complex to just throw in a piece of code and test it without running everything else i wrote so far (i'd hate to comment out stuff at this point). Hmm i guess i'll make a small test-project to try this, though it looks it won't work. What bugs me is that i can both add a KSPEvent at compile time and at runtime. I just tried to replicate this for KSPField but PartModule.Fields[] does not have Add() method. This makes for a difficult if not impossible solution.
- 16 replies
-
- 1
-
-
- kspfield
- kspapiextensions
-
(and 1 more)
Tagged with:
-
Is it possible to add arbitrary number of integer ksp fields at runtime in partmodule ? Closest example is at KSPAPIExtensions github page for a pre-defined chooser-type field, but i need one for int variable created at runtime. I did also find some examples in github sources of Infernal Robotics, but they also apply only to predefined variables. I did compile a variable with KSPField that has functions defined in its getter and setter, no errors were thrown. I don't know how to formulate my question but this is what i need : - variable is allocated at runtime as part of array or list - variable needs to be displayed to user in UI (this is where KSPAPiExt helps) Also, is KSP API Extensions at all capable of displaying values inside array or (preferably) List ?
- 16 replies
-
- kspfield
- kspapiextensions
-
(and 1 more)
Tagged with:
-
Not wanting to criticize, but KSP wiki part cfg Model Parameters section states that "mesh" should be avoided in favor of MODEL{}. I guess "mesh" field is still valid because its not too hard for devs to maintain in new versions of KSP. I hope that if i choose to use the simpler Find() method in my plugin and force part creators to use single MODEL{}, nobody will hold it against me PS: I was surprised how many parts still have "mesh" in their cfgs. PPS : If there is a thread that collects useful code snippets, examples etc, FindModelTransformEx() should be included.
-
ATTENTION : I tried several times to correct a mistake with GetChild() in example sources, it should read GetChild(0). I tried to reload same link in different browser (thus avoiding cached version) and problem persisted. I have found it. My assumption that Transform.Find() didn't work in KSP was only partially correct. It does not work if one tries to use it straight from part.transform.Find(), instead it needs to go two "levels" down in hierarchy where GameObject resides, namely : Transform rootTransform = part.transform.GetChild().GetChild(); Transform targetTransform = rootTransform.Find("base/gate_1_root/gate_1/gate_1_collider_1")); To elaborate on the above : the hierarchy visible in Unity3D editor begins after a second-order child transform. In my designed part, hierachy looks like GameObject > base > gate_1_root > gate_1 > gate_1_collider_1 Here is a breakdown : Debug.Log ("part transform : " + part.transform); // prints "HX1AerodynamicGateShell (UnityEngine.Transform)" // this is same as name field in PART{} node in part.cfg Debug.Log ("part transform child" + part.transform.GetChild()); //prints "model (UnityEngine.Transform)" //hmm looks like variable "model" field in MODEL{} node in part.cfg Debug.Log ("part transform child of child" + part.transform.GetChild(). GetChild()); //prints "0000_MyParts/HX_1_Aerodynamic_Gate_Shell/model(Clone) (UnityEngine.Transform)" //this one seems to reflect a folder path under GameData directory with a cloned model thrown at end So, all that is required to use Transform.Find() (note the upper case) is to go two levels down and then you can input the usual "parent/child/grandchild" format string. NOTE : i did manage to make a rather complicated (and now obsolete) function to augment the "lacking" Find(), and the above should work for anyone. And to @xEvilReeperx in the above i referenced branch with GetChild(0), maybe if using multiple MODEL {} nodes there will be another branch with GetChild(1) ? If anyone has a need for this, it can be easily tested. If i ever need this, i'll try to see if it works.
-
Sorry for late response, i'm busy doing other things, so not much time left for modding KSP. Thanks for the source, it gave me few ideas about custom TransformFind(). Use of Queue class was an eye-opener (i'm new to C# myself), and i'll try to clone/mimick the above code and form my own function. For now, idea is to use Stack class (its reverse of Queue and will do nicely) to try and create a kind of recursive function without calling it from inside and avoid using system/program stack. A kind of recursion without recursive function This is turning out to be also a programming class as well, not just plain API calls bunched together. Anyway, once i build a recursive loop (finally an adequate expression !) it will build an array of strings, each constructed of branch elements that will represent a branching path. Now all i have to do is match one of those paths to one provided in part.cfg. Since all paths should be unique, there ever is only one match possible (unless Unity allows for sibling-components with same name in hierarchy, which is a bad practice anyway). Building such an array of paths and not trying to match inside loop itself may be bruteforce, but it is simple.
-
Here are some results : I was able to get a transform from a path, but in my haste i deleted that code thinking i was on track so i don't remember how i did it. A leading slash character maybe... As for part.cfg, i did reference my model as per guidelines. I used same part.cfg while modeling my part and writing code for testing, it did not give me any trouble before. I also tried to copy/paste the above "GameObjectExtensions" code into my namespace but SharpDevelop complained that ILog could not be found (CS0246). Here are important lines from part.cfg : PART { name = HX1AerodynamicGateShell module = Part author = fatcargo MODEL { model = 0000_MyParts/HX_1_Aerodynamic_Gate_Shell/model } //stuff like attachment nodes, weight, cost etc... MODULE { name = ChainedAnimationsModule // more stuff to be used later in plugin development } } More info to come tomorrow. Thanks for taking time to reply.
-
To elaborate : I'm writing a plugin that will read part.cfg to get a transform for a part's sub-object. There is part.FindModelTransform() but it relies on transform's name being unique. The plugin i'm writing will be released to be used by part creators and will read transform name from part.cfg, so i don't have control over what gets entered. What i want is to use part.transform.Find() that can use full path to named transform but so far i had no luck on my demo part. I tried to recursively build a path from transform to its parents by concatenating their names and it didn't work. I did find an older post about pretty much the same problem and it did show some clear examples but it didn't work for me. Here is example code i tried : Transform partTransform = part.FindModelTransform("gate_shield_root"); string transformPath = partTransform.name; while (partTransform.parent != null) { partTransform = partTransform.parent; transformPath = partTransform.name + "/" + transformPath; } Debug.Log ("path = " + transformPath); Debug.Log("find() = " + (transform.Find(transformPath) != null).ToString()); This printed out HX1AerodynamicGateShell/model/0000_MyParts/HX_1_Aerodynamic_Gate_Shell/model(Clone)/base/gate_shield_root and Find() failed on that one. In Unity, my model hierarchy looks like this (names are as seen in hierarchy view) : GameObject > base > gate_shield_root The only clue how a path should look like in the above mentioned post was this (extra spaces for clarity) model / Your_Game_Object_In_Unity / Root_Object_In_Model / Sub_Object / ... / Sub_Object_WIth_Needed_Transform
-
DMagic thanks ! Setting wrapmode to clampforever enabled me to keep track of playback position with one caveat - normalizedTime variable will continue beyond 0f .. 1f range, so when applying Play() (and setting speed parameter for forward/reverse accordingly), it will "play" but no animation will occur until normalizedTime reaches within 0f .. 1f range. To remedy that i've applied Mathf.Clamp01() to "iron out" normalizedTime inside range and effectively get immediate animation when playback is at either clamped frame. Here is a snippet that solved it for me : partAnimation = part.FindModelAnimators()[]; animationName = "Gate1Animation"; partAnimation[animationName].wrapMode = WrapMode.ClampForever; aState = partAnimation[ animationName ]; [KSPEvent(name = "gate 1 open", active = true, guiActive = true, guiName = "gate 1 open", externalToEVAOnly = false, guiActiveUnfocused = true, guiActiveEditor = true)] public void Gate1Open() { Debug.Log ("gate 1 open"); aState.speed = 0f; //first stop animation aState.normalizedTime = Mathf.Clamp01 (aState.normalizedTime); // now clamp it within 0f .. 01f range, if speed not 0 it may change aState.speed = 1f; //resume animation partAnimation.Play(animationName, PlayMode.StopSameLayer); // Play() it, though it is required only the first time player clicks in menu } [KSPEvent(name = "gate 1 close", active = true, guiActive = true, guiName = "gate 1 close", externalToEVAOnly = false, guiActiveUnfocused = true, guiActiveEditor = true)] public void Gate1Close() { Debug.Log("gate 1 close"); aState.speed = 0f; aState.normalizedTime = Mathf.Clamp01 (aState.normalizedTime); aState.speed = -1f; partAnimation.Play(animationName, PlayMode.StopSameLayer); } [KSPEvent(name = "gate 1 stop", active = true, guiActive = true, guiName = "gate 1 stop", externalToEVAOnly = false, guiActiveUnfocused = true, guiActiveEditor = true)] public void Gate1Stop() { Debug.Log("gate 1 stop"); aState.speed = 0f; //works as good as Stop() and leaves normalizedTime intact } I tried clicking on "gate 1 open" button several times, there were no noticable jumps/jerks in animation - i guess code gets executed quick enough to give appereance of smooth animation. I don't know if it will stay smooth in scenes with complex crafts.
-
Thanks for the reply. I tried again and still nothing, also i removed some of the setup of clips but still nothing. I also tried in Unity itself and same again, time and normalizedTime stay at 0 after animation has finished or after Stop(). Here is code i used, if there is a bug, i don't see it. using System; using System.Collections; using System.Collections.Generic; using UnityEngine; namespace AnimationChaining { public class ChainedAnimationsModule : PartModule { public override void OnLoad(ConfigNode node) { base.OnLoad(node); Debug.Log("chained animations module OnLoad() fired"); } public Animation partAnimation; public string animationName; public override void OnStart(StartState state) { base.OnStart(state); partAnimation = part.FindModelAnimators()[]; if (partAnimation != null) { //animation take 2 animationName = "Gate1Animation"; partAnimation[animationName].speed = 1f; partAnimation[animationName].normalizedTime = 0f; partAnimation[animationName].wrapMode = WrapMode.Once; partAnimation[animationName].layer = 8; partAnimation[animationName].AddMixingTransform(part.FindModelTransform("gate_1_root")); } } [KSPEvent(name = "gate 1 open", active = true, guiActive = true, guiName = "gate 1 open", externalToEVAOnly = false, guiActiveUnfocused = true, guiActiveEditor = true)] public void Gate1OpenEvent() { Debug.Log ("gate 1 open"); partAnimation["Gate1Animation"].speed = 1f; if (partAnimation.IsPlaying("Gate1Animation") == false) partAnimation.Play("Gate1Animation", PlayMode.StopSameLayer); } [KSPEvent(name = "gate 1 close", active = true, guiActive = true, guiName = "gate 1 close", externalToEVAOnly = false, guiActiveUnfocused = true, guiActiveEditor = true)] public void Gate1CloseEvent() { Debug.Log ("gate 1 close"); partAnimation["Gate1Animation"].speed = -1f; if ((partAnimation.IsPlaying("Gate1Animation") == false) && (partAnimation["Gate1Animation"].normalizedTime == 1f)) { partAnimation["Gate1Animation"].normalizedTime = 1f; partAnimation.Play("Gate1Animation", PlayMode.StopSameLayer); } } [KSPEvent(name = "debug log", active = true, guiActive = true, guiName = "debug log", externalToEVAOnly = false, guiActiveUnfocused = true, guiActiveEditor = true)] public void MyDebugLog() { Debug.Log ("debug log"); Debug.Log ("dbg norm time = " + partAnimation["Gate1Animation"].normalizedTime.ToString() + "\n" + "dbg speed = " + partAnimation["Gate1Animation"].speed.ToString () + "\n" + "dbg norm speed = " + partAnimation["Gate1Animation"].normalizedSpeed.ToString ()); } } If i can't get this to work, i might try to create a class that expands Animation and adds extra info, though on my first try IDE threw error about not being able to extend a sealed class. PS: thanks chris for seeing through my badly written code example in OP for my true intent.
-
I'm trying to get playback position within animation that is stopped (either at beggining or the end). AnimationState.time and AnimationState.normalizedTime always return 0 and i need to check at which playback position is animation, even when stopped. Example : public Animation partAnimation = part.FindModelAnimators()[]; //for sake of completness public AnimationState ast = partAnimation["Gate1Animation"]; // get animation state [KSPEvent(name = "gate1open", active = true, guiActive = true, guiName = "gate 1 open", externalToEVAOnly = false, guiActiveUnfocused = true, guiActiveEditor = true)] public void Gate1OpenEvent() { partAnimation["Gate1Animation"].speed = 1f; //if animation is already playing, apply forward playback speed //the below should check if animation is not already playing and at starting position, but time and normalizedTime never have value above 0, so i can't check actual playback position //the consequence is that if player presses several times "gate 1 open" button in part context menu, animation will play from starting position instead of not activating at all (gate 1 is open and stays open on "open" command) if (!partAnimation.IsPlaying("Gate1Animation") && (ast.time == 0.0f)) partAnimation.Play("Gate1Animation"); } So, how do i get animation playback position ? Even if i use some kind of tracking mechanism, it will either have to use coroutines or animation events, either of those seem overkill for this problem. I've found some posts over on unity and stackexchange sites about cloned AnimationStates that are not properly referenced (when using blending and crossfade), but i use only simple Play() function, it should not be a problem ?
-
[resolved] how to start using Part Tools 1.1 with Unity 5.2.4f1
fatcargo replied to fatcargo's topic in KSP1 Mod Development
After a second look i've realized i forgot to extract legacy folder as well from part tools 1.1 zip, now i got the familiar UI to work with. I hope it will be enough for new KSP 1.1+ .- 1 reply
-
- part tools
- unity
-
(and 1 more)
Tagged with:
-
I'm looking for instructions on how to use new Part Tools for KSP 1.1 for part creation. Besides Nifty255's intro video and creating KSPedia entries by BahamutoD i haven't found anything resembling a setup guide. With old Part Tools 0.23 it was straightforward as adding ksp script component with KSP > Part Tools to game object, setting up output folders and pressing "write" button. Now there are two entries "KSPAssets.KSPedia" and "KSPAssets.Loaders". I assume " KSPAssets.Loaders" is right way to go, but rest is just "white noise" to me. I don't get it - there are many plugins and part packs updated for KSP 1.1+ but none of the tutorials for new Part Tools ???
- 1 reply
-
- part tools
- unity
-
(and 1 more)
Tagged with:
-
Sorry for the off-topic, but the below is a result of my investigations into the matter. Small dev news : as i had time, i have poured over source codes of several ksp plugins, some youtube videos and ksp forum. I have managed to proof-test several components i need for my target : - loading part.cfg -modeling, skinning, rigging, arranging animations and exporting to fbx model (learned also to save ONLY keyframes of animated transform channels in export, reduced size quite a bit) -playing multiple animations on single object in unity editor (both as siblings AND in parent-child hierarchy - which was AWESOME discovery for me !) -define a config structure that should let part creator describe model animations in txt format So far, i have covered almost all components, now i have to focus on putting it all together. And have also learned to make a small test-scene in unity editor to test out ideas before putting them in plugin (and anxiously waiting for NREs in KSP ). Also i have discovered part of KSP API as starting point for my next target which i requested earlier (EVA / IVA transitions), but that will have to wait.
-
Thanks for the advice, but my part design requires such level of control as to be usable to a player. If left as single animation, players will have problems using it in crafts with low ground clearance and animations representing part mechanics will be too crude. Also, i took upon myself to complete all steps for this part, including the programming segment. This is the first time i make something for KSP, might as well do most that is offered for modding.
-
I've read about multiple animation takes on forum threads and for most part people have trouble controlling at which frame animation starts. Both ModuleAnimateGeneric and FSAnimateGeneric seem to have this issue. Will conduct my own tests as time permits. Meanwhile, i've discovered i'll need to chain animations to ensure they get executed in proper order and state. And if this requires me to write another plugin, so be it. I'm already on the roll and will finish this. The animation logic i need is (example): -there are 3 animations, let's call them A, B and C -animation A is end-type, a kind of preparation / support / finish -animations B and C are main sequences -before running anim B, anim A is run first, then B -before running anim C, anim A is checked and if not played, its run first, then C -when running anim A in reverse, B and C are executed first in reverse Seems like a lot of work. I hope i get this working. EDIT: Silly me... I've re-read Starwaster's info on github.. You are right it will work. Ahh i guess nobody is immune against a "RTFM"
-
Stuff in the waters
fatcargo replied to KerbalScience's topic in KSP1 Suggestions & Development Discussion
Oh my the gas giants ! Ofcourse ! Challenges to drop a probe lower and lower for more exciting science. And then use that science to enhance existing designs for submersibles on homeworld. -
As title says, i'm designing a part and have managed to do all steps in process except that i don't know how to assign or set layer IDs to multiple animation takes from imported FBX. Model is in FBX 2013 format and Unity is 4.2.2. In previous version, i have already succeeded to design and export UV mapped, textured and animated FBX model into KSP with basic part config that used FSanimateGeneric from FireSpitter. I'm trying to create a model that will have independent animations that will use LayeredAnimations plugin by @Starwaster .
-
Stuff in the waters
fatcargo replied to KerbalScience's topic in KSP1 Suggestions & Development Discussion
Sorry for late response, i look at forums when i have time. To add to previous post : so far, mechanical stress and high temperatures are main factors in durability of crafts and structures. Pressure was never an issue since all parts are assumed to be space-worthy. But if/when underwater environment is implemented, high pressures become major factor and temperatures are important only near areas like hydrothermal vents.