<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tatsuya Ogawa</title>
    <description>The latest articles on DEV Community by Tatsuya Ogawa (@_4a49fbaa067787556beb).</description>
    <link>https://dev.to/_4a49fbaa067787556beb</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3587889%2Ffb85af02-119e-42a8-8b08-0a205fc4e9c3.png</url>
      <title>DEV Community: Tatsuya Ogawa</title>
      <link>https://dev.to/_4a49fbaa067787556beb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/_4a49fbaa067787556beb"/>
    <language>en</language>
    <item>
      <title>Investigating Missing Skeletons in RealityKit After Converting UniRig GLB Files</title>
      <dc:creator>Tatsuya Ogawa</dc:creator>
      <pubDate>Wed, 29 Oct 2025 17:27:25 +0000</pubDate>
      <link>https://dev.to/_4a49fbaa067787556beb/investigating-missing-skeletons-in-realitykit-after-converting-unirig-glb-files-2kfj</link>
      <guid>https://dev.to/_4a49fbaa067787556beb/investigating-missing-skeletons-in-realitykit-after-converting-unirig-glb-files-2kfj</guid>
      <description>&lt;p&gt;UniRig does a great job auto-generating skeletons for GLB models, which makes preparing assets for RealityKit much easier. The surprise came when I pulled that GLB into Reality Composer Pro, exported it as USDZ, and loaded it in a RealityKit app: calling &lt;code&gt;ModelEntity&lt;/code&gt; for the skeleton just returned &lt;code&gt;nil&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;skeletonIterator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;ModelComponent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;!.&lt;/span&gt;&lt;span class="n"&gt;mesh&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contents&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;skeletons&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;makeIterator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same code works flawlessly with Apple's sample &lt;code&gt;robot.usdz&lt;/code&gt;, so the issue clearly lives in the asset converted from UniRig. Here is what I discovered and how I worked around it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Observed
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Convert the UniRig GLB to USDZ via Reality Composer Pro.&lt;/li&gt;
&lt;li&gt;Load the USDZ in RealityKit and the &lt;code&gt;ModelEntity&lt;/code&gt; reports a &lt;code&gt;nil&lt;/code&gt; skeleton.&lt;/li&gt;
&lt;li&gt;Swap in Apple's &lt;code&gt;robot.usdz&lt;/code&gt; and everything behaves, confirming the runtime side is fine.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Digging Into The Asset
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Converted the problematic USDZ from binary (&lt;code&gt;usdc&lt;/code&gt;) to text (&lt;code&gt;usda&lt;/code&gt;) with &lt;code&gt;usdcat&lt;/code&gt; so I could diff it.&lt;/li&gt;
&lt;li&gt;Replaced its skeleton with the one from &lt;code&gt;robot.usdz&lt;/code&gt;; the scene loaded, which pointed to naming or structure in the skeleton data.&lt;/li&gt;
&lt;li&gt;Checked the &lt;code&gt;uniform token[] joints = []&lt;/code&gt; definition and noticed some joint names in the UniRig output contained slashes (&lt;code&gt;XXXX/YYYY&lt;/code&gt;). RealityKit appears to reject skeletons whose joint names include &lt;code&gt;/&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Fixing The Skeleton Names
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Unpack the USDZ you exported from Reality Composer Pro.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;usdcat&lt;/code&gt; to convert the &lt;code&gt;usdc&lt;/code&gt; file to &lt;code&gt;usda&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;In the &lt;code&gt;uniform token[] joints = []&lt;/code&gt; array, batch-replace joint names that contain &lt;code&gt;/&lt;/code&gt; with names that don't, e.g. turn &lt;code&gt;XXXX/YYYY&lt;/code&gt; into &lt;code&gt;XXXXYYYY&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Repack the edited &lt;code&gt;usda&lt;/code&gt; back into USDZ.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After stripping the slashes from those joint names and repacking, RealityKit once again exposes the skeleton without any code changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;p&gt;RealityKit seems intolerant of joint names that include &lt;code&gt;/&lt;/code&gt;. When you pipeline UniRig GLBs through Reality Composer Pro, double-check the skeleton joint names and sanitize them before publishing the USDZ if needed. That one tweak keeps RealityKit happy.*** End Patch&lt;/p&gt;

</description>
      <category>realitykit</category>
      <category>unirig</category>
    </item>
  </channel>
</rss>
