Unity3D 脚本中文参考 (1)
这是一个关于Unity内部脚本如何工作的简单概览。
Unity内部的脚本,是通过附加自定义脚本对象到游戏物体组成。在脚本对象内部不同的函数被特定的事件调用。最常用的列在下面:
Update:这个函数在渲染一帧之前被调用。这里是大部分游戏行为代码被执行的地方,除了物理代码。
FixedUpdate
这个函数在每个物理时间同步被调用一次。这是处理基于物理游戏行为的地方。
在任何函数之外的代码:
在任何函数之外的代码在物体被加载的时候运行。这个可以用来初始化脚本状态。
注意:文档的这个部分假设你是用JS,参考用C#编写脚本获取如何使用C#和Boo编写脚本的信息。
你也能定义事件句柄。它们的名称都以On开始,(例如 OnCollisionEnter)。为了查看完整的预定义事件的列表,参考MonoBehaviour文档。
大多数游戏物体的操作是通过游戏物体的Transform和/或Rigidbody来做的。在行为脚本内部它们可以分别通过transform和rigidbody访问。因此如果你想绕着Y轴每帧旋转5度,你可以如下写:
functionUpdate(){
transform.Rotate(0,5,0);
}
如果你想向前移动一个物体,你应该如下写:
functionUpdate(){
transform.Transtate(0,0,2);
}
Time类包含一个非常重要的类变量,称为deltaTime。这个变量包含从上一次调用Update或FixedUpdate(根据你是在Update函数还是在FixedUpdate函数中)到现在的时间量。
所以对于上面的例子,修改它使这个物体以一个恒定的速度旋转而不依赖于帧率:
function Update(){
transform.Rotate(0,5*Time.deltaTime,0)
}
移动物体:
functionUpdate(){
transform.Translate(0,0,2*Time.deltaTime);
}
如果你加或减一个每帧改变的值,你应该将它与Time.deltaTime相乘。当你乘以Time.deltaTime时,你实际表达:我想以10米/秒移动这个物体而不是10米/帧。这不仅仅是因为你的游戏将独立于帧率运行,同时也是因为运动的单位容易理解。(10米/秒)
另一个例子,如果你想随着时间增加光照的范围。下面的表达式,以2单位/秒改变半径。
functionUpdate(){
light.range*=2.0*Time.delta.Time;
}
当通过力处理刚体的时候,你通常下不必用Time.deltaTime乘,因为引擎已经为你考虑到了这点。
组件被附加到游戏物体。附加Renderer到游戏物体使它在场景中渲染,附加一个Camera使它变为相机物体。所有的脚本都是组件,因为它们能被附加到游戏物体。
最常用的组件可以作为简单成员变量访问:
Component 可如下访问
Transform transform
Rigidbody rigidbody
Renderer renderer
Camera camera(only on camera objects)
Animation animation
Collider collider
……等等。
对于完整的预定义成员变量的列表,查看Component,Behaviour和MonoBehaviour类文档。如果游戏物体没有你想去同类型的组件,上面的变量将被设置为null。
任何附加到一个游戏物体的组件或脚本都可以通过GetComponent访问。
transform.Translate(0,1,0);
//等同于
GetComponent(Transform).Translate(0,1,0);
注意transform和Transform之间大小写的区别。前者是变量(小写),后者是类或者脚本名称(大写)。大小写不同使你能够从类和脚本名中区分变量。
应用我们所学,你可以使用GetComponent找到任何附加在同一游戏物体上的脚本和组件。请注意要使下面的例子能够工作,你需要有一个名为OtherScript的脚本,其中包含一个DoSomething函数。OtherScript脚本必须与下面的脚本附加到相同的游戏物体上。
//这个在同一个游戏物体上找到名为OtherScript的脚本
//并调用它上面的DoSomething.
function Updata(){
otherScript= GetComponent(OtherScript);
otherScript.DoSomething();
}
大多数高级的代码不仅需要操作一个物体。Unity脚本接口有各种方法来找到并访问其他游戏物体和组件。在下图,我们假定有一个名为 OtherScript.js的脚本附加到场景的游戏物体上。
var foo =5;
functionDoSomething(param:String){
print(param + ”with foo:” + foo);
}
1. 通过检视面板赋值引用。
你可以通过检视面板赋值变量到任何物体。
//变量拖动到target槽的物体
var target: Transform;
functionUpdate()
{
target.Translate(0,1,0);
}
你也可以在检视面板中公开到其他物体的引用。下面你可以一个包含 OtherScript的游戏物体到检视面板中的target槽。
//设置在检视面板中赋值的target变量上的foo,调用DoSomething.
vartarget:OtherScript;
functionUpdate()
{
//设置target物体的foo变量
target.foo = 2;
//调用target上的DoSomething
target.DoSomething(“Hello”);
}
2. 通过物体层定位。
对于一个已存在的物体,可以通过游戏物体的Transform组件来找到子和父物体:
//找到脚本所附加的
//游戏物体的子“Hand”
transform.Find(“Hand”).Translate(0,1,0);
一旦在层次视图中找到这个变换,你可以使用GetComponent来获取其他脚本,
//找到名为“Hand”的子。
//调用附加到它上面的OtherScript脚本的DoSomething.
transform.Form(“Hand”).GetComponent(OtherScript)DoSomething(“Hello”);
//找到名为”Hand”的子
//然后应用一个力到附加在hand上的刚体
transform.Find(“Hand”).rigidbody.AddForce(0,10,0);
你可以循环所有的子。
//变换的所有子向上移动10个单位
for(var child: Transform in transform)
{
child.Transform(0,1,0);
}
参考Transform类文档获取更多的信息
3. 根据名称或标签定位
你可以使用GameObject.FindWithTag和GameObject.FindGameObjectWithTag搜索具有特定标签的游戏物体。使用GameObject.Find根据名称查找物体。
functionStart()
{
//按照名称
var go = GameObject.Find(“SomeGuy”);
go.transform.Translate(0,1,0);
//按照标签
var player = GameObject.FindWithTag(“Player”);
player.transform.Transform(0,1,0);
}
你可以在结果上使用GetComponent,在找到的游戏物体上得到任何脚本或组件。
function Start()
{
//按名称
vargo = GameObject.Find(“SomeGuy”);
go.GetComponent(OtherScript).DoSomething();
//按标签
varplayer = GameObject.FindWithTag(“Player”);
player.GetComponent(OtherScript).DoSomething();
}
一些特殊的物体有快捷方式,如主相机使用Camera.main。
4. 作为参数传递
一些事件消息在事件中包含详细信息。例如,触发事件传递碰撞物体的Collider组件到处理函数。
OntriggerStay给我们一个碰撞器的引用。从这个碰撞器我们可以获取附加到其上的刚体。
functionOnTriggerStay(other : Collider){
//如果另一个碰撞器也有一个刚体
//应用一个力到它上面
if(other.rigidbody){
other.rigidbody.AddForee(0,2,0);
}
}
或者我们通过碰撞器获取附加在同一物体上的任何组件。
functionOnTriggerStay(other:Collider){
//如果另一个碰撞器附加了OtherScript
//调用它上面的DoSomething
//大多数时候碰撞器不会附加脚本
//所以我们需要首先检查以避免null引用异常
if(other.GerComponent(OtherScript)){
other.GetComponent(OtherScript).DoSomething();
}
}
注意通过上述例子中的other变量,你可以访问碰撞物体中的任何组件。
5一种类型的所有脚本
使用Object.FindObjectsOfType找到所有具有相同类或脚本名称的物体,或者使用Object.FindObjectOfType找到这个类型的第一个物体。
function Start()
{
//找到场景中附加了OtherScript的任意一个游戏物体
var other: OtherScipt = FindObjectOfType(OtherScript);
other.DoSomething();
}
来源:http://oulehui.blog.163.com/blog/static/796146982010611112655758/
Unity使用Vector3类统一表示全体3D向量。3D向量的不同组件可以通过x,y和z成员变量访问。
varaPosition:Vector3;
aPosition.x= 1;
aPosition.y= 1;
aPosition.z= 1;
你也可能够使用Vector3构造函数来同时初始化所有组件
varaPosition = Vector3(1,1,1);
Vector3也定义了一些常用的常量值。
vardirection = Vector3.up;//与Vector3(0,1,0);相同
单个向量上的操作可以使用下面方式访问:
someVector.Normalize();
使用多个向量的操作可以使用Vector3类函数:
theDistance= Vector3.Distance(oneVector,otherVector);
(注意你必须在函数名之前写Vector3.来告诉JS在哪里找到这个函数,这适用于所有类函数。)
你也可以使用普通数学操作来操纵向量。
combined =vector1 + vector2;
查看Vector3类文档获取完整操作和可用属性的列表。
概览:成员变量&全局变量
定义在任何函数之外的变量是一个成员变量。在Unity中这个变量可以通过检视面板来访问。任何保存在成员变量中的值也可以自动随工程保存。
varmemberVariable = 0.0;
上面的变量将在检视面板中显示名为”Member Variable”的数值属性。
如果你设置变量的类型为一个组件类型(例如Transform,Rigidbody,Collider,任何脚本名称,等等)。然后你可以在检视面板中通过拖动一个游戏物体来设置它们。
varenemy : Transform;
function Update()
{
if(Vector3.Distance(enemy.position,transform.position)<10){
print(“I sense the enemy is near”);
}
}
你也可以创建私有成员变量。私有成员变量可以用来储存那些在该脚本之外不可见的状态。私有成员变量不会被保存到磁盘并且在检视面板中不能编辑。当它被设置为调试模式时,它们在检视面板中可见。这允许你像一个实时更新的调试器一样使用私有变量。
privatevar lastCollider : Collider;
functionOnColliderEnter(collisionInfo : Collision){
lastCollider = collisionInfo.other;
}
全局变量
你也可以使用static关键字创建全局变量。
着创造了一个全局变量,名为someGlobal。
//TheScriptName.js中的一个静态变量
static var someGlobal = 5;
//你也可以在脚本内部像普通变量一样访问它
print(someGlobal);
someGlobal = 1;
为了从另一个脚本访问它,你需要使用这个脚本的名称上加上一个点和全局变量名。
print(TheScriptName.someGlobal);
TheScriptName.someGlobal = 10;
来源:http://oulehui.blog.163.com/blog/static/7961469820107934114974/
Unity 3d 引用 GUI QQ似展开
像QQ一样,你放上面 你鼠标放上去它会向下展开 .
var show = false;
var grow = false;
var min = 0.0;
var max = 50.0;
var height = 0.0;
var speed = 0.0;
//var skin:GUISkin;
function OnGUI ()
{
//GUI.skin = skin;
if(GUI.Button(Rect(5,5,104,25),"List"))
{
grow = true;
if(!show)
show = true;
}
if(show)
{
GUILayout.BeginArea(Rect(7,30,100,height),"","Box");
GUILayout.BeginVertical();
for(i = 0;i<8;i++)
GUILayout.Button(i+".Title");
GUILayout.EndVertical();
GUILayout.EndArea();
}
if(grow)
{
speed += Time.deltaTime*5.0;
height = Mathf.Lerp(min,max,speed);
if(Mathf.Approximately(height,max))
{
grow = false;
max = min;
min = height;
speed = 0.0;
if(min == 0)
show = false;
}
}
}
Unity 3d 给物体添加力
Unity 3D 2010-08-26 17:08:43 阅读62 评论0 字号:大中小 订阅
第一种:
this.gameObject.rigidbody.AddForce(0,0,5);
加力的方向和力度
第二种:
this.gameObject.rigidbody.AddForceAtPosition(ts.position -this.transform.position, transform.position,ForceMode.Impulse);
(力的目标,本身,力的类型)
引用 U3D屏幕截图
Unity 3D 2010-08-23 17:06:12 阅读58 评论0 字号:大中小 订阅
本文引用自博者《U3D屏幕截图》
引用
博者 的 U3D屏幕截图
function ScreenshotEncode()
{
// wait for graphics to render
yield WaitForEndOfFrame();
// create a texture to pass to encoding
var texture:Texture2D = new Texture2D (Screen.width,Screen.height, TextureFormat.RGB24, false);
// put buffer into texture
texture.ReadPixels(Rect(0.0, 0.0, Screen.width,Screen.height), 0.0, 0.0);
texture.Apply();
// split the process up--ReadPixels() and the GetPixels()call inside of the encoder are both pretty heavy
yield;
// create our encoder for this texture
var encoder:JPGEncoder = new JPGEncoder(texture, 75.0);
// encoder is threaded; wait for it to finish
while(!encoder.isDone)
yield;
// save our test image (could also upload to WWW)
File.WriteAllBytes(Application.dataPath +"/../testscreen-" + count + ".jpg", encoder.GetBytes());
count++;
}
//简便方法看下面:
function OnMouseDown() {
Application.CaptureScreenshot("Screenshot.png");
}
Unity 3d 射线(获得鼠标点击的坐标[x,y,z])
Unity 3D 2010-08-19 11:49:40 阅读134 评论0 字号:大中小 订阅
using UnityEngine;
using System.Collections;
public class Lu : MonoBehaviour
{
public Camera cam;
// We need to actually hit an object
RaycastHit hitt = new RaycastHit();
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
Ray ray =cam.ScreenPointToRay(Input.mousePosition);
Physics.Raycast(ray, out hitt, 100);
// Debug.DrawLine(cam.transform.position, ray.direction,Color.red);
if (null != hitt.transform)
{
print(hitt.point);//鼠标点击的坐标
}
}
}
Unity 3d 用代码脚本建造一堵Cube墙
Unity 3D 2010-08-17 10:26:59 阅读142 评论0 字号:大中小 订阅
C#版:
// Use this for initialization
void Start()
{
for (int y = 0; y < 5; y++)
{
for (int x =0; x < 5; x++)
{
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.AddComponent<Rigidbody>();
cube.transform.position = new Vector3(x, y, 0);
}
}
}
JS版:
function Start () {
for (var y = 0; y < 5; y++) {
for (var x = 0; x < 5; x++) {
var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.AddComponent(Rigidbody);
cube.transform.position = Vector3 (x, y, 0);
}
}
}
Unity 3d 里 Render Texture在屏幕中做小屏幕用
Unity 3D 2010-08-16 13:39:06 阅读181 评论2 字号:大中小 订阅
先做准备工作,我们要用到Render Texture.先创建一张rendertexture图片。
这时候这张照片是空的,因为我们没指定摄像机。在顶视图创建一个相机,调整好位置。在target texture 选项里,选择刚才创建的render texture。
这时候render texture 里面就有画面了。如图
接下来我们就要让它显示出来。代码如下:
var pic:RenderTexture;
function OnGUI () {
GUI.B