m0_61196881 2023-02-07 18:36 采纳率: 50%
浏览 16

unity的mesh的纹理出现了问题

最近按照这个教程:
https://www.bilibili.com/video/BV1Ag411m78d/?p=1&vd_source=1943ccc4ab0f1a5fef4ebc75f0c74544
准备用unity做一个简易的minec,但是出现了如图一下情况:

img


mesh上的texture会出现在距离较远情况下无法加载的问题(图中圈上的部分)
考虑过是图片精度的问题,但是检查了一下,图片确实是256*256像素的,每个素材没有任何偏移
找了半天原因都不知道是为什么
这些是代码,和教程中的几乎无改动:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Chunk
{
    private byte abcdefghijklmnopqrstuvwxyz;//一个没用的变量,抢电脑内存用的,不用管
    public ChunkCoord corrd;
    public GameObject chunkObject;
    public MeshRenderer meshrenderer;
    public MeshFilter meshfilter;
    public int vertexIndex = 0;
    public List<Vector3> vertices = new List<Vector3>();
    public List<int> triangles = new List<int>();
    public List<Vector2> uvs = new List<Vector2>();//定义存储方块数据列表
    public byte [,,]voxelMap = new byte [VorelData.chunkLength, VorelData.chunkHeight, VorelData.chunkWidth];//检查看不到的方块表面,并不绘制这些面,节省资源(参考VorelData.cs)
    public world world;
    public Chunk (ChunkCoord c_corrd, world w_world)
    {
        corrd = c_corrd;
        chunkObject = new GameObject();
        world = w_world;
        meshfilter = chunkObject.AddComponent<MeshFilter>();
        meshrenderer = chunkObject.AddComponent<MeshRenderer>();
        meshrenderer.material = world.material;
        chunkObject.transform.SetParent(world.transform);
        chunkObject.transform.position = new Vector3(corrd.x * VorelData.chunkLength, 0.0f, corrd.z * VorelData.chunkWidth);
        chunkObject.name = "Chunk" + corrd.x + "," + corrd.z;
        PopulateVoxelMap();
        CreateChunk();
        CreateMesh();
    }//world.cs中需要调用这些数据
    public bool CheckVoxel(Vector3 pos)
    {
        int x = Mathf.FloorToInt(pos.x);
        int y = Mathf.FloorToInt(pos.y);
        int z = Mathf.FloorToInt(pos.z);
        if((x < 0 || x > VorelData.chunkLength - 1) || (y < 0 || y > VorelData.chunkHeight - 1) || (z < 0 || z > VorelData.chunkWidth - 1))
        {
            return false;
        }
        else
        {
            return world.block[voxelMap[x, y, z]].isSolid;
        }
    }//不生成看不见的方块
    public void CreateChunk()
    {
        for(int x = 0; x < VorelData.chunkLength; x++)
        {
            for(int y = 0; y < VorelData.chunkHeight; y++)
            {
                for(int z = 0; z < VorelData.chunkWidth; z++)
                {
                    AddVoxelDataToChunk(new Vector3(x, y, z));
                }
            }
        }//生成多个方块
    }
    public void PopulateVoxelMap()
    {
        for(int x = 0; x < VorelData.chunkLength; x++)
        {
            for(int y = 0; y < VorelData.chunkHeight; y++)
            {
                for(int z = 0; z < VorelData.chunkWidth; z++)
                {
                    if(y == 0)
                    {
                        voxelMap[x, y, z] = 1;
                    }
                    else
                    {
                        if(y > 0 && y < VorelData.chunkHeight - 1)
                        {
                            voxelMap[x, y, z] = 2;
                        }
                        else
                        {
                            if(y == VorelData.chunkHeight - 1)
                            {
                                voxelMap[x, y, z] = 3;
                            }
                            else
                            {
                                voxelMap[x, y, z] = 0;
                            }
                        }
                    }
                }
            }
        }
    }//不同种类的的方块
    public void AddVoxelDataToChunk(Vector3 pos)
    {
        for(int j = 0; j < 6; j++)
        {
            if(!CheckVoxel(pos + VorelData.faceCheck[j]))
            {
                byte blockID = voxelMap[(int)pos.x, (int)pos.y, (int)pos.z];
                vertices.Add(pos + VorelData.voxelVerts[VorelData.voxelTris[j, 0]]);
                vertices.Add(pos + VorelData.voxelVerts[VorelData.voxelTris[j, 1]]);
                vertices.Add(pos + VorelData.voxelVerts[VorelData.voxelTris[j, 2]]);
                vertices.Add(pos + VorelData.voxelVerts[VorelData.voxelTris[j, 3]]);
                AddTextture(world.block[blockID].GetTextureId(j));//每个面加上对应的纹理
                triangles.Add(vertexIndex);
                triangles.Add(vertexIndex + 1);
                triangles.Add(vertexIndex + 2);
                triangles.Add(vertexIndex + 2);
                triangles.Add(vertexIndex + 1);
                triangles.Add(vertexIndex + 3);
                vertexIndex += 4;
                //将数据添加至列表
            }//检测是否有不必要的面
        }
    }
    public void CreateMesh()
    {
        Mesh mesh = new Mesh();
        mesh.vertices = vertices.ToArray();
        mesh.triangles = triangles.ToArray();
        mesh.uv = uvs.ToArray();
        mesh.RecalculateNormals();
        meshfilter.mesh = mesh;//画出方块,每个面由两个三角组成(参考VorelData.cs)
    }
    public void AddTextture(int textureID)
    {
        float y = textureID / VorelData.textrueAtlasSizeInBlocks;
        float x = textureID - (y * VorelData.textrueAtlasSizeInBlocks);
        y *= VorelData.NormailzedBlockTextrueSize;
        x *= VorelData.NormailzedBlockTextrueSize;//得到每个方块上纹理在总图片中的坐标
        y = 1.0f - y - VorelData.NormailzedBlockTextrueSize;
        uvs.Add(new Vector2(x + 0.001f, y + 0.001f));
        uvs.Add(new Vector2(x + 0.001f, y + VorelData.NormailzedBlockTextrueSize - 0.001f));
        uvs.Add(new Vector2(x + VorelData.NormailzedBlockTextrueSize - 0.001f, y + 0.001f));
        uvs.Add(new Vector2(x + VorelData.NormailzedBlockTextrueSize - 0.001f, y + VorelData.NormailzedBlockTextrueSize - 0.001f));//使坐标从左上角开始计算,0.001是为了防止图片边缘与其他图片混合
    }
}
public class ChunkCoord
{
    public int x;
    public int z;
    public ChunkCoord(int x_x, int z_z)
    {
        x = x_x;
        z = z_z;
    }
}//建立每个chunk的坐标

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class world : MonoBehaviour
{
    public Material material;
    public Block[]block;
    public void Start()
    {
        GenerateWorld();
    }
    public void GenerateWorld()
    {
        for(int i = 0; i < VorelData.worldSizeInChunk; i++) 
        {
            for(int j = 0; j < VorelData.worldSizeInChunk; j++) 
            {
                Chunk newChunk = new Chunk(new ChunkCoord(i, j), this);//连接到chunk,将Chunk.cs中的内容移动到这里并生成chunk
            }
        }
    }
}//生成多个chunk
[System.Serializable]
public class Block
{
    public string blockName;//方块名称
    public bool isSolid;//判断是否为实体方块
    [Header("Texture Values")]
    public int backFaceTextTure;
    public int frontFaceTextTure;
    public int topFaceTextTure;
    public int bottonFaceTextTure;
    public int leftFaceTextTure;
    public int rightFaceTextTure;//六个面不同的数据存放纹理
    public int GetTextureId(int faceIndex)
    {
       switch(faceIndex)
       {
            case 0:
            {
                return backFaceTextTure;
            }
            case 1:
            {
                return frontFaceTextTure;
            }
            case 2:
            {
                return topFaceTextTure;
            }
            case 3:
            {
                return bottonFaceTextTure;
            }
            case 4:
            {
                return leftFaceTextTure;
            }
            case 5:
            {
                return rightFaceTextTure;
            }
            default:
            {
                Debug.Log("Error,faceIndex is " + faceIndex + ",it is not in scope.");
                return 0;
            }
       }
    }//每个面不同纹理
}//存储一个方块的所有数据

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class VorelData
{
    public static readonly int chunkLength = 4;
    public static readonly int chunkWidth = 4;
    public static readonly int chunkHeight = 32;//地图大小
    public static readonly int textrueAtlasSizeInBlocks = 16;//素材中的图片横竖分成七份
    public static readonly int worldSizeInChunk = 16;
    public static float NormailzedBlockTextrueSize
    {
        get
        {
            return 1.0f / (float)textrueAtlasSizeInBlocks;
        }
    }//每个图片的街区
    public static readonly Vector3[] voxelVerts = new Vector3[8]
    {
        new Vector3(0.0f, 0.0f, 0.0f),
        new Vector3(1.0f, 0.0f, 0.0f),
        new Vector3(1.0f, 1.0f, 0.0f),
        new Vector3(0.0f, 1.0f, 0.0f),
        new Vector3(0.0f, 0.0f, 1.0f),
        new Vector3(1.0f, 0.0f, 1.0f),
        new Vector3(1.0f, 1.0f, 1.0f),
        new Vector3(0.0f, 1.0f, 1.0f)//方块8个顶点坐标
    };//存储每个方块的顶点数据的数组(在Chunk.cs中引用)
    public static readonly Vector3[] faceCheck = new Vector3[6]
    {
        new Vector3(0.0f, 0.0f, -1.0f),
        new Vector3(0.0f, 0.0f, 1.0f),
        new Vector3(0.0f, 1.0f, 0.0f),
        new Vector3(0.0f, -1.0f, 0.0f),
        new Vector3(-1.0f, 0.0f, 0.0f),
        new Vector3(1.0f, 0.0f, 0.0f)
    };//检查看不到的方块表面,并不绘制这些面,节省资源(在Chunk.cs中引用)
    public static readonly int[,] voxelTris = new int[6, 4]
    {
        {0, 3, 1, 2},
        {5, 6, 4, 7},
        {3, 7, 2, 6},
        {1, 5, 0, 4},
        {4, 7, 0, 3},
        {1, 2, 5, 6}
    };//一个正方体的面由两个三角组成,这里记录了两个三角绘制时需要的顶点(在Chunk.cs中引用)
    public static readonly Vector2[] voxelUvs = new Vector2[4]
    {
        new Vector2(0.0f, 0.0f),
        new Vector2(0.0f, 1.0f),
        new Vector2(1.0f, 0.0f),
        new Vector2(1.0f, 1.0f)
    };//物体表面纹理的坐标
}

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-02-08 05:33
    关注
    不知道你这个问题是否已经解决, 如果还没有解决的话:

    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 创建了问题 2月7日

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题