2015-04-06 20:27:49 baizihan 阅读数 559

【Unity3d】学习笔记(0)

目录

前言

我学习Unity3d的方法是通过实战案例来学习,碰到不知道的概念在反过来查找并理解概念的意思。我认为这样比单纯的了解一大堆概念之后在开始实践要更有趣,更有动力,理解也更深。但是,同时我也认为这种方法比较适合有一些编程经验的人,一些程序设计的通用概念你可能已经驾轻就熟,而Unity特有的概念可能与你熟知的概念有相似性,关联他们,有助于你加深理解。

正文

我选择的第一个实战案例是泰课在线的别踩白块(这里并非帮忙打广告,只是在选择教程时觉得这个拿来入门比较合适)。我也将自己按照教程实践的项目放到了我的GitHub,其中已包含asset资源,欢迎大家来访。(我ignore了许多Unity自行创建的文件,不建议直接使用我的项目)
下面说说我遇到的一些概念:
- 游戏对象(GameObjects)和组件(Component)
- 物理组件 (Physics Component)
- 预设 (Prefabs)
- 向量(Vector)

游戏对象(GameObjects)和组件(Component)

在教程中经常有创建GameObject并将层级视图(hierarchy)中的对象放入其中的操作,那么GameObject是什么?可以直接通过官方文档查看详细信息。这里简单说明下:
GameObject其实是Component(组件)的容器,它们是包含关系。默认的创建的空GameObject包含一个变换组件(Transform Component)且所有GameObject都必须有一个变换组件。变换组件定义了GameObject的位置,旋转和缩放。除变换组件外,GameObject还可以包含其他组件,如常用的脚本组件,物理组件。组件有不同的值和属性(Properties),在构建游戏时可以在编辑器里调整,或者在运行游戏时由脚本来调整。有两种主要类型的属性 :值 (Values) 和引用 (References)。值通常在检视视图 (Inspector)中编辑,引用通常通过将任何其他类型的组件 (Component)、游戏对象 (GameObjects) 或资源 (Assets)拖动到引用下来指定。

物理组件 (Physics Component)

教程中为了实现按钮的响应,为按钮GameObject添加了箱体碰撞体 (Box Collider)的物理组件。然后在脚本组件中编写OnMouseDown函数即可。更多详细信息可参考官方文档

预设 (Prefabs)

教程中把block图片资源放入hierarchy中,此时Unity把其变为GameObject,绑定脚本组件后又拖回到工程视图中就生产了block的prefab。而原来hierarchy中的GameObject是这个prefab的一个实例。预设 (Prefab) 是一种资源 - 存储在工程视图 (Project View) 中可重复使用的游戏对象 (GameObject)。预设 (Prefabs) 可放入到多个场景中,且每个场景可使用多次。向场景添加一个预设 (Prefab) 时,就会创建它的一个实例。所有预设 (Prefab) 实例都链接到原始预设 (Prefab),实质上是原始预设的克隆。不管您的工程中有多少个实例,您对预设 (Prefab) 作薄出任何更改时,您会看到这些更改应用于所有实例。更多详细信息见官方文档
实例化预设,教程中使用了如下方法:

GameObject o = Instantiate(whiteBlock) as GameObject;

获取该GameObject的Component用了如下方法:

Block b = o.GetComponent<Block>();

简单点说就是游戏中需要大量生成的GameObject,就可以将其创建成预设,在代码中批量按需生成。

向量(Vector)

向量运算是制作三维图形、物理和动画的基础,深入了解向量运算有助于充分利用 Unity 的大部分功能。更多关于向量的信息可参考官方文档。教程中使用向量来设置transform组件的position值:

gameObject.transform.position = new Vector3 (xOff + colIndex * 1.5f, yOff + rowIndex * 2.8f);
2014-03-31 22:26:05 inspironx 阅读数 5969

TexturePacker可以将游戏素材零碎的图片打包在一块,这样更方便读取

而与Unity3d prefabs组合起来使用,使得读取图片达到一个速率更高的层次


TexturePacker:

a.下载最新版的TexturePacker软件

b.打开软件后,点击Add Sprites,添加一些图片

c.然后点击View-textureSettings打开设置面板

d.选择Unity - JSON data(.txt)


e.选择存放目录,回到主界面,点击publish

会在目录下生成两个文件,一个.txt,另一个是.png图片集


在Unity3d中使用:

a.创建一个Empty Object,再在项目视窗中创建一个Material

b.将生成的两个文件加到项目视窗中

c.将Material的Shader选择为Unlit/Transparent Colored

d.用刚生成的.png作为Material的贴图

e.将NGUI的UIAtlas(Script)加载到刚创建的Empty Object上


UIAtlas(Script):中的可选参数


