成长ing中的w的专栏

私信 关注
Data菌
码龄8年
  • 128,938
    被访问量
  • 221
    原创文章
  • 30,097
    作者排名
  • 35
    粉丝数量
  • 于 2012-11-18 加入CSDN
获得成就
  • 获得20次点赞
  • 内容获得12次评论
  • 获得33次收藏
荣誉勋章
兴趣领域
  • #大数据
    #hadoop
TA的专栏
  • CocosCreator
    32篇
  • lua变量
  • 热更新
  • lua
    10篇
  • Laya游戏
  • Html5游戏
  • 大数据
    4篇
  • AR技术学习之路
    3篇
  • Android开发之路
    10篇
  • ios开发之路
    1篇
  • 电脑使用常识
    4篇
  • 手机使用技巧
  • 设计模式
    10篇
  • Office办公软件的使用
  • Guitar
  • C语言学习之路
    12篇
  • PHP工程师成长之路
    13篇
  • Unity
    125篇
  • C#
    17篇
  • 大数据学习之路
    4篇
  • 最近
  • 文章
  • 资源
  • 问答
  • 课程
  • 帖子
  • 收藏
  • 关注/订阅

Unity Shader 数据类型

编写Shader时,不同阶段,顶点着色器、片元着色器处理的和输出的数据格式都不同。需要使用不同的语义来标识。否则着色器并不知道该数据的意义,以及如何处理。Shader "Unlit/DataTypeShader"{ Properties { } SubShader { Pass { CGPROGRAM #pragma vertex vert
原创
26阅读
0评论
0点赞
发布博客于 1 月前

Unity Shader 自定义函数

为了避免混乱,使代码结构清晰明朗,需要自定义一些函数模块Shader "Unlit/FunctionShader"{ Properties { _Color("Color",Color) = (1,1,1,1) } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment
原创
48阅读
0评论
0点赞
发布博客于 1 月前

Unity shader 传递数据使用结构体

有时候我们需要传递控制修改多个信息变量等,此时需要用一个容器来包装,那就是结构体Shader "Unlit/StructShader"{ Properties { _Color("Color",Color) = (1,1,1,1) } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragm
原创
27阅读
0评论
0点赞
发布博客于 1 月前

Unity 渲染管线工作流程

渲染管线:顾明思义,说明渲染的过程就像是数据经过一根管子并且经系列处理后最终显示在屏幕上的过程。主要分3个阶段:对应Shader代码阶段如下所示
原创
31阅读
0评论
0点赞
发布博客于 1 月前

Unity Shader 颜色修改

编写能够改变模型颜色值得ShaderShader "Unlit/ColorShader"{ Properties { _Color("Color",Color) = (1,1,1,1) } SubShader { //渲染一次模型 Pass { //添加Cg/HLSL代码片段 CGPROGRAM //定义顶点着色器
原创
77阅读
0评论
0点赞
发布博客于 1 月前

Unity一键发包工具

如果你的游戏项目只有一个版本或渠道维护,那可能对一键发包的需要不是很大,但是如果需要从一个项目工程发布不同渠道版本包时,最好是搞个一键发包工具,全自动化,只需在发包窗口做一些必要设置如版本号,目标平台等信息,点击发布即可。也避免了需要打开多个面板去设置麻烦,如PlayerSetting面板、EditorBuildSetting、UserBuildSettings,甚至场景里的游戏对象预设等。把它们都集成到同一个发布工具窗口显示修改,防止东漏西漏的可能。这里主要介绍关键常用设置的API。..
原创
53阅读
0评论
0点赞
发布博客于 1 月前

版本号大小比较

游戏项目中需要针对硬件厂商不同代设备实现兼容运行,设备系统低于3.10.XX版本的与高于3.10.XXX版本的接口不同。这种情况下需要我们游戏获取当前运行的设备版本号,区分调用不同API。 /// <summary> /// 检测当前Pico版本号是否大于“3.10.0” /// </summary> /// <returns></returns> private bool CheckPicoVersion(string v
原创
63阅读
0评论
0点赞
发布博客于 1 月前

微信小游戏上传设置成体验版或者提交审核

游戏开发测试都完了,接下来就是上传了,上传到微信公众后台后,可以把小游戏设置成体验版,供外界亲朋好友试玩,另外就是提交审核发布啦!那么如何从微信开发者工具上传呢?1.设置基本信息后,点击上传按钮上传成功后,点击确定登录微信公众后台查看2.接下来可在后台设置当前开发版本为体验版本生成体验版二维码,可下载该二维码分享给大家试玩3.确定要发布了,就提交审核。但会先弹出个填写游戏内容的界面,按照要求填写即可填写完成后,点击提交,按下确定会显示游戏内容审核中返回版本管理点击提交
原创
107阅读
0评论
1点赞
发布博客于 1 月前

开发中微信小程序分享体验试玩

处在开发中的小程序,想分享给其他人如朋友试玩、同事测试等,app的话,我们会发个安装包给他们,那小程序呢?类似的道理,分享给他们该小程序生成的二维码给他们扫描运行体验就行。点击开发工具的预览按钮即可。值得注意的是,我们需要在微信公众后台添加他们为体验人员另外,也可以通过小程序助手,在手机端实现关于该开发中的小程序管理。以上是关于开发中的小程序如何分享给相关人员体验试玩的方法,另外是如何方便有效地管理这些小程序。...
原创
17阅读
0评论
0点赞
发布博客于 2 月前

微信小程序真机调试

微信小游戏在发布前,我们需要安装真机运行并且查看追踪其运行Log日志,以便查询排除隐藏的错误。那么如何通过微信开发者工具实现真机调试呢?1.点击微信开发工具的真机调试按钮,成功的话会生成二维码有时候二维码生成失败,我遇到过的是文件超过最大限制的4M,那你得想办法减少文件包体大小。2.手机登录微信扫描该二维码,实现在“手机上安装运行”,PC端会弹出真机调试的窗口Source是代码执行断点调试窗口Console是运行Log日志输出窗口以上是实现真机调试的过程。另外,你会发现微信开发工具
原创
215阅读
0评论
0点赞
发布博客于 2 月前

Unity BuildSetting中Editor代码中设置场景的显示与隐藏

/// <summary> /// 切换到Pico一体机时,激活Pico_MainScene场景 /// </summary> private void EnablePicoSpeicalScene(bool isEnable) { EditorBuildSettingsScene[] scenes = EditorBuildSettings.scenes; foreach (EditorBuildSett...
原创
18阅读
0评论
0点赞
发布博客于 2 月前

Unity叠加场景加载运行

一般情况下,默认当前有且只有一个场景在运行,但是在某些特殊情况下,我们需要多个场景文件同时运行。比如像之前未“开发”的部分地图场景,而现在玩家解锁进入该部分游戏区域时,可通过叠加场景的方式解决。...
原创
17阅读
0评论
0点赞
发布博客于 2 月前

CocosCreator构建导出微信小程序项目工程文件

众所周知,开发微信小游戏,我们可借助第3方的小游戏开发引擎有Cocos Creator/Laya以及白鹭等。但开发完成需要借助微信开发者工具调试、发布上传。这里介绍Cocos Creator项目如何导出微信小游戏项目文件,接着在微信开发者工具中运行。首先,打开Cocos Creator的 File->Settings,设置微信开发者工具路径。点击Save保存。其次,电脑上安装微信开发者工具后打开运行。并打开设置->安全。以上配置好后,现在开始构建微信小游戏项目工程文件。打开Coco
原创
76阅读
0评论
0点赞
发布博客于 2 月前

UnityShader-属性介绍Properties

着色器属性模块可有可无。Shader "Unlit/MyShader"{ Properties { //颜色 [HDR]_Color("WLQ_Color",Color) = (1,1,1,1) //整型 _Int("WLQ_Int",Int) = 1 //浮点型 _Float("WLQ_Float",Float) = 0.98 //浮点型,带范围 _Float
原创
29阅读
2评论
0点赞
发布博客于 2 月前

性能优化:纹理文件

纹理:是图像文件、一个颜色数据的大列表,以告知插值程序,图像的每个像素应该是什么颜色。精灵:是网格的2D等价物,通常是一个四边形,用于渲染面向当前相机的平面。网格和精灵都使用纹理,将图像渲染于它们的表面。接下来介绍关于优化纹理文件性能的设置:1.减少纹理文件的大小:在保证质量效果的前提下,尽量减小纹理文件的大小。比如最大MaxSize设置、压缩格式Format以及Compressor Quality压缩质量等2.谨慎使用MipMap:勾选该项,会生成多张低分比率的副本,你会发现最终纹理文件会比不
原创
43阅读
0评论
0点赞
发布博客于 2 月前

性能优化:网格文件

网格和动画文件本质是顶点和蒙皮骨骼数据的大型数组。在保证质量效果的前提下,我们可以通过一些技术方式来做优化。1.减少多边形数量:它是简单、直接的提升性能比较明显的方法。由于对象的大部分细节几乎是通过精细的纹理和复杂的阴影来提供的,所以我们可以去掉网格上的不必要的顶点,而玩家却无法分辨它们之间的区别。2.调整网格压缩级别:Off/Low/Medium/High4种设置。增加此设置将把浮点数据转换为固定值、降低顶点位置、法线方向的精度、简化顶点颜色信息等。3.适当使用Read-Write Enabled:
原创
26阅读
0评论
0点赞
发布博客于 2 月前

性能优化:音频文件

音频文件格式设置以及游戏的音频系统实现每一部分都会导致内存和CPU性能低下。总结:针对音效文件本身以及用途,针对性的对其设置,让音效在内存占用、磁盘占用、CPU使用和音效质量各方面做出折中妥协已达到最佳的游戏音效体验。另外,就是音效系统设计实现也会最终影响音效体验。...
原创
14阅读
0评论
0点赞
发布博客于 2 月前

性能优化:静态批处理

静态批处理是Unity的第二种批处理技术。与动态批处理相比主要区别是它只处理标记为Static的对象。那么进行静态批处理需要满足哪些条件呢?1)网格必须标记为Static:被标记为Static的对象,是不能通过任何方式移动、旋转和缩放。2)每个被静态批处理的对象都需要额外的内存:内存需求取决于批处理的网格中复制次数。静态批处理在工作时,将所有标记为static的可见网格数据复制到一个更大的网格数据缓冲中,并通过一个DrawCall传到渲染管线中。值得注意的是,如果使用静态批处理渲染1000个相同的对
原创
45阅读
0评论
0点赞
发布博客于 2 月前

性能优化:动态批处理

动态批处理有如下特点:(1)批处理在运行时生成【批处理是动态产生的】;(2)批处理中包含的对象在不同的帧之间可能有所不同,这跟哪些网格在主摄像机视图中当前时可见的有关【批处理的内容是动态的】;(3)对场景中运动的像也是可以批处理的【对动态对象有效】;那么对网格要进行成功地动态批处理所需要满足哪些条件呢?a.所有网格实例必须使用相同的材质引用;b.只有ParticleSystem和MeshRenderer组件进行动态批处理。SkinnedMeshRenderer组件和其他所有其他可渲染的组件类型不
原创
23阅读
0评论
0点赞
发布博客于 2 月前

性能优化分析:FrameDebugger帧调试器

打开Window/FrameDebugger菜单项,弹出帧调试器,单机Enable按钮,可以观察场景是如何构建的,每次执行一次DrawCall。这对分析如何使用批处理来减少DrawCall很有帮助。对比2个连续DrawCall,可以确定当前DrawCall渲染了哪些对象。总结:通过该工具,可以准确知道DrawCall数量以及每次DrawCall 渲染的对象,为我们优化减少DrawCall提供了依据参考。...
原创
63阅读
0评论
0点赞
发布博客于 2 月前

性能优化:批处理、DrawCall、材质与着色器

批处理一般是指将大量任意数据块组合在一起将它们作为单个大数据块进行处理的过程。批处理的对象既可以是网格、顶点、边、UV坐标和其他用于描述3D对象的不同数据类型的大集合;也可以是音频文件、精灵**、纹理文件等。而Unity批处理技术通常是指批处理几何体的合并即将多个对象的网格数据合并到一起,并在单一指令中渲染它们,而不是单独准备和绘制每个几何体**。Unity提供了2中批处理形式:动态批处理和静态批处理。另外,也必须注意的是,如果没有正确使用批处理,它反而会恶化性能。最后,需要明白的是,使用批处理的主要目标是
原创
32阅读
0评论
0点赞
发布博客于 2 月前

性能优化:对象池

对象池通过避免释放和重新分配,来最小化和建立对内存使用的控制的一种极好方法。using System.Collections;using System.Collections.Generic;using UnityEngine; /* * Author:W * 对象池 */public class PoolSystem : MonoBehaviour { public GameObject prefab; public int Number = 100; private L
原创
10阅读
0评论
0点赞
发布博客于 2 月前

性能优化:其他影响性能的方面

协程:启动协程会产生一定的内存消耗,但注意的是在方法调用yield时不会再有后续消耗。如果内存消耗和垃圾回收是严重的问题,应该尝试避免产生太多短时间的协程,并避免在运行时调用太多的startcoroutine()..Net库函数:.Net类库中提供很多通用功能,以帮助程序员解决日常开发中可能遇到的问题。但它们只是提供了解决方案,但可能不是最优的解决方案。比如LINQ和正则表达式等。...
原创
10阅读
0评论
0点赞
发布博客于 2 月前

性能优化:foreach循环

由于使用foreach循环最终会在调用期间产生不必要的堆内存分配。可以使用但不推荐使用using System.Collections;using System.Collections.Generic;using UnityEngine;/* * Author:W * 循环遍历 */public class ForeachTest : MonoBehaviour { // Use this for initialization void Start () { //会在堆上分配一个
原创
37阅读
0评论
0点赞
发布博客于 2 月前

性能优化:对字典键使用InstanceID

如果我们在项目中需要使用MonoBehaviour或ScriptableObject引用作为字典键时,会导致一些性能慢的一些问题。我们可以使用Object.GetInstanceID()改进,它返回一个整数,用于表示该对象的唯一标志值,在整个程序声明周期中,该值都不会发生变化,如果我们将其“缓存”在对象中,并将其作为字典中键,那么元素的比较将比直接使用对象引用快2至3倍。using System.Collections;using System.Collections.Generic;using Un
原创
12阅读
0评论
0点赞
发布博客于 2 月前

性能优化:UnityAPI中的数组

Unity API中有很多指令会导致堆内存分配,这些需要注意,本质上包括了所有返回数组数据的指令。像GetComponents()、Mesh.vertices、Camera.allCameras等等。每次调用Unity返回数组的API方法时,将会导致分配该数据的全新版本,这些方法应该尽可能避免的,或者仅调用很少次数并缓存结果,避免比实际需要更频繁的内存分配。...
原创
23阅读
0评论
0点赞
发布博客于 2 月前

性能优化:数据结构

原则上我们希望大量的值类型和大量的引用类型分开,如果结构体中含有一个引用类型时,那么GC将会关注整个对象,以及它的所有成员数据、间接引用的对象。当发生标记清除时,必须在移动之前验证对象的所有字段。然而,如果将不同类型分离到不同数组中,那么GC可以跳过大量数据。using System.Collections;using System.Collections.Generic;using UnityEngine;/* * Author:W * 结构体数据结构 */public struct
原创
8阅读
0评论
0点赞
发布博客于 2 月前

性能优化:装箱与拆箱

装箱:是在通过转化或强制转化将值类型视为引用类型时发生的,因此会引起堆内存分配。装箱操作既可以显示进行也可以隐式进行。using System.Collections;using System.Collections.Generic;using UnityEngine;/* * Author:W * 装箱与拆箱 */public class BoxingTest : MonoBehaviour { void Start() { int i = 128;
原创
38阅读
0评论
0点赞
发布博客于 2 月前

性能优化:字符串连接

字符串连接是将字符串追加到另一个字符串后面以形成更大字符串,这样的操作容易导致堆内存的过量分配。字符串连接大概有以下3种方式。1.使用+操作符和+=操作符,这种方式最容易导致内存浪费的,因为它会导致分配链效应。每次+操作会产生1个临时的字符串,直到产生最终的字符串。2.使用StringBuilder,如果我们可以提前知道字符串的最终大小,那么可以提前分配一个适当的缓冲区,以减少不必要的内存分配。它有点儿类似动态数组,如果当前已分配的内存空间不够时,会分配额外的。当然,最好是提前能预估合适的缓冲区,即避免
原创
14阅读
0评论
0点赞
发布博客于 2 月前

性能优化:字符串

字符串本质是字符数组,因此字符串也是引用类型。另外,字符串对象类是不可改变的,当我们重新给字符变量赋值时,实际上是在堆上分配了一个全新的字符串以替换它,原来的内容会复制到新的字符串对象。此种情况下,旧的字符串对象不再被引用,不会在标记-清除过程中标记,最终会被GC清除。因此,字符串操作会导致堆分配和垃圾回收,是比较耗性能的。另外,字符串类型与普通引用类型的区别之处在于:当字符串按值传递方式给另外一个函数时,并且在该函数中对其做“修改即重新赋值”时,因为字符串的“不可变”这个特性的缘故,被传入的字符串的值
原创
32阅读
0评论
0点赞
发布博客于 2 月前

性能优化:数组

数组是引用类型,不管它存储的是值类型还是引用类型的元素。using System.Collections;using System.Collections.Generic;using UnityEngine;/* * Author:W * 数组:引用类型 * 【注意】不管存储的是值类型的还是引用类型的元素 */public delegate void OnMsgHandle(string msgId);public class ArrayTest : MonoBehaviour {
原创
9阅读
0评论
0点赞
发布博客于 2 月前

性能优化:结构体与类比较

结构体对象可以包含私有、受保护的、公共字段,包含方法,可以在运行时实例化,与class类型一样。它们的区别有以下几点:(1)结构体不支持继承,属性不能使用自定义的默认值,默认构造函数不能被覆盖。(2)结构体是值类型,而类是引用类型。using System.Collections;using System.Collections.Generic;using UnityEngine;/* * Author:W * 结构体类型 【注意:值类型】 * 使用场景:如果使用类的唯一目的是在程序中向某
原创
21阅读
0评论
0点赞
发布博客于 2 月前

性能优化:值类型与引用类型

C#类型有值类型与引用类型之分:值类型:既可以分配在栈上也可以分配在堆上。像 bool/int/float这些基础数据类型都是值类型。它们通常是分配在栈上,但一旦值类型包括在引用类型中,如类或数组时,表明该值对于栈而言太大,或存在的时间需要比当前的作用域更长,因而必须分配在堆上,与包含它的引用类型绑定在一起。引用类型:由于引用类型的复杂性、大小和使用方式,它们会(或需要)在内存中存在一段时间,像大的数据集和从类实例化的任何类型的对象、数组(不管是值类型的数组还是引用类型的数组)、委托等。它们才会被GC标
原创
69阅读
0评论
0点赞
发布博客于 2 月前

性能优化:内存管理之手动JIT编译

如果JIT编译导致运行时性能下降,实际上有可能在任何时刻通过反射强制进行方法的JIT编译。反射是C#的一项特性,它允许代码库探查自身类型信息、方法、值和元数据。使用反射是一个非常昂贵的过程,应该避免在运行时使用,最好在初始化或者其他加载时间使用。否则容易导致严重的CPU峰值和游戏卡顿。using System.Collections;using System.Collections.Generic;using UnityEngine;/* * Author:W * JIT C#反射 */pu
原创
18阅读
0评论
0点赞
发布博客于 2 月前

性能优化:内存管理之手动垃圾回收与资源卸载的策略

托管代码的垃圾回收机制是一般自动完成的,但是我们可以通过在合适的时间手动触发一下垃圾回收,是对内存的消耗和效率是有优化作用的。但是,所谓的合适时间又是什么呢?一般推荐确定玩家不会注意到的这种行为时,就可以偷偷触发垃圾回收。比如场景加载、切换时,游戏暂停时,或者打开菜单界面的瞬间。垃圾回收可以通过**System.GC.Collect()**手动调用。另外,Unity引擎某些特定对象类型,它们自己实现了IDisposible接口类,例如:NetworkConnection,WWW,UnityWebReque
原创
18阅读
0评论
0点赞
发布博客于 2 月前

性能优化:分析内存消耗与效率

关于内存管理的问题,我们主要关心消耗了多少内存,以及分配新内存块的频繁程度。内存消耗:Unity标签与Mono标签,它们代指的意义如下截图:上面可以根据上面的可以知道内存的消耗状况。接着关于新内存分配效率的指标,观察GC的行为,它做的工作越多,所产生的浪费就越多,而程序的性能就越差。把Profiler窗口的CPU Usage Area(GarbageCollector复选框)和Memory Area(GC Allocated复选框)都勾选上,以观察GC的工作量和执行时间。...
原创
71阅读
0评论
0点赞
发布博客于 2 月前

性能优化:代码编译

当我们修改了C#代码时,返回Unity编辑器时,我们会看到右下角的菊花”在转动,说明C#代码在编译,那它编译成什么呢?它会转换成通用中间语言CIL,而不是本地机器代码(一种直接运行在特定平台的代码)。CIL这种语言有点儿类似Java字节码,而我们知道有Java虚拟机,虚拟机是Java代码实现可以跨平台运行的原因。同理,C#代码转换生成的CIL代码,也是通过Mono虚拟机实现跨平台运行的原因。Mono虚拟机是.Net公共语言运行时CLR的一个实现。在CLR中,中间CIL代码根据需要编译成本地代码。这种编译通
原创
18阅读
0评论
0点赞
发布博客于 2 月前

性能优化:垃圾回收

在本地代码中,如C++代码编写的语言,它的内存分配是通过手动处理,开发者需要自己来控制内存的分配与释放,如果没有进行正确地内存释放,那很容易发生内存泄漏,因为可能会持续从RAM中分配越来越多的内存,但没有进行清理,直到内存没有可以分配,导致最后的结果是程序崩溃。然而,在托管代码中,如C#代码,它的内存释放是通过垃圾回收器来处理。在Unity程序初始化期间,Mono平台向操作系统申请一串内存。用于生成堆内存空间(俗称托管堆),供C#代码使用。这个堆空间开始时相当小,不到1兆字节,但是随着代码需要的新的内存块
原创
22阅读
0评论
0点赞
发布博客于 2 月前

性能优化分析:Unity游戏引擎的Mono平台和内存域

很多开发者只知道Unity引擎有个什么Mono平台,但很少人会真正了解Mono到底是个什么东西,而它与Unity引擎之间的关系又是什么样的。另外,Unity引擎的内存又是怎么划分的呢?Mono平台 是一个开源项目,是基于API、规范和.Net Framework的工具构建了自己的类库平台。介绍特点(1)跨平台性:它的作用是通过框架提供跨平台开发:允许多种可以编译为.NET的通用中间语言(CIL)的通用编程语言(如:C#、Java、VB.NET、UnityScript等)编写的代码运行在很多不同的硬件平台
原创
41阅读
0评论
0点赞
发布博客于 2 月前

性能优化:游戏对象之间的通信方式比较之消息系统

第4种:消息传递系统。任何游戏对象都可以通过该系统把消息传递给任何可能该消息感兴趣的对象。using System.Collections;using System.Collections.Generic;using UnityEngine;/* * Author:W * 消息系统 *//// <summary>/// 消息基本类型/// </summary>public class Msg{ public string type; public Ms
原创
10阅读
0评论
0点赞
发布博客于 2 月前

性能优化:游戏对象之间的通信方式比较之单例组件

第3种:上一篇介绍了的静态类, 本篇介绍游戏中常用的单例组件。它与静态类最大的区别是可以利用MonoBehaviour的事件回调,协程等特性。比较适合于游戏的管理器类、事件分发等系统并共外界访问调用。MonoBehaviour脚本组件单例模式继承基类脚本如下using System.Collections;using System.Collections.Generic;using UnityEngine;/* * Author:W * MonoBehaviour组件单例模式 */publ
原创
15阅读
0评论
0点赞
发布博客于 3 月前

性能优化:游戏对象之间的通信方式比较之静态类

第2种:使用静态类,一般比较适用于游戏项目中作为“工具”的类实现方式。不能创建实例,体现了单例设计模式的思想,与下篇博客介绍的单例组件组件大体功能等价。using System.Collections;using System.Collections.Generic;using UnityEngine; /* * Author:W * 静态类,全局可访问 */public static class StaticClassTest{ public static int fram
原创
11阅读
0评论
0点赞
发布博客于 3 月前

性能优化:游戏对象之间的通信方式比较之Inspector面板赋值引用

Unity中可以通过Find和SendMessage()方法来实现2个游戏对象之间的访问调用。但是,这种方式开销很大,应该尽量避免使用或者少用。这里介绍几种开销较小常用方法,但每种方式都有其优缺点。第一种:在Inspector面板“暴露”出这些变量字段(也包含被 private修饰的,可以通过[SerializeField]属性修饰即可“暴露”)。值得注意的是,并不是所有对象可以序列化并显示在Inspector窗口中。可显示的包括:基本数据类型(int,float,string,bool等),各种内置类型
原创
13阅读
0评论
0点赞
发布博客于 3 月前

性能优化:自定义Update层

我们知道尽量少在MonoBehaviour脚本的Update回调中处理逻辑,对游戏性能影响比较大。但是有些逻辑又必须写在Update中,比如游戏AI模块,或子系统更新等。更糟糕的是,如果又要求当前场景中有成千上万的NPC敌人在场时,如果每个NPC都有Update回调都执行的话,而且它们极有可能在同一帧触发,这会产生一个巨大的CPU使用峰值。Unity调用Update时,会经历本机-托管桥接,而这是非常耗性能的。换句话来讲,执行10000个Update()回调要比在执行1个Update回调但执行10000个“
原创
33阅读
0评论
0点赞
发布博客于 3 月前

性能优化:叠加、异步地加载场景

我们比较熟知从当前场景切换到另一个场景,然而,其实可以在不卸载前一个场景的同时,再加载一个新的场景“资源”并叠加到当前游戏场景中去。可以通过SceneManager.LoadScene()函数的LoadSceneMode参数进行切换。一般的认知中,我们可以将一个关卡等同于一个场景,进入开启下一个关卡,相当于加载进入下一个场景中。然而,对于部分游戏而言,玩家被“限制”在同一个“关卡场景”中,因为Unity可以通过叠加式加载时,支持多个场景同时加载,所以,我们这里可以将每个场景等价于一个关卡的一小部分。关卡初始
原创
24阅读
0评论
0点赞
发布博客于 3 月前

性能优化:反序列化

Unity有场景文件、预设体、ScriptableObject和各种资产类型(派生自ScriptObject)。当它们需要保存至磁盘时,需要转换为文本文件,Unity称之为“序列化文件”。而在运行时需从磁盘读取和反序列化为原始对象类型,但这是非常非常耗时的操作。这种反序列化在调用Resource.load时发生。因此,场景开始时,你会发现有些场景加载时间会比较长,因为它们开始需要的加载资源太多,会增加加载时间。另外,在运行时动态加载资源它们时,也可能会导致掉帧现象。因此,为了让玩家能快速进入游戏场景以及玩的
原创
30阅读
0评论
0点赞
发布博客于 3 月前

性能优化:使用距离平方而不是距离

CPU比较擅长浮点数相乘,但不擅长计算它们的平方根。magnitude属性,Distance()方法,会执行平方根计算,会消耗大量的CPU开销。sqrMagnitude属性,距离的平方,但不需要昂贵平方根计算。using System.Collections;using System.Collections.Generic;using UnityEngine;/* * Author:W * 距离的平方 */public class SqrMagnitudeTest : MonoBehavio
原创
39阅读
0评论
0点赞
发布博客于 3 月前

性能优化:禁用未使用的脚本和对象

某些游戏项目关卡地图场景很大,而对于玩家而言,他的可视区域只是场景地图一小部分。而那些非可视区域的游戏对象还是还一直在“后台”执行游戏逻辑中,其实是没必要的,而且会对性能造成很大影响。Unity引擎在渲染层面已经做了一些优化:(1)自动对相机视图不可见的游戏对象避免去渲染,称之为“视锥剔除”技术;(2)自动避免渲染隐藏在其他对象后面的对象,称之为“遮挡剔除”技术;但是,它不会影响在CPU上执行任务的脚本组件,比如:AI脚本、UI界面和其他的游戏逻辑。这些必须由我们自己手动来控制。因此,这里列举2种策
原创
9阅读
0评论
0点赞
发布博客于 3 月前

性能优化:关于GameObject/Monbehaviour等Unity对象的空引用检查以及取出字符串属性tag/name成本开销

GameObject和MonoBehaviour是特殊对象,它们在内存中有2种表示:一个表示存在于管理C#代码的相同系统管理的内存中,C#代码是用户编写的(托管代码);另一个表示存在于另一个单独处理的内存空间中(本机代码)。数据可以在两个内存空间之间移动,但是每次移动都会导致额外的CPU开销和可能的额外内存分配。这种现象称为“跨越本机-托管的桥接”。如果发生这种情况,就可能会为对象的数据生成额外的内存分配,以便跨桥复制,这需要垃圾收集器最终执行一些内存自动清理操作。这里以GameObject对象空引用检查和
原创
46阅读
0评论
0点赞
发布博客于 3 月前

性能优化:Update Coroutines 和 InvokeRepeating

Update函数是每帧回调的,最好只把必须在Update计算处理执行的逻辑放在其中,因为它是每帧都会执行的,对帧率影响比较大。另外,即使对必须放在Update函数中执行的计算,看看是否可以降低执行“频率”,在保证正确计算结果情况下。协程Coroutine:它不是线程,线程可以并发方式在完全不同的CPU内核上运行,而且多个线程可以同时运行。然而,协程以顺序的方式在主线程上运行;因此在任何给定时刻只能处理一个协程,每个协程通过yield语句决定何时暂停和继续。协程的执行频率与yield语句相关,WaitFor
原创
45阅读
0评论
0点赞
发布博客于 3 月前

性能优化:共享计算输出

如果这个计算比较复杂耗时比如:(1)在场景中中查找对象(2)从文件中读取数据、解析数据(XML或Json)(3)在大字典或List或数组中找目标内容 (4)为一组AI计算路径 (5)复杂的数学轨迹(6)光学追踪等等。如果很多对象需要共享这个结算结果的话,我们可以就只计算一次结果,然后将结果分发给需要它的每个对象。用例脚本如下:using System.Collections;using System.Collections.Generic;using UnityEngine;/* * Author
原创
18阅读
0评论
0点赞
发布博客于 3 月前

性能优化:缓存组件引用

在实际项目中,我们会在写一些API函数时,里面会调用其他组件来实现某些功能,并且这个API会被外界频繁地访问调用。如果这些组件在API每次调用时重复获取,这会比较吃CPU开销。然而,这些组件只需在初始化时获取一次缓存起来即可。这样虽然牺牲了一些内存,但对CPU减轻了压力。用例脚本如下:using System.Collections;using System.Collections.Generic;using UnityEngine;/* * Author:W * 缓存组件引用 * 目的:不需
原创
11阅读
0评论
0点赞
发布博客于 3 月前

性能优化:移除继承自MononBehaviour类脚本中“空回调”函数

Unity项目中经常创建编写继承自MonoBehaviour类的脚本,而且开发工具会自动帮生成Start()/Update()等父类的方法。需要在目标方法中添加一些代码逻辑。然而,我们常常会忘记或者忽略了把空的方法删除,殊不知这些空回调函数也会蚕食一点CPU性能。下面来做个测试:创建不带Update方法的脚本:MonoNoCallBack,并绑定到一个游戏对象MonoNoCallBack上做成预设using System.Collections;using System.Collections.Gen
原创
13阅读
0评论
0点赞
发布博客于 3 月前

性能优化:获取组件3种方式消耗的性能对比

组件访问是我们常用的API,访问的方式大概有以下三种:GetComponent(“组件名”)、GetComponent()、GetComponent(typeof(组件名称))。测试脚本如下:using System.Collections;using System.Collections.Generic;using UnityEngine; /* * Author:W * 获取组件的方法的性能对比 */public class GetComTest : MonoBehaviour {
原创
20阅读
1评论
0点赞
发布博客于 3 月前

Unity检测玩家PC端鼠标或者移动端手指是否按在了UI上面

using System.Collections;using System.Collections.Generic;using UnityEngine;/* * Author:W * 检测PC端鼠标或者移动端手指是否按在了UI区域 */public class UIZoneTest : MonoBehaviour{ private bool isClickUIZone = false; /// <summary> /// 标记玩家是否在按在了UI区域
原创
25阅读
0评论
0点赞
发布博客于 3 月前

性能分析:针对代码片段执行消耗CPU时间估算的方式2:自定义计时和日志记录工具类

方式二:通过Stopwatch对象来实现计时功能,并加上Log日志可以实现通过看Log日志来查看该段代码执行所消耗的时间。封装的计时器脚本类如下:using System;using System.Diagnostics;/* * Author:W * 代码执行时间计算工具:通过Stopwatch对象来实现 */public class ScrptProcessTimer : IDisposable{ /// <summary> /// 定时器名称 //
原创
13阅读
0评论
0点赞
发布博客于 3 月前

性能分析:针对代码片段执行消耗CPU时间估算的方式1:Profiler.BeginSample()和EndSample()

如果我们想要知道某个代码片段执行具体消耗的时间,以用来评估它对性能的影响的话。有2种方式可以实现。方式一:通过Unity引擎内置的Profiler.BeginSample()和EndSample()方法。
原创
31阅读
0评论
0点赞
发布博客于 3 月前

性能优化分析:工具Profiler真机调试方式二(ADB即USB连线调试)

这篇博客介绍USB真机调试。首先用USB连接PC和测试机,接着打开手机的USB调试模式。然后,进入Android SDK的安装下adb.exe目录按住Shift+点击鼠标右键,进入菜单“在此处打开命令窗口”,输入如下命令行:adb forward tcp:34999 localabstract:Unity-com.a.b回车即可。然后回到Unity,打开Profiler工具窗口,下拉选择“ADB”调试模式,再点击Record开启监测。前一篇博客介绍了wifi调试,两者对比,一般来讲,ADB即U
原创
19阅读
0评论
0点赞
发布博客于 3 月前

性能分析优化:工具Profiler真机调试方式一(WiFi连接)

游戏性能优化连接真机调试,才能真实反映游戏手机上运行时的性能状况,发现导致性能瓶颈的原因所在。Unity连接真机做性能调试的方式有2种,第1种是通过PC端和Android手机都无线连接同一个wifi网络来实现;第2种方式是通过ADB这个调试工具套件来实现。这篇博客先介绍wifi连接调试性能。首先,让PC端和测试手机连接同一个wifi;然后打开Build Settings设置面板,勾选如下2个选项再打开Player Settings面板,勾选如下选项接着用USB线把测试手机与PC端连接起来,点击Bu
原创
40阅读
0评论
0点赞
发布博客于 3 月前

UnityWebRequest的Post请求与JSON数据格式

先导入LitJson.dll文件库创建CustomCertHandler脚本,关于证书处理using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.Networking;/* * Author:W * 自定义证书处理 */public class CustomCertHandler : CertificateHandler{ protected o
原创
106阅读
1评论
1点赞
发布博客于 4 月前

Animation组件的使用

/** * Author:W * 动画组件Animation的使用 */cc.Class({ extends: cc.Component, properties: { }, // LIFE-CYCLE CALLBACKS: onLoad () { this.anim = this.getComponent(cc.Animation); //动画状态事件回调注册 this.anim.on(
原创
711阅读
0评论
0点赞
发布博客于 5 月前

弹幕文本底框随文本内容大小自适应

弹幕消息对象的结构如下弹幕底框的设置如下VIP图标和文本设置成底框的子节点控制脚本如下using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;using TMPro;using ZheJiangVR;using Newtonsoft.Json;/** Author:W* 弹幕对象UI*//// <summary>///
原创
70阅读
0评论
0点赞
发布博客于 5 月前

音效组件的使用

/** * Author:W * 音效组件使用 */cc.Class({ extends: cc.Component, properties: { audioSource:{ default:null, type:cc.AudioSource, } }, // LIFE-CYCLE CALLBACKS: // onLoad () {}, start () {
原创
26阅读
0评论
0点赞
发布博客于 5 月前

对象池的使用

/** * Author:W * 对象池 */cc.Class({ extends: cc.Component, properties: { enmyPrefab:{ default:null, type:cc.Prefab, } }, // LIFE-CYCLE CALLBACKS: onLoad () { this.initPool(); },
原创
15阅读
0评论
0点赞
发布博客于 5 月前

网络接口

/** * Author:W * 网络接口 * 1.XMLHttpRequest:短连接 * 2.WebSocket:长连接 */cc.Class({ extends: cc.Component, properties: { }, // LIFE-CYCLE CALLBACKS: // onLoad () {}, start () { }, //发起短连接 sendHttpRequest:fun
原创
8阅读
0评论
0点赞
发布博客于 5 月前

脚本模块化访问

Module1.js脚本如下/** * Author:W * */ //定义模块-》开放给其他脚本访问var cfg = { age:20, sex:"Man", load:function(){ this.age = 25; }};//开放作用域,对外开放module.exports = cfg;// //私有变量-》开放给其他脚本访问// var isStarted = false;// module.exports
原创
12阅读
0评论
0点赞
发布博客于 5 月前

计时器

/** * Author:W * 计时器 */cc.Class({ extends: cc.Component, properties: { }, // LIFE-CYCLE CALLBACKS: // onLoad () {}, start () { // this.setSchedule(); // setTimeout(function(){ // this.u
原创
10阅读
0评论
0点赞
发布博客于 5 月前

Acton常见的缓动动作

/** * Author:W * 节点的缓动动作:不可以单独存在,它只是用来“修饰”基础动作,可以修改基础动作的时间曲线, * 让动作有快入、缓入、快出等复杂的特效。只有时间间隔动作才支持缓动动作。常见缓动动作参照表如下: * * cc.easeIn 创建easeIn缓动对象,由慢到快 * cc.easeOut 创建easeOut缓动对象,由快到慢 * cc.easeInOut 先由慢到快,再由快到慢 * * cc.easeExponentialIn * cc.easeExponen
原创
95阅读
0评论
0点赞
发布博客于 5 月前

Action动作完成回调

/** * Author:W * 动作回调函数:经常配合顺序动作一起使用 */cc.Class({ extends: cc.Component, properties: { }, // LIFE-CYCLE CALLBACKS: onLoad () { }, start () { //回调函数1 var opt; var callBack1 = cc.callFunc(
原创
22阅读
0评论
0点赞
发布博客于 5 月前

Action常见容器动作API

/** * Author:W * Node节点的常见的"容器"动作:实质是把不同元动作按照一定方式组合起来,从而实现较为复杂的动作效果。 * 1.cc.sequence:动作一个接一个地完成。 * 2.cc.spawn:所有动作同步执行。 * 3.cc.repeat:多次执行同一个动作。 * 4.cc.repeatForever:指无限次执行同一个动作。 * 5.cc.speed:让动作更快或更慢地执行。 */cc.Class({ extends: cc.Component,
原创
6阅读
0评论
0点赞
发布博客于 5 月前

Action常见的即时动作API

/** * Author:W * Node节点的常用即时动作【继承自cc.ActionInstant】:指立即执行的动作。参照表如下: * cc.show 立即显示 * cc.hide 立即隐藏 * cc.toggleVisibility 显示和隐藏状态切换 * cc.removeSelf 从父节点移除自己 * cc.flipX x轴翻转 * cc.flipY y轴翻转 * cc.place 放置在目标位置 * * cc.callFunc 执行回调函数 * * cc.targe
原创
33阅读
0评论
0点赞
发布博客于 5 月前

Action常见的时间间隔动作API

/** * Author:W * Node节点的常见时间间隔动作【继承自cc.ActionInterval】:在一定时间间隔内完成的渐变动作。参照表如下: * cc.moveTo 移动到目标位置 * cc.moveBy 移动目标偏移量到目标位置 * * cc.rotateTo 旋转到目标角度 * cc.rotateBy 旋转目标偏移量到目标角度 * * cc.scaleTo 缩放到目标倍数大小 * cc.scaleBy 缩放目标缩放量到目标大小 * * cc.skewTo 偏斜
原创
53阅读
0评论
0点赞
发布博客于 5 月前

Action API的使用

/** * Author:W * Action动作API的使用 */cc.Class({ extends: cc.Component, properties: { }, // onLoad () {}, start () { this.startMovement(); setTimeout(function(){ cc.log("获取动作对象:"+this.getActionB
原创
23阅读
0评论
0点赞
发布博客于 5 月前

重力感应事件

/** * Author:W * 重力感应事件 */cc.Class({ extends: cc.Component, properties: { }, // LIFE-CYCLE CALLBACKS: onLoad () { //开启重力感应 cc.systemEvent.setAccelerometerEnabled(true); cc.systemEvent.on(cc.Syste
原创
22阅读
0评论
0点赞
发布博客于 5 月前

键盘事件

/** * Author:W * 键盘事件 */cc.Class({ extends: cc.Component, properties: { }, // LIFE-CYCLE CALLBACKS: onLoad () { cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN,this.onKeyDown,this); cc.systemEvent.on(
原创
12阅读
0评论
0点赞
发布博客于 5 月前

触摸事件

/** * Author:W * 触摸事件 */cc.Class({ extends: cc.Component, properties: { }, // LIFE-CYCLE CALLBACKS: // onLoad () {}, start () { this.node.on(cc.Node.EventType.TOUCH_START,function(event){ cc.log
原创
23阅读
0评论
0点赞
发布博客于 5 月前

鼠标事件监听注册

/** * Author:W * 鼠标事件 */cc.Class({ extends: cc.Component, properties: { }, // onLoad () {}, start () { this.node.on(cc.Node.EventType.MOUSE_DOWN,function(event){ cc.log("鼠标在目标节点区域按下时"); });
原创
21阅读
0评论
0点赞
发布博客于 5 月前

事件的监听关闭以及发射

/** * Author:W * 事件:监听、关闭以及发射 * 1.通过this.node.on()函数来注册监听 * 2.通过this.node.off()函数来关闭监听【注意:必须与注册监听时参数一致,否则不能关闭失效】 * 3.通过this.node.emit()函数来发射事件 * 4.也可以通过this.node.dispatchEvent()函数来发射事件【特别之处:可以当做事件来传递】 */cc.Class({ extends: cc.Component, pr
原创
18阅读
0评论
0点赞
发布博客于 5 月前

AssetManager加载远程资源

/** * Author:W * 使用AssetsManager加载远程资源 */cc.Class({ extends: cc.Component, properties: { }, // LIFE-CYCLE CALLBACKS: onLoad () { this.loadRemoteUrlAsset(); }, start () { setTimeout(function(){
原创
347阅读
0评论
0点赞
发布博客于 5 月前

resources文件夹下资源的加载与卸载

/** * Author:W * resources资源的加载与卸载 * cc.resources只能加载应用包和热更新的本地资源 */cc.Class({ extends: cc.Component, properties: { }, // LIFE-CYCLE CALLBACKS: onLoad () { this.loadResourceAssets(); }, start () { set
原创
365阅读
0评论
0点赞
发布博客于 5 月前

场景的加载和预加载

/** * Author:W * 场景加载和预加载 */cc.Class({ extends: cc.Component, properties: { }, // LIFE-CYCLE CALLBACKS: // onLoad () {}, start () { //Next场景预加载 cc.director.preloadScene("Next",this.onPreloadScene);
原创
55阅读
0评论
0点赞
发布博客于 5 月前

节点的创建克隆以及销毁

/** * Author:W * 节点的创建、克隆、销毁 */cc.Class({ extends: cc.Component, properties: { sprite:{ default:null, type:cc.SpriteFrame, }, prefab:{ default:null, type:cc.Prefab,
原创
17阅读
0评论
0点赞
发布博客于 5 月前

组件脚本函数的声明周期

/** * Author:W * 组件脚本的生命周期 */cc.Class({ extends: cc.Component, properties: { }, // LIFE-CYCLE CALLBACKS: //在“节点”的首次激活时触发,在start方法调用前执行。一般进行初始化的操作,都放在这里。 onLoad () { cc.log("onLoad 执行"); }, //在“组件”首次激活
原创
14阅读
0评论
0点赞
发布博客于 5 月前

关于Node节点的操作API

/** * Author:W * 关于节点的操作 */cc.Class({ extends: cc.Component, properties: { parentNode:{ default:null, type:cc.Node, } }, // LIFE-CYCLE CALLBACKS: // onLoad () {}, start () {
原创
19阅读
0评论
0点赞
发布博客于 5 月前

变量的访问方式

方式1:通过全局变量的方式来访问variable.js/** * Author:W * 对已有变量的访问 * 方式1:通过全局变量访问 * 方式2:通过模块访问 */ //方式1:设置全局变量:【注意:使用全局变量需谨慎,不要滥用】 window.Global={ gNode:null };cc.Class({ extends: cc.Component, properties: { }, // LIFE-CYCLE C
原创
71阅读
0评论
0点赞
发布博客于 5 月前

子节点的访问

/** * Author:W * 节点的查找 */cc.Class({ extends: cc.Component, properties: { }, start () { //当前节点的子节点的获取 var childNodes = this.node.children; childNodes.forEach(child => { cc.log("child
原创
9阅读
0评论
0点赞
发布博客于 5 月前

节点或组件的访问方式

/** * Author:W * 节点或组件的访问方式 * 方式1:属性面板设置 * 方式2:脚本中动态获取:通过节点node和getComponent() *///引入其他类var Test = require("Test");cc.Class({ extends: cc.Component, //方式1:通过属性面板直接设置 properties: { player:{ default:null,
原创
10阅读
0评论
0点赞
发布博客于 5 月前

属性的声明方式

/** Author:W* 属性的声明 */cc.Class({ extends: cc.Component, //属性的声明 properties: { //1.一般属性声明方式 id:1, //number类型 name:"Wlq",//字符串型 lod:true,//布尔型 target:null,//object node:cc.node,//节点 pos
原创
41阅读
0评论
0点赞
发布博客于 5 月前

类的定义声明以及继承

//创建一个类,并赋值给一个变量【父类】var Sprite = cc.Class({ name:"SpriteName",//类名,用于序列化,一般可省略 //构造函数的声明 ctor:function(){ //类型判断 cc.log(this instanceof Sprite); cc.log("这是父类的构造函数"); }, //实例方法的声明 print:function(){ cc.log
原创
72阅读
0评论
0点赞
发布博客于 5 月前

获取毫秒级的时间戳

项目中需要获取毫秒级的时间戳,实现方式如下: /// <summary> /// 当前时间戳 【毫秒级】 /// </summary> public long CurrentTimeStamp { get { //将c# DateTime时间格式转换为Unix时间戳格式 System.DateTime ti
原创
25阅读
0评论
0点赞
发布博客于 5 月前

MD5码

前后端关于关键信息数据论证,防止被篡改了,需要MD5码比对校验,以保证数据的准确可靠。本人参与的公司项目前端使用Unity C#,后台是Java实现的。因此,在这里贴出自己写的MD5生成的工具类。服务端Java代码实现如下:public class Md5Util { private static final ThreadLocal<MessageDigest> MESSAGE_DIGEST_CACHE = new ThreadLocal<MessageDigest>()
原创
143阅读
0评论
1点赞
发布博客于 5 月前

AES加密算法

关于登录认证一块儿,往往由于信息数据比较重要,防止传输过程中被篡改之类,前后端需要对这部分数据进行加解密处理。由于项目前端是C#,后台是Java实现的,贴出这两种语言实现的AES加密算法工具脚本共参考。服务端Java实现如下:public class AESUtils { //偏移量 public static final String VIPARA = "xxxxxxxxxxxx"; //编码格式 public static final String bm = "ut
原创
44阅读
0评论
0点赞
发布博客于 5 月前

OneWay广告Unity版SDK接入

之前的文章介绍了OneWay广告的注册和测试设备的添加,这篇文章主要介绍如何将OneWay广告集成到游戏项目中去。由于我的游戏是使用Unity引擎开发的,所以主要介绍Unity版SDK的集成过程。登录OneWay后台,点击技术对接,点击下载Unity版SDK。压缩包解压后如下:将OneWaySDK-Unity 2.3.5.unitypackage资源导入到项目工程中但会报一个关于ios平台的错由于我只出Android的apk,因此,将其报错误的脚本关于iOS的代码注释掉即可。Andro
原创
55阅读
0评论
0点赞
发布博客于 6 月前

OneWay应用广告测试设备添加

应用注册后,就可以为该应用添加测试设备了。1.进入OneWay后台,点击技术接入2.点击添加测试设备3.添加测试手机的imei信息。关于Android手机的imei信息的获取有2种方式可参考:一是在拨号界面输入“*#06#”,会弹出关于手机IMEI码的信息。二是点击手机的设置,关于手机菜单项,也可以查看手机的IMEI码。添加完成后至此,测试手机设备添加完成。...
原创
28阅读
0评论
0点赞
发布博客于 6 月前

OneWay广告后台注册申请

自己做了一些小游戏App,想接入广告挣点儿零花钱。查询了一些关于国内游戏广告平台,其中就有OneWay。本着交流学习互鉴的目的,想把关于OneWay广告的接入流程分享给大家,少走些弯路。1.首先,登录OneWay广告后台,点击新建应用。弹出界面,填入要申请的游戏信息。填完信息,点击确定,切换到App基本信息界面继续编辑,上传apk,广告位截图,也可以编辑广告位等,编辑完后,可以点击提交审核。点击应用列表,可以查看已创建的应用状态信息。这样,OneWay后台App广告申请注册已经完成,等待审
原创
87阅读
2评论
0点赞
发布博客于 6 月前

Unity升级导致TextMeshPro引用丢失问题修复

公司项目因某些原因需要升级Unity版本,Unity2018之前的版本,官方没有把TextMeshPro插件集成到Unity当中去,需要手动导入的。当前项目用的是Unity2017.4.23f版本,现在用Unity2018.4.26f版本打开时,会出现场景中游戏对象TextMeshPro组件丢失。且会报一堆关于TextMeshPro的错。说明升级后的项目TextMeshPro组件必须引用Unity2018内部集成的TextMeshPro插件才行。如果项目中有几百个,手动一个一个地赋值,那工作量很大。如何解决
原创
184阅读
0评论
0点赞
发布博客于 6 月前

游戏弹幕系统实现

现在的公司在做一个VR影院的项目,需要实现弹幕聊天功能。在借鉴其它博主的实现思路上,做了一些改编,希望能为大家提供参考。using UnityEngine;using System.Collections;using UnityEngine.UI;using DG.Tweening;using System.Collections.Generic;using System;using TMPro;/* * Author:W * 弹幕系统 */public class BulletMs
原创
104阅读
0评论
2点赞
发布博客于 6 月前

陀螺仪控制相机运动

有时候我们需要通过陀螺仪控制相机的运动。这里有个demo供大家参考using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;/* * Author:W * 陀螺仪控制相机 */public class GvrScopeCtrl : MonoBehaviour { public Transform cameraTran; public Button re
原创
144阅读
0评论
0点赞
发布博客于 6 月前

相机跟随运动目标

有时候我们需要在项目中实现相机随着player的运动而移动,让player始终处于屏幕中心的位置。using System.Collections;using System.Collections.Generic;using UnityEngine;/* * Author:W * 相机跟随运动的目标,使其一直处于屏幕中心 */public class FollowTarget : MonoBehaviour { /// <summary> /// 目标 /// </s
原创
58阅读
0评论
0点赞
发布博客于 6 月前

UGUI-文本输入框改造:点击屏幕其它区域,只会隐藏屏幕键盘,但不会触发提交

UGUI原生的InputField组件,有OnEndEdit事件可以监听,但是有个问题:点击屏幕其它区域也会触发,不只是点“确定”、“前往”、“搜索”等键盘按钮时。这有可能不是我们希望的。看过一些帖子,直接重写InputField组价OnSubmit方法,也是不行的。最后发现它有个_keyboard变量,可以根据它的status状态值来实现:只有点“确定”、“前往”、“搜索”等键盘按钮时,才会触发。但是protected。于是可以这么继承扩展。using System.Collections;using
原创
97阅读
0评论
0点赞
发布博客于 6 月前