查看: 3036|回复: 5
打印 上一主题 下一主题

Unity简易代码

[复制链接]

20

主题

1

听众

682

积分

初级设计师

Rank: 3Rank: 3

纳金币
678
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

跳转到指定楼层
楼主
发表于 2012-12-5 10:10:22 |只看该作者 |倒序浏览


出一个比较简单易懂的入门知识,启动unity3d.

首先,让我们创建一个用来行走的平面,用一个扁的Cube.

- 创建一个Cube,缩放x,y,z为”5,0.1,5”,它现在看起来应该是一个大平板.在层次视图(Hierarchy View)中重命名为”Plane”.

- 创建第二个Cube,将它放置在这个大平板的中心位置.如果在游戏视图(Game View)看不到它们,那么改变主相机位置使它们可见.重命名该物体为”Cube1”.

- 你也应该建立一个点光源,并且放在大平板之上,使它们更清晰.

- 保存 选择菜单File->Save As保存这个场景文件.


我们第一个脚本 我们现在开始游戏设计.我们打算让Player移动. 通过控制主相机的位置来实现,要做到这一点,我们现在要写一个脚本来读取键盘的输入.然后把脚本和相机链接起来(更多的在下一节).

- 首先创建一个空脚本.选择” Assets->Create->Javascript”并在项目面板重命名为”Move1”.

