Jump to content

Photo

Power Armor furniture animation additive subgraph issues; or, a method to instantly remove an actor from PA?

papyrus animation subgraph power armor reeeeeeeee

  • Please log in to reply
8 replies to this topic

#1
IDontEvenKnow

IDontEvenKnow

    Faithful poster

  • Premium Member
  • 1,265 posts

I swear I have never met another more frustrating issue while modding a Bethesda game.
 
So, I had the idea to add in dimmable headlamps for Power Armor helmets. Not too hard of a problem: add a new craftable OMOD for each helmet, then write a bunch of Papyrus that will swap that headlamp with other OMODs of varying brightness levels when an aid item/hotkey is used.
 
Straightforward enough, until I found that there's an engine bug where the game only properly loads the first headlamp spotlight you equip after entering a suit of Power Armor. All headlamps lights after the first one don't load the gobo (the texture the light filters through to project an image), and the color of the light is not loaded properly either (it'll be tinted purple for some reason).
 
Simple reproduction steps to see this bug in a vanilla game:

Spoiler

 
Anyway, not totally insurmountable: forcing an exit/reentry of the PA frame will reload the light and make it display properly. Here is where the real problem starts.
 
Turns out that getting the player out and back into their PA quickly is almost possible, but every avenue I've tried has been a dead end:

  • The first thing I tried was to simply wearer.SwitchToPowerArmor(None), wearer.SwitchToPowerArmor(PAFrame).
    (Skimming over the boring bits, like finding the PA frame furniture object--also, wearer is my local variable for the actor currently wearing the helmet with an adjustable headlamp)
    So, just kick the player out of their frame, then immediately force them back into it. Was a decent idea, but the second SwitchToPowerArmor() call won't work while the player is playing the exit animation, which is like 3.5 seconds. Adding a wait works, but feels absolutely horrible, because switching from the lowest to highest lamp setting takes up to 15 seconds of watching that damn animation.
     
  • Next I thought to do wearer.SwitchToPowerArmor(None), wearer.MoveTo(wearer), wearer.SwitchToPowerArmor(PAFrame).
    The first time I tried this it worked fine, the wearer.MoveTo(wearer) call would cancel the exit animation, allowing us to complete the whole cycle in just a few frames. A little clunky, but it works...or, it did, until I relaunched the game. After that, moving the player to themselves now always triggers a loading screen. I have no idea why this started, but I cannot get this method to work anymore, even in an unmodded game. I also tried placing something at the player's feet and then MoveTo()ing them to that, or MoveTo()ing to the PA frame, but these also trigger loading screens. I also tried fiddling with the fMinPlayerMoveToDistForLoadScreen ini setting, but it seems to do nothing.

    I have no explanation for why this worked in the first place. Moving on...
     
  • Next I attempted to find some way to cancel an ongoing animation, like playing a different idle with a script, and trying every Papyrus function I could think of that might also interrupt animations. No dice here, nothing seems to be able to do this except for MoveTo().
     
  • Right, so, maybe there's some way to artificially unequip a PA frame without SwitchToPowerArmor(None)? Maybe...wearer.UnequipAll()? Uh, no, oh god no, now my player character requires an SCP designation. Moving on...
     
  • Okay, so what if I make the animation shorter? Easy enough, I just have to find the animation files (in Meshes\Actors\Character\Animations\Furniture\PowerArmor\Neutral: ExitToStand.hkx, ExitToStandCombat.hkx, and QuickExitToStand.hkx), unpack them, hack the duration value to 0, repack and replace. Hacky, but works great as a proof of concept: moving the player out of and then back into their PA is back to only taking a few frames, which is kludgy, but workable.

    But, obviously, this creates a new problem: since this is an animation replacer, the PA exit animation is always instant. Not a good side-effect. 

    Moving on...
     
  • After a little research, it's pretty simple to conditionally use different sets of animations, based on actor keywords, by setting up an animation subgraph. Perfect! Right?
    The process doesn't seem too difficult: in this case, all I (apparently) need to do is:
    • Make a new keyword
    • Duplicate HumanRaceSubGraphData
    • Set it to be Additive to HumanRaceSubGraphData
    • Make a (near) duplicate of the already-existing subgraph entry for Meshes\Actors\Character\Behavoirs\FurnitureNoMirrorBehavior.hkx with a target keyword of FurnitureTypePowerArmor, with some slight modifications: add my new keyword into the Actor Keywords filter, and add a new path pointing to where I've put my custom ExitToStand.hkx/etc animations--like so [image]
    • Confirm that the entry does, in fact, add (the UI is dodgy)
    • Save
    • Run the CK with these arguments to build anim text data:
      CreationKit.exe -GenerateAnimInfo:IDEK_ExitAnimTest.esp .\Data .\Data
    According to the information I've found about this process, this should be all I have to do. Now, if I just add my keyword to an actor with a script, they'll use my instant exit animations, and I can turn the animation set back to vanilla by removing the keyword again.

    Unfortunately, though, this doesn't seem to work, at all. Instead of using a different animation set, this prevents the actor from playing any PA furniture-related animations. If the player character is already in a suit of PA, attempting to exit shows the message  You can't exit your armor here.  Attempting to get into a PA frame shows  You cannot use this at this time.  Removing the keyword for the new subgraph returns things to normal.

    Thinking that this might be because of my crappy hacked animations, I tried setting the animation paths up as an exact duplicate of the vanilla one, except with my actor keyword, and rebuilt anim text data again. Theoretically, then, actors with my keyword should use my new subgraph, but they'll use the exact same animation set as the vanilla subgraph. Same issue. Removing my additive subgraph Race record and moving the (still near-duplicate) subgraph entry as a direct edit into HumanRaceSubGraphData also does not work. #[email protected]%!#?!

So, here's where I'm at. I cannot find an adequate solution to any of these problems:

  • Lights and their gobos not loading properly
  • Reloading an incorrectly loaded spotlight without restarting the game, or exiting and reentering the PA frame
  • Removing an actor from their Power Armor without having to watch the exit animation
  • Cancelling or interrupting a PA exit animation
  • Conditionally replacing the PA exit animations

Since the last one is the most complicated, but also the most promising, I made a little test mod here in case anyone would be willing to experiment with it. It adds an additive subgraph that's active when an actor has a particular keyword, which can be toggled by the Aid item that the mod also adds to your inventory on install. Theoretically, using the item should allow you to instantly exit a PA frame. Using the item again should restore the normal animation. In practice, using the item prevents PA animations from working at all.

Hopefully someone with more knowledge on how subgraphs work can educate me on what I'm doing wrong.
Or, if anyone can think of a solution to any of the other problems I just listed, any one of those would work too, and I would be greatly appreciative.

If nothing else, maybe future generations will find this post and save themselves the bother of attempting such an undertaking.

Thanks for reading my dissertation about an exercise in frustration.



#2
langnao

langnao

    Fan

  • Premium Member
  • 456 posts

One thine I noticed when I did a POC on PA previously, if you messed up the animation, u can't enter the PA ...

 

I take a look at your esp file, it looks ok but somehow I m not able to generate subgraph metadata. Not sure y ??? ...  I took ur modded animation files and dump them under my POC mod (basically to change the sound of entering PA) that I have done previously. Instead of adding the keyword to actor, I add them to the target but that's due to different needs and it shouldn't matter. There are two PA near the bridge (in-game) with the added keyword. There is a holoptape that can be used to control the sound but u have to add it manually thru console. Search for "*PA". Your modded 'quick exit' animation is added for 'sound A'. Sound B will be normal exit animation.

 

Maybe u can take a look and it may solve your problem?

https://drive.google...qMHb_yTzEz/view



#3
IDontEvenKnow

IDontEvenKnow

    Faithful poster

  • Premium Member
  • 1,265 posts

Yep, your implementation works as intended. Thanks for that, really.

 

I've noticed that:

  • The CK will look into archives during the GenerateAnimInfo process, so if there is already existing AnimTextData in a .ba2, the CK will not attempt to regenerate it, even if it needs to

  • Related to the above, it the CK also tends not to regenerate AnimTextData if loose files already exist. If you keep your mods cleanly separated with MO2 like I do, just nuking the entire folder works. If you've got any mods installed directly to your Data folder that aren't packed into archives, this would become much more difficult.

 

Also, I figured out what I was doing wrong, turns out I am a f***ing idiot. There was a subtle typo in a file path that took me a solid three days to discover.

Actors\Character\Behavoirs\FurnitureNoMirrorBehavior.hkx

 

9equaNV.jpg

 

I'm sure I looked at that typo a hundred times and never noticed it. Here's an implementation of the earlier test mod that works properly after fixing the typo and regenerating AnimTextData.

 

At least someone might find something else in my post useful some day.



#4
langnao

langnao

    Fan

  • Premium Member
  • 456 posts

Maybe you wanna try these 'exit animations? They were properly done cutting down just 2 frames with all the proper annotations. I think 2 frames r the lowest u can go.  By just edit and set duration to 0, u miss out the annotations which can be important to the animation. One of them unhide the pipboy ...

 

 

https://drive.google...XQezhjG8fW/view



#5
IDontEvenKnow

IDontEvenKnow

    Faithful poster

  • Premium Member
  • 1,265 posts

Sure, I might as well, thanks. My intended use case always involves immediately shoving the player back into the PA frame, but I was still concerned that my 0 duration hack might screw up the animation graph state (or something) somehow, and it can't hurt to nip a future problem in the bud. All of my released mods are open sourced, so maybe someone else might want to rip the asset for some other purpose in the future.

 

Now I face a new problem, which is that the game doesn't like to reevaluate which animation set it ought to be using very often. In practice, the animation set used on exiting PA tends to be equal to whatever set of keywords the player had when entering the PA, which I suppose means that getting into PA probably immediately forces the game to reevaluate which subgraph to use. AttemptAnimationSetSwitch() doesn't help, as far as I can tell. If only I could see into the future...

 

Well, at least it's progress, and I get to fight something slightly different for a while. Hmm...



#6
langnao

langnao

    Fan

  • Premium Member
  • 456 posts

Entering PA probably reload the subgraph but I know it removes or unregistered whatever 'RegisterForAnimationEvent' you have done. 'AttemptAnimationSetSwitch()' is not something that is immediate. However actions like 'fast' travel', exit from Pipboy and drawing of weapon will cause the subgraph to be loaded immediately. So if u triggered a keyword changed say thru a holotape, since u need to exist the Pipboy, u will see the new animation. But if u triggered that say thru consuming an item, if u consume it thru Pipboy, again u need to exist the Pipbo, everything is fine. However, if u 'favorite' the item and consume thru the favorite menu, u will not see the new animation till u perform those actions that I mentioned earlier ...

After entering PA, its probably falls under 'PA race' and its subgraph and thus AttemptAnimationSetSwitch() may not work for that.



#7
IDontEvenKnow

IDontEvenKnow

    Faithful poster

  • Premium Member
  • 1,265 posts

It seems that the PA frame is very resistant to reloading subgraphs, at least with regards to the exit animation. I tried getting into the PA frame, adding a keyword that should switch subgraphs, calling AttemptAnimationSetSwitch(), then opening/closing the pip-boy menu (well, sort of, since the PA interface is different), drawing and holstering a weapon, then fast travelling, but even then the subgraph that was active when I entered the PA frame is still used. At the moment I have two different subgraphs, where one has my conditional keyword on the actor, and another where it's on the target, and I tried the same process by tweaking either the furniture's keywords, or the actor's keywords, but that turns out to make no difference. Saving and then reloading works, but is obviously not a viable solution.

 

Bah, there has to be some solution that will work, right? The struggle continues.

 

Perhaps there's some unused animation the FurnitureNoMirrorBehavior graph points to that I can "inject" into the Meshes\Actors\Character\Animations\Furniture\PowerArmor\Neutral path, then set up a condition to use that animation in the Idle Animations menu, rather than fuss around with subgraphs. The game is much snappier about selecting from animations within a subgraph than it is switching subgraphs. I doubt this idea is viable, though.



#8
langnao

langnao

    Fan

  • Premium Member
  • 456 posts

Just curious, y do u need to keep changing the 'exit' animation? Or change to a different 'exit' animation while in PA ?



#9
IDontEvenKnow

IDontEvenKnow

    Faithful poster

  • Premium Member
  • 1,265 posts
Eureka!
 
So, the PA furniture exit animations are ExitToStand.hkx, ExitToStandCombat.hkx, and QuickExitToStand.hkx. I had the idea to look closely at the existing idle animations, and it occurred to me that only the first two of those animations are ever actually played, because the condition functions on the idle animation record for QuickExitToStand.hkx are set to be impossible to fulfill for Power Armor. Since it's never used anyway, I can co-opt it for my own purposes by reconfiguring the condition functions like so, and then replacing the vanilla animation with your custom, 2-frame variant.
 
By doing this, it provides me a way to force the player to reenter their power armor in just a few frames, which is an acceptable workaround for the ugly visual bug that had been plaguing me. It took me three weeks to find this.


The visual bug in question makes an appearance around 2:20, so it's not 100% fixed, but without this workaround you always get the bug, and to me it just looks absolutely awful.
 
Unfortunately this does mean that only one mod in a given load order can exploit this particular quirk without a manual patch, but I'd be surprised if there are any other mods that make use of it anyway.
Actually I realized that this is a perfect use case for record injection, see the spoiler.

Also, here's a more detailed description, which I wrote as a PM, but I'm putting up publicly for anyone else who stumbles across this thread:
Spoiler


Edit: The mod this was for been released here: https://www.nexusmod...out4/mods/45572

Attached Files







Also tagged with one or more of these keywords: papyrus, animation subgraph, power armor, reeeeeeeee

Page loaded in: 1.138 seconds