Skip to content

Components and prefabs

Covers components added to a GameObject, placing and changing Unity-made prefabs, and the <Slot> syntax parts use to receive content.

There are 147 components you can add. Their attributes and values are in the Component list.

Assets/Example/Kiosk.mochi.xml
<Kiosk prefab="true">
<Object name="Counter" position="0 0.5 0" static="batching lighting">
<MeshFilter mesh="builtin:Cube"/>
<MeshRenderer material="builtin:Default-Material" shadowCastingMode="TwoSided" receiveShadows="false"/>
<BoxCollider size="1 1 1" center="0 0 0" isTrigger="false"/>
</Object>
<Object name="Lamp" position="0 2 0">
<Light type="Spot" color="#FFE6CC" intensity="2.5" range="6" spotAngle="45" shadows="Soft" lightmapBakeType="Baked"/>
</Object>
<Object name="Speaker">
<AudioSource playOnAwake="false" volume="0.5" loop="true" spatialBlend="1" minDistance="1" maxDistance="20"/>
</Object>
</Kiosk>
SyntaxNumberExample
An enum value written lowercase (point)MOCHI1009enum-case
An attribute not in the table (brightness)MOCHI1005component-attribute

Writing mainTexture or color on a MeshRenderer copies material’s .mat, and the renderer references a copy with the image and color set.

Assets/Example/Lamp.mochi.xml
<Lamp prefab="true">
<Object name="Bulb" position="0 2 0">
<MeshFilter mesh="builtin:Sphere"/>
<MeshRenderer material="../Art/Frame.mat" color="#FFE6CC" shadowCastingMode="Off"/>
<Light type="Point" color="#FFE6CC" intensity="2.5" range="6"/>
</Object>
</Lamp>
materialRequired on the same <MeshRenderer>. Points to a project .mat. A built-in material (builtin:Default-Material) can’t be copied.
Property that’s setThe shader properties tagged [MainTexture] and [MainColor]. If none are found, _MainTex and _Color.
Copy’s name<original .mat name>_<path of the GameObject>.mat. The path joins with _ the key (or the name when there is none) of each GameObject from the root of the entry point down to that GameObject; a GameObject without a key directly inside a <For> puts the row keys before its name. Each GameObject gets a copy of its own
Where the copy is placedThe same generated-files folder as the prefab (generation on save).
Name collisionIt’s an error when the copies of different GameObjects would get the same file name (names that differ only in upper and lower case, or only in characters a file name cannot have) and they set different images or colors. Rename one of them
SyntaxNumberExample
mainTexture with no materialMOCHI1008texture-without-material
color written on a built-in materialMOCHI2001builtin-material-color
Two GameObjects whose names differ only in case setting different imagesMOCHI4001same-name-different-image

<Prefab src="…"> places an instance of a prefab made in Unity. Its attributes and allowed children are in <Prefab>.

Assets/Example/Corner.mochi.xml
<Corner prefab="true">
<Prefab src="../Kit/KitFrame.prefab" name="Frame A" position="2 1.5 0" scale="0.5 0.5 0.5">
<Object name="Note" position="0 -0.5 0"/>
</Prefab>
</Corner>
positionThe value written on the <Prefab>. 0 0 0 when not written
rotation・scale・active・staticThe prefab’s root value when not written (as when the prefab is placed in a scene in Unity). Writing a value replaces it
A model whose root is rotated on importPlaced facing the way Unity shows it. That rotation counts in layout, inspect and gap, as a written rotation does. Write rotation="0 0 0" to remove it
A prefab whose root is a RectTransformUnder a Canvas, anchoredPosition and the other RectTransform values stay the prefab’s when not written
UdonBehaviours insideGameObjects inside a prefab have no key, so a GameObject with two or more UdonBehaviours cannot be pointed to by a path (MOCHI1009)

Changes inside a prefab (<At>, a component change, <Slot> with path) can only be written in a part’s file. To change one from the entry point, make a part that wraps the <Prefab> and use that.

Assets/Example/Wall.mochi.xml
<Wall prefab="true">
<Framed position="0 1.5 0"/>
</Wall>
<!-- file: Assets/Example/Framed.mochi.xml -->
<Framed>
<Prefab src="../Kit/KitFrame.prefab">
<At path="Plate/Label" active="false"/>
<At path="Canvas">
<MeshRenderer material="../Art/Frame.mat"/>
</At>
<At path="Mount">
<Object name="Spot">
<Light type="Spot"/>
</Object>
</At>
</Prefab>
</Framed>
Assets/Example/Wall.mochi.xml
<Wall prefab="true">
<Prefab src="../Kit/KitFrame.prefab">
<At path="Plate/Label" active="false"/>
</Prefab>
</Wall>
SyntaxNumberExample
<At> written in the entry point fileMOCHI3013override-in-entry
A path not in the prefabMOCHI2010at-path-not-found
A change to <Light> not on the prefab’s rootMOCHI3010override-missing-component