Atlas Type:图片集的类型,Normal,Reference(引用已经做好的图片集)

Material:材质,选择我们刚做好的材质

TP Import:图片集的分割选项

Pixel Size:相素比例


将TP Import中加载生成的.txt后会生成Sprite分割选项,至此,Unity3d与TexurePacker的配合使用完成

然后制作成prefabs,在后续创建的Widget中可以引用到


Unity3d NGUI的使用(四)(TexturePacker与UIAtlas生成prefabs)

2017-12-21 18:23:27 hanxiaoyuan32 阅读数 3418

Unity3D

Unity基本操作

Unity基本单位为米,ue4是厘米

Rotation 为度,监事面板是角度,代码里计算的结果是弧度

Scale的单位是倍数。负数为左右镜像

 

创建工程

必要文件夹:

Sences

Scripts

Prefabs

 

工程结构

 

Assets所有素材都在里面,迁移必须

Library临时文件库,迁移工程时不拷贝,临时生成

ProjectSettings 项目设置-projecversion 项目版本号,迁移必须

Temp缓存文件,可以不拷贝。

Meta文件都是unity生成的导入配置信息,例如图片的分辨率,压缩方式,版本控制时,例如svn一般不上传。

X轴旋转到正负90度,会发生万向死锁

组成

Scene(场景)

编辑游戏中所有的内容

右键控制视角,右键+w/s/a/d,对应视角移动操作。

按住鼠标中间切换移动,松开切换回来

Game(游戏窗口)

游戏中真正显示的内容

Project(资源窗口)

包含项目中所有的资源,对应工程下Asset目录

右键-show in exploder  打开对应文件夹

Hierachy(对象实例化的窗口)

游戏世界中所包含的内容。

Inspector(信息面板、检视面板)

Console(控制台)

Debug.Log();

Unity中视觉窗口所有内容都称为Gameobject

坐标

Unity2d的(00)点是game窗口左下角。3d使用左手坐标系。

相对坐标和绝对坐标

库函数

UnityEngine->unity库。

class只有继承了MonoBehaviour才能挂到gameobject身上

DeBug

日志输出

Log 输出,黑色

LogError 打印红色日志,错误

LogWarning 打印黄色警告日志

属性

name属性是当前脚本所在游戏物体的名字

警告处理

1、如果出现了the referenced(引用) script  on this Behaviour is missing ,选中后下发有描述,一般此错误有两种可能,一是脚本被删除,二是脚本名或类名被改变了。

2、如果脚本丢失,建议先删除再重新添加。

3、脚本名必须和类名一致

错误处理

error CS0103: The name `XXX' does not exist in the current context xxx类不存在

error CS1501: No overload for method `xxxx' takes `n' arguments  xxxx方法参数数量有误

unity对大小写敏感。

NullReferenceException(异常): Object reference not set to an instance of an object空引用异常

error CS0266: Cannot implicitly convert type `UnityEngine.Component' to `UnityEngine.Transform'. An explicit conversion exists (are you missing a cast?) 不能转换类型

消息函数

不是主动调用,通过消息机制调用的函数。例如start()update()

SendMessage()发送消息的方法,所有的gameobject对象都可以调用。但不要使用sendmessage,因为效率很低。

生命周期

Awake() 脚本实例化时调用,一般用于初始化,脚本开始只执行一次,Awake在初始化之前调用,在Awake中调用不到其他函数,因为可能还没有初始化。

Start() 脚本第一次启用update前调用(Awake之后执行),也用于初始化,但不同与Awake后于Awake调用

Onenble当组件被激活的时候执行(脚本激活时)。

Ondisable当组件被失活的时候执行。

Update() 运行时,每帧调用。屏幕刷新一遍为一帧,人眼为24

FixedUpdate() update()的帧长不同,FixedUpdate先执行,它的每帧时间完全固定0.02,每帧时间可以在unity中设置,edit中,倒数第三个选项,主要应用于物理受力处理

OnDestroy() 该脚本被移除时调用,同时对应物体被删除时也会调用。(其实还是脚本被删除时调用,删除物体同时也删除了脚本,先删除组件后,再删除物体就不会触发。)

OnGUI(),每一帧调用,和update相同,负责绘制屏幕(game窗口),使用的APIGUI 的类。

物理生命周期

OnCollisionEnter(Collision); 当此collider/rigidbody触发另一个rigidbody/collider时,OnCollisionEnter将被调用

OnCollisionExit(Collision)当此collider/rigidbody停止触发另一个rigidbody/collider时,OnCollisionExit将被调用。

OnCollisionStay(Collision)当此collider/rigidbody触发另一个rigidbody/collider时,OnCollisionStay将会在每一帧被调用。

