Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
3
Question by RLin · Jul 07, 2016 at 07:24 PM · meshmaterialprocesssubmesh

Separating submeshes into unique meshes?

When I import a model, I use OnPostprocessModel to modify the meshes. Some of the meshes will have submeshes. As I am unable to edit these submeshes outside of Unity, I would like to be able to make each submesh its own individual mesh with only one material. Is there any way to do this?

Comment
Add comment · Show 5
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Cherno · Jul 07, 2016 at 10:12 PM 1
Share

A GameObject can only have one mesh (because it can only have one renderer). So you at least have to use shared mateirals.

It should be possible to make meshes from submeshes: Take a look at $$anonymous$$esh.sub$$anonymous$$eshCount and $$anonymous$$esh.GetTriangles.

avatar image RLin · Jul 07, 2016 at 11:44 PM 0
Share

I know that I will have to use separate game objects. That is not the issue. I can't find any documentation on getting the vertices and uvs for a specific submesh and only that submesh. I managed to copy the triangles, so the submesh looks correct, but the vertices and UVs are also copied in their entirety and I can't figure out how to only get the ones used by the submesh.

The result is a correct looking mesh with a bunch of extra unused vertices and uvs.

avatar image Cherno RLin · Jul 08, 2016 at 12:16 AM 2
Share

I don't know what's the problem with the documentation... It's all there in the Scripting API as far as I can see. Did you see this thread from last year?

Create a mesh from a sub mesh

avatar image RLin Cherno · Jul 08, 2016 at 01:07 AM 0
Share

It's not that the documentation isn't there, it's just that it's a little confusing and vague for someone that is a beginner and doesn't have quite a bit of pre existing knowledge on the topic.

Strangely, a Google search didn't yield that thread you posted. After reading the thread and the answer @Bunny83 posted, I feel that it makes a lot more sense.

avatar image Bunny83 RLin · Jul 08, 2016 at 01:13 AM 0
Share

I've edited my answer and included a $$anonymous$$esh extension method that can extract a submesh from a given mesh.

5 Replies

· Add your reply
  • Sort: 
avatar image
10
Best Answer

Answer by Bunny83 · Jul 08, 2016 at 12:16 AM

Submeshes still share the same vertices. A submesh simply has a seperate indices list. The easiest solution is to create a seperate gameobject / mesh for each submesh and assign each the same vertices array. Now you only need to call GetTriangles for each submesh and assign the resulting arrays to each mesh instance.

The problem here is that each mesh might have some overhead vertices which aren't used in the individual mesh instances.

To solve that you would need to "remap" the indices and only copy the used vertices.

So as a simple example if a sub mesh is a single triangle with the indices 20, 25 and 5 in the original mesh, you would need to create a new vertices array with 3 members and copy those 3 vertex elements over. The new indices / triangle array would need to be adjusted. Since the element "0" in the new vertices array is the old element 20, element "1" is the old "25" and "2" is the old "5", Your indices / triangle array would simply be "0, 1, 2".

This remapping is a bit tricky but not too complicated. A Dictionary would be handy to do the remapping. It basically works like this:

  • Get the triangle list for your submesh

  • iterate through all indices and for each, check if the index is already in the dictionary.

  • If it is already known, use the dictionary to get the "new index" for that vertex.

  • If it's not in the dictionary, copy the vertex from the original array into your new vertex list. In addition you store the old index into the dictionary along with the new one. The new index is the position of that vertex in the new list.

  • Finally you create a new index / triangle list and use the same dictionary to map the indices.

