2018-12-18 03:47:52 ChinarCSDN 阅读数 641

Chinar blog www.chinar.xin

TexturePacker

Unity 图集制作工具



本文提供全流程,中文翻译。

Chinar 的初衷是将一种简单的生活方式带给世人

使有限时间 具备无限可能

Chinar —— 心分享、心创新!

学习使用 TexturePacker Unity 制作图集,并提供动态加载

为新手节省宝贵的时间,避免采坑!

Chinar 教程效果:
在这里插入图片描述



全文高清图片,点击即可放大观看 (很多人竟然不知道)


1

Intro —— 简介


为什么使用图集?

简单说就是:将大量的小图,合并到一张大图上,可以有效的降低 Drawcall

绘制一个图像需要提交图片(纹理)到显存,然后再进行绘制显示到屏幕上

在这个过程中 CPU 会产生一次 DrawCall ,也就是说绘制 88 张图片就要产生 88 次DrawCall

这显然非常消耗性能。图集就是为了解决此类问题

1. 减少性能消耗
2. 分类明确,易于管理
3.一次加载或者卸载完成多图片的处理,提高了运行效率

Unity 官方模糊了图集的概念,使开发者专注于开发,在打包时才会将图片进行合并

自行打包图集,网络大神各抒己见,皆有特色,想要官方的可以自行搜索

Chinar 的风格大家都懂,什么高效来什么!只为大家介绍更为好用的插件

我们今天的主角:TexturePacker、TexturePackerImporter


2

Download —— 下载、安装



TexturePacker 是一个独立的软件程序,支持多个引擎,安装后记得选择Unity平台

TexturePackerImporterUnity Store中免费插件,搜索下载导入工程即可

举个例子

点击下载 —— TexturePacker (官网)

点击下载 —— TexturePacker X64 (Chinar免费)
在这里插入图片描述

在这里插入图片描述


3

Import Plugin —— 导入插件


TexturePacker 安装完成后,打开先不管,我们先来创建一个Unity工程,导入TexturePackerImporter

Ctrl+9 快捷键 打开 Asset Store 资源商店

→→搜索 TexturePacker Importer,下载并导入工程

先导入这个插件是为了适配之后 TexturePacker 生成并导入Unity 中的文件。直接进行处理,使一张大图自动切分
举个例子
在这里插入图片描述


4

Texture usage —— 软件用法


我们回到 TexturePacker 软件界面,来简单学习下如何制作与导出文件

图片直接拖进来,算法会自动将所有小图切割合并到一张大图中,细节 Chinar 做的图已经很详细了

最后点击publish sprite sheet 会将生成的图集数据文件直接放到我们选择的目录中

(推荐直接放到 Unity 项目中。为了规范性,Chinar 放在了 Resources/Texture/Atlas 下)

举个例子
在这里插入图片描述
在这里插入图片描述

为了便于让初学者理解流程,我还准备了动图

在这里插入图片描述


5

Unity Project —— 项目数据


切换到 Unity 软件界面,等待文件编译

由于我们之前先导入了 TexturePacker Importer ,所以图片数据导入到 Unity 中会自动切分,我们只需直接使用即可

直接将sprite拖到UI image 组件上即可,用法上没什么不同

举个例子
在这里插入图片描述


6

dynamic loading —— 动态加载 Sprite


多数情况下,除了通过拖拽的方式,我们还需要用代码来动态的改变 UI 元素

很多大神,提出直接将UI做成预设物,通过加载预设的方式来实现动态改变UI。这样做有优点也有缺点,对于初学者来讲维护不方便,而且需要建立大量的预设物,量大后会造成不便。

Chinar 推荐方式:

注意: 需将图集文件放在 Resources / 其子目录下,用数据类型散列表(字典) Dictionary 来记录实现,动态加载图片
举个例子
在这里插入图片描述


7

Lookup function —— 查找函数


我们需要一个查找函数,以便我们获取目标图集中的对应精灵

