燈光
基本項
烘焙
燈光的種類
Lighting窗口
預設體
瞭解預設體
利用代碼操作預設體
實例化預設體Instantiate
//預設體的類型也是GameObject,名字是CubePre。
public GameObject CubePre;
//注意這一步:在unity中,將預設體關聯到腳本的變量上來。
void Start () {
/*法一:實例化到指定位置。
預設體,位置(中心),旋轉(默認四元數。此處設爲不轉)。返回值是剛生成的物體。*/
GameObject go = Instantiate(CubePre, transform.position, Quaternion.identity);
//法二:不指定位置的實例化。
Instantiate(CubePre);
}
刪除
位置:Start
刪除物體
/*刪除物體。一般是在一幀完了之後刪除。
不能寫在Update裏,因爲這個刪除是有延遲的,和垃圾回收機制一樣。*/
Destroy(go);
3秒之後刪除
Destroy(go, 3f); //3秒之後刪除
立刻刪除
//立刻刪除(強制刪除)。可以寫在Update裏。費性能,少用。
DestroyImmediate(go);
刪除組件
//刪除組件。例如刪除AudioSource組件
Destroy(GetComponent<AudioSource>());
3d物體的事件
注意:該物體需勾已選碰撞器這個組件;在Game窗口進行操作
鼠標移動進物體,在物體範圍內,離開物體
//鼠標移動進物體
private void OnMouseEnter()
{
Debug.Log("Enter");
}
//鼠標在物體範圍內
private void OnMouseOver()
{
Debug.Log("Over");
}
//鼠標離開物體
private void OnMouseExit()
{
Debug.Log("Exit");
}
鼠標按下,擡起,按下並擡起
//鼠標按下
private void OnMouseDown()
{
Debug.Log("Down");
}
//鼠標擡起。如果按下是在物體上,那麼一出物體時,擡起是調用的
private void OnMouseUp()
{
Debug.Log("Up");
}
//按下並擡起(上面兩個方法的結合)。按下並擡起必須都在物體身上
private void OnMouseUpAssButton()
{
Debug.Log("Butten")
}
按下持續調用
//按下持續調用(可用於拖拽,但拖拽更多是用射線)
private void OnMouseDrag()
{
Debug.Log("Drag");
}
碰撞體、剛體
兩個物體產生碰撞的條件:兩個物體都要有碰撞體,且至少一個有剛體。
注意:運行時添加的組件,在運行結束後會消失。
Unity裏
代碼
產生碰撞的時候會調用OnCollisionEnter
//產生碰撞的時候會調用。
/*unity裏面的碰撞器是Collider,但代碼中Colision是一個類,它裏面包含一些數據信息。
裏面可以找到碰撞器、遊戲物體、剛體等。 */
private void OnCollisionEnter(Collision collision)
{
}
當碰撞結束的時候會調用OnCollisionExit
//當碰撞結束的時候會調用
private void OnCollisionExit(Collision collision)
{
Debug.Log("Exit");
}
獲得碰撞的物體的碰撞器,碰撞點,碰撞法線
//產生碰撞的時候會調用。
private void OnCollisionEnter(Collision collision)
{
//獲得碰撞的物體的碰撞器
Collider collider = collision.collider;
Debug.Log("Enter" + collider.name); //此時獲得的是地面
//碰撞點。它是個數組,因爲物體不同,碰撞點的個數不同。
Vector3 point = collision.contacts[0].point;
//碰撞法線
Vector3 normal = collision.contacts[0].normal;
}
移動物體
法一:無剛體時用。有剛體,速度特別快時,不能用(遇牆抖動)。
void Update () {
//移動物體,法一:無剛體時用。有剛體,速度特別快時,不能用。向前每秒走十米
transform.Translate(transform.forward * 10 *Time.deltaTime);
}
法二:給力Rbody.AddForce(利用剛體,只給一次力。所以速度是越來越慢的)
//移動物體,法二、法三:利用剛體
private Rigidbody Rbody;
void Start () {
//先得到物體身上的剛體組件
Rbody = GetComponent<Rigidbody>();
//法二:給力(給一次。所以速度是越來越慢的 )。方向(前方向量)* 力
Rbody.AddForce(transform .forward * 300f);
}
法三:給速度Rbody.velocity(利用剛體)
//移動物體,法二、法三:利用剛體
private Rigidbody Rbody;
void Start () {
//先得到物體身上的剛體組件
Rbody = GetComponent<Rigidbody>();
}
void Update () {
/*移動物體,法三:給速度。velocity代表當前物體的速度。
transform.forward我的前方,如果是會滾動的物體,那麼它的前方是會發生改變,
所以注意是否需要鎖定滾動。*/
Rbody.velocity = transform.forward * 10;
//勻速移動。Vector3.forward世界的前方,方向不會變。
Rbody.velocity = Vector3.forward * 10;
}
炸箱子
課程代碼
//產生碰撞的時候會調用。
/*unity裏面的碰撞器是Collider,但代碼中Colision是一個類,它裏面包含一些數據信息。
裏面可以找到碰撞器、遊戲物體、剛體等。 */
private void OnCollisionEnter(Collision collision)
{
//爆炸範圍半徑5m
float r = 5;
//Physics物理的類,它有很多方法,比如此處的OverlapSphere。
//得到圓心爲collision.contacts[0].point,半徑爲r的圓中間的所有碰撞體。
Collider[] colliders = Physics.OverlapSphere(collision.contacts[0].point,r);
//在unity裏面把箱子的標籤統一成Box
//遍歷碰撞體
foreach(Collider collider in colliders)
{
//判斷是不是可以被擊飛的箱子
if(collider.tag == "Box")
{
/*給箱子添加爆炸力。首先拿它的剛體GetComponent,
然後給它一個爆炸力AddExplosionForce,參數:力(50),爆炸點(圓心),半徑(r)*/
collider.GetComponent<Rigidbody>().AddExplosionForce(500f, collision.contacts[0].point, r);
}
}
複習自寫代碼
//產生碰撞時調用
void OnCollisionEnter(Collision collision)
{
//爆炸半徑
float radius = 5f;
//爆炸點
Vector3 point = collision.contacts[0].point;
//拿到要炸的物體
Collider[] colliders = Physics.OverlapSphere(point, radius);
//遍歷物體,找到要炸的
for(int i = 0; i < colliders.Length; i++)
{
if (colliders[i].CompareTag("Box"))
{
//給爆炸力
colliders[i].GetComponent<Rigidbody>().AddExplosionForce(500f, point, radius);
}
}
}
觸發器
下面的實例中,腳本在球上,讓球穿過立方體,立方體的觸發器應該打上勾。
進入觸發區域調用
//進入觸發區域調用。other代表你(球)進入的那個物體(立方體)的觸發器
private void OnTriggerEnter(Collider other)
{
//打印觸發器的名字,結果是立方體
Debug.Log("Enter" + other.name);
}
離開觸發區域調用
//離開觸發區域調用
private void OnTriggerExit(Collider other)
{
Debug.Log("Exit");
}
物理材質
射線
畫出射線
void Start () {
//射線。射線的起始點,射線向量。從003的點向下4米的射線。
Ray ray = new Ray(Vector3.up * 3, Vector3.down * 4);
}
void Update () {
//畫出射線
Debug.DrawRay(Vector3.up * 3, Vector3.down * 4);
}
檢測碰撞
法一:只顯示第一個碰撞點
void Start () {
//射線。射線的起始點,射線向量。從003的點向下4米的射線。
Ray ray = new Ray(Vector3.up * 3, Vector3.down * 4);
//取得射線碰撞的物體。RaycastHit碰撞數據結構體。
RaycastHit hit; //聲明一個碰撞數據結構體。
/*檢測射線碰撞。out的意思就是,我們把hit傳進去,
它在內部可以給hit賦值,之後我們就可以把hit拿出來了。*/
bool res = Physics.Raycast(ray, out hit);
if (res == true)
{
//鼠標點在地面上。打印碰撞點(只會打印第一個碰撞點)。
//Debug.Log("鼠標點在:" + hit.point);
}
}
void Update () {
//畫出射線
Debug.DrawRay(Vector3.up * 3, Vector3.down * 4);
}
}
}
法二:RaycastHit[]碰撞點的集合
void Start () {
//射線。射線的起始點,射線向量。從003的點向下4米的射線。
Ray ray = new Ray(Vector3.up * 3, Vector3.down * 4);
//取得射線碰撞的物體。RaycastHit碰撞數據結構體。
RaycastHit hit; //聲明一個碰撞數據結構體。
//法二:檢測射線碰撞
RaycastHit[] hits = Physics.RaycastAll(ray);
}
void Update () {
//畫出射線
Debug.DrawRay(Vector3.up * 3, Vector3.down * 4);
}
}
}
鼠標點在地面上
void Update () {
if(Input.GetMouseButtonDown(0))
{
//取得射線。Camera.main主攝像機。屏幕座標的位置
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
//取得射線碰撞的物體。RaycastHit碰撞數據結構體。
RaycastHit hit; //聲明一個碰撞數據結構體。
/*檢測射線碰撞。
意思就是,我們把hit傳進去,它在內部可以給hit賦值,之後我們就可以把hit拿出來了。*/
bool res = Physics.Raycast(ray, out hit);
if (res == true)
{
//鼠標點在地面上。打印碰撞點(只會打印第一個碰撞點)。
Debug.Log("鼠標點在:" + hit.point);
}
}
}
物體向鼠標點擊的位置移動
public class ReyTest : MonoBehaviour {
//目標點traget
private Vector3 target;
void Start () {
//首先,目標點位置就是自身位置
target = transform.position;
}
// Update is called once per frame
void Update () {
if(Input.GetMouseButtonDown(0))
{
//取得射線。Camera.main主攝像機。屏幕座標的位置
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
//取得射線碰撞的物體。RaycastHit碰撞數據結構體。
RaycastHit hit; //聲明一個碰撞數據結構體。
/*檢測射線碰撞。out的意思就是,我們把hit傳進去,
它在內部可以給hit賦值,之後我們就可以把hit拿出來了。*/
bool res = Physics.Raycast(ray, out hit, 500f,1<<LayerMask.NameToLayer("Ground"));
if (res == true)
{
//鼠標點在地面上。打印碰撞點(只會打印第一個碰撞點)。
//Debug.Log("鼠標點在:" + hit.point);
//之後,將鼠標點擊的位置賦值給目標點
target = hit.point;
//如果希望Y軸不變,則等於它自身的Y值
target.y = transform.position.y;
}
//判斷一下目標位置和我的位置之間的距離,如果大於0.3就向目標距離前進
if(Vector3.Distance(target,transform.position)> 0.3f)
{
//得到向量。(目標位置-我的位置),然後轉換成單位向量,這樣便於計算速度。
Vector3 dir = (target - transform.position).normalized;
//轉向這個向量。Quaternion四元數
transform.rotation = Quaternion.LookRotation(dir);
//前進
transform.Translate(Vector3.forward * 2 * Time.deltaTime);
}
}
}
}
特別說明
法一:(ray, out hit)兩個參數(會出現牆後位置不能到達的問題)
//法一:(ray, out hit)兩個參數。會出現牆後位置不能到達的問題。
//檢測射線碰撞。out的意思就是,我們把hit傳進去,它在內部可以給hit賦值,之後我們就可以把hit拿出來了。
bool res = Physics.Raycast(ray, out hit);
法二:四個參數(指定與哪一層進行檢測,解決牆後位置不能到達的問題)
參數3:射線長度是500米。參數4:第幾層(層Ground在第8層)。
第四個參數:
1、左移運算符<<
2、導致兩種寫法:比如此處都是要檢測地面。
3、第四個參數還影響着:如果不想和誰檢測。
即將第四個參數用小括號括起來,前面加波浪線。例如:~(1<<8)
寫法一:1<<8 查看地面是哪一層,把層數寫在這裏,此處爲8.
/*左移運算符<<。LayerMask:1<<層數,就代表和這層進行射線檢測。
如果是兩層,則加|隔開,例如:1<<8 | 1<<9*/
//法一:1<<8 查看地面是哪一層,把層數寫在這裏,此處爲8.
bool res = Physics.Raycast(ray, out hit, 500f,1<<8);
寫法二:1<<LayerMask.NameToLayer(“Ground”) 直接寫要檢測的物體的名字,此處爲地面
//法二:1<<LayerMask.NameToLayer("Ground") 直接寫要檢測的物體的名字,此處爲地面
bool res = Physics.Raycast(ray, out hit, 500f,1<<LayerMask.NameToLayer("Ground"));