跳至主要内容

博文

目前显示的是 2016的博文

ScriptableObject 序列化

  ScriptableObject是一个类,它允许你存储大量用于共享的数据独立脚本实例,不要迷惑这个类同样可以叫做 SerializableObject,可以理解成是一个Unity串行化工具。这是一个编辑器类并且你可以在Inspector面板中编辑数据。例如: 如果你有一个存储了一百万数据的 int[],这个数组占用4MB内存,放在Prefab上,那么当你每次实例化Prefab,你都会得到这个数组的一个副本。如果你实例化10个这个 Prefab,那就会占用40MB内存。 可序列化的类型 Unity的serializes(序列化)支持所有原生的类型,也支持strings,arrays,lists还有Unity的Vector3等都支持,而且还支持自定义的类,但需要有一个串行的属性。 使用情景 预期使用情况,使用ScriptableObject是减少内存使用量,避免Values的副本。但是你也可以用它来定义可插拨的数据集。这方面的 一个例子是:想像RPG游戏中的NPC商店,你可以创建自定义ShopContens ScriptableObject,每个资产定义了一组可用于购买物品。在这样一个场景,游戏中有三个区域,每个区域都可以提供不同层级的项目。你的店铺 脚本将引用ShopContents对象,定义哪些项目可供选择。 Tips 当在检查ScriptableObject引用时,你可以在Inspector双击这个参考字段。 你可以创建一个自定义的Editor来查看不同的类似在Inspector,以帮助你管理它所表示的数据。 游戏关卡数据序列化 策划需求 一个游戏中的配置表数据,这些数据一般都是由策划在Excel等工具上配置,要运用到游戏中时,一般需要做一个转换,比如类似转换。这时可以使用 ScriptableObject,将数据预先处理成程序需要访问的数据结构,存储在ScriptableObject中,然后打包成一个外部文件,这样 在游戏运行的时候就不用做解析和组装了,这个功能对大批量的公用数据尤其有用!! 思路分析 策划在Art工程拼接好关卡信息之后,客户端根据关卡的中元素的位置,大小等信息生成出关卡,这中间有一个存储关卡信息的过程。我们的做法是把关卡 的信息存储在ScriptableObject上,然后在E...

Unity 协程与线程

协程是不同步的 协程 不是 线程, 协同程序是 不同步 的       一个线程在程序中和其他线程是异步运行的,在多处理器机器中一个线程可以同时与所有其他线程的实时运行其代码,这使得线程编程能够解决很复杂的事情,因为 可能在相同的时间里一个线程在改变它而另一个线程正在读取它,这意味着另一个线程实际上可以改变的东西在游戏中处理的中间似乎是你的源代码一行。这是因为 你写的代码是由机器变成汇编语言,更是更复杂。正因为如此,你必须通过锁,以确保这种情况不会由任何确保没有共享内存发生。或者通过锁定其他线程使用同一 块内存,当他们在读取或更改时。 什么是协程?       协同程序绝对不是一个线程。这意味着在同一时间只有一个协同程序在执行,它会被执行在游戏的主线程上,所以实际上在同一时间游戏的核心只有一个协同程序在运行[这段翻译的不太准确]      你永远不需要担心同步或锁定一个值当你正在编写一个协同程序。你有完全的控制权,直到你的代码执行到 yiedld   因此总结一下协程的定义     协程只是部分执行,并假定在适当的条件得到满足,在未来的某一时刻将被恢复,直到它的工作完成 Unity函数执行图 Unity processes coroutines every frame of the game for every object that has one or more running.  The processing occurs after Update and before LateUpdate for most yield statements, but there are special cases: Unity的流程协同程序在游戏的每一帧每个对象为具有一个或多个正在运行的。Update() 之后,LateUpdate()之前 ,发生的 yield 语句的处理,但也有特殊情况 When the coroutine is activated it will execute right up to the next y...

[3D跑酷] DataManager

DataManager管理游戏中数据,当然这个类中大部分的属性和方法都是Public 函数列表

[3D跑酷] GameManager