重点函数:Object[] atlas = Resources.LoadAll(spriteAtlasPath);
目录中,图片数据 “Chinar”是一张.png图片 ,需放在 Resources 目录下
因图片是单个文件, 如果用 Resources.Load只能返回一个 Object 对象,这里采用 Resources.LoadAll 返回 Object[]

我封装了一个极简的静态通用函数,适用于内外部数据的读取,无需挂载直接调用

将获取对应名称的 UI Sprite简化到一行代码

LoadSprite(string atlasPath, string spriteName, bool isResources = true)

举个例子

using UnityEngine;
using System.Collections.Generic;


/// <summary>
/// 静态函数,无需挂载
/// 主函数:LoadSprite()
/// </summary>
public class ChinarAtlas
{
    private static readonly Dictionary<string, Object[]> _atlasDic = new Dictionary<string, Object[]>(); //图集字典


    /// <summary>
    /// 加载对应图集中,对应名称的精灵图片
    /// </summary>
    /// <param name="atlasPath">图集路径</param>
    /// <param name="spriteName">精灵名称</param>
    /// <param name="isResources">默认内部 Resources 加载,false 时,通过 AssetBundle 方式加载</param>
    /// <returns>Sprite</returns>
    public static Sprite LoadSprite(string atlasPath, string spriteName, bool isResources = true)
    {
        Sprite sprite                                = null;                                                               //字典中包含 目标图集
        if (_atlasDic.ContainsKey(atlasPath)) sprite = SpriteFormAtlas(_atlasDic[atlasPath], spriteName);                  //得到该图集中对应名称的 Sprite
        if (sprite != null) return sprite;                                                                                 //返回找到的 Sprite
        Object[] atlas = isResources ? Resources.LoadAll(atlasPath) : AssetBundle.LoadFromFile(atlasPath).LoadAllAssets(); //选择内外部加载方式
        _atlasDic.Add(atlasPath, atlas);                                                                                   //到字典中
        sprite = SpriteFormAtlas(atlas, spriteName);                                                                       //找到 Sprite
        return sprite;                                                                                                     //返回找到的 Sprite
    }


    /// <summary>
    /// 删除图集缓存
    /// </summary>
    /// <param name="atlasPath">图集路径</param>
    public static void DeleteAtlas(string atlasPath)
    {
        if (_atlasDic.ContainsKey(atlasPath)) _atlasDic.Remove(atlasPath);
    }


    /// <summary>
    /// 遍历图集并找出 Sprite
    /// </summary>
    /// <param name="atlas">Object[]</param>
    /// <param name="spriteName">精灵名称</param>
    /// <returns>Sprite</returns>
    private static Sprite SpriteFormAtlas(Object[] atlas, string spriteName)
    {
        foreach (var obj in atlas)
        {
            if (obj != null && obj is Sprite && obj.name == spriteName) return (Sprite) obj;
        }

        Debug.LogWarning("图集中未查找到名为:<" + spriteName + ">的精灵");
        return null;
    }
}

8

Dynamic loading usage —— 动态加载用法


直接调用函数 ChinarAtlas.LoadSprite(图集文件全路径,目标Sprite名称,(不填) 默认Resources加载/false 是AssetBundle)

极尽封装,就是这么简单
举个例子

using UnityEngine;
using UnityEngine.UI;


/// <summary>
/// 动态读取数据、添加/改变UI元素
/// </summary>
public class ChinarDemo : MonoBehaviour
{
    private AssetBundle ab; //AB包对象


    public Image UiResourcesImage
    {
        get { return GameObject.Find("Resources Image").GetComponent<Image>(); }
    }

    public Image UiAssetBundleImage
    {
        get { return GameObject.Find("AssetBundle Image").GetComponent<Image>(); }
    }


    void Start()
    {
        ResourcesLoadMethod();
        AssetBundleLoadMethod();
    }


