Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to edit mesh/vertices in Unity

Tags:

c#

unity3d

vertex

I would like to edit 1 vertex on a cube, but I don't know how to. I've tried looking everywhere for this function, but I can't find a solution.

Here is an image of what I want to achieve:

enter image description here

like image 600
Christopher Lovell Avatar asked Sep 23 '15 07:09

Christopher Lovell


People also ask

Can you edit vertices in Unity?

You can edit vertices via the MeshFilter component and Mesh class.

How do you reduce vertices in Unity?

To reduce the vertex count of a game object containing a mesh renderer and a mesh filter, you just need to invoke the Unity Mesh Simplifier API on the mesh itself. Ideally, you can develop a custom inspector to make this poly count reduction. You can do that.

How do I edit a object in ProBuilder?

Use the ProBuilder Edit modes to access the individual elements of your Mesh, or the Mesh as a whole. Click the button that matches the object or element mode you'd like to edit in from the Edit mode toolbar. Select objects, modify the normals and the pivot, and merge objects together.


2 Answers

http://answers.unity3d.com/questions/14567/editing-mesh-vertices-in-unity.html

This code is not mine. Bellow is the same code as the link above. I just separated it into two files. (one per class)

It work quite good. BUT make sure to save you scene before using it, it's a bit buggy.

  • Don't forget to leave edit mode when you are done whit your modification.

  • You don't need to add "editMesh" tag to the gameobject you are modifying, or it will be erased when you leave edit mode.

  • Lastly, if you modify a primitive from unity, the modification will be applied for every instance of that primitive ! (if you change a cube for a pyramid, every cube will become a pyramid)

To avoid that make a copy of your primitive mesh, change the mesh you are using in your mesh renderer by your copy and then modify it. (bellow a script to add simple copy function in unity menu)

EditMesh.cs

#if UNITY_EDITOR
using UnityEngine;
using System.Collections;

/// <summary>
/// http://answers.unity3d.com/questions/14567/editing-mesh-vertices-in-unity.html
/// </summary>
[AddComponentMenu("Mesh/Vert Handler")]
[ExecuteInEditMode]
public class EditMesh : MonoBehaviour {

    public bool _destroy;

    private Mesh mesh;
    private Vector3[] verts;
    private Vector3 vertPos;
    private GameObject[] handles;

    private const string TAG_HANDLE = "editMesh";

    void OnEnable() {
        mesh = GetComponent<MeshFilter>().sharedMesh; // sharedMesh seem equivalent to .mesh
        verts = mesh.vertices;
        foreach (Vector3 vert in verts) {
            vertPos = transform.TransformPoint(vert);
            GameObject handle = new GameObject(TAG_HANDLE);
            //         handle.hideFlags = HideFlags.DontSave;
            handle.transform.position = vertPos;
            handle.transform.parent = transform;
            handle.tag = TAG_HANDLE;
            handle.AddComponent<EditMeshGizmo>()._parent = this;

        }
    }

    void OnDisable() {
        GameObject[] handles = GameObject.FindGameObjectsWithTag(TAG_HANDLE);
        foreach (GameObject handle in handles) {
            DestroyImmediate(handle);
        }
    }

    void Update() {
        if (_destroy) {
            _destroy = false;
            DestroyImmediate(this);
            return;
        }

        handles = GameObject.FindGameObjectsWithTag(TAG_HANDLE);

        for (int i = 0; i < verts.Length; i++) {
            verts[i] = handles[i].transform.localPosition;
        }

        mesh.vertices = verts;
        mesh.RecalculateBounds();
        mesh.RecalculateNormals();


    }

}

#endif

EditMeshGizmo.cs

#if UNITY_EDITOR
using UnityEngine;
using System.Collections;

/// <summary>
/// http://answers.unity3d.com/questions/14567/editing-mesh-vertices-in-unity.html
/// </summary>
[ExecuteInEditMode]
public class EditMeshGizmo : MonoBehaviour {

    private static float CURRENT_SIZE = 0.1f;

    public float _size = CURRENT_SIZE;
    public EditMesh _parent;
    public bool _destroy;

    private float _lastKnownSize = CURRENT_SIZE;

    void Update() {
        // Change the size if the user requests it
        if (_lastKnownSize != _size) {
            _lastKnownSize = _size;
            CURRENT_SIZE = _size;
        }

        // Ensure the rest of the gizmos know the size has changed...
        if (CURRENT_SIZE != _lastKnownSize) {
            _lastKnownSize = CURRENT_SIZE;
            _size = _lastKnownSize;
        }

        if (_destroy)
            DestroyImmediate(_parent);
    }

    void OnDrawGizmos() {
        Gizmos.color = Color.red;
        Gizmos.DrawCube(transform.position, Vector3.one * CURRENT_SIZE);
    }

}
#endif

CopyMesh.cs (put it in a directory named "Editor") (you should then find it in your menu bar)

using UnityEditor;
using UnityEngine;

namespace Assets {

    /// <summary>
    /// 
    /// </summary>
    public class CopyMesh : MonoBehaviour {

        [MenuItem("Assets/CopyMesh")]
        static void DoCopyMesh() {
            Mesh mesh = Selection.activeObject as Mesh;
            Mesh newmesh = new Mesh();
            newmesh.vertices = mesh.vertices;
            newmesh.triangles = mesh.triangles;
            newmesh.uv = mesh.uv;
            newmesh.normals = mesh.normals;
            newmesh.colors = mesh.colors;
            newmesh.tangents = mesh.tangents;
            AssetDatabase.CreateAsset(newmesh, AssetDatabase.GetAssetPath(mesh) + " copy.asset");
        }

        [MenuItem("Assets/CopyMeshGameObject")]
        static void DoCopyMeshGameObject() {
            Mesh mesh = (Selection.activeGameObject.GetComponent<MeshFilter>()).sharedMesh;
            Mesh newmesh = new Mesh();
            newmesh.vertices = mesh.vertices;
            newmesh.triangles = mesh.triangles;
            newmesh.uv = mesh.uv;
            newmesh.normals = mesh.normals;
            newmesh.colors = mesh.colors;
            newmesh.tangents = mesh.tangents;
            print(AssetDatabase.GetAllAssetPaths()[0]);
            AssetDatabase.CreateAsset(newmesh, AssetDatabase.GetAllAssetPaths()[0] + "/mesh_copy.asset");
        }
    }
}
like image 126
Ambroise Rabier Avatar answered Oct 18 '22 03:10

Ambroise Rabier


Lately Unity has added access to the ProBuilder package via "Package Manager".

More info here: https://docs.unity3d.com/Packages/[email protected]/manual/index.html

like image 3
Wiseman Avatar answered Oct 18 '22 02:10

Wiseman