GameManager在游戏中很重要,处理整个游戏的流程,但是在这个类中尽量也只是写一些重要的方法,调用其它类中的方法。 枚举项 函数列表 方法解释 // 当玩家碰到障碍(障碍Type,碰撞Position) public void obstacleCollision(ObstacleObject obstacle, Vector3 position) // 当玩家收集到金币 public void coinCollected() // 道具激活(道具Type,activate bool) public void activatePowerUp(PowerUpTypes powerUpType, bool activate) // 游戏结束(导致结束Type,waitForFram bool) public void gameOver(GameOverType gameOverType, bool waitForFrame) // 重新开始游戏(bool start) public void restartGame( bool start) // 返回主菜单(和GUIManager相关) public void backToMainMenu( bool restart) // 游戏暂停事件 public void pauseGame( bool pause) // 道具升级 public void upgradePowerUp(PowerUpTypes powerUpType) // 游戏暂停事件 public delegate void PauseHandler( bool paused); public event PauseHandler onPauseGame;

[3D跑酷] MissionManager

之前写了GUIManager,GUIClickEventReceiver还有AudioManager,这次写MissionManager 引用关系 首先看下MissionManager在项目中的引用关系 解释一下引用关系: MissionManager是一个单例类,类中定义了和任务相关的属性的方法,其它类中通过单例引用MissionManager中的方法 GameManager public void gameOver (GameOverType gameOverType, bool waitForFrame) { missionManager.gameOver (); } 再来查看MissionManager中的GameOver() public void gameOver() { checkForCompletedMissions(); } 这里的逻辑是,在GameOver的时候检查MissionManager中的任务是否完成 DataManager public int getScore () { return Mathf.RoundToInt (score * missionManager.getScoreMultiplier ()); } DataManager中 获取玩家得分  MissionManager中的倍率*Score=玩家最后的得分 GUIManager public void showGUI (GUIState state) { // activate the new gui state, deactivate the old. changeGUIState ( true , state); changeGUIState ( false , guiState); switch (state) { case GUIState.EndGame: endGameScore.text = dataManage...

3D跑酷遇到的问题

项目名称:3D跑酷项目 写作目地:使用Asset Server进行多人协作开发过程中,记录遇到的问题 问题1:UIAtlas无法自动更新 描述:NGUI的Atlas图集(图片)无法自动更新 后果:sprite丢失,切图不对应,到另一个同事那儿UI变乱了 解决办法 方法一:把NGUI的Atlas用SVN的lock功能 方法二:容易出问题的部分由一个人管理 问题2:模型的贴图无法同步 描述:模型的贴图无法同步 后果:模型贴图丢失 解决办法 排除法:使用 ResourceCheck,小工具,检查当前场景中的资源使用情况 问题3:场景中UI prefab丢失 描述:不同场景的NGUI的prefab丢失 后果:每个场景的UI都需要重新更换一遍 解决办法 方法一:多个场景共用一套UI,当切换场景时不销毁UI DontDestroyOnLoad(Object target); 方法二:把UI放在一个单独的场景 问题4:场景信息丢失 描述:场景信息丢失 后果:不能同时存在自己和他人修改的数据 解决办法 尽量不要同时多人修改同一场景中的同一GameObject,当更新时查看更新日志及检查自己的提交信息 问题5:项目目录乱 描述:项目目录乱 后果:提交或更新项目时,Unity容易Down机 解决办法 定期整理项目目录,删除/标识 无用资源,写好日志记录

[3D跑酷] GUIManager UI管理

UI元素更新及界面跳转 继上篇日志《Unity开发之 GUIClickEventReceiver》,再谈一下我们如何管理游戏中的UI元素更新及界面跳转 UI绑定 图一:Inspector面板 Public GameObjectName与GameObject一一对应 UI结构及命名规范 图二:Hierarchy面板 UI父子结构及组件命名规范 UI枚举种类 图三:enum GUIState UI绑定代码 图四:public UI控件定义 与Hierarchy命名规范 UI主要方法及逻辑 图五:主要方法及逻辑 主要方法 1、隐藏Transform及子Transform #if !UNITY_3_5 private void activeRecursively(Transform obj, bool active) { foreach (Transform child in obj) { activeRecursively(child, active); } obj.gameObject.SetActive(active); } #endif private GameObject panelFromState(GUIState state) { switch (state) { case GUIState.MainMenu: return mainMenuPanel; case GUIState.InGame: return inGamePanel; case GUIState.EndGame: return endGamePanel; case GUIState.Store: return storePanel; case GUIState.Stats: return statsPanel; case GUISt...

[3D跑酷] UI事件处理系统

在我们的Unity游戏项目中,GUI的表现采用NGUI。记录一下我们的处理方式: 需要解决的问题 1、需要处理大量按钮的点击事件 2、需要处理界面跳转事件 3、需要处理界面元素更新事件 解决方案 GUIClickEventReceiver 解决按钮点击事件 GUIManager 管理GUI的跳转与更新 具体实现 Inspector选择事件 在编辑器中为按钮选择点击事件 事件代码结构 主要逻辑 public void OnClick () { bool playSoundEffect = true ; switch (clickType) { case ClickType.StartGame: GameManager.instance.startGame (); break ; case ClickType.Store: GUIManager.instance.showGUI (GUIState.Store); break ; case ClickType.Stats: GUIManager.instance.showGUI (GUIState.Stats); break ; case ClickType.DoubleCoinUpgrade: GameManager.instance.upgradePowerUp (PowerUpTypes.DoubleCoin); break ; case ClickType.CoinMagnetUpgrade: GameManager.instance.upgradePowerUp (PowerUpTypes.CoinMagnet); break ; case ClickType.InvincibilityUpgrade: GameManager....

[3D跑酷] AudioManager

Unity音频管理 游戏中的声音管理最常用的组件莫过于AudioSource和AudioClip,我的做法是建立是一个AudioManager类(单例类)管理各个音频,谈一下我的经验: 函数列表 Start函数:设置音频整体参数; 编辑器面板 拖拽文件赋值 AudioSource文档 逻辑实现代码 public void playSoundEffect(SoundEffects soundEffect) { AudioClip clip = null ; float pitch = 1; switch (soundEffect) { case SoundEffects.ObstacleCollisionSoundEffect: clip = obstacleCollision; break ; case SoundEffects.CoinSoundEffect: clip = coinCollection; pitch = 1.5f; break ; case SoundEffects.PowerUpSoundEffect: clip = powerUpCollection; break ; case SoundEffects.GameOverSoundEffect: clip = gameOver; break ; case SoundEffects.GUITapSoundEffect: clip = guiTap; break ; } soundEffectsAudio.pitch = pitch; //音调 so...

【译】《全境封锁》的开放世界渲染:执着于光影表现

Snowdrop(雪莲花)引擎的全局照明技术介绍   UBIMassive 工作室的 Nikolay Stefannov      3 月 18 日, UBI Soft 的技术主管 NikolayStefannov 进行了题为【 Global Illumination in 'Tom Clancy's TheDivision' 】(全境封锁的全局照明技术)的 Session 。      在家用机和 PC 游戏的世界, GI 已经变得习以为常了。既然 GI 已经是必须的话,那就要以现今有效的 GI 光照为前提,并向有一定风格的【画面制作】的焦点转移。画面制作,并不仅仅是美术师在数据绘制上的方法,还有程序上的技术。这里, Stefannov 就是以【全镜封锁】画面制作的技术方面进行了解说。     【游戏世界中光源的移动变化】      【全境封锁】,是 UBI 的瑞典工作室 UBI Massive 开发的第三人称射击游戏,引擎使用的是 UBI 自研的雪莲花引擎。【全境封锁】有着 RPG 元素,游戏场景变成了开放世界。以纽约曼哈顿的 6 平方公里为游戏舞台,世界内有有着总计 200 万的实体(物体对象)。车辆总数约 2 万量,垃圾堆 3 万座。      因为要重视开放世界的整体性,光照为了强调美术师的演出意图,在项目上做了限制,日光无法照明到所有的空间,经常有发暗的地方。      雪莲花的 GI 光照,因为全部都是动态的,什么时候都可以进行调整。为了提升性能,很多的游戏引擎通常会把光源的影响的预计算结果烘培到光照贴图里。而本作的雪莲花引擎,最大的特征就是完全的动态光照。使用的 Light Probe ,因为管理太复杂,也并不太适应项目的设计。   【本作技术的核心特性】   GI 的影响范围不仅仅是室外。本作中,为了系统可以不区分室内和室外,在室内也会有很大的开口让真实的光照射入,根据游戏世界里时间的变化,光影的色彩...

谷歌Adsense广告代码异步加载解决谷歌联盟广告老卡的问题

最近一段时间,谷歌中国的服务器从香港撤走,导致很多朋友连谷歌也无法访问了,而像部落这样,在网站中投放了谷歌Adsense广告的,也经常会出 现网站打开,加载到谷歌广告位置时,网站就卡在那里了,估计一些网速慢的用户,可能就永远卡那里了。对于这种情况,我们可以利用异步加载的广告代码来解决 这个问题。 Google广告会因为各种原因经常打不开,如果不用异步加载的方法,会导致在您的网站中,google广告后面的代码显示被阻塞,这样的话,很影响用户体验。经常网页不能完全打开的话,必然会导致用户的在面积流失。 上图是部落的网站首页,在没有使用广告代码异步加载前,经常会出现这样的现像,首页右边的一个300X300的谷歌广告位无法正常显示了。 当然,使用谷歌Adsense广告代码异步加载,您的网站加载速度会明显提升,特别是对一些网速慢的用户来说,但有一点和我们站长相矛盾的,那就是上次谷歌承诺广告发布商的广告被有效浏览才收费,很明显,异步加载有可能会降低您站内广告的浏览量。 使用谷歌Adsense广告代码异步加载 其实使用方法很简单,我们进入自己的谷歌联盟后台,在“广告单元”中找到需要异步加载的广告位,点击“获取代码”,如下图: 我们在代码类型中选择“异步”,就能获得异步加载的广告位代码,将您之前在网站中投放的广告代码替换就行了。 之前传统的google广告异步加载代码 不知您有没有发现,之前传统的google广告异步加载代码之这次部落所说的有很大的不同了,例如部落之前同样是采用的广告代码同步加载,代码内容如下: --> 显然,以上代码会影响您的网站加载速度。而之前的异步加载代码,则是在后面加上了一段JS代码。内容就不放出了。 部落在谷歌官方找到一些异步加载说明:google广告在google服务器正常的情况下会及时的正常显示,google服务器不正常的情况下也不会影响后面页面的加载。 而自己正式体验后,才发现,谷歌联盟的广告加载速度真是超快,只是加载的内容,匹配性没之前那么好了,究其原因,部落猜想应该是在调用本地电脑数据的cookis时,就直接调用了其中的广告数据,只有这样,加载速度才会达到最快。当然,这纯粹只是个人猜想而已。

网站站内、站外链接优化技巧与作用

其实网站站内链接优化和站外链接优化一样重要,两者是相辅相成的,可能在对不同的搜索引擎的时候有些不一样,在相同条件下百度更加注重的是内容,谷歌更加注重的是链接,所以这两个都要同时做好才能让网站对搜索引擎更加友好。 一、先说内链吧 ,很多站长和网站管理员都在拼命的做外部链接,其实外部链接比较受限制,内部链接反而在掌握之中,这个时候建议你先把站内链接优化好再做外部链接,就是俗话说的磨刀不误砍柴工。下面说一下站内链接优化内容。 1、做好网站地图放网站首页和提交给搜索引擎 网站地图是很重要的一个环节,因为搜索引擎蜘蛛可以通过网站地图到达地图上任何一个位置,只要你网站地图做的好,可以让搜索蜘蛛快速爬取网站,还节 省时间,这是搜索引擎非常乐意见到的,可以给搜索引擎节约大量的时间和资源。还建议站长把网站地图放在网站首页,这样用户和搜索引擎都可以轻松找到。还要 把网站地图提交给搜索引擎,以便其能及时发现网站链接更新,及时收录网站页面。 2、减小网站文章链接深度 对于小型网站来说文章链接埋的越深越不容易被用户发现,其实搜索引擎和人是一样的,你埋藏的越深越不容易被搜索引擎发现,这样就更别谈被收录、索 引、排名了,所以建议文章最好能在网站首页或者更容易被发现的地方出现,例如优本财富网站从网站首页点击3次即可看到最终文章页。 3、文章关键词描文本 在写作文章的时候对关键词可以创建描文本,这样搜索引擎就会认为这个词比较重要,然后通过这个词再抓取网页,这样搜索引擎就会给予这个词比较高的关注,这个词也就会提高排名的几率。 4、不排名页面添加noffllow标签 网站首页那些不参加排名的链接可以添加noffllow,这样可以保留网站首页的权重,防止首页权重的不必要流失,还可以促进网站关键词的排名,其实给网站首页增加权重一共有两大方法一个是开源,另一个就是节流,增加noffllow标签就算是节流了。 5、频道页、内容页互相建立链接 现在很多网站使用的都是树形结构,树形结构的网站并不是互相之间没有链接,树形结构网站的链接应该这样做,频道页与频道页之间建立链接,同一个频道页下的文章进行链接,不同频道下的文章尽量减小链接,如果有需要也是可以进行链接的,这个要看个人的需要。 二、站外链接如何优化 1、增加友链深度 说到换友链人们想到的当然就是高权重网站首...