    /// <summary>
    /// 第一种:Resources加载 —— 内部 
    /// </summary>
    private void ResourcesLoadMethod()
    {
        UiResourcesImage.sprite = ChinarAtlas.LoadSprite("Texture/Atlas/Chinar", "Chinar1");
    }


    /// <summary>
    /// 第二种:AssetBundle加载 —— 外部 
    /// </summary>
    private void AssetBundleLoadMethod()
    {
        UiAssetBundleImage.sprite = ChinarAtlas.LoadSprite(Application.streamingAssetsPath + "/ChinarAssetBundles/atlas/chinar.unity3d", "Chinar2", false);
    }
}

在这里插入图片描述


9

Share —— 项目分享



项目文件为 unitypackage 文件包:

下载导入 Unity 即可使用

举个例子
开源,促进发展

CSDN (积分支持)

NetDisk (Chinar 免费)


10

AssetBundle —— AB包知识 (扩展)


如果是初学者不太了解 AssetBundle 知识的话

给大家提供2个教程。便于学习 打包、读取
举个例子

Unity 打包 AssetBundle 资源教程

Unity 读取 AssetBundle 资源教程(所有读取方式)


支持

May Be —— 开发者,总有一天要做的事!


拥有自己的服务器,无需再找攻略

Chinar 提供一站式《零》基础教程

使有限时间 具备无限可能!

Chinar 知你所想,予你所求!( Chinar Blog )


Chinar

END

本博客为非营利性个人原创,除部分有明确署名的作品外,所刊登的所有作品的著作权均为本人所拥有,本人保留所有法定权利。违者必究

对于需要复制、转载、链接和传播博客文章或内容的,请及时和本博主进行联系,留言,Email: ichinar@icloud.com

对于经本博主明确授权和许可使用文章及内容的,使用时请注明文章或内容出处并注明网址

2017-03-02 20:59:29 clleop 阅读数 3191
笔者用的版本是Unity3D 5.5.1

注:AssetBundle 可以包含模型,材质,纹理和场景文件等资源。但是 AssetBundle 不能包含脚本。
 
