Unity怎么用unity脚本控制shader删除Resource 中的图片

10531人阅读
本系列主要参考一书(感谢原书作者),同时会加上一点个人理解或拓展。是本书所有的插图。是本书所需的代码和资源(当然你也可以从下载)。========================================== 分割线&==========================================写在前面最近由于成为研一新生,被入学的各种事情耽误,好久没有更新博客,好惭愧。。。刚收拾好我就来更新博客啦~快表扬我一下。。。前几天有好心人给我提建议说代码和解释分开容易导致学习不连贯,其实我也有这个感觉。我我为什么不写到注释里呢?一个是因为解释的内容比较多,注释里面说不太清楚;更重要的原因是,我的Mono不支持中文输入。。。只能复制粘贴!如果有人知道Mac的Mono里面怎么输入中文可以告诉我。。。为了让学习过程更连贯,以后的“解释”部分大部分都会移到“实现”中每一步的解释里面!这节是一个新的章节,倒数第二章喽~Render Texture是一个非常好用的东西,通过本章我们就来学习如何用它来实现一些画面特效,像老电影效果、雪花效果等等。先来介绍一下本章。学习编写Shader一个很有用的地方就是可以创建各种自定义的画面特效,也被称为后期特效(post effects)。使用这些画面特效,我们可以创建很多美妙的实时图像,例如(Bloom),运动模糊(Motion Blur),(HDR effects)等等。大多数市面上的现代游戏使用了很多这样的画面特效,以此来得到,高光效果,甚至是进行颜色矫正。通过本章,我们将学习如何建立一个脚本系统,来控制创建这些画面特效。我们会学习什么是render texture,什么是深度缓冲,以及怎样像Photoshop那样创建画面特效。通过这些内容,你不仅可以进一步加深Shader知识,还可以自己动脑在Unity中创建很棒的实时渲染。那么怎样创建画面特效呢?一般,我们会抓取一个完整的画面图像(或纹理),使用Shader在GPU上处理它的像素后,再返回给Unity的渲染器渲染到屏幕上,也就是一个后期处理的过程。这允许我们可以对渲染后的游戏图像进行实时地逐像素操作,从而给了我们一个全局的控制能力。我们想象一个场景。我们需要调整游戏最后的画面对比度。如果我们去调整每个材质,虽然的确可能做到,但这会非常麻烦。而通过利用画面特效,我们就可以整体调整画面最后的效果。为了让我们的画面特效系统能够建立并正常运行,我们需要创建一个单独的脚本来作为游戏当前已渲染的图像(也就是Unity的render texture)的通信员。这个脚本会把当前的render texture传递给Shader。我们第一个画面特效是一个非常简单的灰度效果。那,开始吧!准备工作创建一个新的场景,创建一个平行光。创建一个新的C#脚本,命名为TestRenderImage.cs。创建一个新的Shader和Material,命名为ImageEffect。创建一个球体,并把新材质赋给它。这个新的材质可以使用任何Shader,这里我们使用一个简单的红色高光反射材质,Specular Material。最后,你的场景大概是这个样子的:实现我们总共需要一个脚本和一个Shader。脚本:负责在编辑中实时更新图像,同时也负责从主摄像机抓取render texture,然后把该texture传递给Shader。Shader:一旦render texture到达Shader后,我们就在这里面进行逐像素操作。首先,我们来实现C#脚本。为了让我们在Unity非运行时刻,也可以实时编辑和查看画面效果,我们需要在TestRenderImage类的上面声明下面的语句:[ExecuteInEditMode]
public class TestRenderImage : MonoBehaviour {解释:ExecuteInEditMode的文档在。通常,一个脚本仅会在play模式下运行。而添加了这个声明后,我们的脚本就可以进行一些回调函数,即使Unity并不是在play模式下。而我们常见的一些回调函数的回调方式也有所不同:Update:在scene发生变化时被调用OnGUI:在Game视图接受到Event时被调用OnRenderImage:在Scene视图或Game视图重绘时被调用打开TestRenderImage.cs脚本。首先我们添加一些新的变量:public class TestRenderImage : MonoBehaviour {
#region Variables
public Shader curS
public float grayScaleAmount = 1.0f;
private Material curM
#endregion解释:这里面的#region没有实际作用,仅仅是方面coder阅读源码~因为我们的画面特效要使用Shader来执行对画面图像的像素操作,所以我们需要创建一个材质来运行Shader。如果没有材质,我们就不可以访问Shader的属性。因此,我们在C#中创建一个属性来检查是否有这样一个材质,如果没有就创建一个。 #region Properties
public Material material {
if (curMaterial == null) {
curMaterial = new Material(curShader);
curMaterial.hideFlags = HideFlags.HideAndDontS
return curM
#endregion现在,我们需要建立一些检查,来看看当前的游戏平台是否支持画面特效。如果不支持,我们在脚本的一开始就disable它: // Use this for initialization
void Start () {
if (SystemInfo.supportsImageEffects == false) {
if (curShader != null && curShader.isSupported == false) {
}为了真正从Unity渲染器中抓取被渲染过的图像,我们需要使用Unity内置的OnRenderImage函数。下面的代码允许我们访问当前被渲染的图像: void OnRenderImage (RenderTexture sourceTexture, RenderTexture destTexture){
if (curShader != null) {
material.SetFloat(&_LuminosityAmount&, grayScaleAmount);
Graphics.Blit(sourceTexture, destTexture, material);
Graphics.Blit(sourceTexture, destTexture);
}解释:一旦通过上述的各种检查,我们就需要调用内置的OnRenderImage函数来实现画面特效。这个函数负责从Unity渲染器中抓取当前的render texture,然后使用Graphics.Blit()函数再传递给Shader(通过sourceTexture参数),然后再返回一个处理后的图像再次传递回给Unity渲染器(通过destTexture参数)。这两个行数互相搭配是处理画面特效的很常见的方法。你可以在下面的连接中找到这两个函数更详细的信息::该摄像机上的任何脚本都可以收到这个回调(意味着你必须把它附到一个Camera上)。允许你修改最后的Render Texture。:sourceTexture会成为material的_MainTex。我们的画面效果需要一个名为的变量,它是用于控制最终屏幕效果的灰度值的。因此,我们需要保证这个值的范围在0到1,0表示没有任何灰度效果,1表示完全灰度化。我们在Update函数里执行这个操作: // Update is called once per frame
void Update () {
grayScaleAmount = Mathf.Clamp(grayScaleAmount, 0.0f, 1.0f);
}最后,由于我们在一开始创建了一个虚拟材质,我们需要在脚本被disable时,销毁该对象: void OnDisable () {
if (curMaterial != null) {
DestroyImmediate(curMaterial);
}完整的TestRenderImage.cs代码如下:using UnityE
using System.C
[ExecuteInEditMode]
public class TestRenderImage : MonoBehaviour {
#region Variables
public Shader curS
public float grayScaleAmount = 1.0f;
private Material curM
#endregion
#region Properties
public Material material {
if (curMaterial == null) {
curMaterial = new Material(curShader);
curMaterial.hideFlags = HideFlags.HideAndDontS
return curM
#endregion
// Use this for initialization
void Start () {
if (SystemInfo.supportsImageEffects == false) {
if (curShader != null && curShader.isSupported == false) {
void OnRenderImage (RenderTexture sourceTexture, RenderTexture destTexture){
if (curShader != null) {
material.SetFloat(&_LuminosityAmount&, grayScaleAmount);
Graphics.Blit(sourceTexture, destTexture, material);
Graphics.Blit(sourceTexture, destTexture);
// Update is called once per frame
void Update () {
grayScaleAmount = Mathf.Clamp(grayScaleAmount, 0.0f, 1.0f);
void OnDisable () {
if (curMaterial != null) {
DestroyImmediate(curMaterial);
现在,我们可以把该脚本赋给当前的主摄像机。你将会看到面板上出现一个grayScaleAmount值以及一个为Shader赋值的区域。现在运行的话,你不会看到任何变化,我们还差一个Shader啦~继续Shader的编写。首先还是需要一些新的属性: Properties {
_MainTex (&Base (RGB)&, 2D) = &white& {}
_LuminosityAmount (&GrayScale Amount&, Range(0.0, 1.0)) = 1.0
}解释:之前提到,通过Graphics.Blit()函数,我们可以把抓取获得的Render Texture作为该材质的_MainTex属性传递给Shader。这次的Shader需要利用纯正的Cg Shader代码,而不是Unity内置的Surface Shader。这会使得我们更加优化画面特效,因为我们仅仅需要去计算render texture的像素。因此,我们创建一个新的pass,并使用一些新的#pragma声明: SubShader {
#pragma vertex vert_img
#pragma fragment frag
#include &UnityCG.cginc&解释:这涉及到了Vertex&Fragment Shader的知识。呜,后面补一篇入门级文章好了。这里简单解释一下。Vertex&Fragment Shader如它的名字一样,需要我们实现两个函数:vertex和fragment。vertex函数负责把模型顶点位置转换到摄像机的透视坐标系中,以及处理模型各顶点对应的纹理坐标等。fragment则负责输出最后屏幕每个像素的颜色值。这里,第一个#pragma指明我们使用名为vet_img的vertex函数,这个函数Unity为我们写好了,在UnityCG.cginc里,它就是完成了两个最简单的计算,计算顶点对应的透视坐标以及纹理坐标。第二个#pragma指明我们使用名为frag的fragment函数,这是在下面的步骤里实现的。为了访问新的属性,我们需要在CGPROGRAM里创建对应的变量:
uniform sampler2D _MainT
fixed _LuminosityA最后,我们仅仅需要编写自己的像素函数,也就是这里的frag()函数。这是画面特效中真正改变画面像素值的地方。这个函数将会处理render texture的每个像素,然后向TestRenderImage.cs返回一个新的图像:
fixed4 frag(v2f_img i) : COLOR
//Get the colors from the RenderTexture and the uv's
//from the v2f_img struct
fixed4 renderTex = tex2D(_MainTex, i.uv);
//Apply the Luminosity values to our render texture
float luminosity = 0.299 * renderTex.r + 0.587 * renderTex.g + 0.114 * renderTex.b;
fixed4 finalColor = lerp(renderTex, luminosity, _LuminosityAmount);
return finalC
}完整的ImageEffect.shader代码如下:Shader &Custom/ImageEffect& {
Properties {
_MainTex (&Base (RGB)&, 2D) = &white& {}
_LuminosityAmount (&GrayScale Amount&, Range(0.0, 1.0)) = 1.0
SubShader {
#pragma vertex vert_img
#pragma fragment frag
#include &UnityCG.cginc&
uniform sampler2D _MainT
fixed _LuminosityA
fixed4 frag(v2f_img i) : COLOR
//Get the colors from the RenderTexture and the uv's
//from the v2f_img struct
fixed4 renderTex = tex2D(_MainTex, i.uv);
//Apply the Luminosity values to our render texture
float luminosity = 0.299 * renderTex.r + 0.587 * renderTex.g + 0.114 * renderTex.b;
fixed4 finalColor = lerp(renderTex, luminosity, _LuminosityAmount);
return finalC
FallBack &Diffuse&
}保存,返回Unity查看。把上述Shader赋给TestRenderImage.cs中的Shader变量。此时,我们改变grayScaleAmount的值就会发现游戏画面的灰度发生了变化(从左到右灰度值分别是0.0,0.5,1.0):&&&&上面的过程展示了我们如何使用一种方便的方法检验画面特效Shader。下面,我们来更深入地了解这其中render texture到底发生了什么变化,以及从头到尾它们到底是怎么被处理的。解释画面特效是顺序处理的,这就像Photoshop中的layers。如果你有多个屏幕特效,你可以按顺序添加给该Camera,那么它们就会按照这个顺序被处理。上述的过程是被简化过的,但通过这些我们可以看出画面特效的核心是如何工作的。最后,我们总结上述使用Render Texture实现画面特效的核心过程:在脚本中检查当前平台对特效的支持;通过OnRenderImage()函数抓取render texture,再通过Graphics.Blit()函数传递给虚拟材质中的Shader进行后处理;Shader的_MainTex即为接收到的render texture,在frag函数里对图像进行逐像素处理后再返回给OnRenderImage函数,得到最后的屏幕画面。
版权声明:本文为博主原创文章,未经博主允许不得转载。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:682950次
积分:8816
积分:8816
排名:第1020名
原创:103篇
转载:20篇
译文:21篇
评论:1309条
我叫乐乐,程序媛一枚,就读于上海交通大学软件学院,研究生,数字媒体方向。感兴趣的领域有人机交互,增强现实,游戏等等啦,我喜欢新奇好玩绚丽的东西和技术~
邮件:lelefeng1992 # gmail DOT com
PS:为防止垃圾邮件,请自行转换为正确格式哦~
阅读:25030
阅读:9966
文章:45篇
阅读:290410
(1)(1)(2)(2)(4)(2)(3)(6)(3)(8)(5)(6)(3)(6)(5)(7)(1)(2)(8)(1)(4)(5)(4)(3)(15)(2)(3)(27)(5)脚本方面 ,官方脚本分:
Runtime Classes : 游戏中使用的脚本,可以操作游戏中所有的GameObject,Components,
&&&&&&Attributes:&&&&&&&&脚本里的用的, 在js代码中以@开头...可以操作脚本中的变量,脚本执行时机,
&&&&&&&Enumerations: 脚本中枚举参数的定义.
Editor classes :  Unity工具修改的脚本.可以给Editor开发插件.也可以修改Unity里的各个视图显示的信息.
&&&&&&&Enumerations : Editor classes里头枚举参数的定义.
官方脚本的说明很详细,还附有代码,多是javaScript.
[ Debug ]&&&&&&&调式类:
Debug.Log(" 在控制台的输出 ");&&&&&&这个语句可以很方便的在控制台里显示信息.控制在在Unity3d软件的下面状态条的地方.在菜单中开启的选项.此代码可以写在任何的方法体内.
Debug.Break() ;&&&&使脚本运行停下来,然后点击运行键可以一帧一帧的执行,但是不可以单步执行.
[ Input ] &&&&&&&&输入类:
一个输入类: 通过次类可以获得鼠标的位置,按键的事件, 如果是iphone上,还可以获得当前几个点触摸,跟触摸的位置.此代码要写在Update()方法体内.
if( Input.GetKey("A") ) {} 当按下a键时响应..
Input.mousePosition 获得鼠标当前位置 返回类型Vector2 .. 坐标为屏幕左下角 0,0 点 .
官方有多个Demo ,都有此功能. 而且其中一个代码有iphone 模拟摇竿的代码 joystate .
可以自行封装 pc mac iphone平台的按键输入. 会用到 Application 类的isEditor方法. 此方法返回运行的程序是否在Unity3d软件下.
Unity中 碰撞检测的发起者有: CharacterController&与 RigodBody&.
能接收到碰撞的有: 所有的Collider ..同时包括CharacterController ,RigodBody..
CharacterController(CC) : 为胶囊状碰状外型. 在运动中会与碰撞发起者,碰撞接收者.发生碰撞,并始终保持与他们分离状态.比如 CC 能站在 mash 的地面上.会撞到BoxCollider上,不能穿越.
通过脚本 character.Move(Vector3)可以修改其所在GameObject的世界位置.此处不能用transform 否则CC会进入其他物体内..
在没有脚本处理下落时,CC 不会下落,还句话说,默认时CC不具备物理特性..
RigodBody (RB) : 为Components 可以与CC 同时为于一个GameObject中. 他使GameObject具有物理的特性.比如下落的重力,比如收外力被击飞...能把其他物体挤跑.等等. 与其碰撞的物体会被调用其下的脚本OnCollisionEnter()脚本.
碰撞接收者 : 当 与发起者碰撞时,会发生反映,并触发其下脚本.当接收者为Trigger时,发生碰撞时,会只发生脚本调用OnTriggerEnter()..不会有真实的物理放映.
所以当你决定用Unity处理复杂碰撞时,需要最开始就定义好,游戏中各个物体的碰撞模型.否则可能会出现冲突.比如2个物体有放映不触发脚本,或是不该相互放映的时候发生反映了。
在目前掌握的情况分析,在Unity中参与碰撞的物体分2大块:1.发起碰撞的物体。2.接收碰撞的物体。
1. 发起碰撞物体有:Rigodbody , CharacterController&.2. 接收碰撞物体由:所有的Collider .
工作的原理为:发生碰撞的物体中必须要有&发起碰撞&的物体。否则,碰撞不响应。比如:墙用BoxCollider ,所以墙与墙之间无反应。比如:一个带有Rigidbody属性的箱子,能落到带有MeshCollider属性的地面上。比如:一个带有Rigidbody属性的箱子,可以被一个带有CharacterController 属性的人推着跑。
就是此原因。
在所有Collider上有一个Is Trigger 的boolean型参数。当发生碰撞反应的时候,会先检查此属性。当激活此选项时,会调用碰撞双方的脚本 OnTrigger***, 反之,脚本方面没有任何反应。当激活此选项时,不会发生后续物理的反应。反之,发生后续的物理反应。
总结:Is Trigger 好比是一个物理功能的开关, 是要&物理功能&还是要&OnTrigger脚本&。
在Rigodbody 上有一个Use Gravity 的boolean型参数.
Unity 物理引擎,处理的一个细节:当一个CharacterController不发生位置变化,一个Collier发生位置变化后,产生碰撞。将不会调用任何碰撞反映。物理引擎视为CharacterController无碰撞.
GUI在3d游戏中 可以用脚本OnGUI() 画2D的前景贴图。比如按钮,血条。等等。步骤:新建空GameObject.加入空脚本脚本中加入OnGUI():每帧都回调用 Update():每帧都会调用。OnGUI()里使用GUI.DrawTexture等方法画贴图。
注 :Unity里默认Resources文件夹为2d资源存放的地方。把2d图片放到里头。创建图片的方法:private var img : Texture2D ;img = Resources.Load( "cmd.png" , typeof(Texture2D) );
阅读(...) 评论() &用心创造滤镜
扫码下载App
汇聚2000万达人的兴趣社区下载即送20张免费照片冲印
扫码下载App
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
绘画、动画、游戏、CG技术研究爱好者。博客文章自由共享,转载时请保持内容完整。
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
什么是Script(脚本)?简而言之,就是使用代码来执行一系列动作命令的特殊文本,它需要编译器来从新解读。U3D内部如何解读脚本,这不是我们所要关心的—这是引擎开发人员的活,我们所要知道的就是脚本的使用规则。【三种语言的特点】U3D支持C#,JavaScript,BOO三种语言格式的代码编写。首先来简单介绍下这三种语言的特点:对U3D来说,这是入门级的脚本语言,U3D内置的函数都能通过JS方便的调用。语法上,JS和传统的C语言差不多,需要分号结束符,变量类型定义,大括号……不过它的变量类型定义,是通过冒号接在变量右边,如:Name:string=”Li”。相对其他两种语言,使用JS语法,很多函数不需要实例化就能直接使用,如:vector3 direction=vector3(1,2,3)。如果使用C#,则需要使用new关键字:vector3 direction=new vector3(1,2,3)。JavaScript直接继承自U3D的MonoBehaviour类,因此不像C#和BOO那样需要使用Using或Import来加载类库。这看似省心,不过因为缺少了加载特殊类库,JavaScript能调用的第三方函数不多(当然,我们可以载入net类库给JavaScript调用,虽然看着有点奇怪……)。*注意:JavaScript不是Java,同时,U3D中的JavaScript也有别于独立的JavaScript语言。C#(发音C Sharp),微软开发的面向对象编程语言。由于有强大的net类库支持,以及由此衍生出的很多跨平台语言,C#逐渐成为U3D开发者推崇的程序语言。U3D内置的脚本范例中,C#脚本也占了很大一部分(其他脚本是JavaScript脚本)。另外,在装有VisualStudio的电脑上,我们也可以使用微软的脚本编辑工具来编写U3D脚本。C开头,那么语法上和C语言是很接近的,除了面向对象语言所具有的一些特点。当然,我不用在这进行太多说明,因为C#的相关学习资料很多。BOO是新兴的基于Python的语言。语法上,BOO和Python大同小异,都是通过换行来实现语句的结束,它省略了分号、大括号,甚至条件语句的小括号等。Python在很多大型三维图形软件上都有应用,由此可以看出它的跨平台性能很不错,我也选择使用Python来编写maya特效脚本;不过,对于游戏事件的编写,个人感到这种精简的语法反而有些难以适应。如基本的变量类型定义,BOO(类Python)语法就显得不那么便捷: direction as vector3 =vector3(1,2,3)。游戏事件不同于特效脚本,前者是过程中的交互,而后者只需要看到结果。因此,游戏中经常需要大量的具有明确类型的变量出现,BOO语言可以省略变量类型的优势在这里反而容易引发问题。引擎编译时,三种语言的执行效率是一样的,因为U3D会内部进行它自己的语言格式的转换。尽管我们可以在不同语言编写的脚本之间进行变量和方法的调用,但是我不推荐那么做,因为测试确实会存在一些意想不到的问题。使用不同语言编写多个脚本时,应尽量让脚本之间没有直接联系。最后,个人认为,在windows平台下,C#是U3D脚本语言的最佳选择。【脚本的使用规则】U3D的脚本作用方式很有趣,我称之为“拖放法”。无论是作用在一个具体的场景物体还是管理着批量的物体,脚本首先必须依附于场景中的一个元素才能被执行。要将脚本赋予物体的方式很简单,就是按住鼠标左键将脚本文件拖放到物体的属性面板上(也可以拖放到场景的物体上)。U3D有个概念,那就是component(成分)--类似Maya的节点。包括脚本,所有元素属性都是游戏物体的component。添加、删除、停用、读取、写入component信息,就是脚本所要做的(尽管脚本也是个component)。net语言的C#,在不同脚本之间调用变量和方法时,如果脚本位于同一路径下,那么只需要对非static(静态)成员进行new实例化即可。例如a.cs和b.cs,要调用脚本a中的一个非静态变量cc,需要在脚本b中写入:a &c=new a(),然后c.cc的格式完成调用。不过,作为一个component,要调用不同脚本之间的成员,U3D的规则是使用GetComponent函数来完成(其实也就相当于new的作用,只是U3D不支持这种脚本间调用的写法)。如:& &&someScript = GetComponent&ExampleScript&();如果是在C#脚本中调用JavaScript脚本,则使用强制类型转换语法:&
someScript = GetComponent(“ExampleScript”) as ExampleS*&&这个特殊的符号表示使用的是C#中的泛型功能,用于避免强制类型的转换,减少装箱量(将值类型专为引用类型的操作)。根据脚本使用的情况,可以有以下做法:1.脚本位于同一个物体上。可直接使用泛型或者类型转换语法调用。如:someScript = GetComponent&ExampleScript&();2.脚本位于不同物体上。需要使用Find或相关的搜索函数,取得指定名称的物体信息后,再+”.GetComponent”函数。如:GameObject.Find("stone").GetComponent&ExampleScript&()。3.脚本位于同一路径或者被调用脚本位于主脚本的路径及以下(脚本是否被物体使用都可)。将被调用脚本中的成员(变量或方法)使用static标识,然后可以通过”脚本.成员”的格式直接调用。例如:ScriptA.CS…public static mm();…ScriptB.CS…ScriptA.mm();…不过,static成员的调用虽然提高了效率,但因为它常驻内存,所以在会产生大量系统资源要求的情况下要慎用。*static是C#定义变量或方法类型的关键字,使用static的变量或方法,不需要new实例化即可直接调用。【脚本内容】除了JavaScript函数,C#和BOO的脚本都需要预先载入类库。这里以C#为例:using UnityEusing System.Cpublic class NewBehaviourScript : MonoBehaviour {}NewBehaviourScript是脚本的名称,它必须和脚本文件的外部名称一致(如果不同,脚本无法在物体上被执行)。所有游戏执行语句,都包含在这个继承自MonoBehaviour类的自创脚本中(大括号内)。以下介绍一些常用的内置运行函数(定义函数时,JavaScript的关键字是function,C#是void,BOO是def。如:void Start()。Awake:在游戏运行时调用,用于初始化。Start&: 只在游戏开始时执行一次,在Awake()函数后执行;Update:在游戏每一帧都执行一次,在Start()函数后执行;LateUpdate:同Update,只是它会在Update()函数执行后再执行;FixedUpdate:当游戏中引入刚体系统,使用适配的方式同步物理时钟,可以让动力学更精确的计算;OnGUI:绘制游戏界面的函数,因为每一帧执行多次,所以一些时间相关的函数要尽量避免直接在其内部使用。OnMouseOver:鼠标停留在物体上时执行该函数的内容。OnMouseEnter:鼠标进入物体范围时执行该函数的内容。和OnMouseOver不同,该函数只执行一次。OnMouseExit:鼠标离开物体范围时执行该函数的内容。OnMouseDown:鼠标按下时执行该函数的内容。OnMouseUp:当鼠标释放时执行该函数的内容。OnMouseDrag:按住鼠标拖动时执行该函数的内容。OnMouse系列函数是针对指定物体的,如果要使用全局鼠标控制操作,则需要使用射线相关函数。还有很多特殊的游戏触发事件的函数,这里就不一一列出。U3D内置的代码有个命名规则,开头第一个字母大写的词组都属于类或者函数,而开头小写的词组则是变量。新手经常会混淆它们之间的区别。简单说来,函数词组可以作为变量的类型,还可以直接执行功能,词组后必接成对小括号;变量是对应函数的分支,实现的是对一个具体属性的控制。例如:Camera和camera。当场景中存在一个默认的主摄像机,脚本位于摄像机时,Camera.mainCamera.transform和camera.transform是等同的;假如脚本在其他物体上,Camera.mainCamera.transform仍旧直接获取了主摄像机,而camera.transform必须要使用Find函数先找到指定名称的摄像机:GameObject.Find("mainCamera").camera.transform。当然,这里是列出细节来比较,实际运用时,脚本位于特殊元素上我们可以不用声明这个元素的类别,如camera.transform可以简化到transform。GameObject和gameObject。前者包含查找,破坏和产生游戏物体的函数,同时可以将一个变量定义为“游戏物体”类型;后者则包含丰富的游戏物体属性,例如名称,变形信息,动画,渲染等。同上面列举的camera,对于直接作用于指定物体的脚本,gameObject也可以省略掉。不过,在开始学写代码时,书写完整的变量名能让我们更深刻的记忆每个属性和变量的关系。通过以上对比后可以这么理解,函数通常是全局控制(包含脚本外的其他物体),而变量是需要指出具体的应用对象。*如果书写代码时语句不在函数作用范围内,编译器将无法智能完成一些变量的全名显示。更多函数的运用方法,用户可参考官方提供的帮助文档。【简单例子】在一个箱子上按下鼠标左键,箱子就开始旋转,同时灯光被点亮,屏幕出现“Test”的字样。1.点击Hierarchy栏下的Create,创建一个Cube,Plane和Spotlight。2.在Assets目录下,创建文件夹(右键,Create-&Folder),用于存放游戏的各种资源:模型,动画,材质,脚本,Prefab等。3.双击进入myScript文件夹,创建一个C#脚本。4.给脚本命名,然后再双击开启脚本编辑工具(如果脚本名称和内部的类名称不同,一定要更正)。5.加入鼠标相关函数,这里我需要用到OnMouseOver,OnMouseExit,OnMouseDown。此类特殊函数不会有智能拼写出现。6.语法方面就不傻瓜式的一步步进行了,实现的思路是:当鼠标移动到物体上,物体的材质色彩变为黄色,同时将一个初始值为假的布尔变量1的值取真;当鼠标离开后,物体材质色彩还原,布尔变量1值为假;当按下鼠标左键,且布尔变量1的值为真,布尔变量2的值为真。*OnMouse函数都是执行一次的函数,因此不能将和动画有关的控制函数放于其内执行,通常会使用布尔开关来控制Update函数中的动画函数。7.接着在Update函数内实现:当布尔变量2的值为真,物体旋转。8.将写好的脚本拖拽到场景中的方块上(或者先选择方块,将脚本拖到方块的属性栏),调好摄像机位置,执行测试;9.因为脚本只作用于其所依附的物体,要控制灯光,我们有两个选择:创建新的脚本,使用查找物体函数。很显然,我没必要为这么简单的功能加入一个新的脚本。因此我使用Find函数获取灯光的强度属性。*脚本中遇到这样一串长长的语句时,通常会使用一个自定义变量来替代,而且很多时候还能降低计算量。例如:float LightInt =GameObject.Find("Spotlight").light.intensity。如果在Start函数中初始化,Update中就不必每帧执行查找函数,降低游戏效率。不过这里作为一个测试,我也就很省事的忽略了。10.GUI的使用。要在游戏视图显示各种UI信息,都需要使用U3D的UI组件或者GUI函数。为方便阅读,我将其他函数的内容收起,并使用GUI函数的Label创建简单的文字显示功能(有关GUI更多的详细信息,请参阅官方文档,我会在后面再做讨论)。11.最终测试:12.发布。执行File-&BuildSettings,开启发布界面。设置好要发布游戏的平台以及一些发布的信息,点击Build按钮即可发布一个完整的游戏客户端。U3D支持发布的平台与用户授权和操作系统有关,如IOS游戏需要MAC平台的U3D才能发布,Android需要在系统安装安卓SDK包,次世代主机平台则需要用户向官方购买额外解决方案。*由于商业策略的分歧,U3D刚宣布了中止flash平台的后续开发,看来想玩U3D开发的网页游戏,还是需要先安装U3D官方的网页插件。【结语】游戏制作并不简单,这里仅仅是一个初入门的小例子,主要是对脚本使用方式的练习。后面会逐步深入学习U3D丰富的函数功能。
阅读(30610)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'【U3D】Unity3D的脚本-script入门',
blogAbstract:'Unity3D的基本操作很容易就能掌握了,接下来就是游戏系统的核心部分:脚本。什么是Script(脚本)?简而言之,就是使用代码来执行一系列动作命令的特殊文本,它需要编译器来从新解读。U3D内部如何解读脚本,这不是我们所要关心的—这是引擎开发人员的活,我们所要知道的就是脚本的使用规则。',
blogTag:'unity,script,u3d,脚本',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:3,
publishTime:2,
permalink:'blog/static/',
commentCount:9,
mainCommentCount:6,
recommendCount:11,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'绘画、动画、游戏、CG技术研究爱好者。博客文章自由共享,转载时请保持内容完整。',
hmcon:'0',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}

我要回帖

更多关于 unity 删除脚本 的文章

 

随机推荐