OnTriggerEnter 

Collider(碰撞体)进入trigger(触发器)时调用OnTriggerEnter

OnTriggerEnter2D 

当另一个对象进入到这个对象附加的触发碰撞器时发送消息(仅2D物理)。

OnTriggerExit 

Collider(碰撞体)停止触发trigger(触发器)时调用OnTriggerExit

OnTriggerExit2D 

当另一个对象离开附加在这个对象的触发碰撞器时发送消息(仅2D物理)。

OnTriggerStay 

当碰撞体接触触发器时,OnTriggerStay将在每一帧被调用。

OnTriggerStay2D 

当另一个对象停留在这个对象附加的触发碰撞器内时,每帧发送消息(仅2D物理)。

预制体prefab

场景内容是临时存在的,预制体是永久存在的,所以,场景内的物体拖不到预制体的代码中。

创建预制体

将物体直接拖到资源窗口,就能自动创建预制体

游戏中使用预制体的物体,最上方或多出三个属性:select(选中当前使用预制体的文件),apply(应用修改的数据到预制体,所有使用此预制体的物体都会改变),revert点击会恢复默认的预制体数据。

 

加载预制体

加载预制体,就必须把预制体放在Resources目录下,通过Resources.Load(路径)获取预制体,然后通过Instantiate()实例化。

禁忌:禁止直接使用预制体,因为这样会在运行期间直接修改预制体的数据,停止运行后预制体数据不会还原

Resources目录

该目录属于unity官方指定目录,必须使用此名字,存放资源使用。

一般存放预制体,贴图,音效等内容。

加载通过Resources.Load(“路径及文件名”),或者Resources.Load<T>(路径及文件名);

路径根起点默认为Resources,因此不用写Resources

例如:Resources.Load<GameObject>(“A”);

加载后需要通过实例方法(Instantiate())添加到世界中。

Instantiate(original: Object, position: Vector3, rotation: Quaternion) 克隆原始物体并返回克隆物体。

Resurces.load是堵塞性加载,加载内容时程序会一直停在这里,加载完成时才会继续往下执行。

Resurces.load加载后,不使用了需要释放掉,否则会一直在内存中加载,使用Resources.UnloadAsset(变量名); 随后变量名一定要置空,否则该变量会变成一个未知指向的野指针。

不要在update中使用Resurces.load

动态资源加载(异步资源加载)

Resources.LoadAsync();异步加载。异步加载不会堵塞主线程

返回ResourceRequest类型的对象,该对象继承于AsynOperation

AsynOperation中有一个progress进度函数,该值为0-1,常用于场景切换的进度条。

AsynOperation中有属性isDone,是否加载完成

加载完成的资源在ResourceRequest的对象.asset字段中

异步加载常常配合协程使用。

遇到函数Async结尾一定都是异步,sync肯定是同步的。

场景切换

场景类Application类(早期版本使用)

Application.Quit();退出场景,结束游戏

Application.Load ();已弃用。

SceneManager

使用要先using unityEngine.SceneManager

SceneManager.loadScene(场景索引);

加载场景的异步加载

SceneManager.LoadSceneAsync(场景索引);返回值是asyncOperation类型,也有progress

异步加载完后会自动跳转场景,不会等待指令。

asyncOperationallowSceneActiveation属性改为false后,就不会加载完成后自动跳跃了,但此时进度也会永远变不了100%,最大停留在0.9的位置,isDone永远为false,发送跳跃指令后才会完成。

工程与工程之间的资源迁移

导出,再导入

Export package,系统会自动选中所有关联资源

2013-08-20 00:04:04 jukai7 阅读数 7548

       今天我们来学一下UnityD中预设Prefab的使用方法,首先来了解一下预设:Unity3D项目中,Prefabs(预设)是一种可被重复使用的游戏对象。具有以下特点:

        1.  它可以被置入多个场景中,也可以在一个场景中多次置入。

        2.  当你在一个场景中增加一个Prefabs,你就实例化了一个Prefabs。

        3.  所有Prefabs实例都是Prefab的克隆,所以如果实在运行中生成对象会有(Clone)的标记。

        4.  只要Prefabs原型发生改变,所有的Prefabs实例都会产生变化。

