• Content Count

  • Joined

  • Last visited

Community Reputation

48 Excellent

About fatcargo

  • Rank
    Spacecraft Engineer

Recent Profile Visitors

1,286 profile views
  1. Ohh that's perfect ! That means i can add emissive, not worry about (too much) overhead and it will work in dark ! Yay ! Oh and update : i removed source anims, compiled anim works completely alone but i'm also curious about a possibility of adding curves for animating properties with arbitrarily set animation keys, even if animation with imported mesh does not have reserved time slots for it. Here is a post that hints at this,
  2. THANKS FOR THE PIC ! IT WORKED ! That small thing ... so much difference. And now i can use ModuleAnimateGeneric, no need for exotic stuff (yet ). I have to note that info is scattered across several threads but here is what i found : This is useful reference to see how parts are constructed, i used "light" demo to confirm my Unity install worked properly, "Central" reference with information (there may be smaller bits of info one can miss if tired/distracted), In my case, my mesh was imported as FBX file with Animation component, added to GameObject that holds PartTools. I've added a plain KSP/UnlitColor material to small piece of mesh to be used as color indicator (which is child of other meshes in animation). Then i created a new property animation (i guess this is appropriate name for it) and in "Reference" field wrote path to my color indicator mesh as first_level_child_of_imported_file/child_level_1/color_indicator_mesh. You can see this in yt video posted in Color Animation Editor thread when demonstrating Reference setup to "HierarchyEmissive" part of video. Pay attention at what is going on when watching it, it is easy to miss crucial details as design process is quite quick. This animation is targeting property "_Color" (note the leading underscore) found in KSP/UnlitColor material assigned to color_indicator_mesh. Then i selected my color_indicator_mesh in scene tab and opened Animation tab (menu Window > Animation or CTRL+6) and edited keys as needed. Next step was to, inside Project tab, CTRL+click multi-select both animation imported along with FBX and a newly created property animation, then right-click on any of selected items and from menu choose Animation > Compile Selected. This creates a new animation named "CompiledAnimation" in same folder as source animations. Don't forget to set "Legacy" flag as noted in previous post. Now i added that to a list of animations to root item where original imported animation resides. So there were three animations, original, property and freshly compiled one in animation array (i also added property animation). Finally, i did the usual exporting step and copied to GameData. After that i added CompiledAnimation to ModuleAnimateGeneric in animationName field, tested and that was it. It worked More useful bits of info to ones learning : while i was trying to make it work, i had two types of failures : part compiler failed to compile part and subsequently model was not found. Not much to do here except try again.This error is visible during load. Second failure type was far more dangerous - it made my KSP game eat up nearly all of my RAM, it used up 6.5GB in middle of load. For several times i barely managed to end task before it turned my machine into crawling pile of mud. One more thing : do not be alarmed when editing keys in property animation and see property names in yellow coilor with "(Missing!)" text, it works and it can be tested by dragging animation cursor. I'll try emissives next, they need extra step for creating textures. Which brings me to my next question : @JadeOfMaar some long time ago i've read on forums about limits for number of lights in scene. Does this apply to emissives as well ? I wouldn't want to burden player's machines with even more ultra-deluxe bang-whizz-splash
  3. I've managed to create a test part that includes both standard mesh animation and color animation, driving Color property of KSP/UnlitColor material on one of animated parts. I can execute mesh animation with ModuleAnimateGeneric, but i don't know how to also start Color animation at the same time. Is there an extra parameter that ModuleAnimateGeneric can parse ? Or, is there a custom plugin that can run two animations at the same time ?
  4. Here : https://github.com/KSP-RO/RealismOverhaul/blob/612877a538158025b72dc6cec48062441e2b5c0e/GameData/RealismOverhaul/RO_SuggestedMods/RO_B9.cfg#L3554 This shows exact file name and line number
  5. Hmm IF i remember this right - transmitter (at least stock module) doesn't work on EVA kerbals, didn't bother to memorize why.
  6. ... Wold totaly work for some live action shots, go-pro-style. Parachutes, breaking sound barrier on sub-orbital trajectory, riding a rocket, bathing in flames of launched rocket, exiting cockpit in flight...
  7. Sorry to repeat myself, but here is a link to my old post to give some ideas (look also at replies below so you are aware of limitations)
  8. @blowfish I have created a single part to expand upon available HX pack, not yet released. It is created using assets from B9 Aerospace HX. There will be more parts to make this expansion a complete package, i just need to clear it first with you. I'd like to also release FBX files used to create parts, in separate or single package. FYI, i also used and changed textures to fit my parts (pitty i could not use original textures for my geometry). Also, the first of HX parts i created requires my custom animation plugin to work properly. For now, my focus is on releasing and showcasing my plugin in separate thread, but since it uses part derived from B9 Aerospace HX package, i ask for permission to use it in my to-be-created WIP plugin release thread. I'm collecting permissions, license info, github how-to and other info to get ready for first release.
  9. Thanks for the idea ! It made my code simpler since i needed to add event in my partmodule, then initialize listener for every event, customize its variables and then call my player function from those listeners. Now i have just one listener and one player. Also, i kept the string var to pass needed arguments via stringParameter. Though it still needs a single call to myAnimation.gameObject.AddComponent<MyListener>() to work.
  10. Thanks for reply ! I did just that (and by sheer luck i googled the answer after thinking WHERE i could set these custom paramaters). I've set a several custom variables inside a listener, which get converted/packed into string and then event handler "unpacks" the string and gets data. Lucky for me, event handler lives inside my class so all i had to send is a few ints used as indexes used with my lists/arrays. What i did was to add, for each animation event, a listener via AddComponent() with customized parameters. All listeners then send a customized message to same single event handler inside my original class. What i became aware of later, is that i was also very very lucky that for each call to AddComponent(), a new instance of listener is created and all parameters are nicely separated. If it were static and all subsequent calls to AddComponent() either failed or have overwritten previous listener, this whole thing would not be possible.
  11. While making my animation plugin i started my last (pre-release) phase of adding sound support (Configuration, Animation, Control, Utility and Visual are done) I want to add sound fx to my animation(s) but my currently employed method of control/tracking animations properties can be a hit-and-miss for sound support (controlling animations looks fine for now). It works via PartModule.Update() and PartModule.OnUpdate(). These are not directly visible in PartModule (ie not suggested by VS IDE), but can be used because it inherits from Monobehaviour. After successfully doing some basic audio tests, i wanted to write an event handler that receives a reference to my class holding all needed data. And this is where i hit a wall. AnimationEvent handler is not designed to receive data in arbitrary form. There is objectReferenceParameter, but i don't know how to reference my class this way, it expects UnityEngine.Object. If example is needed, i'll try to provide a short version. Reference material
  12. Ok here it goes. The following code should be self-contained so copy/paste into IDE would work out of the box. It is derived from my code which is a mess and posting it directly would not be helpful. I had to make a separate block of code in editor just to make sure no errors creep in. This is demonstration of how to maintain top/left position of window while it changes size. No reset to coordinates given at SpawnPopupDialog(), no flickering during position update. public Vector3 popupOldPosition = Vector3.zero; public Vector2 popupOldSize = Vector2.zero; public Vector3 popupCorrectedPosition = Vector3.zero; public bool popupIsDragging = false; public bool doRefresh = false; public PopupDialog myDialog = null; public bool showDescription = false; public void ShowDialog() { myDialog = PopupDialog.SpawnPopupDialog( new MultiOptionDialog( "visible title text", "", "", HighLogic.UISkin, new Rect(0.5f, 0.5f, 300f, 300f), new DialogGUIVerticalLayout( new DialogGUIButton("Close", () => { }, true), new DialogGUIToggleButton(false, "show/hide", (b) => { showDescription = b; RecordOldPos(); }, 100f, 15f), new DialogGUILabel("long text that needs to fit inside available width of window so it has to break on multiple lines", 100f, -1f) { OptionEnabledCondition = () => { return showDescription; } } ) ), false, HighLogic.UISkin, false); myDialog.dialogToDisplay.OnResize = () => { if (!popupIsDragging && myDialog != null && doRefresh) { doRefresh = false; RestoreOldPos(); } }; EventTrigger popupDialogEvent = myDialog.gameObject.AddOrGetComponent<EventTrigger>(); EventTrigger.Entry popupBeginDrag = new EventTrigger.Entry() { eventID = EventTriggerType.BeginDrag }; popupBeginDrag.callback.AddListener((e) => { popupIsDragging = true; }); popupDialogEvent.triggers.Add(popupBeginDrag); EventTrigger.Entry popupEndDrag = new EventTrigger.Entry() { eventID = EventTriggerType.EndDrag }; popupEndDrag.callback.AddListener((e) => { popupIsDragging = false; RecordOldPos(); }); popupDialogEvent.triggers.Add(popupEndDrag); } public void RecordOldPos() { if (myDialog != null) { popupOldPosition = myDialog.RTrf.position; popupOldSize = myDialog.RTrf.rect.size; } doRefresh = true; } public void RestoreOldPos() { if (myDialog != null) { popupCorrectedPosition.x = popupOldPosition.x + (popupOldSize.x - myDialog.RTrf.rect.size.x) / 2; popupCorrectedPosition.y = popupOldPosition.y + (popupOldSize.y - myDialog.RTrf.rect.size.y) / 2; popupCorrectedPosition.z = popupOldPosition.z; myDialog.RTrf.position = popupCorrectedPosition; } } Note the use of custom added events to properly capture window position. Until i understood the coordinate system used for positioning and size of window i couldn't make heads or tails from available positional data. I'll add comments to code here instead of code box to keep it clean. "showDescription" is used to set visibility of label via toogle button. "popupIsDragging" is used for checking if dragging has ended (BeginDrag event is needed just to reinitializeset this variable. In this case it may appear superfluous, but may be necessary for more complex code that may update window contents during dragging operation). "popupOldPosition" , "popupOldSize" and "popupCorrectedPosition" are used to capture old and calculate new coordinates to maintain visually position of window while it's contents change. Now for the DRAWBACKS. The RecordOldPos() function HAS to be manually inserted into callback for any UI element that may cause window resizing event. I have not found any callback that fires just before window resize event, if there was one, it would capture all changes in one neat function. In above example a toggle button calls RecordOldPos() inside its onToggled() callback event. Note that myDialog.dialogToDisplay.OnResize() callback first sets "doRefresh" to false then calls RestoreOldPos(). Ordering is important because it may trigger another OnResize() event. During initial testing i haven't added this check and managed to crash KSP by causing self-triggering. The coordinate system used for positioning is centered inside display area, so setting window at (0,0) will put in middle. Also, a window transform is also put in center of window itself, not on any of corners. ASCII art time Deptiction of center coordinates on "screen space". X and Y are positive going right and upward. Negative coordinates move to left and below of screen's center. /|\ Y+ | ____________|___________ | | | | | | | (0,0) ------------- |-------------> X+ | | | | |______________________| Similar is with popup window's transform. It is also located at center of window and has same orientation. Now, a few words of caution. While i tested my code, i managed to get window completely outside visible area. It seems that authors intentionally added coordinate origin to center of screen, so if plugin sets window XY position to 0, it won't disappear. Also, whenever window is resized, its vital UI elements may end up outside visible area (for some rare cases for gigantic-sized windows) so it tries to reset to center, maximizing utility and minimizing loss of control. Bear in mind that modal windows will block user input and if they "fly" outside available screen space... Well, you get the picture
  13. Quick update : i'm still trying to find a way to keep window top/left position constant. No luck so far...
  14. HA! I managed to make it clean, no more stutter when doing visibility toggle on UI element ! I'll post an example tomorrow, but for now a hint : use yourDialog.dialogToDisplay.OnResize() callback to set position with yourDialog.RTrf.position Vector3 variable. It will nicely reposition the window BEFORE it gets rendered. Oh, i also added a bool refresh flag which is set to true at point where visibility toggle runs and then clear it in OnResize(). That way, callback won't cause runaway self-triggering (hmm i'll try without that refresh flag to see if it indeed self-triggers). The only thing left (avoidable) is when hide/show happens, the whole window changes size, so top/left position still jumps. I'll try to cook up some math to compensate for it.
  15. Yes it is pretty much same issue - i switch visibility of label via toggle button and window gets reset to positions defined at spawn. I did manage to set it back to last position prior to switching visibility, but you can still see for a brief moment how it jumps to old position then moves back. I will do more tests to see if i can hide that visual "stutter".