Unity3D脚本编程--基本概念
1. 简单介绍
在Unity3D中,游戏对象(GameObject)的行为是由附加其上的脚本来控制的,游戏开发人员通过编写脚本来控制游戏中的全部对象,如移动Camera等。
GameObject能够被附加不同类型的组件。但每种类型的组件仅仅能有一个或没有。
脚本本质上也是一种组件。
在Unity3D中默认的脚本代码例如以下所看到的:
<span style="font-family:Arial;"><span style="font-family:Arial;">// ***** C# script *****
using UnityEngine;
using System.Collections; public class ffc : MonoBehaviour { // Use this for initialization
void Start () { } / Update is called once per frame
void Update () {
}
} //***** Java script ***** #pragma strict function Start () {
} function Update () { }
</span></span>
由此可见,脚本代码与大家熟悉的Java代码类似,即都是由下面两部分组成:
• 变量
• 函数
• 其他代码:在不论什么函数之外的代码在物体被载入的时候执行。这个能够用来初始化脚本状态。
MonoBehaviour是全部脚本的基类。每一个Javascript脚本自己主动继承MonoBehaviour,使用C#或Boo时,须要显式继承MonoBehaviour.
1.1 脚本成员变量
脚本变量就是指类的成员变量(即在JavaScript或C#或Boo中定义的成员变量,而不是基类MonoBehaviour中定义的变量),在Unity3D中将成员变量设为公有的时候,当把它附加到游戏对象后。能够在游戏对象的监视面板中的脚本组件那栏里面看到该“公有变量”。即能够在编辑器中直接对该公有变量进行赋值,同一时候在Debug状态下也能够在面板中看到它的值。
1.2 基类可被继承的成员变量(内置变量)
| 变量名 | 描写叙述 |
| transform | The Transform attached to this GameObject (null if there is none attached). |
| rigidbody | The Rigidbody attached to this GameObject (null if there is none attached). |
| camera | The Camera attached to this GameObject (null if there is none attached). |
| light | The Light attached to this GameObject (null if there is none attached). |
| animation | The Animation attached to this GameObject (null if there is none attached). |
| constantForce | The ConstantForce attached to this GameObject (null if there is none attached). |
| renderer | The Renderer attached to this GameObject (null if there is none attached). |
| audio | The AudioSource attached to this GameObject (null if there is none attached). |
| guiText | The GUIText attached to this GameObject (null if there is none attached). |
| networkView | The NetworkView attached to this GameObject (Read Only). (null if there is none attached) |
| guiTexture | The GUITexture attached to this GameObject (Read Only). (null if there is none attached) |
| collider | The Collider attached to this GameObject (null if there is none attached). |
| hingeJoint | The HingeJoint attached to this GameObject (null if there is none attached). |
| particleEmitter | The ParticleEmitter attached to this GameObject (null if there is none attached). |
| gameObject | The game object this component is attached to. A component is always attached to a game object. |
| tag | The tag of this game object. |
1.3 基类可被继承的类函数
| 类函数 | 描写叙述 |
| Destroy | Removes a gameobject, component or asset. |
| DestroyImmediate | Destroys the object obj immediately. It is strongly recommended to use Destroy instead. |
| DontDestroyOnLoad | Makes the object target not be destroyed automatically when loading a new scene. |
| FindObjectOfType | Returns the first active loaded object of Type type. |
| FindObjectsOfType | Returns a list of all active loaded objects of Type type. |
| Instantiate | Clones the object original and returns the clone. |
1.4 基类可被继承的函数
| 类函数 | 描写叙述 |
| GetComponent | Returns the component ofType type if the game object has one attached, null if it doesn't. function GetComponent (type :Type) : Component |
| GetComponent | Returns the component withnametype if the game object has one attached, null if it doesn't. function GetComponent (type :string) : Component |
| GetComponentInChildren | Returns the component of Type type in the GameObject or any of its children using depth first search. |
| GetComponentsInChildren | Returns all components of Type type in the GameObject or any of its children. |
| GetComponents | Returns all components of Type type in the GameObject. |
| CompareTag | Is this game object tagged tag? |
| SendMessageUpwards | Calls the method named methodName on every MonoBehaviour in this game object and on every ancestor of the behaviour |
| SendMessage | Calls the method named methodName on every MonoBehaviour in this game object. |
| BroadcastMessage | Calls the method named methodName on every MonoBehaviour in this game object or any of its children. |
| GetInstanceID | Returns the instance id of the object. |
| ToString | Returns the name of the game object. |
1.5 基类可重写函数
1.5.1 常规更新事件
| 函数名 | 描写叙述 |
| Update | Update is called every frame, if the MonoBehaviour is enabled. |
| LateUpdate | LateUpdate is called every frame, if the Behaviour is enabled. LateUpdate is called after all Update functions have been called. This is useful to order script execution. For example a follow camera should always be implemented in LateUpdate because it tracks objects that might have moved inside Update. |
| FixedUpdate | This function is called every fixed framerate frame, if the MonoBehaviour is enabled. |
1.5.2 初始化事件
| 函数名 | 描写叙述 |
| Awake | Awake is called when the script instance is being loaded. |
| Start | Start is called just before any of the Update methods is called the first time. |
| Reset | Reset to default values. |
1.5.3 GUI元素或Collider碰撞体事件
| 函数名 | 描写叙述 |
| OnMouseEnter | nMouseEnter is called when the mouse entered the GUIElement or Collider. |
| OnMouseOver | OnMouseOver is called every frame while the mouse is over the GUIElement or Collider. |
| OnMouseExit | OnMouseExit is called when the mouse is not any longer over the GUIElement or Collider. |
| OnMouseDown | OnMouseDown is called when the user has pressed the mouse button while over the GUIElement or Collider. |
| OnMouseUp | OnMouseUp is called when the user has released the mouse button. |
| OnMouseUpAsButton | OnMouseUpAsButton is only called when the mouse is released over the same GUIElement or Collider as it was pressed. |
| OnMouseDrag | OnMouseDrag is called when the user has clicked on a GUIElement or Collider and is still holding down the mouse. |
1.5.4 Collider碰撞体事件
| 函数名 | 描写叙述 |
| OnTriggerEnter | OnTriggerEnter is called when the Collider other enters the trigger. |
| OnTriggerExit | OnTriggerExit is called when the Collider other has stopped touching the trigger. |
| OnTriggerStay | OnTriggerStay is called once per frame for every Collider other that is touching the trigger. |
1.5.5 Collider碰撞体或rigibody刚体事件
| 函数名 | 描写叙述 |
| OnCollisionEnter | OnCollisionEnter is called when this collider/rigidbody has begun touching another rigidbody/collider. |
| OnCollisionExit | OnCollisionExit is called when this collider/rigidbody has stopped touching another rigidbody/collider. |
| OnCollisionStay | OnCollisionStay is called once per frame for every collider/rigidbody that is touching rigidbody/collider. |
2. 控制游戏对象(GameObject)
在Unity3D中,能够在监视器面板中改动物体的组件属性,可是很多其它的时候,须要使用脚本来进行动态操作。
2.1 訪问组件
最常见的一个情形是须要使用脚本訪问附加到同样游戏对象(GameObject)上的还有一个组件(当前脚本就是一个组件,其它的组件也就是还有一个组件了)。
一个组件实质上是一个类的实例。因而首先须要做的是获取想要操作的组件实例的引用。这个通过GetComponent函数来实现。典型的,可能会想要将一个组件赋值给一个变量,例如以下代码所看到的:
void Start () {
Rigidbody rb = GetComponent<Rigidbody>();
}
一旦获取了组件实例的引用,就能够对它的属性进行想要的操作。同一时候也能够调用它的一些功能函数。
假设想要訪问还有一个脚本文件。也能够使用GetComponent,仅仅需使用脚本的类名作为该函数的组件类型參数(由于脚本本来就也是一个组件)。
// You can access script components in the same way as other components.
function Start () {
var someScript : ExampleScript;
someScript = GetComponent (ExampleScript);
someScript.DoSomething ();
}
假设想要去获取一个并没有加入到当前游戏对象的组件。GetComponent函数会返回null。假设试图去改变一个null对象上的不论什么值,将会发生null引用错误。
因为一些组件类型常常使用。unity提供了一些内置的变量来訪问它们,參见1.2(内置变量)。其演示样例代码例如以下:
void Start () {
transform.position = Vector3.zero;
}
2.2 訪问其它对象
尽管游戏对象(GameObject)都有各自的组件(包含脚本)进行处理,使用代码进行跟踪其它物体是常有的事。
比如,一个追赶的敌人可能须要知道玩家的位置,Unity提供了一系列的方法来获取其它对象,以适合不同的场合。
2.2.1 将对象【静态】链接到公有成员变量
最直接的办法是将一个游戏对象加入到脚本的公有成员变量上。直接在编辑器中将须要訪问的游戏对象拖到相应脚本组件的那个公有成员变量上,Unity3D会自己主动依据变量的类型将加入的游戏对象中同样的组件类型映射到该变量。
比如将一个游戏对象拖给一个Transform的成员变量。就会自己主动的将游戏对象的Transform组件和该变量映射起来。
直接将对象和变量链接起来在处理须要有永久链接的对象的时候是最实用的方法。
同一时候也能够使用一个数组变量和几个同样类型的对象链接起来,可是这样的链接必须在Unity3D编辑器中完毕,而不能在执行时进行。
2.2.2 【动态】定位其他对象
2.2.2.1 查找子物体
假设一个游戏场景中有非常多同一类型的对象,比如敌人、路点(waypoints)和障碍物。这些对象在游戏中须要由一个特定的脚本来监视和响应。这个时候使用变量来链接这些对象太过麻烦。对于这样的情况。通常更好的方法是将一系列的对象加入到一个父对象以下,这些子对象能够通过使用父对象的Transfrom组件来获得。
public class WaypointManager : MonoBehaviour {
public Transform waypoints;
void Start() {
waypoints = new Transform[transform.childCount];
int i = 0;
for (Transform t in transform) {
waypoints[i++] = t;
}
}
}
同一时候也能够使用Tranfrom.Find来查找某个详细的子对象。使用Transform来进行对象查找操作是由于每个游戏对象都有Transfrom组件。
2.2.2.2 通过名称或标签訪问对象
仅仅要有一些信息。在层级场景中的不论什么位置定位到该游戏对象是可能的。单个对象能够通过GameObject.Find函数进行查找。例如以下:
GameObject player;
void Start() {
player = GameObject.Find("MainHeroCharacter");
}
某个对象或者一系列的对象也能够分别通过GameObject.FindWithTag和GameObject.FindObjectsWidthTag函数进行定位。
2.2.2.3 查找特定类型的对象
static Object FindObjectOfType(Type type)
返回指定类型对象中的第一个活动的载入对象, 须要注意的是这个函数非常慢(可能是因为要在整个场景中进行遍历),不推荐每一帧都使用这个函数。在大多数情况下能够使用单件模式。比如:
Camera cam = FindObjectOfType(typeof(Camera)) as Camera;
因为该函数返回的类型是Object,所以须要使用as进行一下强制转换。
static Object[ ] FindObjectsOfType(Type type);
返回指定类型的载入活动对象的列表。速度也慢
HingeJoint[ ] hinges = FindObjectsOfType(typeof(HingeJoint)) as HingeJoint[ ];
3. 创建和销毁对象
在执行时创建和销毁对象是常有的事。
在Unity3D中。能够使用Instantiate函数对现有的一个对象做一个拷贝来创建一个新的游戏对象。
实例化很多其它通经常使用于实例投射物(如子弹、榴弹、破片、飞行的铁球等)。AI敌人,粒子爆炸或破坏物体的替代品。
// Instantiates 10 copies of prefab each 2 units apart from each other
var prefab : Transform;
for (var i : int = 0;i < 10; i++) {
Instantiate (prefab, Vector3(i * 2.0, 0, 0), Quaternion.identity);
}
值得注意的是用于进行拷贝的对象并不一定须要放置在场景中。
更普遍的做法是将一个预设(Prefab)拖到脚本的相应公有成员变量上,实例化的时候直接对这个成员变量进行实例化就可以。
// Instantiate a rigidbody then set the velocity
var projectile : Rigidbody;
function Update () {
// Ctrl was pressed, launch a projectile
//按Ctrl发射炮弹
if (Input.GetButtonDown("Fire1")) {
// Instantiate the projectile at the position and rotation of this transform
//在该变换位置和旋转。实例化炮弹
var clone : Rigidbody;
clone = Instantiate(projectile, transform.position, transform.rotation); // Give the cloned object an initial velocity along the current object's Z axis
//沿着当前物体的Z轴给克隆的物体一个初速度。 clone.velocity = transform.TransformDirection (Vector3.forward * 10);
}
}
实例化也能直接克隆脚本实例,整个游戏物体层次将被克隆。而且返回被克隆脚本的实例。
同一时候也有一个Destroy函数在帧更新函数完毕后或设定的一个延时时间后销毁一个对象。
// Kills the game object
//销毁游戏物体
Destroy (gameObject); // Removes this script instance from the game object
//从游戏物体删除该脚本实例
Destroy (this); // Removes the rigidbody from the game object
//从游戏物体删除刚体
Destroy (rigidbody); // Kills the game object in 5 seconds after loading the object
//载入物体5秒后销毁游戏物体
Destroy (gameObject, 5); // When the user presses Ctrl, it will remove the script
// named FooScript from the game object
//当按下Ctrl将从游戏物体删除名为FooScript的脚本
function Update () {
if (Input.GetButton ("Fire1") && GetComponent (FooScript))
Destroy (GetComponent (FooScript));
}
注意到Destroy函数能够销毁单独的组件而不正确游戏对象本身产生影响,一个通常易犯的错误是Destroy(this); 这句代码只销毁脚本组件,而不销毁该脚本所附加在的对象。
4. 协程(Coroutines)
一个coroutine就像一个能够暂停运行并将控制权返回给Unity3D的函数,可是在下一帧的时候又能够在它停止的位置继续运行。在C#中,这样声明一个coroutine:
IEnumerator Fade() {
for (float f = 1f; f <= 0; f -= 0.1f) {
Color c = renderer.material.color;
c.alpha = f;
renderer.material.color = c;
yield return;
}
}
实质上它是一个返回类型为IEnumerator的函数,同一时候在函数体中添加了yield return这句代码。yield return这行就是会在运行的时候暂停、在下一帧的时候恢复运行的位置。要启动coroutine,须要使用StartCorutine函数。
void Update() {
if (Input.GetKeyDown("f")) {
StartCoroutine("Fade");
}
}
默认的情况下。一个coroutine在它暂停后的下一帧恢复,可是也能够使用WaitFroSeconds来引入一个延时。
IEnumerator Fade() {
for (float f = 1f; f <= 0; f -= 0.1f) {
Color c = renderer.material.color;
c.alpha = f;
renderer.material.color = c;
yield return new WaitForSeconds(.1f);
}
}
这个能够用于产生一个随时间变化的效果,同一时候也是一个用于进行优化的有效方法。游戏中的很多人物须要周期性的运行。最经常使用的做法是将它们包括在Update函数中。可是Update函数通常每秒会调用多次。
当有的任务并不须要这么频繁的被调用的时候,能够将它放在一个coroutine中按一定时间进行调用,而不是每一帧都调用。
Unity3D脚本编程--基本概念的更多相关文章
- unity3d脚本编程
一 创建和使用脚本 1 概述 GameObject的行为都是被附加到其上面的组件控制,脚本本质上也是一个组件. 在unity中创建一个脚本,默认内容例如以下: using UnityEngine; u ...
- Unity3d脚本编程_
UnityEngine.Component引入了新的成员,如下: 新引入的成员 ...
- 【浅墨Unity3D Shader编程】之二 雪山飞狐篇:Unity的基本Shader框架写法&颜色、光照与材质
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/40955607 作者:毛星云(浅墨) ...
- Shell脚本编程30分钟入门
Shell脚本编程30分钟入门 转载地址: Shell脚本编程30分钟入门 什么是Shell脚本 示例 看个例子吧: #!/bin/sh cd ~ mkdir shell_tut cd shell_t ...
- javascript学习 真正理解DOM脚本编程技术背后的思路和原则
本文学习来源于<javascriptDOM编程艺术>仅作笔记 学会怎样才能利用DOM脚本编程技术以一种既方便自己更体贴用户的方式去充实和完善你们的网页. 循序渐进:从最核心的内容开始,逐步 ...
- 【浅墨Unity3D Shader编程】之一 夏威夷篇:游戏场景的创建 & 第一个Shader的书写
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/40723789 作者:毛星云(浅墨) ...
- Unity3D脚本调用Objective C代码实现游戏内购买
0.开篇吐槽: 一年之内从WP转到iOS,又从iOS转到U3D,真心伤不起. 1.Unity3D脚本调用OC代码的原理: 其实也没啥神秘的,因为OC是和C互通的 ,C#又可以通过DllImport的形 ...
- Unity3D脚本中文系列教程(十六)
Unity3D脚本中文系列教程(十五) ◆ function OnPostprocessAudio (clip:AudioClip):void 描述:◆ function OnPostprocess ...
- javascript进阶——分离式DOM脚本编程
编写分离式(unobstrusive)代码意味着对HTML内容的完全分离:数据来自服务器端,javascript代码用来动态化和交互.这种分离的好处是在不同浏览器之间使用是可以完全降级或升级运行,对于 ...
随机推荐
- shp系列(六)——利用C++进行Dbf文件的写(创建)
上一篇介绍了shp文件的创建,接下来介绍dbf的创建. 推荐结合读取dbf的博客一起看! 推荐结合读取dbf的博客一起看! 推荐结合读取dbf的博客一起看! 1.Dbf头文件的创建 Dbf头文件的结构 ...
- 如何使用fetch
Fetch API 提供了一个 JavaScript接口,用于访问和操纵HTTP管道的部分,例如请求和响应.它还提供了一个全局fetch()方法,该方法提供了一种简单,合乎逻辑的方式来跨网络异步获取 ...
- hdu 2489 dfs枚举组合情况+最小生成树
大家都说,搜索是算法的基础.今天最这题就有体会了.在n个顶点里选择m个顶点,求最小生成树.用到了深搜的回溯.所有情况都能枚举. #include<iostream> #include< ...
- 在YII2中使用redis
一.安装YII2的redis扩展 composer require --prefer-dist yiisoft/yii2-redis 二. 配置basic/config/web.php 在compon ...
- 使用一行代码解决IE浏览器兼容问题
在网站开发中不免因为各种兼容问题苦恼,针对兼容问题,其实IE给出了解决方案Google也给出了解决方案 百度也应用了这种方案去解决IE的兼容问题 百度源代码如下 <!Doctype html&g ...
- PythonOpenCV--Rtrees随机森林
360确实很个性,哈哈,你个貔貅,只吃不吐! Rtrees介绍!参考链接:http://docs.opencv.org/modules/ml/doc/random_trees.html 原文链接:Py ...
- logging模块、shutil模块、subprocess模块、xml模块
logging模块 shutil模块 subprocess模块 xml模块 logging模块 函数式简单配置 import logging logging.debug('debug message' ...
- Drop it FreeCodeCamp
function drop(arr, func) { // Drop them elements. for(var start=0 ;start<arr.length; start++){ if ...
- [luogu3237 HNOI2014] 米特运输 (树形dp)
传送门 Description 米特是D星球上一种非常神秘的物质,蕴含着巨大的能量.在以米特为主要能源的D星上,这种米特能源的运输和储存一直是一个大问题. D星上有N个城市,我们将其顺序编号为1到N, ...
- Linux Shell脚本编程-基础1
概述: shell脚本在Linux系统管理员的运维工作中非常重要.shell脚本能够帮助我们很方便的管理服务器,因为我们可以指定一个任务计划,定时的去执行某一个脚本以满足我们的需求.本篇将从编程基础 ...