edit
I've just written a Mesh class extentions that can extract a submesh with all it's properties. It does only copy the relevant vertices and only the used vertex attributes.

 using UnityEngine;
 using System.Collections.Generic;
 
 public static class MeshExtension
 {
     private class Vertices
     {
         List<Vector3> verts = null;
         List<Vector2> uv1 = null;
         List<Vector2> uv2 = null;
         List<Vector2> uv3 = null;
         List<Vector2> uv4 = null;
         List<Vector3> normals = null;
         List<Vector4> tangents = null;
         List<Color32> colors = null;
         List<BoneWeight> boneWeights = null;
 
         public Vertices()
         {
             verts = new List<Vector3>();
         }
         public Vertices(Mesh aMesh)
         {
             verts = CreateList(aMesh.vertices);
             uv1 = CreateList(aMesh.uv);
             uv2 = CreateList(aMesh.uv2);
             uv3 = CreateList(aMesh.uv3);
             uv4 = CreateList(aMesh.uv4);
             normals = CreateList(aMesh.normals);
             tangents = CreateList(aMesh.tangents);
             colors = CreateList(aMesh.colors32);
             boneWeights = CreateList(aMesh.boneWeights);
         }
 
         private List<T> CreateList<T>(T[] aSource)
         {
             if (aSource == null || aSource.Length == 0)
                 return null;
             return new List<T>(aSource);
         }
         private void Copy<T>(ref List<T> aDest, List<T> aSource, int aIndex)
         {
             if (aSource == null)
                 return;
             if (aDest == null)
                 aDest = new List<T>();
             aDest.Add(aSource[aIndex]);
         }
         public int Add(Vertices aOther, int aIndex)
         {
             int i = verts.Count;
             Copy(ref verts, aOther.verts, aIndex);
             Copy(ref uv1, aOther.uv1, aIndex);
             Copy(ref uv2, aOther.uv2, aIndex);
             Copy(ref uv3, aOther.uv3, aIndex);
             Copy(ref uv4, aOther.uv4, aIndex);
             Copy(ref normals, aOther.normals, aIndex);
             Copy(ref tangents, aOther.tangents, aIndex);
             Copy(ref colors, aOther.colors, aIndex);
             Copy(ref boneWeights, aOther.boneWeights, aIndex);
             return i;
         }
         public void AssignTo(Mesh aTarget)
         {
             if (verts.Count > 65535)
                 aTarget.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
             aTarget.SetVertices(verts);
             if (uv1 != null) aTarget.SetUVs(0, uv1);
             if (uv2 != null) aTarget.SetUVs(1, uv2);
             if (uv3 != null) aTarget.SetUVs(2, uv3);
             if (uv4 != null) aTarget.SetUVs(3, uv4);
             if (normals != null) aTarget.SetNormals(normals);
             if (tangents != null) aTarget.SetTangents(tangents);
             if (colors != null) aTarget.SetColors(colors);
             if (boneWeights != null) aTarget.boneWeights = boneWeights.ToArray();
         }
     }
 
     public static Mesh GetSubmesh(this Mesh aMesh, int aSubMeshIndex)
     {
         if (aSubMeshIndex < 0 || aSubMeshIndex >= aMesh.subMeshCount)
             return null;
         int[] indices = aMesh.GetTriangles(aSubMeshIndex);
         Vertices source = new Vertices(aMesh);
         Vertices dest = new Vertices();
         Dictionary<int, int> map = new Dictionary<int, int>();
         int[] newIndices = new int[indices.Length];
         for (int i = 0; i < indices.Length; i++)
         {
             int o = indices[i];
             int n;
             if (!map.TryGetValue(o, out n))
             {
                 n = dest.Add(source, o);
                 map.Add(o,n);
             }
             newIndices[i] = n;
         }
         Mesh m = new Mesh();
         dest.AssignTo(m);
         m.triangles = newIndices;
         return m;
     }
 }

With that extention somewhere in your project you can simply do

 Mesh subMesh = someMesh.GetSubmesh(0);

Note: I've written that extension from scratch. I haven't tested it yet but it's syntax-checked and should work. If you find any error / misbehaviour, please leave a comment.

edit

I just added an automatic index format selecting into the "AssignTo" method in order to support Unity's new 32 bit index buffers if necessary. Note that i just put the limit to the usual 65535. However as far as i remember Unity had a slightly smaller limit (at least when there was only a 16bit index buffer in the past). This should work in most cases, if you want to be sure you may want to run some tests on a recent Unity version to test when the 16bit index buffer starts to throw errors.

Comment
Add comment · Show 7 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Jul 08, 2016 at 01:16 AM 0
Share

The private class "Vertices" is just a helper class which handles the "copying" of all vertex attributes at once but only those which are actually present.

avatar image RLin · Jul 08, 2016 at 01:17 AM 0
Share

Great answer and great example! I have yet to test it, as I won't be back on my computer until tomorrow, but this is amazing! $$anonymous$$uch thanks.

avatar image fra3point · Sep 23, 2018 at 04:33 PM 0
Share

Hi, @Bunny83 !

I need a "split submeshes" function for a texture baking system I'm developing, and I find your script very useful for this purpose.

But I have a problem with it. As you can see in the following image, the right model (generated with your script by splitting the left one) has some wrong triangles. Could you please help me to fix this?

alt text

Thanks, Francesco

issue.jpg (61.2 kB)
avatar image Bunny83 fra3point · Sep 23, 2018 at 06:24 PM 0
Share

No, i can't really help you fix this with that little information. Your mesh seems to be quite detailed. $$anonymous$$aybe your mesh exceeds the 64k vertices? The $$anonymous$$esh class now supports more that 64k, but you have to explicitly set the $$anonymous$$esh.indexFormat to the 32 bit format if you have more than 64k vertices.


