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中按一定时间进行调用,而不是每一帧都调用。

參考:http://game.ceeger.com/Script/

时间: 2024-10-14 01:34:24

Unity3D脚本编程--基本概念的相关文章

unity3d脚本编程

一 创建和使用脚本 1 概述 GameObject的行为都是被附加到其上面的组件控制,脚本本质上也是一个组件. 在unity中创建一个脚本,默认内容例如以下: using UnityEngine; using System.Collections; public class MainPlayer : MonoBehaviour { // Use this for initialization void Start () { } // Update is called once per frame

【浅墨Unity3D Shader编程】之五 圣诞夜篇: Unity中Shader的三种形态对比&amp;混合操作合辑

本系列文章由@浅墨_毛星云 出品,转载请注明出处.  文章链接:http://hpw123.net/a/C__/kongzhitaichengxu/2014/1222/164.html 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] QQ交流群:330595914 更多文章尽在:http://www.hpw123.net 本文算是固定功能Shader的最后一篇,下一次更新应该就会开始讲解表面Shader,而

【浅墨Unity3D Shader编程】之四 热带雨林篇: 剔除、深度测试、Alpha测试以及基本雾效合辑

本系列文章由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://hpw123.net/a/C__/kongzhitaichengxu/2014/1222/163.html 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] QQ交流群:330595914 更多文章尽在:http://www.hpw123.net 本文介绍了Unity中Shader书写中会用到的剔除.深度测试.Alpha测试以及基

shell脚本编程学习笔记(1)

在linux上编程,离不开shell,计划好好看看shell编程,并在这里做些笔记以供有相同兴趣的人分享,主要参考<shell脚本学习指南>. 学习shell脚本编程之前,需要了解脚本编程语言和编译型语言的概念. 一般很多中型.大型的程序是用编译型语言写成的,比如C.C++.Java等.这类程序从源代码编译成目标代码,直接通过计算机执行.编译型语言执行效率比较高,大多运作于底层,处理的是字节.整数.浮点数等机器层级的对象,因此实现一个具体的功能,比如"将一个目录里的所有文件复制到另外

shell 脚本编程基础

一.编程基础 程序:指令+数据 程序编程风格: 过程式:以指令为中心,数据服务于指令 对象式:以数据为中心,指令服务于数据 shell程序:提供了编程能力,解释执行 1.程序的执行方式 计算机:运行二进制指令: 编程语言: 低级:汇编 高级: 编译:高级语言–>编译器–>目标代码 java,C# 解释:高级语言–>解释器–>机器代码 shell, perl, python 2.编程基本概念 编程逻辑处理方式: 顺序执行 循环执行 选择执行 shell编程:过程式.解释执行 编程语言

DAY9:bash脚本编程基础(1)

内容主要为: 一.编程基础 二.shell脚本及其基本格式 三.变量 四.运算 五.条件测试 六.流程控制 一.编程基础 1)程序 程序:指令+数据 程序编程风格: 过程式:以指令为中心,数据服务于指令(C,bash) 对象式:以数据为中心,指令服务于数据 (java,C++,Python) shell程序:提供了编程能力,解释执行 2)程序的执行方式 计算机:运行二进制指令: 编程语言: 低级:汇编 高级: 编译:高级语言-->编译器-->目标代码 java,C# 解释:高级语言-->

Shell脚本编程30分钟入门

什么是Shell脚本 示例 看个例子吧: #!/bin/sh cd ~ mkdir shell_tut cd shell_tut for ((i=0; i<10; i++)); do touch test_$i.txt done 示例解释 第1行:指定脚本解释器,这里是用/bin/sh做解释器的 第2行:切换到当前用户的home目录 第3行:创建一个目录shell_tut 第4行:切换到shell_tut目录 第5行:循环条件,一共循环10次 第6行:创建一个test_1…10.txt文件 第7

【浅墨Unity3D Shader编程】之七 静谧之秋篇: 表面着色器的写法(二)——自定义光照模式

本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://hpw123.net/plus/view.php?aid=183 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 邮箱: [email protected] QQ交流群:330595914 更多文章尽在:http://www.hpw123.net 本文主要讲解了Unity中SurfaceShader的自定义光照模式的写法. 上篇文章中我们已经说到,表面着色器将分为两次讲解,上

8.11_Linux之bash shell脚本编程入门篇(一)

什么是bash shell脚本编程? 答:Linux里面有多种shell,而CentOS和redhat的默认shell是bash shell.至于shell脚本,这个跟windows操作系统里面的批处理文件有点像(.bat的文件).不知道大家还是否记得Linux的哲学思想吗?其中有那么两点点:由众多目的的单一应用程序组成:一个程序只做一件事,且做好:组合目的的单一的小程序完成复杂的任务.我觉得shell脚本编程就很好的体现了这个哲学思想.shell脚本利用shell的功能缩写的一个"程序&quo