unity---Mesh网格编程

Posted 格拉格拉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity---Mesh网格编程相关的知识,希望对你有一定的参考价值。

目录

1.绘制圆形立方体

2.代码

3.点击变形动画


unity---Mesh网格编程(四)这里说了用Mesh 创建一个圆角立方体

1.绘制圆形立方体

2.代码

using UnityEngine;

//脚本挂载到物体时自动添加 MeshFilter 与 MeshRenderer 组件
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class Circle : MonoBehaviour

    //直径
    public int _diameterSize;
    //半径
    private float _radius;

    public float _unitDistace;
    private Vector3[] _vertices;
    private int[] _triangles;
    private int _t = 0, _v = 0;
    private Vector3[] _normals;

    void Awake()
    
        Mesh mesh = new Mesh();
        MeshFilter filter = GetComponent<MeshFilter>();
        filter.mesh = mesh;
        mesh.name = "circleMesh";
        GenerateMesh(mesh);

        _radius = _diameterSize * _unitDistace / 2;
        //添加collider组件,用于接收点击或射线事件
        gameObject.AddComponent<SphereCollider>();
    

    private void GenerateMesh(Mesh mesh)
    
        GenerateVextex();

        _normals = new Vector3[_vertices.Length];
        Vector3 inner;
        for (int i = 0; i < _vertices.Length; i++)
        
            inner = SetNormal(i);
            ResetVextexPos(i, inner);
        

        mesh.vertices = _vertices;
        GenerateTriange(mesh);
    

    private int GetVextexCount()
    
        int connerVertexCount = 8;
        int edgeVertexCount = (_diameterSize + _diameterSize + _diameterSize - 3) * 4;
        int faceVertexCount = (_diameterSize - 1) * (_diameterSize - 1) * 2
                              + (_diameterSize - 1) * (_diameterSize - 1) * 2
                              + (_diameterSize - 1) * (_diameterSize - 1) * 2;

        return connerVertexCount + edgeVertexCount + faceVertexCount;
    

    private void GenerateVextex()
    
        _vertices = new Vector3[GetVextexCount()];
        int index = 0;

        for (int y = 0; y < _diameterSize + 1; y++)
        
            for (int x = 0; x < _diameterSize + 1; x++, index++)
            
                _vertices[index] = GetVertexPos(x, y, 0);
            

            for (int z = 1; z < _diameterSize + 1; z++, index++)
            
                _vertices[index] = GetVertexPos(_diameterSize, y, z);
            

            for (int x = _diameterSize - 1; x >= 0; x--, index++)
            
                _vertices[index] = GetVertexPos(x, y, _diameterSize);
            

            for (int z = _diameterSize - 1; z > 0; z--, index++)
            
                _vertices[index] = GetVertexPos(0, y, z);
            
        

        for (int z = 1; z < _diameterSize; z++)
        
            for (int x = 1; x < _diameterSize; x++, index++)
            
                _vertices[index] = GetVertexPos(x, _diameterSize, z);
            
        

        for (int z = 1; z < _diameterSize; z++)
        
            for (int x = 1; x < _diameterSize; x++, index++)
            
                _vertices[index] = GetVertexPos(x, 0, z);
            
        
    

    private Vector3 GetVertexPos(int xSize, int ySize, int zSize)
    
        return new Vector3(xSize, ySize, zSize) * _unitDistace;
    

    private int GetTriangeCount()
    
        return _diameterSize * _diameterSize * 4 + _diameterSize * _diameterSize * 4 + _diameterSize * _diameterSize * 4;
    

    private void GenerateTriange(Mesh mesh)
    
        _triangles = new int[GetTriangeCount() * 3];
        int circleVextexCount = 2 * _diameterSize + 2 * _diameterSize;


        GenerateSide(mesh, circleVextexCount);

        GenerateTop(mesh, circleVextexCount);

        GenerateBottom(mesh, circleVextexCount);

        mesh.triangles = _triangles;
    

    private void GenerateSide(Mesh mesh, int circleVextexCount)
    
        for (int y = 0; y < _diameterSize; y++)
        
            for (int i = 0; i < circleVextexCount; i++, _v++, _t += 6)
            
                SetQuad(_triangles, _t, _v, _v + 1, _v + circleVextexCount, _v + 1 + circleVextexCount, circleVextexCount);
            
        
    

    private void GenerateTop(Mesh mesh, int circleVextexCount)
    
        for (int x = 0; x < _diameterSize - 1; x++, _v++, _t += 6)
        
            SetQuad(_triangles, _t, _v, _v + 1, _v + circleVextexCount - 1, _v + circleVextexCount);
        

        SetQuad(_triangles, _t, _v, _v + 1, _v + circleVextexCount - 1, _v + 2);
        _t += 6;

        int vMin = circleVextexCount * (_diameterSize + 1) - 1;
        int vMid = vMin + 1;
        int vMax = _v + 2;
        for (int z = 0; z < _diameterSize - 2; z++, vMin--, vMid++, vMax++)
        
            SetQuad(_triangles, _t, vMin, vMid, vMin - 1, vMid + _diameterSize);
            _t += 6;

            for (int i = 0; i < _diameterSize - 2; i++, _t += 6, vMid++)
            
                SetQuad(_triangles, _t, vMid, vMid + 1, vMid + _diameterSize - 1, vMid + _diameterSize);
            

            SetQuad(_triangles, _t, vMid, vMax, vMid + _diameterSize - 1, vMax + 1);
            _t += 6;
        

        int vTop = vMin - 2;
        SetQuad(_triangles, _t, vMin, vMid, vMin - 1, vTop);
        _t += 6;

        for (int i = 0; i < _diameterSize - 2; i++, vMid++, vTop--)
        
            SetQuad(_triangles, _t, vMid, vMid + 1, vTop, vTop - 1);
            _t += 6;
        

        SetQuad(_triangles, _t, vMid, vTop - 2, vTop, vTop - 1);
        _t += 6;
    

    private void GenerateBottom(Mesh mesh, int circleVextexCount)
    
        int vMin = circleVextexCount - 1;
        int vMid = _vertices.Length - (_diameterSize - 1) * (_diameterSize - 1);

        SetQuad(_triangles, _t, vMin, vMid, 0, 1);
        _t += 6;

        int vMax = 1;
        for (int i = 0; i < _diameterSize - 2; i++, _t += 6, vMax++, vMid++)
        
            SetQuad(_triangles, _t, vMid, vMid + 1, vMax, vMax + 1);
        

        SetQuad(_triangles, _t, vMid, vMax + 2, vMax, vMax + 1);
        _t += 6;

        vMid++;
        vMax += 2;

        for (int z = 0; z < _diameterSize - 2; z++, vMin--, vMid++, vMax++)
        
            SetQuad(_triangles, _t, vMin - 1, vMid, vMin, vMid - _diameterSize + 1);
            _t += 6;

            for (int i = 0; i < _diameterSize - 2; i++, _t += 6, vMid++)
            
                SetQuad(_triangles, _t, vMid, vMid + 1, vMid - _diameterSize + 1, vMid - _diameterSize + 2);
            

            SetQuad(_triangles, _t, vMid, vMax + 1, vMid - _diameterSize + 1, vMax);
            _t += 6;
        
        vMid = vMid - _diameterSize + 1;

        SetQuad(_triangles, _t, vMin - 1, vMin - 2, vMin, vMid);
        _t += 6;

        int vBottom = vMin - 2;
        for (int i = 0; i < _diameterSize - 2; i++, _t += 6, vBottom--, vMid++)
        
            SetQuad(_triangles, _t, vBottom, vBottom - 1, vMid, vMid + 1);
        

        SetQuad(_triangles, _t, vBottom, vBottom - 1, vMid, vBottom - 2);
        _t += 6;
    

    private void SetQuad(int[] triangles, int i, int v00, int v10, int v01, int v11, int circleVextexCount)
    
        v10 = (v00 / circleVextexCount) * circleVextexCount + v10 % circleVextexCount;
        v11 = (v01 / circleVextexCount) * circleVextexCount + v11 % circleVextexCount;

        SetQuad(triangles, i, v00, v10, v01, v11);
    

    private void SetQuad(int[] triangles, int i, int v00, int v10, int v01, int v11)
    
        triangles[i] = v00;
        triangles[i + 1] = v01;
        triangles[i + 2] = v10;

        triangles[i + 3] = v01;
        triangles[i + 4] = v11;
        triangles[i + 5] = v10;
    

    //圆角逻辑
    private Vector3 SetNormal(int i)
    
        var vextex = _vertices[i];
        var inner = new Vector3(_radius, _radius, _radius);
        _normals[i] = (vextex - inner).normalized;
        return inner;
    

    private void ResetVextexPos(int i, Vector3 inner)
    
        _vertices[i] = _normals[i] * _radius + inner;
    

3.点击变形动画

using UnityEngine;

public class MeshClick : MonoBehaviour

    //作用力
    public float _force = 10;
    //位移
    private float _offset = 0.1f;

    private Mesh _mesh;
    //圆形 原顶点位置
    private Vector3[] _oldVertices;
    //圆形 变形后顶点位置
    private Vector3[] _newVertices;
    
    private Vector3[] _vertexVelocities;
    //弹力
    private float _springForce = 20;
    //阻力
    private float _damping = 0.9f;

    void Start()
    
        _mesh = GetComponent<MeshFilter>().mesh;
        _oldVertices = _mesh.vertices;
        _newVertices = new Vector3[_oldVertices.Length];
        for (int i = 0; i < _oldVertices.Length; i++)
        
            _newVertices[i] = _oldVertices[i];
        

        _vertexVelocities = new Vector3[_oldVertices.Length];
    

    public void AddForce(Vector3 hitPos, float force)
    
        //世界坐标转本地坐标    
        hitPos = transform.InverseTransformPoint(hitPos);
        for (int i = 0; i < _newVertices.Length; i++)
        
            AddForceToVertex(i, hitPos, force);
        
    

    private void AddForceToVertex(int i, Vector3 hitPos, float force)
    
        Vector3 point = _newVertices[i] - hitPos;
        //力的衰减
        force = force / (1 + point.sqrMagnitude);
        float velocity = force * Time.deltaTime;
        _vertexVelocities[i] += point.normalized * velocity;
    

    private void Update()
    
        for (int i = 0; i < _newVertices.Length; i++)
        
            _vertexVelocities[i] += GetReactiveVelocity(i);
            _vertexVelocities[i] *= _damping;
            _newVertices[i] += _vertexVelocities[i] * Time.deltaTime;
        

        _mesh.vertices = _newVertices;
        _mesh.RecalculateNormals();

        //点击变形
        if (Input.GetMouseButton(0))
        
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            
                //受力的点  = 射线法向量 * 位移 + 点击的点
                var point = hit.normal * _offset + hit.point;
                AddForce(point, _force);
            
        
    

    private Vector3 GetReactiveVelocity(int i)
    
        //点击圆球时,圆球内部的反作用力
        Vector3 reactiveForce = _oldVertices[i] - _newVertices[i];
        return reactiveForce * Time.deltaTime * _springForce;
    

以上是关于unity---Mesh网格编程的主要内容,如果未能解决你的问题,请参考以下文章

unity---Mesh网格编程

unity---Mesh网格编程

unity---Mesh网格编程

unity---Mesh网格编程

unity---Mesh网格编程

unity---Mesh网格编程