I'll edit my answer to add some automatic format setting inside the "AssignTo" method. However if that doesn't fix your problem you should post a seperate question and add more information. if you can't provide a copy of the model (copyright?) at least tell us it's stats (vertex / triangle count, submesh count, ...)

avatar image fra3point Bunny83 · Sep 24, 2018 at 06:34 PM 0
Share

Thanks for the reply, @Bunny83 !

That fixed the problem!!! You saved me from a terrible headache... I didn't realize the mesh format index needed to be explicitly changed.

Francesco

avatar image Brain-_-Fail · Jun 15, 2020 at 01:56 PM 0
Share

Any clues on how to correctly copy over bind poses and blend shapes?. I am having a lot of issues with bind pose mismatch and animations.

avatar image Bunny83 Brain-_-Fail · Jun 15, 2020 at 04:47 PM 0
Share

What exact issues do you have? Keep in $$anonymous$$d that a Skinned$$anonymous$$eshRenderer has a reference to all the bone Transform components. So when you create seperate objects for each submesh, make sure you set the same bone array to all of them. Of course you must not remove or rearrange any bones from the bones array.


If you need further help your your specific issue, please ask a seperate question and add more details over there. If it's related to this question or answer you can always include a link to this question in your question.


Note that Blendshapes are a completely different beast. However it generally works the same way. Blendshapes have to use the same vertex order as the original vertex array. So if you're creating a new vertex list the way I do, you essentially need to use the index map to figure out which vertices to keep and in which order.

avatar image
2

Answer by x4000 · Aug 20, 2017 at 06:09 PM

