【第006问 Unity中如何把Texture中指定位置区域像素显示到Mesh上?】

Unity中如何把Texture中的指定区域显示在Mesh对象上?

一、如何把下图数字按照1-16的先后顺序显示出来?

在这里插入图片描述

二、分析

在UGUI或者是NGUI中我们都会用到图集,图集就是把许多图片,通过一系列排序组合成一张图片;也就是多张图的使用变成对一张图片的使用,如果这里需要对上面这张图片分别显示单个数字,也就是按照从1-16或者随机显示任意一个数字该怎么显示呢?这里需要从以下几个方面入手:

  • 首先需要知道该图片的大小【512*512】
  • 每个数字所占区域的大小【128*128】
  • 无论图片大小,图片的取值范围是0-1,也就是UV的坐标范围;
  • 根据每个数字所占的大小和图片的宽高比例,计算出每个数字在Texture中的4个【左下角、左上角、右上角、右下角】UV坐标
  • 计算出UV坐标以后,把对应的UV坐标赋值给对应的顶点,即可渲染显示出对应区域的像素图片

三、实例分析 如何计算出下图中数字6的4个UV坐标值

在这里插入图片描述

  • 首先需要知道每个Mesh有2个三角形组成,6个顶点组成;但这里的数字6的Mesh共用1、3顶点【也可以通用4、2】,所以这里只需要计算出1234的对应UV坐标即可。
  • 计算顶点1的UV坐标UV(1)=(128/512,128/512)
  • 计算顶点2的UV坐标UV(2)=(128/512,256/512)
  • 计算顶点3的UV坐标UV(3)=(256/512,256/512)
  • 计算顶点4的UV坐标UV(4)=(256/512,128/512)

这样就计算出数字6的4个UV坐标,然后通过如下代码赋值即可:

 	List<Vector2> uvs = new List<Vector2>(); 
	uvs.Add(leftBottomPoint);
	uvs.Add(leftTopPoint);
	uvs.Add(rightTopPoint);
	uvs.Add(rightBottomPoint);
	mesh.SetUVs(0, uvs);

四、动画效果演示

在这里插入图片描述

五、源码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ValakiUvDemo : MonoBehaviour
{
    private Mesh mesh;
    private MeshFilter meshFilter;
    private float defaultImgWidth = 512;
    private float defaultImgHeight = 512;
    float characterWidth = 128;
    float characterHeight = 128;

    // Start is called before the first frame update
    void Start()
    {
        CreateMesh();
        StartCoroutine(DelayLoopIndex(0));
    }


    /// <summary>
    /// 创建Mesh
    /// </summary>
    void CreateMesh()
    {
        meshFilter = gameObject.GetComponent<MeshFilter>();

        mesh = new Mesh();
        meshFilter.mesh = mesh;

        int width = 10;
        Vector3[] vertexts = new[]
        {
            new Vector3(0, 0, 10),
            new Vector3(0, width, 10),
            new Vector3(width, width, 10),
            new Vector3(width, 0, 10),
        };

        int[] indices = new int[] {0, 1, 2, 0, 2, 3};
        mesh.SetVertices(vertexts);
        mesh.SetTriangles(indices, 0);
    }

    IEnumerator DelayLoopIndex(int index)
    {
        ShowImageByIndex(index);
        yield return new WaitForSeconds(0.2f);
        index++;
        StartCoroutine(DelayLoopIndex(index));
    }


    /// <summary>
    /// 根据索引显示UV图片
    /// </summary>
    /// <param name="index"></param>
    void ShowImageByIndex(int index)
    {
        //uv的坐标是从左下角开始的 那么索引也是从0 开始

        int rowIndex = index % 4;
        int colIndex = index / 4;

        //左下角
        Vector2 leftBottomPoint = Vector2.zero;
        leftBottomPoint.x = rowIndex * characterWidth / defaultImgWidth;
        leftBottomPoint.y = colIndex * characterHeight / defaultImgHeight;


        //左上角
        Vector2 leftTopPoint = Vector2.zero;
        leftTopPoint.x = leftBottomPoint.x;
        leftTopPoint.y = (colIndex + 1) * characterHeight / defaultImgHeight;

        //右上角
        Vector2 rightTopPoint = Vector2.zero;
        rightTopPoint.x = (rowIndex + 1) * characterWidth / defaultImgWidth;
        rightTopPoint.y = leftTopPoint.y;

        //右下角
        Vector2 rightBottomPoint = Vector2.zero;
        rightBottomPoint.x = rightTopPoint.x;
        rightBottomPoint.y = leftBottomPoint.y;

        List<Vector2> uvs = new List<Vector2>(); 
        uvs.Add(leftBottomPoint);
        uvs.Add(leftTopPoint);
        uvs.Add(rightTopPoint);
        uvs.Add(rightBottomPoint);
        mesh.SetUVs(0, uvs);
    }
}
结语

这个春节是确实冷,真真儿的叫冻成狗【valaki

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值