Skip to content

Commit fd489e8

Browse files
author
Roberto De Ioris
authored
Update FixingMixamoRootMotionWithPython.md
1 parent 62517fb commit fd489e8

File tree

1 file changed

+28
-9
lines changed

1 file changed

+28
-9
lines changed

tutorials/FixingMixamoRootMotionWithPython.md

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Once our mixamo assets are imported we need to do the following steps:
1616

1717
* Modify the SkeletalMesh bone influences as indexes will be shifted after the adding of a new bone
1818

19-
* Split the 'Hips' related animation curve in two other curves, one containing the root motion (translations, relative to local axis origin) that will be mapped to the 'root' track, and the other mapped to the 'Hips' track that will contain only rotations.
19+
* Split the 'Hips' related animation curve in two other curves, one containing the root motion (translations, relative to local axis origin) that will be mapped to the 'root' track, and the other mapped to the 'Hips' track that will contain only rotations. The 'root' track must be the first one.
2020

2121
To avoid damages, we will generate a copy of each asset, so you will be able to always use the original ones.
2222

@@ -326,31 +326,50 @@ class RootMotionFixer:
326326
new_anim.NumFrames = animation.NumFrames
327327
new_anim.SequenceLength = animation.SequenceLength
328328

329-
# iterate each track to copy/fix
329+
# first step is generatin the 'root' track
330+
# we need to do it before anything else, as the 'root' track must be the 0 one
330331
for index, name in enumerate(animation.AnimationTrackNames):
331-
data = animation.get_raw_animation_track(index)
332332
if name == bone:
333+
data = animation.get_raw_animation_track(index)
333334
# extract root motion
334-
root_motion = [position - data.pos_keys[0] for position in data.pos_keys]
335-
336-
# remove root motion from original track (but leave a single key for position, otherwise the track will break)
337-
data.pos_keys = [data.pos_keys[0]]
338-
new_anim.add_new_raw_track(name, data)
335+
root_motion = [(position - data.pos_keys[0]) for position in data.pos_keys]
339336

340337
# create a new track (the root motion one)
341338
root_data = FRawAnimSequenceTrack()
342339
root_data.pos_keys = root_motion
343340
# ensure empty rotations !
344341
root_data.rot_keys = [FQuat()]
345342

346-
# add the track
343+
# add the track
347344
new_anim.add_new_raw_track('root', root_data)
345+
break
346+
else:
347+
raise DialogException('Unable to find bone {0}'.format(bone))
348+
349+
# now append the original tracks, but removes the position keys
350+
# from the original root bone
351+
for index, name in enumerate(animation.AnimationTrackNames):
352+
data = animation.get_raw_animation_track(index)
353+
if name == bone:
354+
# remove root motion from original track
355+
data.pos_keys = [data.pos_keys[0]]
356+
new_anim.add_new_raw_track(name, data)
348357
else:
349358
new_anim.add_new_raw_track(name, data)
350359

351360
new_anim.save_package()
352361
```
353362

363+
The two 'for loops' is where the fix happens. Take into account that some animation could require additional manipulation,
364+
as an example you may want to remove z and x transformations for a running loop:
365+
366+
```python
367+
# extract root motion
368+
root_motion = [((position - data.pos_keys[0]) * FVector(0, 1, 0)) for position in data.pos_keys]
369+
```
370+
371+
And always remember that modifying the z axis in root motion, requires your Character to be in 'Flying' movement mode.
372+
354373
Now add support for AnimSequence in your final loop:
355374

356375
```python

0 commit comments

Comments
 (0)