llde / xOBSE

Oblivion Script extender source
252 stars 36 forks source link

ToggleSpecialAnim - Updating anim data & Stagger/Recoil engine animation preference #91

Open Gazareth opened 3 years ago

Gazareth commented 3 years ago

I've been working on a mod which would dynamically pick an appropriate stagger animation when a character gets hit-- the idea is that the character will stagger proportionally to who/what hit them, and also in the appropriate direction, and it'll look a lot better and more reactive etc. etc.

I thought I'd use ToggleSpecialAnim to do this, similar to how VipCxj did with his Air Fight System mod, where you can toggle a set of flight animations onto a specific actor with a key press. But unfortunately I've run into a couple of issues:

  1. Animations don't update immediately, so you have to call a function to update the actor's anim data (and said function will come with side effects).
  2. Stagger and recoil both suffer from what I believe are engine 'feature's, whereby you can have multiple animations loaded in under the same name/slot, and the engine selects randomly which one to use each time.

Workarounds/Issues

With (1) I can call Update3D - but this resets the pose each time, it ends up looking quite jarring. Or I can use RefreshAnimData from @shadeMe's blockhead - which doesn't seem to reset the pose (edit: was wrong on this, it does also reset the pose šŸ˜¢), but it does cause the camera to jolt forwards, so not ideal either.

With (2) I can sort of get around it by duplicating the animation several times and toggling them all in, but you end up with something like this: image

If you have 10 of them, it does seem to yield a 90% chance of the specialanim being picked, presumably because they're equally weighted. But I'd probably want at least a 95% chance of the correct animation being picked, and that would mean loading in around 20 .kf's in and out each time a character gets hit.


So I was wondering if anyone had delved a bit more into the animation code? We have a linked list of AnimationNodes, and ToggleSpecialAnim appends to that list. Presumably, calling Update3D or RefreshAnimData causes the animation engine to update/refresh its internal list from the linked list. My thought was if we could flag certain animations with priorities via a CS command, if we could hook into the part where it picks from the internal list exactly which one it's going to play, and check against our reference list with priorities, make a 'better' decision, then send in the preferred animation.

Kinda similar to what I did with CBAS (Not ideal, but works šŸ¤·ā€ā™‚ļø), only instead of shoehorning in a change in the animation time period, shoehorn in the animation name/path/ID! šŸ™Œ

I think this could really help a lot of modders out if we got it into xOBSE though because I think one of the things Oblivion suffers with is its animation, and if people had the ability to, say, easily set a particular guard NPC to start looking tired/groggy towards the end of a fight, or even just holding their weapons differently as the player comes near... there's a lot of possibility there I think.

llde commented 3 years ago

I do plan to improve the managment of animation and animgroups in xOBSE. Thanks for the report, I will investigate

Gazareth commented 3 years ago

That's great to hear. More robust animation control would be amazing!

In the meantime, I've put together some example code & documentation which aims to show how ToggleSpecialAnim can be used, along with some videos demonstrating some behaviours.

Thought it might be useful for someone stumbling upon this issue, so - https://www.nexusmods.com/oblivion/mods/51036/

Vedamir commented 3 years ago

I do plan to improve the managment of animation and animgroups in xOBSE. Thanks for the report, I will investigate

That's great to hear !