mirror of
https://github.com/bdunderscore/modular-avatar.git
synced 2025-01-17 11:50:11 +08:00
1 line
10 KiB
JavaScript
1 line
10 KiB
JavaScript
"use strict";(self.webpackChunkmodular_avatar_docs=self.webpackChunkmodular_avatar_docs||[]).push([[671],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>p});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,a,o=function(e,t){if(null==e)return{};var n,a,o={},r=Object.keys(e);for(a=0;a<r.length;a++)n=r[a],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a<r.length;a++)n=r[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=a.createContext({}),d=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},m=function(e){var t=d(e.components);return a.createElement(l.Provider,{value:t},e.children)},c={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,l=e.parentName,m=s(e,["components","mdxType","originalType","parentName"]),u=d(n),p=o,h=u["".concat(l,".").concat(p)]||u[p]||c[p]||r;return n?a.createElement(h,i(i({ref:t},m),{},{components:n})):a.createElement(h,i({ref:t},m))}));function p(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,i=new Array(r);i[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:o,i[1]=s;for(var d=2;d<r;d++)i[d]=n[d];return a.createElement.apply(null,i)}return a.createElement.apply(null,n)}u.displayName="MDXCreateElement"},9881:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>c,frontMatter:()=>r,metadata:()=>s,toc:()=>d});var a=n(7462),o=(n(7294),n(3905));const r={sidebar_position:1},i="Modular Avatar",s={unversionedId:"intro",id:"intro",title:"Modular Avatar",description:"Modular Avatar is a suite of non-destructive tools for modularizing your avatars, and for distributing avatar",source:"@site/docs/intro.md",sourceDirName:".",slug:"/intro",permalink:"/docs/intro",draft:!1,editUrl:"https://github.com/bdunderscore/modular-avatar/tree/main/docs/docs/intro.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",next:{title:"test",permalink:"/docs/test"}},l={},d=[{value:"Merging outfits (and similar things)",id:"merging-outfits-and-similar-things",level:2},{value:"Merging more complex gimmicks",id:"merging-more-complex-gimmicks",level:2},{value:"Placing objects elsewhere in the avatar",id:"placing-objects-elsewhere-in-the-avatar",level:3},{value:"Animating humanoid bones",id:"animating-humanoid-bones",level:3},{value:"Animating non-humanoid bones",id:"animating-non-humanoid-bones",level:3}],m={toc:d};function c(e){let{components:t,...r}=e;return(0,o.kt)("wrapper",(0,a.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"modular-avatar"},"Modular Avatar"),(0,o.kt)("p",null,"Modular Avatar is a suite of ",(0,o.kt)("strong",{parentName:"p"},"non-destructive")," tools for modularizing your avatars, and for distributing avatar\ncomponents.\nWith Modular Avatar, adding a new outfit or gimmick to your avatar is as easy as drag-and-drop!"),(0,o.kt)("p",null,"Modular Avatar currently supports:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Merging prefab armatures into the parent avatar, as is often done to add outfits. MA minimizes the number of bones\nthat are created in this process, reusing existing bones where possible."),(0,o.kt)("li",{parentName:"ul"},"Merging subcomponent animators into the parent avatar, for use with various types of avatar gimmicks.")),(0,o.kt)("h2",{id:"merging-outfits-and-similar-things"},"Merging outfits (and similar things)"),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"img_1.png",src:n(1700).Z,width:"1492",height:"672"})),(0,o.kt)("p",null,"By attaching the Modular Avatar Merge Armature script to the armature of an outfit, Modular Avatar will merge this\noutfit armature into the parent armature automatically at build or play time. The result looks a bit like this:"),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"img_3.png",src:n(2846).Z,width:"1487",height:"670"})),(0,o.kt)("p",null,"Note that new bones have only been created for bones that are present only in the outfit."),(0,o.kt)("p",null,"The Merge Armature script will automatically find corresponding bones under the Merge Target for each bone under the\ntransform it is attached to. It assumes each bone under the prefab to be merged to start with the Prefix and end with\nthe Suffix. If it finds an object that does not match, or if it can't find a corresponding base object, it will attach\nthis transform as a new child object in the base avatar (this can be used for bones corresponding to e.g. skirts or\nribbons)."),(0,o.kt)("p",null,"The outfit can be enabled or disabled (including physbones and other dynamics) simply by toggling the prefab. To\nfacilitate this, any physbones or other components on the armature bones will remain at their old location, but will be\nadjusted to reference the bones in the armature instead. For PhysBones and contacts, the root transform will be set to\npoint to the corresponding armature bone. For other components, a parent constraint will be automatically generated if\nnecessary."),(0,o.kt)("p",null,"Note also that as part of the armature merge, skinned meshes are adjusted (bindposes recalculated) in order to be\ncompatible with the base avatar's mesh. This means that outfits generated using different 3D software are still\ncompatible."),(0,o.kt)("p",null,"If fine adjustments to positioning are required, they can be made to the prefab armature before merging; as long as\nthe 'locked' option (described later) is disabled, the world position of the bones will be retained (effectively, it\nwill behave as if each bone was moved inside the corresponding bone in the base avatar)."),(0,o.kt)("h2",{id:"merging-more-complex-gimmicks"},"Merging more complex gimmicks"),(0,o.kt)("p",null,"For gimmicks involving animators, Modular Avatar has a ",(0,o.kt)("inlineCode",{parentName:"p"},"Merge Animator")," component."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"img_4.png",src:n(705).Z,width:"835",height:"672"})),(0,o.kt)("p",null,"This component will merge the specified animator controller into the corresponding Avatar 3.0 playable layer.\nIf ",(0,o.kt)("inlineCode",{parentName:"p"},"Delete Attached Avatar")," is enabled, any animator on the same gameobject will also be deleted (having such an\nanimator around can be handy for editing animations)."),(0,o.kt)("p",null,"In order to ease editing, animations on a merged animator should have their clips created based off of the location of\nthe Merge Animator script in the hierarchy. In other words, you don't cite the path up to the merge animator script, but\nonly the path from that point:"),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"img_5.png",src:n(229).Z,width:"422",height:"806"})),(0,o.kt)("p",null,"If you use the unity 'record animation' mode to record an animation on an animator on the same game object, this should\nall Just Work."),(0,o.kt)("h3",{id:"placing-objects-elsewhere-in-the-avatar"},"Placing objects elsewhere in the avatar"),(0,o.kt)("p",null,"Your gimmick may sometimes need to put objects (eg contacts) at other places in the hierarchy. To do this, you could use\nthe Merge Armature script as described above, but this depends on matching up bone names and positions, and so is not\nideal for a gimmick that is meant to work with any avatar."),(0,o.kt)("p",null,"Instead, you can use the ",(0,o.kt)("inlineCode",{parentName:"p"},"Modular Avatar Proxy Bone")," component. Attaching this component to a transform will cause that\ntransform to match its position and orientation to the humanoid bone (or sub-bone) in question."),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"img_6.png",src:n(5683).Z,width:"394",height:"292"})),(0,o.kt)("p",null,"Just drag the transform your want to reference onto Target, and the bone reference and sub path will be automatically\nconfigured."),(0,o.kt)("p",null,"At build time, the proxy bone object will be moved under the actual bone in question, and animation references will be\nupdated to match."),(0,o.kt)("h3",{id:"animating-humanoid-bones"},"Animating humanoid bones"),(0,o.kt)("p",null,"Normal humanoid animations can be used with merged animators without special setup."),(0,o.kt)("h3",{id:"animating-non-humanoid-bones"},"Animating non-humanoid bones"),(0,o.kt)("p",null,"When animating non-humanoid bones (e.g. cat ears), some special setup is needed. Use a ",(0,o.kt)("inlineCode",{parentName:"p"},"Modular Avatar Merge Armature"),"\ncomponent with the ",(0,o.kt)("inlineCode",{parentName:"p"},"Locked")," setting enabled:"),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"img_7.png",src:n(6097).Z,width:"1134",height:"668"})),(0,o.kt)("p",null,"When locked is enabled, the base bone and prefab bone will be locked together; if you move one, the other will move.\nThis means you can move your prefab's merge-armature proxy bones when recording an animation, and the corresponding\nbase-avatar bone will also update, making it easy to see what you're doing."),(0,o.kt)("p",null,"At build time, these proxy bones will be merged into the base avatar, so they won't count against performance stats."))}c.isMDXComponent=!0},1700:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/img_1-80880403f6f7ae3518b167d63511f28c.png"},2846:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/img_3-85406f3c725f156a51f933bdfe6fed56.png"},705:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/img_4-93695aa922cd7bd377b5c8961843811d.png"},229:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/img_5-e1459030e1d2bebe9ab9fd2e94cf8210.png"},5683:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/img_6-a4e78a20ded289ad4cc6f5d5ccd59027.png"},6097:(e,t,n)=>{n.d(t,{Z:()=>a});const a=n.p+"assets/images/img_7-aa712d94bc0c0e6ebd2f7a557945978e.png"}}]); |