Expanding on this a bit, here's the combined version that I wound up using for my own purposes:

 using UnityEditor;
 using UnityEngine;
 using System.Collections.Generic;
 
 public class ArcenSubmeshSplitter
 {
     //http://answers.unity3d.com/questions/1213025/separating-submeshes-into-unique-meshes.html
     [MenuItem( "Arcen/Submesh Splitter" )]
     public static void BuildWindowsAssetBundle()
     {
         GameObject[] objects = Selection.gameObjects;
         for ( int i = 0; i < objects.Length; i++ )
         {
             ProcessGameObject( objects[i] );
         }
         Debug.Log( "Done splitting meshes into submeshes!  " + System.DateTime.Now );
     }
 
     public class MeshFromSubmesh
     {
         public Mesh mesh;
         public int id; // Represent the ID of the sub mesh from with the new 'mesh' has been created
     }
 
     private static void ProcessGameObject( GameObject go )
     {
         // Isolate Sub Meshes
         MeshFilter meshFilterComponent = go.GetComponent<MeshFilter>();
         if ( !meshFilterComponent )
         {
             Debug.LogError( "MeshFilter null for '" + go.name + "'!" );
             return;
         }
         MeshRenderer meshRendererComponent = go.GetComponent<MeshRenderer>();
         if ( !meshRendererComponent )
         {
             Debug.LogError( "MeshRenderer null for '" + go.name + "'!" );
             return;
         }
         Mesh mesh = go.GetComponent<MeshFilter>().sharedMesh;
         if ( !mesh )
         {
             Debug.LogError( "Mesh null for '" + go.name + "'!" );
             return;
         }
         List<MeshFromSubmesh> meshFromSubmeshes = GetAllSubMeshAsIsolatedMeshes( mesh );
         if ( meshFromSubmeshes == null || meshFromSubmeshes.Count == 0 )
         {
             Debug.LogError( "List<MeshFromSubmesh> empty or null for '" + go.name + "'!" );
             return;
         }
         string goName = go.name;
         for ( int i = 0; i < meshFromSubmeshes.Count; i++ )
         {
             string meshFromSubmeshName = goName + "_sub_" + i;
             GameObject meshFromSubmeshGameObject = new GameObject();
             meshFromSubmeshGameObject.name = meshFromSubmeshName;
             meshFromSubmeshGameObject.transform.SetParent( meshFilterComponent.transform );
             meshFromSubmeshGameObject.transform.localPosition = Vector3.zero;
             meshFromSubmeshGameObject.transform.localRotation = Quaternion.identity;
             MeshFilter meshFromSubmeshFilter = meshFromSubmeshGameObject.AddComponent<MeshFilter>();
             meshFromSubmeshFilter.sharedMesh = meshFromSubmeshes[i].mesh;
             MeshRenderer meshFromSubmeshMeshRendererComponent = meshFromSubmeshGameObject.AddComponent<MeshRenderer>();
             if ( meshRendererComponent != null )
             {
                 // To use the same mesh renderer properties of the initial mesh
                 EditorUtility.CopySerialized( meshRendererComponent, meshFromSubmeshMeshRendererComponent );
                 // We just need the only one material used by the sub mesh in its renderer
                 Material material = meshFromSubmeshMeshRendererComponent.sharedMaterials[meshFromSubmeshes[i].id];
                 meshFromSubmeshMeshRendererComponent.sharedMaterials = new[] { material };
             }
             // Don't forget to save the newly created mesh in the asset database (on disk)
             string path = "Assets/_Meshes/Split/" + meshFromSubmeshName + ".asset";
             AssetDatabase.CreateAsset( meshFromSubmeshes[i].mesh, path );
             Debug.Log( "Created: " + path );
         }
     }
 
     private static List<MeshFromSubmesh> GetAllSubMeshAsIsolatedMeshes( Mesh mesh )
     {
         List<MeshFromSubmesh> meshesToReturn = new List<MeshFromSubmesh>();
         if ( !mesh )
         {
             Debug.LogError( "No mesh passed into GetAllSubMeshAsIsolatedMeshes!" );
             return meshesToReturn;
         }
         int submeshCount = mesh.subMeshCount;
         if ( submeshCount < 2 )
         {
             Debug.LogError( "Only " + submeshCount + " submeshes in mesh passed to GetAllSubMeshAsIsolatedMeshes" );
             return meshesToReturn;
         }
         MeshFromSubmesh m1;
         for ( int i = 0; i < submeshCount; i++ )
         {
             m1 = new MeshFromSubmesh();
             m1.id = i;
             m1.mesh = mesh.GetSubmesh( i );
             meshesToReturn.Add( m1 );
         }
         return meshesToReturn;
     }
 }
 
 public static class MeshExtension
 {
     private class Vertices
     {
         List<Vector3> verts = null;
         List<Vector2> uv1 = null;
         List<Vector2> uv2 = null;
         List<Vector2> uv3 = null;
         List<Vector2> uv4 = null;
         List<Vector3> normals = null;
         List<Vector4> tangents = null;
         List<Color32> colors = null;
         List<BoneWeight> boneWeights = null;
 
         public Vertices()
         {
             verts = new List<Vector3>();
         }
         public Vertices( Mesh aMesh )
         {
             verts = CreateList( aMesh.vertices );
             uv1 = CreateList( aMesh.uv );
             uv2 = CreateList( aMesh.uv2 );
             uv3 = CreateList( aMesh.uv3 );
             uv4 = CreateList( aMesh.uv4 );
             normals = CreateList( aMesh.normals );
             tangents = CreateList( aMesh.tangents );
             colors = CreateList( aMesh.colors32 );
             boneWeights = CreateList( aMesh.boneWeights );
         }
 
         private List<T> CreateList<T>( T[] aSource )
         {
             if ( aSource == null || aSource.Length == 0 )
                 return null;
             return new List<T>( aSource );
         }
         private void Copy<T>( ref List<T> aDest, List<T> aSource, int aIndex )
         {
             if ( aSource == null )
                 return;
             if ( aDest == null )
                 aDest = new List<T>();
             aDest.Add( aSource[aIndex] );
         }
         public int Add( Vertices aOther, int aIndex )
         {
             int i = verts.Count;
             Copy( ref verts, aOther.verts, aIndex );
             Copy( ref uv1, aOther.uv1, aIndex );
             Copy( ref uv2, aOther.uv2, aIndex );
             Copy( ref uv3, aOther.uv3, aIndex );
             Copy( ref uv4, aOther.uv4, aIndex );
             Copy( ref normals, aOther.normals, aIndex );
             Copy( ref tangents, aOther.tangents, aIndex );
             Copy( ref colors, aOther.colors, aIndex );
             Copy( ref boneWeights, aOther.boneWeights, aIndex );
             return i;
         }
         public void AssignTo( Mesh aTarget )
         {
             aTarget.SetVertices( verts );
             if ( uv1 != null ) aTarget.SetUVs( 0, uv1 );
             if ( uv2 != null ) aTarget.SetUVs( 1, uv2 );
             if ( uv3 != null ) aTarget.SetUVs( 2, uv3 );
             if ( uv4 != null ) aTarget.SetUVs( 3, uv4 );
             if ( normals != null ) aTarget.SetNormals( normals );
             if ( tangents != null ) aTarget.SetTangents( tangents );
             if ( colors != null ) aTarget.SetColors( colors );
             if ( boneWeights != null ) aTarget.boneWeights = boneWeights.ToArray();
         }
     }
 
     public static Mesh GetSubmesh( this Mesh aMesh, int aSubMeshIndex )
     {
         if ( aSubMeshIndex < 0 || aSubMeshIndex >= aMesh.subMeshCount )
             return null;
         int[] indices = aMesh.GetTriangles( aSubMeshIndex );
         Vertices source = new Vertices( aMesh );
         Vertices dest = new Vertices();
         Dictionary<int, int> map = new Dictionary<int, int>();
         int[] newIndices = new int[indices.Length];
         for ( int i = 0; i < indices.Length; i++ )
         {
             int o = indices[i];
             int n;
             if ( !map.TryGetValue( o, out n ) )
             {
                 n = dest.Add( source, o );
                 map.Add( o, n );
             }
             newIndices[i] = n;
         }
         Mesh m = new Mesh();
         dest.AssignTo( m );
         m.triangles = newIndices;
         return m;
     }
 }
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image gwiasdeczka2 · Mar 23, 2020 at 01:54 PM 0
Share

