Importing Collada characters and animations from Mixamo into Xcode
Jun 13, 2024
If you’re looking to add an animated character to your iPhone application, this article will guide you through importing Mixamo characters into Xcode. Additionally, I’ll introduce my tool, xcode-collada, which ensures your DAE files are correctly formatted for Xcode.
Mixamo is an Adobe online service that provides the ability to automatically rig characters, along with an extensive library of character animations. However, out of the box, these characters cannot be directly used in Xcode; some clean up and code is required. Before discussing the various hurdles and solutions, let’s discuss the basic workflow.
Workflow
This article assumes you already have an unrigged character model. The process of animating and bringing this character into Maya is as follows:
Export your character in the
OBJ
formatImport this character into Mixamo, following the instructions on how to rig them
Export the character in a t-pose using the Collada (
DAE
) format.Select the animations you like and export without the skin to a
DAE
formatClean up
DAE
files for use in Xcode (using the xcode-collada tool, discussed below)Add all
DAE
files to XcodeAdd the code below to set up your
SCNScene
Most of these steps should be either self explanatory or be well documented online. The areas that presented issues for me were as follows:
Mixamo failed to export
The
DAE
files were not correctly recognised by XcodeNo code examples for loading multiple animations onto a single character
The rest of this article discusses these issues.
Issue: Mixamo failed to export
When trying to export the animations, I found that Mixamo would time out and not produce a file. The fix was relatively simple: reduce the file size by reducing the complexity of the model.
If you are using a piece of software like Maya, you can use the Reduce function. Just note not to use 100% reduction, as it can produce undesirable results:
Issue: Xcode unable to load the Collada files
Prior to attempting this process, I didn’t know much about the Collada format. Having now had to better understand the format, here are somt things to note about the file format:
Collada uses an
XML
format - so it uses a tree hierarchyThey can include both topology and animations (whereas
OBJ
files can only include vertex data)Xcode lets you manipulate the imported data by continuing to alter the hierarchy (this becomes relevant in the next section)
After importing and trying to use my animation files without success, I Googled around a noted the files can exhibit the following issues:
DAE
files, will use separate<animations>
tags for each bone rather than using a single animation for the whole body. Likewise, when exporting with Blender and Maya there can be an additional wrapping<animation>
tag (as discussed in custom animations article)DAE
files may include inconsistent newlinesThe IDs may include spaces, resulting in the following:
The document "Foo Bar.dae" could not be opened., NSLocalizedRecoverySuggestion=The document does not have a scene. Please check that it has not been corrupted.
I found a couple of existing solutions to resolve these including:
The suggestion to run the following to ensure the
XML
is correctly formatted:
The creation of a Automator workflow that runs the command:
Manually cleaning up some naming issues
Short version: use xcode-collada
To make it easy to perform all of these steps in one, I created a tool called xcode-collada. Full instructions can be found on the GitHub page, but the quick version is:
Issue: Load multiple character animations into Xcode
At this point, you should hopefully have:
A t-pose character file (without any animations)
One or more cleaned up animation files (without the skin/character)
To load these into Xcode, we first load the t-pose:
The loaded scene will have the same tree hierarchy as the Collada file format. Much in the same way JavaScript is used to manipulate the HTML DOM structure in realtime, we can alter the file by manipulating the imported hierarchical data. To do this we do the following:
For each animation we load the animation and add to the animations node:
To load many we can put this logic into a loop. When we want to play a specific one by name we can call a function like follows: