一、Awake 和 Start
Awake 和 Start 是在加载脚本时自动调用的两个函数,在一个对象绑定脚本的生命周期内只能调用一次。
Awake:还未启用脚本组件便已调用,适合用于在脚本与初始化之间设置任何引用 Start:在Awake之后调用,直接在首次更新之前调用,前提是已经启用了脚本组件,这样可以将初始化代码的任何部分,延迟到真正需要的时候再调用。
例如,有一个敌人进入游戏,并使用Awake获得了分配的弹药,但要想射击,需在启用脚本组件时,使用Start在定义时间实现射击。
using UnityEngine;
using System.Collections;
public class AwakeAndStart : MonoBehaviour
{
void Awake ()
{
Debug.Log("Awake called.");
}
void Start ()
{
Debug.Log("Start called.");
}
}


二、Update 和 FixedUpdate
Update:在每个使用它的脚本中每帧调用一次,基本上只要需要变化或调整都需要使用Update来实现。Update并不是按固定时间调用,如果某一帧比下一帧处理时间长,那么调用的时间间隔就会不同。 FixedUpdate:与Update类似,但FixedUpdate按固定时间调用,调用后会立即进行任何必要的物理计算,因此任何影响刚体(物理对象)的动作都应使用FixedUpdate执行。
using UnityEngine;
using System.Collections;
public class UpdateAndFixedUpdate : MonoBehaviour
{
void FixedUpdate ()
{
Debug.Log("FixedUpdate time :" + Time.deltaTime);
}
void Update ()
{
Debug.Log("Update time :" + Time.deltaTime);
}
}
 Unity中的Update和其他许多特殊函数,都可以在Visual Studio中迅速轻松创建,使用MonoBehaviour脚本编写向导即可实现。按Ctrl+Shift+M启动向导,勾选想要添加的方法即可在光标处添加函数。
三、启用和禁用组件
只需使用enabled标记,设为false即可禁用组件。 注意,脚本也是组件,也可以通过enabled禁用。
using UnityEngine;
using System.Collections;
public class EnableComponents : MonoBehaviour
{
private Light myLight;
void Start ()
{
myLight = GetComponent<Light>();
}
void Update ()
{
if(Input.GetKeyUp(KeyCode.Space))
{
myLight.enabled = !myLight.enabled;
}
}
}
四、SetActive、Active Self、Active in Hierarchy
SetActive:通过脚本在场景中激活或停用对象。需要注意的是,停用父对象,那么场景中活跃的子对象也会停止,但子对象仍在其层次结构中保持活跃状态。下图例子中,停用父对象PhysicsDoor,子对象Door变灰,但在层次结构中仍旧保持活跃状态。  
SetActive示例——停用对象
------------------------------------------------------
using UnityEngine;
using System.Collections;
public class ActiveObjects : MonoBehaviour
{
void Start ()
{
gameObject.SetActive(false);
}
}
------------------------------------------------------
Active Self:检测对象在场景中是否处于活跃状态。 Active in Hierarchy:检测对象在层次结构中是否处于活跃状态。
Active Self、Active in Hierarchy示例——输出对象状态
-----------------------------------------------------------------------
using UnityEngine;
using System.Collections;
public class CheckState : MonoBehaviour
{
public GameObject myObject;
void Start ()
{
Debug.Log("Active Self: " + myObject.activeSelf);
Debug.Log("Active in Hierarchy" + myObject.activeInHierarchy);
}
}
-----------------------------------------------------------------------
五、位置和旋转
1. 位置变换:transform.Translate()
-----------------------------------------------------------------------
参数:Vector3
Time.deltaTime:两次Update函数调用的间隔时长
功能:每帧移动一定距离,乘上Time.deltaTime后为匀速运动
transform.Translate(Vector3.forward * moveSpeed * Time.deltaTime);
-----------------------------------------------------------------------
2. 旋转:transform.Rotate()
-----------------------------------------------------------------------
参数1:Vector3,表示围绕哪个轴旋转
参数2:float,表示旋转量
transform.Rotate(Vector3.up, turnSpeed * Time.deltaTime);
-----------------------------------------------------------------------
3. 应用 在小飞机上挂载脚本,实现方向键控制小飞机的运动速度和方向。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyJet : MonoBehaviour
{
public float moveSpeed = 0f;
public float turnSpeed = 0f;
void Start()
{
}
void Update()
{
if (Input.GetKey(KeyCode.UpArrow))
{
moveSpeed += 0.01f;
}
else if (Input.GetKey(KeyCode.DownArrow))
{
moveSpeed -= 0.01f;
}
if (Input.GetKey(KeyCode.LeftArrow))
{
turnSpeed += 0.1f;
}
else if (Input.GetKey(KeyCode.RightArrow))
{
turnSpeed -= 0.1f;
}
if (Input.GetKey(KeyCode.Space))
{
moveSpeed = 0;
turnSpeed = 0;
}
if (moveSpeed > 0)
{
transform.Rotate(Vector3.forward, turnSpeed * Time.deltaTime);
}
else if(moveSpeed < 0)
{
transform.Rotate(Vector3.forward, -turnSpeed * Time.deltaTime);
}
transform.Translate(Vector3.up * Time.deltaTime * moveSpeed);
}
}
六、transform.lookAt(Transform target)
LookAt 函数使一个游戏对象的变换组件面向另一个游戏对象的变换组件,也就是使自身的Z轴指向另一个游戏对象,可用于摄像机对运动物体的跟踪拍摄。
using UnityEngine;
using System.Collections;
public class CameraLookAt : MonoBehaviour
{
public Transform target;
void Update ()
{
transform.LookAt(target);
}
}
七、线性插值
在制作游戏时,有时可以在两个值之间进行线性插值。这是通过 Lerp 函数来完成的。线性插值会在两个给定值之间找到某个百分比的值。例如,我们可以在数字 3 和 5 之间按 50% 进行线性插值以得到数字 4。这是因为 4 是 3 和 5 之间距离的 50%。 在 Unity 中,有多个 Lerp 函数可用于不同类型。对于我们刚才使用的示例,与之等效的将是 Mathf.Lerp 函数,如下所示:
float result = Mathf.Lerp (3f, 5f, 0.5f);
Mathf.Lerp 函数接受 3 个 float 参数:一个 float 参数表示要进行插值的起始值,另一个 float 参数表示要进行插值的结束值,最后一个 float 参数表示要进行插值的距离。在此示例中,插值为 0.5,表示 50%。如果为 0,则函数将返回“from”值;如果为 1,则函数将返回“to”值。 Lerp 函数的其他示例包括 Color.Lerp 和 Vector3.Lerp。这些函数的工作方式与 Mathf.Lerp 完全相同,但是“from”和“to”值分别为 Color 和 Vector3 类型。在每个示例中,第三个参数仍然是一个 float 参数,表示要插值的大小。这些函数的结果是找到一种颜色(两种给定颜色的某种混合)以及一个矢量(占两个给定矢量之间的百分比)。 让我们看看另一个示例:
Vector3 from = new Vector3 (1f, 2f, 3f);
Vector3 to = new Vector3 (5f, 6f, 7f);
Vector3 result = Vector3.Lerp (from, to, 0.75f);
在此示例中,结果为 (4, 5, 6),因为 4 位于 1 到 5 之间的 75% 处,5 位于 2 到 6 之间的 75% 处,而 6 位于 3 到 7 之间的 75% 处。 使用 Color.Lerp 时适用同样的原理。在 Color 结构中,颜色由代表红色、蓝色、绿色和 Alpha 的 4 个 float 参数表示。使用 Lerp 时,与 Mathf.Lerp 和 Vector3.Lerp 一样,这些 float 数值将进行插值。 在某些情况下,可使用 Lerp 函数使值随时间平滑。请考虑以下代码段:
void Update ()
{
light.intensity = Mathf.Lerp(light.intensity, 8f, 0.5f);
}
如果光的强度从 0 开始,则在第一次更新后,其值将设置为 4。下一帧会将其设置为 6,然后设置为 7,再然后设置为 7.5,依此类推。因此,经过几帧后,光强度将趋向于 8,但随着接近目标,其变化速率将减慢。请注意,这是在若干个帧的过程中发生的。如果我们不希望与帧率有关,则可以使用以下代码:
void Update ()
{
light.intensity = Mathf.Lerp(light.intensity, 8f, 0.5f * Time.deltaTime);
}
这意味着强度变化将按每秒而不是每帧发生。 请注意,在对值进行平滑时,通常情况下最好使用 SmoothDamp 函数。仅当您确定想要的效果时,才应使用 Lerp 进行平滑。
八、Destroy
在运行时使用 Destroy() 函数删除游戏对象和组件。
using UnityEngine;
using System.Collections;
public class DestroyBasic : MonoBehaviour
{
void Update ()
{
if(Input.GetKey(KeyCode.Space))
{
Destroy(gameObject);
}
}
}
using UnityEngine;
using System.Collections;
public class DestroyOther : MonoBehaviour
{
public GameObject other;
void Update ()
{
if(Input.GetKey(KeyCode.Space))
{
Destroy(other);
}
}
}
using UnityEngine;
using System.Collections;
public class DestroyComponent : MonoBehaviour
{
void Update ()
{
if(Input.GetKey(KeyCode.Space))
{
Destroy(GetComponent<MeshRenderer>());
}
}
}
九、GetButton 和 GetKey
GetButton 和 GetKey 用于在 Unity 项目中获取输入的按钮或键。 GetKey:使用KeyCode明确指定按键名称。 GetButton:指定自定义的控制。 输入管理器可以指定输入名称并给它指定一个键或按钮。方法为:顶部菜单 Edit -> Project Settings -> Input Manager,通过设置 Name 和 Positive Button 引用该按键。 输入共有三种状态并返回相应布尔值。
1. 还未按下按键  2. 按下按键后的第一帧  3. 保持按住按键  4. 松开按键后的第一帧  5. 停止动作  总之,Up 和 Down 仅在按下和松开的第一帧变为 true,其余时候为 false,而 GetButton 可以用来判断是否按住了按键,GetKey也是如此。
十、GetAxis
GetAxis 是基于轴输入,与 GetButton、GetKey 类似,同样可以通过 Input Manager 设置,但返回的是介于-1到1之间的浮点数,相当于是介于正负1之间的滑尺。 Positive Button:按下后返回值介于0到1之间。 Negative Button:按下后返回值介于-1到0之间。 Gravity:设置输入重新居中的速度。仅当 Type 设置为 key / mouse button 时,此属性才适用。Gravity 越高,归零的速度越快,反之越慢。 Sensitivity:影响按钮按下后到达1或-1的速度,对于键盘输入,值越大,响应越快。较小的值将更加平滑。对于鼠标增量,该值会缩放实际鼠标增量。 Dead:任何小于此数字的正值或负值都视为零。适用于游戏杆。 Snap:启用此选项可在接收相反输入后立即将轴值重置为零。仅当 Type 设置为 key / mouse button 时,此属性才适用。
void Update ()
{
float h = Input.GetAxis("Horizontal");
float xPos = h * range;
transform.position = new Vector3(xPos, 2f, 0);
}
十一、GetComponent
功能:访问其他脚本或组件。 用法:GetComponent<>( ),尖括号的作用是让类型作为参数
UsingOtherComponents
using UnityEngine;
using System.Collections;
public class UsingOtherComponents : MonoBehaviour
{
public GameObject otherGameObject;
private AnotherScript anotherScript;
private YetAnotherScript yetAnotherScript;
private BoxCollider boxCol;
void Awake ()
{
anotherScript = GetComponent<AnotherScript>();
yetAnotherScript = otherGameObject.GetComponent<YetAnotherScript>();
boxCol = otherGameObject.GetComponent<BoxCollider>();
}
void Start ()
{
boxCol.size = new Vector3(3,3,3);
Debug.Log("The player's score is " + anotherScript.playerScore);
Debug.Log("The player has died " + yetAnotherScript.numberOfPlayerDeaths + " times");
}
}
AnotherScript
using UnityEngine;
using System.Collections;
public class AnotherScript : MonoBehaviour
{
public int playerScore = 9001;
}
YetAnotherScript
using UnityEngine;
using System.Collections;
public class YetAnotherScript : MonoBehaviour
{
public int numberOfPlayerDeaths = 3;
}
十二、数据类型
Value(值类型) | Reference(引用类型) |
---|
int | Classes | float | Transform | double | Gameobject | bool | | char | | Structs(Vector3,Quaternion) | |
- 值类型变量:包含某个值(改变后不改变原来的值)
- 引用类型变量:包含值存储位置的存储地址(改变后该位置存储的值改变)
DatatypeScript
using UnityEngine;
using System.Collections;
public class DatatypeScript : MonoBehaviour
{
void Start ()
{
Vector3 pos = transform.position;
pos = new Vector3(0, 2, 0);
Transform tran = transform;
tran.position = new Vector3(0, 2, 0);
}
}
十三、Instantiate
在运行期间使用 Instantiate 创建预制件的克隆体
Instantiate(projectile,barrelEnd.position,barrelEnd.rotation)
-------------------------------------------------------------
projectile:要实例化的对象
barrelEnd.position:新克隆的对象的位置
barrelEnd.rotation:新克隆的对象的旋转
Instantiate(projectile):克隆体默认出现在挂载脚本的对象的位置
-------------------------------------------------------------
UsingInstantiate
using UnityEngine;
using System.Collections;
public class UsingInstantiate : MonoBehaviour
{
public Rigidbody rocketPrefab;
public Transform barrelEnd;
void Update ()
{
if(Input.GetButtonDown("Fire1"))
{
Rigidbody rocketInstance;
rocketInstance = Instantiate(rocketPrefab, barrelEnd.position, barrelEnd.rotation) as Rigidbody;
rocketInstance.AddForce(barrelEnd.forward * 5000);
}
}
}
RocketDestruction
using UnityEngine;
using System.Collections;
public class RocketDestruction : MonoBehaviour
{
void Start()
{
Destroy (gameObject, 1.5f);
}
}
十四、数组
使用数组将变量集合在一起以便于管理
Arrays
using UnityEngine;
using System.Collections;
public class Arrays : MonoBehaviour
{
public GameObject[] players;
void Start ()
{
players = GameObject.FindGameObjectsWithTag("Player");
for(int i = 0; i < players.Length; i++)
{
Debug.Log("Player Number "+i+" is named "+players[i].name);
}
}
}
十五、Invoke
Invoke 函数可用于安排在以后的时间进行方法调用。
Invoke(name,time)
-------------------------------------------------------
name:字符串类型,想调用的方法名称
time:以秒为单位的延时时长
只有不包含参数,且返回类型为void的函数能调用Invoke
-------------------------------------------------------
InvokeScript
using UnityEngine;
using System.Collections;
public class InvokeScript : MonoBehaviour
{
public GameObject target;
void Start()
{
Invoke ("SpawnObject", 2);
}
void SpawnObject()
{
Instantiate(target, new Vector3(0, 2, 0), Quaternion.identity);
}
}
InvokeRepeating(name,timeBeforeMethod,timeAfterMethod)
-------------------------------------------------------
name:字符串类型,想调用的方法名称
timeBeforeMethod:调用方法之前的延时,以秒为单位
timeAfterMethod:后续方法调用间隔的延时,以秒为单位
-------------------------------------------------------
CancelInvoke(name)
-------------------------------------------------------
无参:停止这个脚本中由Invoke调用的所有实例
name:想暂停的方法名称,停止某个指定的Invoke
-------------------------------------------------------
InvokeRepeating
using UnityEngine;
using System.Collections;
public class InvokeRepeating : MonoBehaviour
{
public GameObject target;
void Start()
{
InvokeRepeating("SpawnObject", 2, 1);
}
void SpawnObject()
{
float x = Random.Range(-2.0f, 2.0f);
float z = Random.Range(-2.0f, 2.0f);
Instantiate(target, new Vector3(x, 2, z), Quaternion.identity);
}
}
十六、枚举
枚举可用于创建相关常量的集合。
格式:enum Name {A, B, C, D};
每个常量都有默认值,为从0开始往上数的整数,上例A=0,B=1,C=2,D=3
enum Name {A=1, B, C, D};默认值从1开始往上数
也可以声明每个常量的值
枚举中常量的类型可以更改为任意整数类型 ->enum Name : short {A, B, C, D};
EnumScript
using UnityEngine;
using System.Collections;
public class EnumScript : MonoBehaviour
{
enum Direction {North, East, South, West};
void Start ()
{
Direction myDirection;
myDirection = Direction.North;
}
Direction ReverseDirection (Direction dir)
{
if(dir == Direction.North)
dir = Direction.South;
else if(dir == Direction.South)
dir = Direction.North;
else if(dir == Direction.East)
dir = Direction.West;
else if(dir == Direction.West)
dir = Direction.East;
return dir;
}
}
|