great one, thanks for sharing

avatar image
1

Answer by ypoeymirou · Mar 23, 2017 at 03:23 PM

Here is some code for my previous post.

The code has to be adapted, this is a general example, an extract from my custom importation process.

 public class MeshFromSubmesh
 {
     public Mesh mesh;
     public int id; // Represent the ID of the sub mesh from with the new 'mesh' has been created
 }

 private void OnPostprocessModel(GameObject go)
 {
     // Isolate Sub Meshes
     MeshFilter meshFilterComponent = go.GetComponent<MeshFilter>();
     MeshRenderer meshRendererComponent = go.GetComponent<MeshRenderer>();
     Mesh mesh = go.GetComponent<MeshFilter>().sharedMesh;

     List<MeshFromSubmesh> meshFromSubmeshes = GetAllSubMeshAsIsolatedMeshes(mesh);
     for (int i = 0; i < meshFromSubmeshes.Count; i++)
     {
         string meshFromSubmeshName = "SubMesh_" + i;

         GameObject meshFromSubmeshGameObject = new GameObject();
         meshFromSubmeshGameObject.name = meshFromSubmeshName;
         meshFromSubmeshGameObject.transform.SetParent(meshFilterComponent.transform);
         meshFromSubmeshGameObject.transform.localPosition = Vector3.zero;
         meshFromSubmeshGameObject.transform.localRotation = Quaternion.identity;

         MeshFilter meshFromSubmeshFilter = meshFromSubmeshGameObject.AddComponent<MeshFilter>();
         meshFromSubmeshFilter.sharedMesh = meshFromSubmeshes[i].mesh;

         MeshRenderer meshFromSubmeshMeshRendererComponent = meshFromSubmeshGameObject.AddComponent<MeshRenderer>();
         if (meshRendererComponent != null)
         {
             // To use the same mesh renderer properties of the initial mesh
             EditorUtility.CopySerialized(meshRendererComponent, meshFromSubmeshMeshRendererComponent);

             // We just need the only one material used by the sub mesh in its renderer
             Material material = meshFromSubmeshMeshRendererComponent.sharedMaterials[meshFromSubmeshes[i].id];
             meshFromSubmeshMeshRendererComponent.sharedMaterials = new[] { material };
         }

         // Don't forget to save the newly created mesh in the asset database (on disk)
         AssetDatabase.CreateAsset(meshFromSubmeshes[i].mesh, "*YourAssetFolder*/IsolatedSubmeshes/*YourAssetName*" + "@" + mesh.name + "@" + meshFromSubmeshName + ".asset");
     }
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by ypoeymirou · Mar 25, 2017 at 08:52 AM

Excellent solution thanks !

However, don't forget to set the materials correctly on the new meshes' renderers.

For example, if the initial mesh had 2 materials in its mesh renderer (aka 2 IDs in 3DMax), you must setup the mesh renderer for the first created mesh (from first submesh) to use ONLY the 1st material. And the mesh renderer for the second created mesh (from second submesh) to use ONLY the 2nd material.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by pachermann · Jun 03, 2021 at 12:20 PM

This is amazing, thank you so much for sharing this!

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

56 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to apply a texture to a submesh 1 Answer

Surfaces from merged submeshes are affected by light differently. 0 Answers

Layered Textures/Materials 0 Answers

How can I ensure Unity does not rearrange the sub-mesh order of a mesh from Maya?,How can I ensure Unity does not rearrange sub-mesh order of a mesh? 0 Answers

Do submeshes get sorted properly for transparent materials? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges