当前位置: 首页 > article >正文

Unity使用打成图集的Sprite作为模型贴图使用的问题

  大家好,我是阿赵。
  有时候用Unity引擎做项目的时候,会遇到这样的需求,美术做了一些模型或者特效,然后策划想在游戏运行的时候,读取一些游戏图标放在特效或者模型上面当做贴图使用。
  这个需求实现起来很简单,比如这样:
在这里插入图片描述

  我这里随便找了一些icon图片,在Unity里面设置成了Sprite的贴图类型。并且输入了Packing Tag,意思是这些图片将会作为一个图集来使用。
在这里插入图片描述

  然后我建了一个面片,当做模型。
在这里插入图片描述

  接下来写代码了,代码很简单:

    private void SetTextureBySprite(Sprite sp)
    {
        render.material.SetTexture("_MainTex", sp.texture);
	}

  在编辑器里面执行代码,会发现贴图被赋予上去了:
在这里插入图片描述

  不过,如果我们实际打包游戏运行之后,会发现效果是不对的:
在这里插入图片描述

  为什么会出现编辑器和实际打包运行效果不一致的情况呢?
  这是因为上面我设置了Packing Tag,这样,同一个Tag的图片,将会打包成一个图集。
  由于打图集的时间比较长,所以一般来说在编辑器环境下,会把图集取消掉:
在这里插入图片描述

  勾选Disabled或者Enabled For Builds,在编辑器都是不打图集就运行的。
  如果想在编辑器里面就能看到图集效果,要选Always Enabled,这样编辑器里面运行的效果就和打包之后的效果一致了。不过这样每次图集里面的图片有改动时,Unity会先重新生成图集,会比较慢。
在这里插入图片描述

  用SpritePacker看一下:
在这里插入图片描述
在这里插入图片描述

  在实际运行中,这些icon的贴图不再是单张的Texture,而是组合成这样一张贴图了。
  再查看一下Unity的API:
在这里插入图片描述

  里面很明确的说明了,假如packed了,sprite.texture指向的是整个图集。
  怎样解决这个问题呢?
  再继续看Unity的API:
在这里插入图片描述

  Unity提供了textureRect的API,可以把原来的Sprite在现在整张图集所占的位置通过Rect返回。于是我们就可以用这个Rect来计算,实际的Sprite占整张图集的位置,也就是求出了采样的UV坐标了:

    private void SetTextureBySpriteRect(Sprite sp)
    {
        Texture2D tex = sp.texture;
        float texWidth = tex.width;
        float texHeight = tex.height;
        Rect rect = sp.textureRect;
        Vector4 uv =new  Vector4(rect.width / texWidth, rect.height / texHeight, rect.x/tex.width, rect.y/tex.height);
        render.material.SetTexture("_MainTex", sp.texture);
        render.material.SetVector("_MainTex_ST", uv);
	}

  这里注意的是,求出的UV,是通过SetVector设置进材质球的,用的变量名_MainTex_ST是对应主贴图_MainTex的,熟悉写Shader的朋友应该都知道,你声明了一张贴图置换,贴图名称后面接_ST就是这张贴图的UV。
  所以这里通过_MainTex_ST设置UV不是固定的,要根据你实际的贴图名称来改。
  最后运行代码,这次显示就应该是正确的了,其实这里面的原理,和之前说的地形局部采样UV是一样的。


http://www.kler.cn/news/163322.html

相关文章:

  • ubuntu server 20.04 备份和恢复 系统 LTS
  • 小红书用户采集工具:掌握策略,轻松吸引潜在客户
  • 【flink番外篇】1、flink的23种常用算子介绍及详细示例(1)- map、flatmap和filter
  • 【链表Linked List】力扣-82 删除链表中的重复元素II
  • velocity-engine-core是什么?Velocity模板引擎的使用
  • pr抖音素材42个手机竖屏抖音视频转场特效PR剪辑模板
  • 浅谈5G基站节能及数字化管理解决方案的设计与应用-安科瑞 蒋静
  • 智慧城市是什么?为什么要建智慧城市?
  • 8_企业架构缓存中间件分布式memcached
  • 云原生系列1
  • 力扣(LeetCode)1038. 从二叉搜索树到更大和树(C++)
  • 卷积之后通道数为什么变了
  • java实现冒泡排序算法
  • 做题笔记:SQL Sever 方式做牛客SQL的题目--SQL156
  • 什么是Nginx反向代理?Nginx反向代理配置指南
  • Centos图形化界面封装OpenStack Centos镜像
  • Kubernetes(K8s)数据存储-09
  • c/c++中一些不常用但有用的知识
  • 【数据结构】插入排序,希尔排序,选择排序,堆排序,冒泡排序
  • 限流算法,基于go的gRPC 实现的
  • 阿里云磁盘在线扩容
  • 生信技能30 - 获取CNV开始位置和结束位置所在的染色体区带
  • L1-028:判断素数
  • JavaScript常用技巧专题一
  • Flink流批一体计算(23):Flink SQL之多流kafka写入多个mysql sink
  • 达梦数据库dm8守护集群部署手册
  • 浅谈Elastic Stack组件集成和应用
  • (时域和频域)控制系统响应速度和稳定性分析
  • 三种定时任务总结
  • C# .NET平台提取PDF表格数据,并转换为txt、CSV和Excel表格文件