- 双击Move1脚本,它将打开,并且默认包含有Update()函数,我们将我们的代码插入这个函数,任何加入Update()函数中的代码都将在每一帧(frame)执行一次. 在Unity中为了移动一个游戏对象我们需要用transform来更改它的位置,属于Translate,这个Translate函数有x,y和z三个参数,因为我们想通过光标键控制主相机,我们只需要下面这些代码,来决定按键按下后参数的变化: function Update () { transform.Translate(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")); }  
Java代码  

            





Input.GetAxis()函数返回-1或1的一个值,例如在横轴上左光标键映射为-1,右光标键映射为1.

注意参数0为y轴,因为我们不希望镜头上仰.横轴和竖轴是在输入设置(Input Settings)中预先定义好的.从Edit->roject Settings->Input中很容易重定义按键映射.

- 打开脚本Move1并输入上面的代码,注意大小写.

连接脚本 现在我们第一个脚本写完了,怎么让Unity的游戏对象具有这个脚本行为呢?我们要做的是赋予这个脚本给游戏对象来体现脚本的行为.

- 首先点击你希望应用此脚本的游戏对象,对于我们而言,这里将是主相机,你可以从层次视图和场景视图中选择它.

- 然后从菜单中选择Components->Scripts->Move1 ,将这个脚本赋予相机,你在检视面板中看到主相机有Move1这个组件. 提示:你也可以从项目视图拖拽脚本到场景视图的游戏对象上.

- 点击播放按钮运行游戏,你能通过光标键或W,S,A,D键来移动主相机.你也许注意到了,摄影机移动的有点太快了,让我们来找一种更好的办法来控制摄像头的速度.

注:其实这里Input.GetAxis只是获得一个方向,真正的是需要我们定义一个时间和速度。

Delta time

正如先前在Update()函数里的代码,相机的速度是按帧执行的.然而我们需要游戏对象的移动按秒执行.为了实现这一目标,我们需要将返回的值乘以Input.GetAxis() 函数中的Time.deltaTime:
Java代码   

            var speed = 5.0;   
            function Update () {   
            var x = Input.GetAxis("Horizontal") * Time.deltaTime * speed;   
            var z = Input.GetAxis("Vertical") * Time.deltaTime * speed; transform.Translate(x, 0, z);  
             }   



- 将上面的代码更新到Move1脚本.

注意Update()外的这个速度变量.这是所为的暴露变量,这个变量会在检视面板中看到.它是很有用的,实际使用中可以方便的调整它的值,这比改变代码来说方便的多.

链接变量:





通过Unity界面来连接变量是非常强大的.

Unity的功能.它允许在Unity界面上拖拽(drag and drop)的方式来赋予脚本代码. 这是快速又简洁的主意.这样在Unity界面中完成连接变量,我们知道我们总是需要脚本代码中暴露的变量,以便我们在检视面板中指派参数.为了演示连接变量的概念,我们建立一个跟随玩家(主相机)的聚光灯.

- 添加一个聚光灯到场景视图,移动它靠近其他游戏对象.

- 创建一个JavaScript脚本并重命名为Follow.

让我们想想我们要做的,我们希望主相机的地方有个聚光灯所照耀.事实上,Unity中有个函数能做到这一点. transform.LookAt(). 如果你开始想”我该怎么做?”和已经想了很多代码.那么要记得经常查看Unity的函数API.,我们能同样的猜想查看API中的” transform’”章节,为感兴趣的游戏对象的位置和旋转. 现在,我们来到连接变量章节,我们如何使用LookAt()参数呢?我们可以编写代码指定一个游戏对象,但是我们是想通过Unity GUI来指派变量,因此我们将用一个暴露变量(Transform类型).我们的Follow.js脚本应该如下:
Java代码   

            var target : Transform;   
            function Update () { transform.LookAt(target);  
             }  



- 赋予脚本给聚光灯,当这个脚本成功添加后,”target”变量就会暴露了. - 选中聚光灯,从层次视图拖拽主相机到监视面板中的”target”暴露变量上分配给target变量,即聚光灯将跟随主相机.如果我们想聚光灯跟随不同的对象,我们也可以拖拽不同的对象过去(当然只要它的类型是Transform).

- 播放游戏,在场景视图中你能看到聚光灯跟随在主相机周围.你可以改变聚光灯的位置来改变效果.
访问组件





作为一个游戏对象能有多个脚本(或其他组件).它不可避免的要访问其他组件的函数或变量.Unity中通过GetComponent() 函数来实现这个. 我们现在要添加另外的脚本来让按下跳跃键(默认空格键)时让聚光灯射向Cube1.

让我们先思考这个问题,我们要做的是:

1. 监视跳跃键被按下.

2. 当跳跃键按下时,聚光灯将照射Cube1.我们如何做到这一点呢?那么Follow脚本包含一个”target”变量,其值确定哪些游戏对象被聚光灯所照射.我们需要为这个值设定一个新的参数.我们可以写代码给这个值为cube(看本节后的”写代码”),但我们知道暴露了这个变量,通过GUI上指定变量的值是更好的办法:

- 创建一个新的JavaScript脚本并重命名为Switch,添加代码到Switch.js:
Java代码   

            var switchToTarget : Transform;   
            function Update () {   
            if (Input.GetButtonDown("Jump")) GetComponent(Follow).target = switchToTarget;   
            }  



这样写代码

前面的教程中我们提到,可以通过写代码的方式指定变量(而不是通过Unity界面),让我们看看如何做.记住,这只是用来比较,建议通过Unity界面来给变量赋值.早先按下空格时告诉聚光灯聚焦到Cube1上.我们的解决方案是做一个暴露变量在Switch脚本,我们便可以在Unity的界面上拖拽Cube1上去.在代码中主要有两种方法做到这一点:

1. 使用游戏对象的名称(name)

2. 使用游戏对象的标签(tag)

1. 游戏对象名称 可以从层次视图中看到游戏对象的名称.用GameObject.Find()函数来使这些名称作为参数. 因此如果我们想按下跳跃键时候切换聚光灯从主相机到Cube1,代码如下::
Java代码  

            function Update () {  
            if (Input.GetButtonDown("Jump")) {   
               var newTarget = GameObject.Find("Cube").transform;   
               GetComponent(Follow).target = newTarget;   
               }   
            }  



注意没有暴露变量而是直接使用代码.查看API获得更多Find()的用法.

2. 游戏对象标签 游戏对象表情是字符串用于识别一个组件.在检视视图中点击Tag按钮查看内建的标签.你也可以创建自己的标签. GameObject.FindWithTag()函数能通过具体标签寻找组件和返回一个字符串作为参数.代码如下:
Java代码  

            function Update () {   
            if (Input.GetButtonDown("Jump")) {   
                 var newTarget = GameObject.FindWithTag("Cube").transform;     GetComponent(Follow).target = newTarget;   
               }  
             }  



7.  实例

通常在运行时创建(create)对象(如游戏正在播放).要这样做,我们要用到Instantiate函数. 让我们讲述如何在每次按下开火按钮(或按鼠标左键或左Ctrl键)后通过实例(建立)一个新的游戏对象. 那么我们怎么做呢?我们希望用户像往常一样走动,当按下开火按钮,实例化创建一个新的对象.思考以下几点:

1. 哪个物体做我们的实例?

2. 在哪里做实例化?

关于哪个对象到实例,最好的解决办法是暴露变量.这意味着我们随时可以通过拖拽游戏对象到变量来改变对象为实例. 至于哪里做实例化,现在我们只要实现当按下开火按钮时在用户(主相机)当前位置创建新的游戏对象. 实例化函数有三个参数:

(1)我们要建立一个对象,

(2)对象的三维位置

(3)对象的旋转位置.

完整的代码如下(Create.js):
Java代码  

            var newObject : Transform; function Update () {   
            if (Input.GetButtonDown("Fire1")) { Instantiate(newObject, transform.position, transform.rotation); }   
            }  



不要忘记, transform.position和transform.rotation是附加到脚本的transform的位置和选择的,这里假如是主相机(Main Camera).然而,当一个对象被实例化,通常将对象设置为预设(prefab),我们现在将Cube1游戏对象设置为预设.

- 首先,让我们嫩创建一个空的预设,选择Assets->Create->refab.重命名这个预设为”Cube”.

- 从层次视图拖拽Cube1游戏对象到项目视图的Cube预设上.注意预设图标的变化. 现在我们创建Javascript代码.

- 创建一个新的脚本和命名为Create ,并插入上面的代码.

- 把这个脚本赋予给主相机(Main Camera)和将Cube预设赋予主相机上的newObject 变量.

- 运行游戏,并向以往一样走动.每当按下开火按钮(鼠标左键或左Ctrl)你都能看到一个新的Cube出现.
调试

调试是发现和修正你的代码中人为错误的技巧,Unity中提供了Debug类,我们现在看看Debug.Log()函数.

Log Log()函数允许用户发送信息到Unity的控制台.这样做的原因可能包括:

1. 在运行时要验证某部分代码是否达成.

2. 报告变量的状态. 我们现在使用Log()函数,当用户点击开火按钮时发送一个消息到Unity控制台.

- 打开创建的脚本并在” Instantiate’”代码内”if”处添加如下代码:
Java代码  

            Debug.Log("Cube created");  



- 运行游戏和点击开火按钮,你能看到Unity界面下方显示” Cube created”,你可以点击这个提示详细查看Unity控制台.

Watch

另外一个有用的功能是用于调试私有变量.这使得当Debug模式被选中时检视视图中的变量,但它不能被编辑.为了证明这一点,我们将暴露一个私有变量作为Cube实例的计数. - 再次打开创建的脚本并添加两行:

(1) 添加私有变量引用cubeCount

(2) 当一个cube实例创建后增加这个变量 完整代码如下(Create.js):
Java代码  

            var newObject : Transform;   
            private var cubeCount = 0;  
             function Update () {  
             if (Input.GetButtonDown("Fire1")) { Instantiate(newObject, transform.position, transform.rotation); Debug.Log("Cube created"); cubeCount++; }  
             }  



- 运行游戏并点击开火按钮创建一些Cube,注意每当一个新的Cube实例创建后cubeCount变量的递增.同样这个数值是灰色的,意味着变量是只读的(不能编辑).

常见脚本类型

每当一个新Javascript被创建,默认情况下将包含Update()函数.这一届将讲述其他常见的函数,简单的从下面列表中替换Update()函数名字.

FixedUpdate()

置于这个函数中的代码每隔一定间隔执行(固定的帧率).它通常被用来Rigibody中用力的时候.
Java代码  

            // Apply a upwards force to the rigid body every frame function FixedUpdate () {   
            rigidbody.AddForce (Vector3.up);   
            }   



Awake()

这里的代码将被用作初始化. Start() 这个函数将在Update()之前,但在Awake()之后执行. Start () 函数和Awake()函数的不同点在于Start()函数仅在脚本启用时候执行(检视视图如果它的复选框被选中).

OnCollisionEnter()

当游戏对象的碰撞脚本与另外的游戏对象碰撞时执行这个函数内的代码.

OnMouseDown()

当鼠标在一个载有GUI元素(GUIElement)或碰撞器(Collider)的游戏对象里按下时执行该函数内的代码.
Java代码  

            // Loads the level named "SomeLevel" as a response  
             // to the user clicking on the object   
            function OnMouseDown () { Application.LoadLevel ("SomeLevel"); }   

OnMouseOver()

当鼠标在一个载有GUI元素(GUIElement)或碰撞器(Collider)的游戏对象里的按下动作抬起后执行该函数内的代码.

Java代码  

            // Fades the red component of the material to zero  
             // while the mouse is over the mesh   
            function OnMouseOver () { renderer.material.color.r -= 0.1 * Time.deltaTime; }   
分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

Zack    

459

主题

1

听众

5478

积分

高级设计师

Rank: 6Rank: 6

纳金币
5531
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

沙发
发表于 2012-12-5 19:55:01 |只看该作者
顶一个,支持楼主的教程!
回复

使用道具 举报

2317

主题

54

听众

2万

积分

资深设计师

Rank: 7Rank: 7Rank: 7

纳金币
20645
精华
62

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

板凳
发表于 2012-12-5 22:16:30 |只看该作者
很不错的内容,保存了!
回复

使用道具 举报

955

主题

164

听众

7万

积分

版主

Rank: 7Rank: 7Rank: 7

纳金币
59338
精华
28

活跃会员 荣誉管理 突出贡献 优秀版主 论坛元老

地板
发表于 2012-12-6 02:29:36 |只看该作者
很值得给学习者的参考资料!
回复

使用道具 举报

700

主题

1

听众

1万

积分

资深设计师

Rank: 7Rank: 7Rank: 7

纳金币
16564
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

5#
发表于 2012-12-8 08:13:05 |只看该作者
回复

使用道具 举报

2317

主题

54

听众

2万

积分

资深设计师

Rank: 7Rank: 7Rank: 7

纳金币
20645
精华
62

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

6#
发表于 2012-12-27 21:24:24 |只看该作者
本帖最后由 艾西格亚 于 2013-5-7 12:50 编辑

这个对于入门的用户来说很有帮助
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2025-7-23 05:41 , Processed in 0.076896 second(s), 32 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部