• 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
Question by Coguelin · Jun 20, 2014 at 10:13 AM · shadermeshserializationvertex shadervertex color

Changes to Mesh Vertex Colors Reset on Build

Hey folks,

I created a more complex version of Alex's Vertex Color Method for my artist a few days ago, allowing her to change multiple vertex colors in her meshes : the idea being that she could (e.g.) create a model of a house with a different vertex colour for the roof, door and walls, then give the house a vertex colour material and change the colours of these elements individually.

The vertex colour editing scrip looks like this :

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 [ExecuteInEditMode]
 public class UpdateVertexColors : MonoBehaviour
 {
     private int[] colorPosition;
 
     private List<Color> colors = new List<Color>();
     
     private MeshFilter meshFilter;
 
     private Mesh mesh;
     
     private MeshFilter MeshFilter
     {
         get
         {
             return this.GetComponent<MeshFilter>();
         }
     }
     
     private Mesh Mesh
     {
         get
         {
             return this.MeshFilter.mesh;
         }
         set
         {
             this.MeshFilter.mesh = value;
         }
     }
     
     public List<Color> Colors
     {
         get
         {
             if(this.colors.Count == 0)
             {
                 this.GetColors();
             }
             
             return this.colors;
         }
         set
         {
             this.colors = value;
         }
     }
 
     public void GetColors()
     {
         int i = 0;
         
         colorPosition = new int[this.Mesh.vertices.Length];
         
         while(i < this.Mesh.vertices.Length)
         {
             if(!colors.Contains(this.Mesh.colors[i]))
             {
                 this.colors.Add(this.Mesh.colors[i]);
             }
             
             colorPosition[i] = this.colors.IndexOf(this.Mesh.colors[i]);
             i++;
         }
     }
     
     public void SetColors()
     {
         int i = 0;
         
         Color[] newColors = new Color[this.Mesh.vertices.Length]; 
         
         while(i < this.Mesh.vertices.Length)
         {
             newColors[i] = this.colors[this.colorPosition[i]];
             i++;
         }
         
         this.Mesh.colors = newColors;
     }
 }
 

... and in order to simplify the artist's life, it's manipulated by a custom inspector that looks like this :

 using System.Collections.Generic;
 using UnityEditor;
 using UnityEngine;
 
 [CustomEditor(typeof(UpdateVertexColors))]
 public class UpdateVertexColorInspector : Editor
 {
     UpdateVertexColors script;
 
     public override void OnInspectorGUI()
     {
         base.OnInspectorGUI();
 
         int i = 0;
 
         while(i < this.Script.Colors.Count)
         {
             this.Script.Colors[i] = EditorGUILayout.ColorField("§", this.Script.Colors[i]);
             i++;
         }
 
         if(GUI.changed)
         {
             this.Script.SetColors();
         }
     }
     
     private UpdateVertexColors Script
     {
         get
         {
             if(script == null)
             {
                 script = (UpdateVertexColors)target;
             }
             
             return script;
         }
     }
 }

The script works absolutely fine, and the artist can adjust colours to her little heart's content BUT almost all the changes disappeared the moment we make a Build (originally to test the Shaders on Android devices, but I have since tested the problem with a Standalone build and the same thing happens).

I say "almost all the changes" because a number of trees, which she appears to have copied and pasted after changing their colour, appear to retain their new colour.

The colours are also wiped out in the Editor. I've tried various combinations of serializing the Mesh / Meshfilter etc. and it doesn't seem to have any kind of effect.

Thoughts? I'm out of ideas at this point.

R.

Comment

People who like this

0 Show 0
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

1 Reply

  • Sort: 
avatar image

Answer by MakeCodeNow · Jun 20, 2014 at 03:19 PM

On changes, mark the Mesh with EditorUtility.SetDirty() so that Unity knows to save it.

Comment

People who like this

0 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 Coguelin · Jun 20, 2014 at 03:56 PM 0
Share

Good thought @MakeCodeNow, I made the Mesh property public in my script and added EditorUtility.SetDirty(this.Script.Mesh); after this.Script.SetColors(); in the custom inspector, but it doesn't seem to have made any difference. I tried the same thing setting the MeshFilter and/or the entire GameObject dirty, but that didn't do it either.

Just to be clear, this only happens if I make a Build from the File menu, pressing Play doesn't appear to wipe the Vertex Colour changes from my meshes. It occurred to me that this might somehow be a serialization issue, but I'm not entirely sure how to address it if that's the case.

avatar image MakeCodeNow · Jun 20, 2014 at 06:59 PM 0
Share

Are you modifying a Mesh that's imported from an FBX or the like? If so, that's the problem. You'd need to duplicate the original mesh to a new mesh asset, assign that to the object, and then mutate the vert colors on that copy.

avatar image Coguelin · Jun 23, 2014 at 08:24 AM 0
Share

@MakeCodeNow, that sounds promising and it would certainly explain why some trees are retaining their changes.

Questions, though : The meshes of the trees that retain their colours are labeled "Instance" somehow, but I'm not sure how/where that happened. So the surviving trees have meshes named Fichte6_050 Instance rather than the normal Fichte6_050

I assume that's essentially what you're describing?

Do you mean that I should duplicate the meshes in editor, or that I should do it in code as part of the colour-changing process? (I ask because I've just duplicated the meshes in editor as a test run and it doesn't appear to have changed anything, but I'm essentially just duplicating an imported .fbx so I might be going about it the wrong way).

Thanks for your help!

avatar image MakeCodeNow · Jun 23, 2014 at 05:41 PM 1
Share

You should read up on the difference between the mesh and the sharedmesh attributes of MeshFilter. That will explain where the instances are coming from. In general, though, if you want to take a mesh, change it's vertex colors, and have it be saved, you'll need to make a new mesh resource in code, copy the original mesh data into it, modify the vertex colors, and then save it using AssetDatabase.

avatar image Coguelin · Jun 24, 2014 at 11:06 AM 0
Share

Hi @MakeCodeNow, I'm familiar with the difference between meshes and sharedmeshes, but I'm still not sure where the instances are coming from (or how our artist managed to create these instances in editor). What do you mean?

Alright, I was hoping I would be able to avoid creating and saving new mesh resources, but it does increasingly look like that's the only way. I'll amend my scripts and see what exciting new issues that might create.

Thanks for your thoughts. R.

Show more comments

Unity Answers is in Read-Only mode

Unity Answers content will be migrated to a new Community platform and we are aiming to launch a public beta by June 9. Please note, Unity Answers is now in read-only so we can prepare for the final data migration.

For more information and updates, please read our full announcement thread in the Unity Forum.

Follow this Question

Answers Answers and Comments

3 People are following this question.

avatar image avatar image avatar image

Related Questions

Create a Wireframe Shader with Shader Forge 1 Answer

Vertex Shader and Non-uniformly scaled meshes 1 Answer

Painted Vertices are Blockly, Looking to smooth them Out 1 Answer

How do I adapt this vertex manipulation shader so that my object (point cloud) keeps its original colouring? 0 Answers

How to use Vertex Colors 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