描述
开 本: 16开纸 张: 胶版纸包 装: 平装是否套装: 否国际标准书号ISBN: 9787302379904
这本书是作者多年来游戏开发经验的总结,可以说毫无保留地披露了很多游戏开发经验和心得,其中有相当多内容你在其他书中是根本找不到的,通过学习本书,你可以快速找到Unity开发方面的工作,或者你可以使用Unity开发出自己的商业级游戏。
本书**版出版后受到行业人士的广泛赞誉,并长期占据同类书排行榜**名,被数十所高校和培训学校选为教材,也被很多Unity游戏开发公司指定为员工读本,成为Unity开发人员的**,这足以说明本书价值。我认为本书的优秀之外就在于它完全来自于实践,是实际游戏开发工程的展现,是作者宝贵开发经验的无私分享,这与很多只讲知识点或菜单命令功能的同类书完全不同。
第2版是根据全新的Unity4.6版本全新改写,除了仍保留通篇实例的特色外,全书做了大量改进,新增了如编辑器扩展,新UI,2D游戏示例,以及使用Python脚本批量编译Android工程等大量内容,几乎重写了读者关注的网络部分,还对原有的代码进行了优化,使得本书显得更高效、更深入、更完整。
如果你想成为专业的Unity游戏开发工程师,一本好书可让你少走弯路,快速登堂入室,本书正是这样一本会让你受益非浅的精品之作。
本书以实例教学为主线,循序渐进地介绍了Unity在游戏开发方面的不同功能。第1章,由零开始,引导读者熟悉Unity编辑器的各个功能模块,这部分内容对Unity程序员、美工和策划都有帮助。第2~4章是3个不同特色的3D游戏实例,让读者对Unity游戏开发有一个较全面的认识。第5章是一个2D游戏实例,全方位地介绍了Unity在2D游戏方面的应用。第6章和第7章,重点介绍了Unity在网络方面的应用。第8~10章介绍了如何将Unity游戏移植到网页、iOS和Android平台。另外,本书最后附有C#语言的快速教程,帮助缺乏程序开发基础的读者快速入门,同时也包括Unity编辑器菜单栏的中英文对照表供读者查阅。
本书还提供了所有实例的源代码与素材文件,供读者上机练习使用,读者可从网上下载本书资源文件。下载地址:http://
本书适用于广大游戏开发人员、游戏开发爱好者、软件培训机构,以及计算机专业的学生等。
第1章 Unity入门
(重要改进:与第一版相比,合并了原来的第1章和第5章,修改了
Shader部分的内容。)
1.1 Unity简介
1.2 运行Unity
1.2.1 Unity的版本
1.2.2 安装Unity
1.2.3 在线激活Unity
1.2.4 运行示例工程
1.2.5 安装Visual Studio 6
1.3 创建一个“Hello World”程序
1.4 调试程序
1.4.1 显示Log
1.4.2 设置断点
1.5 光照
1.5.1 光源类型
1.5.2 环境光与雾
1.5.3 Lightmapping
1.5.4 Light Probe
1.6 Terrain
1.7 Skybox
1.8 粒子
1.9 物理
1.10 自定义Shader
1.10.1 自定义字体
1.10.2 创建Shader
1.11 游戏资源
1.11.1 贴图
1.11.2 3ds Max静态模型导出
1.11.3 3ds Max动画导出
1.11.4 Maya模型导出
1.12 Unity动画系统
1.13 美术资源的优化
小结
第2章 太空射击游戏
(重要改进:与第一版相比,改进了一些细节,同时增加了内容,包
括用鼠标控制飞机、创建精准的碰撞模型、自动创建
Prefab和代码优化等内容。)
2.1 浅谈游戏开发
2.1.1 开始一个游戏项目
2.1.2 阶段性成果
2.1.3 策划
2.1.4 编写脚本
2.1.5 美术
2.1.6 QA测试
2.1.7 发布游戏
2.2 游戏策划
2.2.1 游戏介绍
2.2.2 游戏UI
2.2.3 主角
2.2.4 游戏操作
2.2.5 敌人
2.3 导入美术资源
2.4 创建场景
2.4.1 创建火星背景
2.4.2 设置摄像机和灯光
2.5 创建主角
2.5.1 创建脚本
2.5.2 控制飞船移动
2.5.3 创建子弹
2.5.4 创建子弹Prefab
2.5.5 发射子弹
2.6 创建敌人
2.7 物理碰撞
2.7.1 添加碰撞体
2.7.2 触发碰撞
2.8 高级敌人
2.8.1 创建敌人
2.8.2 发射子弹
2.9 声音与特效
2.10 敌人生成器
2.11 游戏管理器
2.12 标题界面
2.13 用鼠标控制主角
2.14 精确的碰撞检测
2.15 自动创建Prefab
2.16 发布游戏
2.17 代码优化
小结
第3章 第一人称射击游戏
(重要改进:与第一版相比,改进了UI和小地图部分的内容。)
3.1 策划
3.1.1 游戏介绍
3.1.2 UI界面
3.1.3 主角
3.1.4 敌人
3.2 游戏场景
3.3 主角
3.3.1 角色控制器
3.3.2 摄像机
3.3.3 武器
3.4 敌人
3.4.1 寻路
3.4.2 设置动画
3.4.3 行为
3.5 UI界面
3.6 交互
3.6.1 主角的射击
3.6.2 敌人的进攻与死亡
3.7 出生点
3.8 小地图
小结
第4章 塔防游戏
(重要改进:与第一版本相比,本章有很多全新的内容,如动画的使
用,创建自定义的编辑器,使用NGUI创建UI界面等。)
4.1 策划
4.1.1 场景
4.1.2 摄像机
4.1.3 胜负判定
4.1.4 敌人
4.1.5 防守单位
4.1.6 UI界面
4.2 游戏场景
4.3 制作UI
4.4 创建游戏管理器
4.5 摄像机
4.6 路点
4.7 敌人
4.8 敌人生成器
4.8.1 在Excel中设置敌人
4.8.2 创建敌人生成器
4.8.3 遍历敌人
4.9 防守单位
4.10 生命条
4.11 地图编辑器
4.11.1 创建一个自定义窗口
4.11.2 绘制多边形
4.11.3 在Inspector窗口添加自定义UI控件
小结
第5章 2D游戏
(全新内容:包括创建Sprite,动画的播放和一个较为完整的2D捕鱼
游戏实例 )
5.1 Unity 2D系统简介
5.2 创建Sprite
5.2.1 使用SpriteEditor创建Sprite
5.2.2 使用SpritePacker创建Sprite
5.2.3 图层排序
5.3 动画制作
5.3.1 序列帧动画
5.3.2 使用脚本实现序列帧动画
5.3.3 骨骼动画
5.4 2D物理
5.5 捕鱼游戏
5.5.1 游戏玩法
5.5.2 准备2D资源
5.5.3 创建鱼
5.5.4 创建鱼群生成器
5.5.5 创建大炮
5.5.6 物理碰撞
5.6 2D 材质
5.6.1 修改默认材质
5.6.2 自定义的黑白效果材质
小结
第6章 与Web服务器的交互
(重要改进:与第一版相比,去掉了一些冗余的内容,使用JSON实现
网络消息收发。)
6.1 建立服务器
6.1.1 安装Apache
6.1.2 安装MySQL
6.1.3 安装PHP
6.1.4 显示PHP信息
6.1.5 调试PHP代码
6.2 WWW基本应用
6.2.1 HTTP协议
6.2.2 GET请求
6.2.3 POST请求
6.2.4 上传下载图片
6.2.5 下载声音文件
6.3 分数排行榜
6.3.1 创建数据库
6.3.2 创建PHP脚本
6.3.3 上传下载分数
6.4 MD5验证
小结
第7章 基于TCP/IP协议的聊天实例
(重要改进:与第一版相比,本章的变化很大,增加了入门教程,优
化了网络使用的步骤,方法更灵活也更富有技巧。)
7.1 TCP/IP开发简介
7.2 一个简单的网络程序
7.3 网络引擎
7.3.1 数据包
7.3.2 逻辑处理
7.3.3 网络功能
7.3.4 创建聊天协议
7.4 聊天客户端
7.5 聊天服务器端
7.6 Protobuf简介
小结
第8章 用Unity创建网页游戏
(重要改进:与第一版相比,增加了AssetBundle部分的内容。)
8.1 网页游戏简介
8.2 Unity Web 游戏
8.2.1 Streaming关卡
8.2.2 上传游戏到Kongregate
8.2.3 与网页通信
8.2.4 在网页上记录积分
8.2.5 自定义网页模板
8.2.6 自定义启动画面
8.3 Flash游戏
8.3.1 软件安装
8.3.2 导出Flash游戏
8.3.3 调试Flash游戏
8.3.4 从Flash工程读取Unity 导出的Flash游戏
8.3.5 在Unity内调用AS3代码
8.3.6 Flash版本的太空射击游戏
8.4 AssetBundle
8.4.1 打包资源
8.4.2 下载资源
8.4.3 批量打包AssetBundle
8.4.4 安全策略
小结
第9章 将Unity游戏移植到iOS平台
(核心重点:着重介绍了如何在Xcode开发环境中开发Unity插件,实
现Game Center和内消费功能。)
9.1 iOS简介
9.2 软件安装
9.3 申请开发权限
9.4 设置iOS开发环境
9.5 测试iOS游戏
9.6 发布iOS游戏
9.6.1 申请发布证书
9.6.2 创建新应用
9.6.3 提交审核
9.7 集成Game Center
9.7.1 Xcode到Unity
9.7.2 设置高分榜和成就
9.7.3 实现Game Center功能
9.8 集成内消费系统
9.8.1 设置内消费
9.8.2 实现内消费
9.9 本地存储位置
小结
第10章 将Unity游戏移植到Android平台
(重要改进:与第一版相比,改进了插件制作流程,增加了使用脚本
自动编译游戏的教程。)
10.1 Android简介
10.2 软件安装
10.3 运行Android游戏
10.3.1 设置Android手机
10.3.2 安装驱动程序
10.3.3 设置Android游戏工程
10.3.4 测试Android游戏
10.3.5 发布Android游戏
10.4 触屏操作
10.5 从eclipse到Unity
10.5.1 创建.jar文件
10.5.2 导入.jar到Unity
10.5.3 使用LogCat查看Log
10.6 从Unity到Eclipse
10.6.1 导出eclipse工程
10.6.2 设置导出的eclipse工程
10.6.3 发布程序
10.7 使用脚本编译游戏
10.7.1 使用脚本输出Android工程
10.7.2 使用脚本编译Android工程
小结
附录A C#语言
A.1 C#基础
A.2 面向对象编程
A.3 字符串
A.4 数组和排序
A.5 I/O操作
A.6 委托
小结
附录B 特殊文件夹
附录C Unity编辑器菜单中英文对照
游戏开发是一项复杂的工作,本书在编写过程中十分注重与实际开发相结合,全书以实例为基础,使读者在较短的时间内能快速掌握Unity的各种工具和开发技巧,并应用于实践当中。
本书从内容结构上,可以分为几个部分,第1章是入门部分,从总体上对Unity编辑器的各个功能模块进行了介绍;第二部分通过4个实例,包括太空射击游戏、第一人称射击游戏、塔防游戏和一个2D捕鱼游戏,使读者对Unity游戏开发有一个较全面的认识,能有开发一般休闲游戏的能力;第三部分重点介绍了Unity在HTTP和TCP/IP网络通信方面的应用;第四部分专门介绍了如何将Unity游戏移植到网页、iOS和Android平台。另外,本书还附有C#的入门教程和Unity编辑器菜单的中英文对照介绍。
本书为第2版,下面是各章节的内容概要及与第一版的区别。
第1章介绍了Unity编辑器的各个功能模块,与第一版相比,合并了原来的第1章和第5章,修改了Shader部分的内容。
第2章是一个太空射击游戏教程,这是一个入门级的教程,从如何创建一个脚本,到一个完整的游戏有较为细致的介绍。与第一版相比,改进了一些细节,同时增加了内容,包括用鼠标控制飞机(适用于手机),创建精准的碰撞模型,自动创建Prefab和代码优化等内容。
第3章是一个第一人称射击游戏教程,涉及人工智能寻路、动画控制、摄像机控制等内容。与第一版相比,改进了UI和小地图部分的内容。
第4章是一个塔防游戏教程,介绍了创建更为复杂的关卡,导入由Excel创建的数据等。与第一版本相比,本章有很多全新的内容,如动画的使用,创建自定义的编辑器,使用NGUI创建UI界面等。
第5章是全新的一章,介绍了Unity在2D游戏方面的应用,包括创建Sprite,动画的播放和一个较为完整的2D捕鱼游戏实例。
第6章介绍了Unity在HTTP网络通信方面的应用,还涉及了PHP和MySQL的基础应用,使Unity游戏可以与Web服务器进行通信,上传得分记录等。与第一版相比,去掉了一些冗余的内容,使用JSON实现网络消息收发。
第7章是一个完整的、基于TCP/IP协议的聊天实例,在这一章中介绍了使用Unity创建聊天客户端,并使用.NET开发环境创建聊天服务器端。与第一版相比,本章的变化很大,增加了入门教程,优化了网络使用的步骤,方法更灵活也更富有技巧。
第8章介绍了如何将Unity游戏转为Unity 网页游戏和Flash游戏,重点介绍了面向不同网页平台的一些专门技术要点,如何编写Flash插件等。与第一版相比,增加了AssetBundle部分的内容。
第9章介绍了如何将Unity游戏移植到iOS平台,从如何申请iOS平台开发资格,到测试、发布iOS游戏都有详细的介绍,最后着重介绍了如何在Xcode开发环境中开发Unity插件,实现Game Center和内消费功能。
第10章介绍了如何将Unity游戏移植到Android平台,并详细介绍了几种为Unity开发Android插件的方法。与第一版相比,改进了插件制作流程,增加了使用脚本自动编译游戏的教程。
本书的读者主要是游戏开发程序员和Unity爱好者,同时也适合游戏策划和美工使用。
对于本书的完成,要特别感谢王金柱编辑给予的帮助和指导,感谢我的妻子在深夜帮助我校对书稿,还要感谢我的儿子给我莫大的精神支持。
编者
2014.8
关于unity3d的书我基本上都是通过东东买的,仅仅就内容来说,看了之后不后悔就是这本吧。
——东东,青竹工作室,职业,年龄38,程序员
本人使用unity3d进行开发有一年的左右时间了。也买基本unity3d的书。我先对本书进行一下评价。1.本书老少皆宜。无论你是初学,还是已经工作一段时间,你都能从本书中或多或少的得到一些技术知识要点,这点很难得。2.本书大体翻了一下,没有糊弄,不像其他的书一样,要不就是通篇的代码,让人看着一个劲打瞌睡,要么就是通篇大图,让人以为在看连环画,总体来说。这本书代码量适中,内容也清晰,不过入门的话,建议自学的话,先从《Unity3D游戏开发》那本书开始学,那本基础讲的比较多一些,而且也更容易提起兴趣。3.整本书主要以几个案例作为讲解,大体看了一下,基本unity3d最擅长制作的方面都有涉及,特别是服务器交互那块,如果作者没有非常丰富的经验的,估计也写不出来这么全面的书,虽然我没有读完,但我觉得,受益将会匪浅。我作为读者,感谢作者能出版这本书,无私的把一些技术要点奉送,希望今后能出版更多这类技术的书籍,分享技术,造福程序猿!
——霸气的月牛
Unity实战好书。整本书是以游戏实战开发为主线的,实际操作的内容比较多,很好
——T***T
这本书讲解深入浅出,让人受益匪浅。书中图片挺多的,让人很容易接受。对手机游戏开发讲解算是很到位的,让我在短短的时间内对它有比较全面系统的认识。里面的程序都列出来,很容易重现和在电脑上操作,有很好的指引作用。等读完这本书,我相信我就有能开发一般休闲游戏的能力了。书本纸张有一丁点发黄,不过总体看着还可以,是值得购买的一本书。
——Xuehua549919020
内容很丰富,实例很精辟,很实用。只需要一步一步跟着书做实例就好。看了80页代码还没遇到bug。真是没白买,这两天学到很多。
——amaverick
真正Unity3D游戏开发专家的力作。
看过几本Unity3d开发的书,我觉得这本是有经验与最实用的。首先作者通篇通过热点范例教学,如第一人称射击游戏,太空射击游戏,塔防游戏等,其中的内容效果都来自作者自身开发的游戏,如《野人大作战》(大家可以在网络上搜到这款游戏,),不像很多书,代码一大堆,浪费了很多版面,本书代码适中,并加入了必须的注解,第二是图片适中,不像有的书,全是大图,占用了很多版面,结果没有效果,第三是经验之作,比如关于网络部分的讲解,*是很多书不多涉及的,内容极其有效,这块内容作者真是毫无保留,让游戏开发者少走很多弯路,一看就明白怎么回事了,*核心,价值所在,没有开发经验的只是看帮助文件写书的,肯定没有这种效果。学习了,非常受用,一本有价值的好书。想要开发手游的你一定要看这本书。
——minus911
这本书都是U3D的经典书籍,推荐!
——fardece
适合有一定经验的人去提高,也适合快速入门
——小强Robert
作者各方面都能有独到的自己的见解,确实Unity书籍中的独一无二。
——旮旯
第4章塔防游戏
4.1策划
移动平台上的塔防游戏已经多得数不胜数,笔者也曾经开发过一款叫做《野人大作战》的塔防游戏(英文名为WildDefense)。塔防游戏的基本玩法比较类似,在场景中我方有一个基地,敌人从场景的另一侧出发,沿着相对固定的路线攻打基地。我方可以在地图上布置防守单位,攻击前来进攻的敌人,防止他们闯入基地。
本章我们也将制作一款塔防游戏,它将具备塔防游戏的最基本要素。
4.1.1场景
塔防游戏的场景有些固定的模式,它由一个二维的单元格组成,每个格子的用途可能都不同:
?专用于摆放防守单位的格子。
?专用于敌人通过的格子。
?即无法摆放防守单位,也不允许敌人通过的格子。
4.1.2摄像机
摄像机始终由上至下俯视游戏场景,按住鼠标左键并移动可以移动摄像机的位置。
4.1.3胜负判定
我方基地有10点生命值,敌人攻入基地一次减少一点生命值,当生命值为零,游戏失败。
敌人以波数的形式向我方基地进攻,每波由若干个敌人组成。在这个实例中,一关有10波,当成功击退敌人10波的进攻则游戏胜利。
4.1.4敌人
敌人有两种,一种在陆地上行走,另一种可以飞行。每打倒一个敌人会奖励一些铜钱,用来购买新的防守单位。
4.1.5防守单位
塔防游戏会有多种类型的防守单位,为了使本篇教程尽可能简单,我们只完成两种类型的防守单位,一种是近战类型,另一种是远程,每造一个防守单位需要消耗相应数量的铜钱。
4.1.6UI界面
游戏中的UI包括防守单位的按钮,敌人的进攻波数,基地的生命值和铜钱数量。
当防守单位攻击敌人时,在敌人的头上需要显示一个生命条表示剩余的生命值。
当游戏失败或胜利后显示一个按钮重新游戏。
4.2游戏场景
塔防游戏的场景通常比较简单,就像一个棋盘格,可以在上面摆放防守单位,并专门留给敌人一条通道。在这个实例中,我们使用数组来表示场景中的格子,每个格子有几种状态,分别为允许摆放防守单位的格子、专门供敌人前进的格子和无作用的格子。
打开本书资源文件目录chapter04_TD_Start内的Unity工程,在这个工程中,已经预先提供了本游戏所需要的模型、动画、音效等资源。此外,这个工程中还包括了笔者专门为这个教程编写的编辑器扩展工具,用来创建场景,在本章后面将会介绍如何创建一个这样的工具。首先我们简单看一下如何使用它,在菜单栏选择【Tools】→【TileCreator】打开窗口,【TileobjectName】是场景模型的名称,【tileSize】表示每一个格子的大小,xtilecount和ztilecount表示x、z轴方向上格子的数量,确定后,选择【CreateTileObject】按钮创建场景模型。如图4-1所示。
图4-1编辑器扩展窗口
在【TileCreator】窗口内创建的场景模型,它的Mesh默认被保存在工程路径Assets/TileEditor/Mesh下,创建相同名称的模型,后创建的会覆盖掉前面创建的模型。
现在创建出的场景模型只是一个平面物体,还没有材质,我们将为其指定两种材质。选择场景模型,在MeshRenderer中为其指定两个材质球,如图4-2所示。
图4-2指定材质
新建一个名为tile的Layer,将场景模型的Layer指定为tile,然后在TileObject组件内指定TileLayer为tile。选中【Edit】进入编辑模式,在【MaterialID】中选择材质编号,然后即可为场景模型绘制材质,如图4-3所示。
图4-3绘制材质
选择Data,在【DataID】中选择数值。在这个游戏中,我们定义0表示可以摆放防守单位,1表示专用于敌人通过,2表示无效格子,即不能摆放防守单位,也不能供敌人通过。选择相应的数值,直接在场景中将数值绘制到格子上面,如图4-4所示。
图4-4绘制数值
TileObject.cs这个脚本是编辑器扩展功能的一部分,它有一个int数组成员,数组中的每个数值与场景内的格子一一对应。绘制数值的过程即是修改数组中数值的过程,默认数组内的每个值都为零。
在工程路径Assets/Rawdata/level/中提供了少量场景模型,我们可以根据自己的喜好摆放到场景中,也可以使用Lightmapping技术为场景提供灯光效果,最后的塔防场景如图4-5所示,道路最左边是敌人出发的位置,最右边的房子是敌人的进攻目标。
图4-5塔防游戏场景
4.3制作UI
从Unity4.6开始,Unity推出了一套新的UI系统,功能非常强大,接下来,我们将使用这套全新的UI系统创建UI界面。
在工程路径Assets/GUI/内存放有所有的UI图片,选择所有的图片,然后在【Inspector】窗口将TextureType设为Sprite类型,如图4-6所示。Unity新UI系统只能使用Sprite类型的图片,关于更多Sprite设置的细节可以参考本书2D游戏部分的介绍。
图4-6创建Sprite
首先,我们先创建几个UI文字控件。在菜单栏选择【GameObject】→【UI】→【Text】创建文字,在创建文字物体的同时,还会自动创建Canvas和EventSystem物体。Canvas会自动作为文字控件的父物体,所有的UI控件都需要放到Canvas层级下。EventSystem物体上有很多UI事件脚本,用来管理和响应UI事件,如图4-7所示。
图4-7创建基础的UI控件
接下来我们设置文字的位置。在编辑器的上方,选择UI编辑按钮,然后选择文字控件即可移动它的位置,如图4-8所示。
图4-8移动控件
在不同的分辨率下对齐UI的位置一直是件很麻烦的事情,不过使用Unity的新UI系统,一切将变得非常简单。选择前面创建的文本UI控件,在【Inspector】窗口的RectTransform中可以快速设置控件的对齐方式,比如左对齐,右对齐等,如图4-9所示。
图4-9对齐控件
除了对齐,我们还需要UI控件根据不同的屏幕分辨率进行缩放。选择Canvas物体,然后在菜单栏选择【Component】→【Layout】→【ReferenceResolution】,在Resolution中设置默认的分辨率,UI控件将以这个分辨率为基础,在不同的分辨率下进行缩放适配,如图4-10所示。
图4-10适配分辨率
这里一共需要创建3个不同的文字控件,分别用来显示敌人进攻的波数、铜钱和生命值。在【Inspector】窗口我们可以设置文字的内容、字体、大小和颜色等等,我们也可以使用Unity的RichText功能,在文本中添加标记语言,使文字的色彩不同,如图4-11所示。关于RichText的语法,在Unity的帮助文档中搜索“richtext”即可找到相关详细说明
图4-11设置文本
现在很多游戏都给文字配上了描边,那么我们也加一个吧,选择文字,在菜单栏选择【Component】→【UI】→【Effects】→【Outline】,如图4-12所示。
图4-12描边字
最后我们要创建几个按钮,包括创建防守单位的按钮和重新游戏的按钮。在菜单栏选择【GameObject】→【UI】→【Button】即可在场景中创建一个新的按钮控件,默认按钮控件下面还有一个文字控件用来显示按钮的名称。在【Inspector】窗口找到Image组件下的SourceImage设置按钮的图片,选择下面的SetNativeSize可以使按钮的大小与图片的尺寸快速适配。在Button组件中,将NormalColor的Alpha值设为255使图片完全不透明。如图4-13所示。
图4-13创建按钮
最后的UI效果如图4-14所示。注意UI控件的名字,我们在后面需要通过名字来查找UI控件。UI控件的层级关系也比较重要,因为控件均位于Canvas或其他层级之下,所以它们的位置只是相对于父物体的相对位置,如果通过脚本去修改控件的位置,通常是修改transform.localPosition,而不是transform.position。
图4-14创建的UI
完成UI设置后,可以将UI保存成Prefab。
评论
还没有评论。