1.新建Unity3D项目,接着 File -> New Scene 命名 abTest。
2.创建AssetBundles文件夹(放打包资源)、Editor文件夹(放编辑器脚本)、创建Resource文件夹(放预设资源)
Unity3D特殊文件夹参考(http://www.xuanyusong.com/archives/3229

3.在层级视图 (Hierarchy)创建一个Cube,并将Cube拖至Resource文件夹。


4.选中Cube预设,在检视面板(Inspector)下方有个AsetBundle选项,点击右侧选项New资源名称(例如:cube)

5.在Editor创建BuildAssetBundle.cs
using UnityEditor;
using UnityEngine;

namespace Assets
{
    public class BuildAssetBundle
    {
        [MenuItem("Custom/Build Asset Bundle")]
        static void buildAssetBundle()
        {
            string str = Application.dataPath + "/AssetBundles";
            //打包资源路径(参数1:资源保存路径   参数2:未了解    参数3:选择平台,各个平台间不能混用)
            BuildPipeline.BuildAssetBundles(str, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows);
        }
    }
}

通过编辑器打包生成AssetBundle资源

6.接下来就是创建资源加载脚本 LoadAssetBundle.cs
using UnityEngine;
using System.Collections;

public class LoadAssetBundle : MonoBehaviour
{

    private GameObject curObj;
    private string filePath = "";
    private string ObjName = "cube";

    void Start()
    {
        filePath = "file://" + Application.dataPath + "/AssetBundles/" + ObjName;
        StartCoroutine(GetAssetBundleObj(filePath));
    }

    IEnumerator GetAssetBundleObj(string filePath)
    {
        WWW www = new WWW(filePath); //利用www类加载
        yield return www;
        AssetBundle curBundleObj = www.assetBundle; //获得AssetBundle
        AssetBundleRequest obj = curBundleObj.LoadAssetAsync(ObjName, typeof(GameObject)); //异步加载GameObject类型
        yield return obj;
        curObj = Instantiate(obj.asset) as GameObject;
        curObj.name = "cube";
        yield return null;
        curBundleObj.Unload(false);     //卸载所有包含在bundle中的对象,已经加载的才会卸载
        //www.Dispose(); //Unity官方的角度已不再推荐使用Dispose()。官方例子也没有了Dispose()
    }
}
7.将LoadAssetBundle脚本拖至Camera,然后运行程序。

2013-11-05 11:40:32 qn9663 阅读数 1500

      之前有一段时间在想可视化脚本做游戏的可行性.首先看了Playmaker,感觉非常强大,把脚本API封装成脚本组件,把判断语句也封装了.对调用流程用流程图显示,并且可以看到执行过程,我觉得这点上面做的非常好.看了其脚本的变量定义,其实我觉得她有一个缺点,她不能访问宿主变量,也就会吧底层完全分离.考虑到需求,觉得目前她不合适做大项目.

      后来用了uScript,发现她是通过模块(类似UML)那样的界面做好流程,然后生成脚本代码,也就意味着她的想法是通过界面生成原生脚本,这样的优点是代码执行效率高,可以随意访问宿主变量.确实变的灵活不少.试用后发现,事件多了,变量多了,她也很麻烦,比如if((a || b || c) && d)和对象引用后,她可能要很多可视化的逻辑控制器完成.结果就是可视化界面看起来盘大无比.失去了可视化的优势.


总结:

       不管是Playermaker还是后者,都有一样的问题

      1,不能做宏定义.后期移植麻烦

      2,不能做批量查找和替换,后期修改很麻烦.

      3,不能做查找,比如找到响应的事件逻辑段.

      4,对于一些不是RPG,ARPG,类型的游戏不适用.

我当初的需求其实是想有一个可视化可以图形化显示我的函数调用流程.

综合因素,我不选择可视化脚本.因为U3D已经是可视化引擎了.

2018-08-07 11:35:30 chengxunxinshou 阅读数 415

欢迎使用Markdown编辑器写博客

本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦:

  • Markdown和扩展Markdown简洁的语法
  • 代码块高亮
  • 图片链接和图片上传
  • LaTex数学公式
  • UML序列图和流程图
  • 离线写博客
  • 导入导出Markdown文件
  • 丰富的快捷键

快捷键

  • 加粗 Ctrl + B
  • 斜体 Ctrl + I
  • 引用 Ctrl + Q
  • 插入链接 Ctrl + L
  • 插入代码 Ctrl + K
  • 插入图片 Ctrl + G
  • 提升标题 Ctrl + H
  • 有序列表 Ctrl + O
  • 无序列表 Ctrl + U
  • 横线 Ctrl + R
  • 撤销 Ctrl + Z
  • 重做 Ctrl + Y

Markdown及扩展

Markdown 是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档,然后转换成格式丰富的HTML页面。 —— [ 维基百科 ]

使用简单的符号标识不同的标题,将某些文字标记为粗体或者斜体,创建一个链接等,详细语法参考帮助?。

本编辑器支持 Markdown Extra ,  扩展了很多好用的功能。具体请参考Github.

表格

Markdown Extra 表格语法:

项目 价格
Computer $1600
Phone $12
Pipe $1

可以使用冒号来定义对齐方式:

项目 价格 数量
Computer 1600 元 5
Phone 12 元 12
Pipe 1 元 234

定义列表

Markdown Extra 定义列表语法:
项目1
项目2
定义 A
定义 B
项目3
定义 C

定义 D

定义D内容

代码块

代码块语法遵循标准markdown代码,例如:

@requires_authorization
def somefunc(param1='', param2=0):
    '''A docstring'''
    if param1 > param2: # interesting
        print 'Greater'
    return (param2 - param1 + 1) or None
class SomeClass:
    pass
>>> message = '''interpreter
... prompt'''

脚注

生成一个脚注1.

目录

[TOC]来生成目录:

数学公式

使用MathJax渲染LaTex 数学公式,详见math.stackexchange.com.

  • 行内公式,数学公式为:Γ(n)=(n1)!nN
  • 块级公式:

x=b±b24ac2a

更多LaTex语法请参考 这儿.

UML 图:

可以渲染序列图:

Created with Raphaël 2.1.2张三张三李四李四嘿,小四儿, 写博客了没?李四愣了一下,说:忙得吐血,哪有时间写。

或者流程图:

Created with Raphaël 2.1.2开始我的操作确认?结束yesno
  • 关于 序列图 语法,参考 这儿,
  • 关于 流程图 语法,参考 这儿.

离线写博客

即使用户在没有网络的情况下,也可以通过本编辑器离线写博客(直接在曾经使用过的浏览器中输入write.blog.csdn.net/mdeditor即可。Markdown编辑器使用浏览器离线存储将内容保存在本地。

用户写博客的过程中,内容实时保存在浏览器缓存中,在用户关闭浏览器或者其它异常情况下,内容不会丢失。用户再次打开浏览器时,会显示上次用户正在编辑的没有发表的内容。

博客发表后,本地缓存将被删除。 

用户可以选择 把正在写的博客保存到服务器草稿箱,即使换浏览器或者清除缓存,内容也不会丢失。

注意:虽然浏览器存储大部分时候都比较可靠,但为了您的数据安全,在联网后,请务必及时发表或者保存到服务器草稿箱

浏览器兼容

  1. 目前,本编辑器对Chrome浏览器支持最为完整。建议大家使用较新版本的Chrome。
  2. IE9以下不支持
  3. IE9,10,11存在以下问题
    1. 不支持离线功能
    2. IE9不支持文件导入导出
    3. IE10不支持拖拽文件导入


  1. 这里是 脚注内容.
2012-07-18 10:40:23 Koupoo 阅读数 1163




如果你不会写代码 或者是懒得写代码
那么这款插件完全能满足你的要求。
事实上这款插件不仅仅能不用写代码就完整的制作出一款游戏
更令我意外的是他还有Debug的功能 而且也是图形化操作!
无论是游戏制作流程还是调试 全都一览无余 非常的方便


Unity3D视觉脚本工具Playmaker发布1.33版本

Playmaker让你快速创建游戏原型,A.I.行为,动画图形,互动物体,引擎内置剪切场景,互动攻略等。
Playmaker让全部团队成员从中获益 – 不论是美术,设计师,还是程序员。美术和设计师能够使用成千上百的与架构动作来编写互动内容,程序员则能够在用户友好的视觉状态编辑器中编写新的动作并演示它们。
Playmaker 1.1新功能和动作
- iTween:强大的iTween库带来全面支持,包括激活的路径编辑。让开发者简单创建出流畅的动作和效果!
- iOS/Android:快速的衔接移动设备动作,包括触摸时间,加速输入,重击动作和GPS!
- 模板:改进了复制/粘贴和模板的工作流。开发者能够复制全部FSM或创建一个模板库并快速的将它们应用到新的游戏对象上。
- 执行:使用新的PlayMakerGUI组件改进了OnGUI动作的执行。如果不适用OnGUI的话就不会耗费精力。
- GUI编辑:在游戏没有运行的时候实时的编辑GUI控制!
- PlayerPrefs:在运行时段保存/载入变量。
此外,工作流的改善让编辑过程更加流畅,新的样本场景帮助开发者实现地面奔跑。






官网地址:http://hutonggames.com/company.html
youtube:http://www.youtube.com/user/HutongGamesLLC?feature=watch
(以上地址均需翻墙)
assetStore 有售Web3D纳金网www.narkii.com


哈哈,这个爬来不容易!祝愿大家更上一层楼。

unity3d 游戏内付费

阅读数 2847

没有更多推荐了,返回首页