<Slot> is the place inside a part that receives the content the caller writes as children (attributes are in <Slot>).

Assets/Example/Board.mochi.xml
<Board prefab="true">
<Card>
<Object name="Body"/>
<Object name="Title" slot="title"/>
</Card>
</Board>
<!-- file: Assets/Example/Card.mochi.xml -->
<Card>
<Object name="Top"><Slot name="title"/></Object>
<Object name="Bottom"><Slot/></Object>
</Card>
How to write contentWritten as a child of the part’s tag. You can also write slot on children inside <For> and <If>.
Binding contentReads the props and row of the file where the content is written. It can’t read the part’s props.
Content with nowhere to goIs an error.
Assets/Example/Board.mochi.xml
<Board prefab="true">
<Framed>
<Object name="Picture" slot="content"/>
</Framed>
</Board>
<!-- file: Assets/Example/Framed.mochi.xml -->
<Framed>
<Prefab src="../Kit/KitFrame.prefab">
<Slot name="content" path="Mount"/>
</Prefab>
</Framed>
SyntaxNumberExample
A slot name not in the partMOCHI2012slot-unknown
A default <Slot/> placed in two spotsMOCHI3011slot-twice

fill attaches the children added under the prefab’s root, one by one, to objects inside the prefab whose names match a pattern (mount points).

Assets/Example/Hall.mochi.xml
<Hall prefab="true">
<Rooms/>
</Hall>
<!-- file: Assets/Example/Rooms.mochi.xml -->
<Rooms>
<Prefab src="../Kit/KitRoom.prefab" fill="Mount*">
<For each="art" in="folder('../Gallery/art/')">
<Object key="{art.key}" name="{art.title}"/>
</For>
</Prefab>
</Rooms>
Patterns* matches any run of characters, including none. It’s compared against the whole name.
Order of attachmentThe order of a depth-first walk of the prefab’s hierarchy. Numbers in names aren’t read. In the example KitRoom.prefab, the order is Mount1, Mount0, Mount3, Mount2.
Children that are countedOnly children added under the prefab’s root. Children added with <At> and component changes aren’t counted.
Leftover mount pointsStay empty.
Not enough mount pointsIs an error, unless overflow="repeat" is written.
SyntaxNumberExample
More children than mount pointsMOCHI3012too-many-to-fill

Writing overflow="repeat" adds more instances of the same prefab to fill the rest, when there are more children than mount points.

Assets/Example/Hall.mochi.xml
<Hall prefab="true">
<Prefab src="../Kit/KitRoom.prefab" fill="Mount*" overflow="repeat" gap="0 0 12">
<For each="art" in="folder('../Gallery/art/')">
<Object key="{art.key}" name="{art.title}"/>
</For>
<For each="row" in="table('../Data/art.csv')">
<Object key="{row.key}" name="{row.title}"/>
</For>
<Object name="Guide"/>
</Prefab>
</Hall>
gapThe offset (x y z) from one instance to the next. It is turned by the rotation of the original instance (the rotation written, or the rotation of the prefab’s root when not written) before it is applied
Name of an added instanceContinues as original name (1), original name (2).
Same as the originalRotation, scale, active, and Static, plus, of the changes inside the prefab, component changes, <At>’s active, and components added with add="true" (a value that points to an object inside the prefab or to another added component points to the one in the same instance).
Only on the original instanceChildren added with <At> and <Slot path>, and children placed in the mounts of the original instance. A component change or a component added with add="true" that points to one of these, or to anything under them, is an error (MOCHI9001). Pointing to an object inside the prefab points to that instance’s own object in each instance; an object outside the prefab is shared by all instances.
Checking whether gap is presentOnly done once there are more children than mount points.

While there are enough mount points, missing gap isn’t an error.

Assets/Example/Hall.mochi.xml
<Hall prefab="true">
<Prefab src="../Kit/KitRoom.prefab" fill="Mount*" overflow="repeat">
<For each="art" in="folder('../Gallery/art/')">
<Object key="{art.key}" name="{art.title}"/>
</For>
</Prefab>
</Hall>
SyntaxNumberExample
overflow="repeat" with no gap, when there are more children than mount pointsMOCHI1008repeat-without-gap