如果需要创建一些想要重复使用的东西,如游戏中的子弹等,就应该使用Prefab了。下面介绍一下使用方法。

       新建一个工程,我们取名"Test",然后新建一个平面Plane,一个长方体Cube,一个球体Sphere。如下图所示:

                 

            我们要实现的效果是当小球落到平面上时,销毁小球,接着从小球的原始位置重新创建一个小球,使其下落,重复下去,使空中一直有小球下落。

           我们还要设置平面上的长方体的组件属性和小球的组件属性,分别如下所示:

                                 

         可以看到去掉了长方体Mesh Render组件的对勾,使其透明化,增加了Box Collider组件,使它接受碰撞,并在是否触发 Is Trigger上打了对勾;然后小球我们增加了重力感应组件Rigidbody,使其能够下落,然后增加了球体碰撞Sphere Collider。这里要注意的是碰撞双方不能都是Mesh Collider,否则检测不到碰撞。如果非要用两个Mesh Collider检测碰撞,则可勾选其中之一的Mesh Collider下的Convex属性。

        接下来创建预设Prefab,我们先在Project面板下新建一个文件夹“resources”,然后Create-->Prefab,重命名为“ball”,然后将Hierarchy下的ball对象拖拽到上面,可以发现它前面原本灰色的图标变蓝了。好了,最后让我们编写c#脚本代码,源代码如下:

using UnityEngine;
using System.Collections;

public class script : MonoBehaviour {

    //定义小球预设
    private GameObject prefab;

	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
	
	}
    //触发进入检测函数
    void OnTriggerEnter(Collider col)
    {
     
        //注意此处第一个小球的名字为ball,而后来克隆的小球名字都为ball(Clone)
        if (col.gameObject.name == "ball" || col.gameObject.name == "ball(Clone)")
        {
            //销毁小球
            Destroy(col.gameObject);
        }
        //实例化小球预设,我们从resources文件夹下载入预设,注意预设资源必须放在
        //Assets目录下新建的resource文件夹,否则不识别
        prefab = (GameObject)UnityEngine.Object.Instantiate(Resources.Load("ball"));

    }
}

      将脚本拖放到cube对象上,运行游戏,效果如下:

                

最后附上项目资源下载地址:点此下载


2011-11-05 21:51:53 dlnuchunge 阅读数 3177

本篇不是我写的,感觉不错所以拷贝来了,呵呵呵,原创的链接:http://bbs.9ria.com/thread-97976-1-1.html

 解释:Prefabs(预设)是一种资源类型,可被重复使用的游戏对象。它可以被置入多个场景中,又或者能够在一个场景中被多次置入。当你在一个场景中增加一个Prefabs,你就实例化了一个Prefabs。所有Prefabs实例都是Prefab的克隆,只要Prefabs原型发生改变,所有的Prefabs实例都会产生变化。

Prefabs的用法:如果大家要创建一些想要重复使用的东西,那么就该用到它了。

接下来我们写个小例子,看看如何使用它

1 搭建如下场景:一个地板,一个下落的立方体,调整摄像机的角度和位置,加个平行光,位置参考下图的Scene窗口,效果如Game窗口展示的那样。同时给立方体加上刚体属性(Component -> Physics -> Rigidbody)



然后调整一下立方体的角度,运行一下,让它滚一下。

2  创建Prefabs

在Preject窗口,点Create-> Prefab。然后我们从Hierarchy窗口中将立方体拖到Project窗口新创建的Prefab上。当Hierarchy中的立方体变成了蓝色,Prefabs就完成了填充。



然后你从Preject窗口中将创建的Prefabs拖入Scene窗口中,运行一下。就完成了一次克隆。它们就像双胞胎一样。


3  接着我们配合Instantiate,来用代码创建多个Prefabs的实例。

Instantiate:克隆原始物体。设置位置,角度。如果一个对象,组件,脚本实例被传入。将克隆整个对相爱难过的层次,以及所有子对象。

各位同学,让我们在Project窗口点Create -> Javascript创建一个脚本

我发现可以用as3的写法来写这里面的js,各位同学请看

  1. public var Pre:GameObject;//在编辑器中用来绑定的Prefabs

  2. private function Update ():void
  3. {
  4.         var instance:GameObject=Instantiate(Pre,transform.position,transform.rotation);
  5.         //Instantiate用法,注意参数
  6.         //Pre  用来克隆的Prefabs
  7.         //transform.position  脚本绑定对象的位置 就像this.transform….
  8.         //transform.rotation  脚本绑定对象的角度 就像this.transform….
  9. }
复制代码

是不是有很亲切的感觉?

4 写完脚本,我们要把它绑定到一个对象上。这时候,我们可以删除Hierarchy窗口中的立方体,然后创建一个空的游戏对象(GameObject->Create Empty),放置到原来立方体的位置上。将脚本拖放到Hierarchy窗口中的新键的空对象上,让它来执行代码。

5 在Hierarchy窗口中单击空对象,在它的Inspector窗口中就能看到绑定的脚本。然后我们把早前创建的Prefabs拖到脚本Pre右边的框上,完成了脚本中变量的绑定。


6 按小三角运行一下,搞的像粒子效果一样,是不是很嗨?

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