小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Unity從青銅 到 王者!只差這篇讓你學會Unity中最重要的部分——腳本組件

 敲代碼的小Y 2021-12-01
  • ??腳本概念

  • ??開發(fā)工具

  • ??腳本結(jié)構(gòu)介紹

  • ??腳本的生命周期

  • ??調(diào)試方法

  • ??Unity腳本常用的API

  • ??Unity實現(xiàn)功能的三部曲

??前言

  • 如果你點進來了,那么恭喜你看到了一篇關(guān)于Unity中的腳本超級詳細的全面介紹??
  • 內(nèi)容干不干,往下看就知道了!??
  • 本篇博客來簡單介紹一下Unity組件中很重要的一種——腳本組件的介紹 ??
  • 幾乎覆蓋了關(guān)于腳本內(nèi)容的大部分,希望感興趣的小伙伴可以認真看完哦??
  • 如果看完學不會請順著網(wǎng)線來咬我??!
在這里插入圖片描述

??腳本

  • 首先讓我們回顧一下上一篇文章中對Unity中的腳本的簡單介紹

  • 腳本在Unity中也是一種組件,在之前的組件介紹文章中已經(jīng)說過

  • 腳本必須要繼承MonoBehaviour,而且文件名要和類名一致(如果在Unity里更改了C#文件的名稱,在這個腳本里也要改類名),不然腳本掛不上游戲?qū)ο蟆?/p>

在這里插入圖片描述

??腳本概念

  • 腳本是附加在游戲物體上用于定義游戲?qū)ο笮袨榈闹噶畲a
  • 腳本腳本就是Unity中寫代碼的東西!(??小白提醒~)
  • Unity支持三種高級編程語言:C#JavaScript Boo Script(unity4以前支持的)

??開發(fā)工具

開發(fā)工具指的是需要用來寫代碼,寫腳本的東西!(??小白提醒~)

MonoDevelop

  • unity自帶的腳本編輯器,創(chuàng)建Mono應(yīng)用程序,適用于Linux、Mac OSX和Windows的集成開發(fā)環(huán)境,支持C#和JavaScript等
  • 這款編輯器應(yīng)該是Unity5.0或者是之前的老版本使用的,目前是被淘汰了用不到

Visual Studio

  • 微軟公司的開發(fā)工具包,包括了整個軟件生命周期中需要的大部分工具,如團隊開發(fā)工具,集成開發(fā)環(huán)境等等。
  • 在Unity中通過菜單設(shè)置修改默認的腳本編輯器,Visual Studio 官網(wǎng)下載鏈接在這
在這里插入圖片描述

JetBrains Rider

  • JetBrains Rider 是一款基于 IntelliJ 平臺和 ReSharper 的跨平臺 .NET IDE。
  • Rider 支持 .NET 框架、新的跨平臺框架 .NET Core 和基于 Mono 的項目。
  • 這使您可以開發(fā)廣泛的應(yīng)用程序,包括:.NET 桌面應(yīng)用程序、服務(wù)和庫、Unity 游戲、Xamarin 應(yīng)用、ASP.NET 和 ASP.NET Core web 應(yīng)用程序。
  • JetBrains Rider官網(wǎng)下載鏈接在這,感興趣的可以下載試試,跟VS開發(fā)差不多

??腳本結(jié)構(gòu)介紹

  • 在這里說一下Monobehaviour的繼承關(guān)系
  • 腳本—>Monobehaviour—>Behaviour—>Component—>Object
  • 下面是一個普通腳本的結(jié)構(gòu)介紹
using 命名空間;
public class 類名:MonoBehaviour
{
    void 方法名()
    {
        Debug.Log("調(diào)試顯示信息");
        print("本質(zhì)就是Debug.Log方法");
    }
}
  • 下面是新建一個腳本打開的樣子,Start() 方法和 Update() 方法是Unity中新建一個腳本時自動就有的方法
  • Start() 方法在程序開啟的第一幀執(zhí)行
  • Update() 方法在程序的每一幀都會執(zhí)行
  • Unity中每一幀是0.02秒

創(chuàng)建腳本有好幾種方法,這里簡單介紹兩種

1.Project面板右鍵-> Create-> C# Script

2.在游戲?qū)ο?/span>上點擊Add Component,直接輸入想要創(chuàng)建的腳本名稱就可以了 這樣腳本會自動創(chuàng)建完成并且掛載到剛才點擊的游戲?qū)ο笊厦?/strong>


??腳本的生命周期

  • 說道腳本,自然要談一談Unity中的腳本生命周期啦。

  • 因為我們所寫的代碼都要有一個執(zhí)行順序,才能有條不紊的執(zhí)行我們需要讓程序執(zhí)行的事情,聽起來還有些繞口~

  • 類似Android中的Activity也有自己的生命周期

  • 先來看一張挺長的圖,這張圖幾乎涵蓋了腳本的所有方法執(zhí)行的順序啦~

看完了圖是不是感覺有點慌,有的小伙伴就要說啦:這個圖的方法那么多,看著就頭大啦,看不明白~

那不要擔心,我們今天主要講的是Unity腳本生命周期的九大回調(diào),也是腳本中最常用到的方法了 想讓回調(diào)函數(shù)執(zhí)行有個前提,就是  腳本必須以組件的方式掛載到場景中某一個游戲?qū)ο笊砩?/span>

  • 九大回調(diào)說的就是就是下面圖中這九個方法啦
  • 三種Update都是每幀執(zhí)行一次
  • FixedUpdate一般用于表現(xiàn)物理效果的時候使用會比Update效果好
  • LateUpdate在相機腳本上使用較好,因為相機可以在Update執(zhí)行之后運行,不會出現(xiàn)畫面Bug的現(xiàn)象

其中他們的執(zhí)行順序:Awake——>OnEnable——>Start——>FixedUpdate——>Update——>LateUpdate——>OnGUI——>OnDisable——>OnDestroy  

  • 如果有多個腳本中同時在Awake()或Start()中寫了方法,哪一個腳本中的先執(zhí)行呢?

這個問題需要考慮,不然的話代碼中會出現(xiàn)一個時效出錯,空引用之類的錯誤

這里告訴大家一個辦法,就是下面這套流程。可以在下圖面板上將腳本的先后順序添加上,程序就會按照我們設(shè)置的順序來執(zhí)行啦 如果沒有設(shè)置這個,那不同腳本先后執(zhí)行速度就是隨機的了,不過AwakeStart也都是在第一幀執(zhí)行的

  • Edit->Project Settings->Script Execution Order

??調(diào)試方法

Unity編輯器調(diào)試

在腳本代碼中用打印方法調(diào)試Debug.Log()或者print()進行打印log調(diào)試

使用Visual Studio調(diào)試

調(diào)試步驟:

  1. 在可能出錯的行添加斷點
  2. 啟動調(diào)試
  3. 在Unity中Play場景
  4. 在vs中按F11逐條調(diào)試
  5. 調(diào)試完畢按F5退出調(diào)試
在這里插入圖片描述

也可以在調(diào)試時右鍵–>快速監(jiān)視,在快速監(jiān)視面板便捷的調(diào)試和查看數(shù)據(jù)。還可以在即時窗口輸入代碼進行調(diào)試

因為Update和其他方法不同,它是逐幀運行的,所以在調(diào)試時需要單幀調(diào)試

  • 步驟:啟動調(diào)試->運行場景->暫停游戲->加斷點->單幀執(zhí)行->結(jié)束
在這里插入圖片描述

??Unity腳本常用的API

閱讀編程資料時經(jīng)常會看到API這個名詞,網(wǎng)上各種高大上的解釋估計放倒了一批初學者。

API(Application Programming Interface,應(yīng)用程序編程接口)是一些預(yù)先定義的函數(shù),目的是提供應(yīng)用程序與開發(fā)人員基于某軟件或硬件得以訪問一組例程的能力,而又無需訪問源碼,或理解內(nèi)部工作機制的細節(jié)?!俣劝倏?/p>

網(wǎng)上關(guān)于API的介紹有一大堆,大多數(shù)還舉了例子介紹 其實把API看成一個使用文檔就得了~哪來這么多事

既然介紹完了腳本,那就順帶介紹幾種腳本常用的API吧,可以先來看一下Unity的核心類圖(圖片上網(wǎng)上我能找到的最清晰的了,雖然還是有些模糊~)

GameObject(游戲?qū)ο?

GameObject游戲?qū)ο螅?span style="font-size:18px;color:#43cd80;">GameObject提供了添加、設(shè)置游戲?qū)ο?,查找、銷毀游戲?qū)ο蟮墓δ?下圖是GameObject的屬性參數(shù)。下面使用代碼示例來學習一下

void Start()
{
Debug.Log(gameObject.activeSelf);//當前游戲?qū)ο蟮募せ顮顟B(tài)
gameObject.SetActive(false);//設(shè)置當前對象的激活狀態(tài)
gameObject.SetActive(!gameObject.activeSelf);//設(shè)置當前游戲?qū)ο蟮募せ顮顟B(tài)為當前狀態(tài)的反向狀態(tài)

Debug.Log(gameObject.name);//獲取當前對象名字
Debug.Log(gameObject.tag);//獲取當前對象標簽
Debug.Log(gameObject.layer);//獲取當前對象層

Light mylight = gameObject.GetComponent(type:"Light"as Light;
mylight = gameObject.GetComponent(typeof(Light))as Light;

mylight = gameObject.GetComponent<Light>();//獲取當前游戲?qū)ο蟮慕M件
mylight = gameObject.AddComponent<Light>();//添加一個組件到游戲?qū)ο笊砩?,并返回這個組件
---
GameObject lt = GameObject.Find("Directional Light");//通過名字找到單個游戲?qū)ο?/span>
GameObject com = GameObject.FindWithTag("Player");//通過標簽找到單個游戲?qū)ο?/span>
com = GameObect.FindGameObjectWithTag("MainCanmer");

GameObject[] coms = GameObject.FindGameObjectWithTag(MainCanmer);//通過標簽找到多個游戲?qū)ο?/span>
}

特別要注意的是不同通過Find找到處于未激活狀態(tài)的對象Inspector面板上這里未勾選就是未激活的意思,相應(yīng)的在Hierarcht面板上的游戲?qū)ο缶蜁兂?strong style="font-weight: bold;color: black;">灰色。

Component(組件)

Component就是組件,在上篇博客已經(jīng)介紹了,這里再重新介紹下腳本API的使用吧 添加、獲取和銷毀組件的方法添加組件

GameObject Cube= GameObject.CreatePrimitive(PrimitiveType.Cube);//創(chuàng)建一個方格
Cube.AddComponent<BoxCollider>();//添加盒形碰撞器組件
Cube.AddComponent<Rigidbody>();//添加剛體組件
Cube.AddComponent<Test>();//添加Test腳本

獲取組件

BoxCollider boxCollider = Cube.GetComponent<BoxCollider>();//獲取盒形碰撞器組件
Rigidbody rigidbody = Cube.GetComponent<Rigidbody>();//獲取剛體組件
Test test= Cube.GetComponent<Test>();//獲取某個Test腳本

GetComponent
GetComponents

GetComponentInChildren
GetComponentsInChildren

GetComponentInParent
GetComponentsInParent

銷毀組件

//()中的參數(shù)為創(chuàng)建相應(yīng)組件時的組件名稱
Destroy(boxCollider );//銷毀盒形碰撞器組件
Destroy(rigidbody);//銷毀剛體組件

Transform

Transform組件在上篇介紹組件的博客也說過了,這里在提一下在腳本使用的API下面來用代碼示例學一下Transform的使用

void Start(){
//1.控制游戲?qū)ο蟮淖儞Q
Debug.Log(transform.position);//世界坐標
Debug.Log(ransform.localPostion);//本地坐標

Debug.Log(transform.eulerAngles);//世界歐拉角
Debug.Log(transform.localEulerAngles);//本地歐拉角

Debug.Log(transform.rotation);//世界旋轉(zhuǎn)(四元數(shù))
Debug.Log(transform.localRotation);//本地旋轉(zhuǎn)(四元數(shù))

//本地縮放
 Debug.Log(transform.localScale);
 //方向
//自身前方的方向向量
Debug.Log(transform.forward);
 //自身右方的方向向量
Debug.Log(transform.right);
//自身上方的方向向量
 Debug.Log(transform.up);

//描述游戲?qū)ο蟮膶蛹夑P(guān)系
 //父對象
Debug.Log(transform.parent);
   //根對象
Debug.Log(transform.root);

//設(shè)置父物體
transform.parent = lookAtTarget;
//==>
transform.SetParent(lookAtTarget);

 //遍歷所有的子對象
 foreach (Transform tra in transform)
 {
 Debug.Log(tra);
  }

//遍歷所有的子對象
for (int i = 0; i < transform.childCount; i++)
{
 Debug.Log(transform.GetChild(i));
 }

 //找當前對象的子對象
Transform sph = transform.Find("Cylinder/Sphere");
 Debug.Log(sph);
}

private void Update()
    {
        //角色朝自身前方移動
        // transform.position += transform.forward * 0.05f;
        // transform.Translate(transform.forward * 0.05f);
 //自轉(zhuǎn)
 transform.Rotate(new Vector3(0,1,0),2,Space.World)
// ==>
 transform.eulerAngles += new Vector3(0,1,0);

transform.Rotate(new Vector3(0,1,0),2,Space.Self);
//==>
transform.localEulerAngles += new Vector3(0,1,0);

//繞某個點沿某個軸,旋轉(zhuǎn)
transform.RotateAround(new Vector3(000), new Vector3(010), 5);

transform.LookAt(new Vector3(0,0,0));
transform.LookAt(lookAtTarget);//看向某個對象

Vector3(三維向量)

Vector3向量,在三維坐標系中帶有方向和大小的數(shù)據(jù),下圖介紹了Vector3的屬性參數(shù)下面來用代碼示例學一下 Vector3的使用

//創(chuàng)建一個三維向量
        Vector3 dir = new Vector3(1,2,3);
        //創(chuàng)建一個二維向量
        Vector2 dir2 = new Vector2(3,3);
        //創(chuàng)建一個四維向量
        Vector4 dir4 = new Vector4(1,2,3,4);
        
//獲取一個向量的單位向量
Vector3 normalDir = dir.normalized;
//將當前向量變成單位向量
        dir.Normalize();
        //向量的長度【?!?/span>
        float mag = dir.magnitude;
        //模的平方【用來做向量長度的對比】
        float sqrMag = dir.sqrMagnitude;
 // Vector3.forward
        // Vector3.back
        // Vector3.left
        // Vector3.right
        // Vector3.up
        // Vector3.down
        // Vector3.zero
        // Vector3.one       

        Vector3 pointA = Vector3.forward;
        Vector3 pointB = Vector3.right;
        //求兩個坐標的距離
        float dis = Vector3.Distance(pointA, pointB);
 
        Vector3 dirA = Vector3.one;
        Vector3 dirB = Vector3.right;

        //求兩個向量的夾角
        float angle = Vector3.Angle(dirB, dirA);
        float newAngle = Vector3.Angle(new Vector3(110), Vector3.zero);

      //求兩個向量的點乘
        float dot = Vector3.Dot(dirA, dirB);

      //求兩個向量的叉乘【求兩個向量的法向量】
        Vector3 normal = Vector3.Cross(dirA, dirB);

      //求一個向量在某個方向上的投影向量
        Vector3 pro = Vector3.Project(new Vector3(110), Vector3.right);

   //求兩個向量中間的插值坐標
        Vector3.Lerp(new Vector3(100), new Vector3(500), 0.5f);

//由快到慢運動過去
        transform.position = Vector3.Lerp(transform.position, new Vector3(500), 0.03f);
 

Quaternion(四元數(shù)旋轉(zhuǎn))

Quaternion四元數(shù)本質(zhì)上是一種高階復數(shù),是一個四維空間,相對于復數(shù)的二維空間。在Unity里,tranform組件有一個變量名為Rotation,它的類型就是四元數(shù)。用于在Unity中控制旋轉(zhuǎn)的一種方式

下面來用代碼示例學一下 Quaternion的使用

public class ReadQuaternion : MonoBehaviour
{
    
    public float turnSpeed = 3f;
    public Transform target;
    
  void Start()
    {
        //空旋轉(zhuǎn)【相當于歐拉角的(0,0,0)】
        Debug.Log(Quaternion.identity);
        //將當前角色的旋轉(zhuǎn)設(shè)置空旋轉(zhuǎn)
        transform.rotation = Quaternion.identity;
    }
    void Update()
    {
        // transform.LookAt(target);
        //插值旋轉(zhuǎn)
        // transform.rotation 起點四元數(shù)

        //玩家指向敵人的方向向量
        Vector3 dir = target.position - transform.position;
        //目標四元數(shù)
        Quaternion targetQua = Quaternion.LookRotation(dir);
        
        // transform.position = Vector3.Lerp(transform.position,Vector3.right*5,0.02f);

        //插值轉(zhuǎn)身
        transform.rotation = Quaternion.Lerp(transform.rotation, targetQua, 0.02f * turnSpeed);
    }
}

Time(時間)

首先介紹兩個概念:現(xiàn)實時間游戲時間大多數(shù)Time類都是依賴于游戲時間的?,F(xiàn)實時間也就是不依賴于程序內(nèi)部,就算程序暫停也會繼續(xù)計算的真實時間,而游戲時間是基于程序內(nèi)部的,可以自行調(diào)整。我們這里用的都是游戲時間下面來用代碼示例學一下 Time 類的使用

public class ReadTimeAndMathf : MonoBehaviour
{

    //時間縮放
    public float timeScale = 1f;

    public float moveSpeed = 2;

    private void FixedUpdate()
    {
        Debug.Log(Time.fixedDeltaTime);
        transform.position += Vector3.forward * Time.fixedDeltaTime * moveSpeed;
    }

    void Update()
    {
        // Debug.Log(Time.time);//游戲過來多長時間
        Debug.Log(Time.deltaTime);//每幀的時間間隔

        //調(diào)整時間縮放
        Time.timeScale = timeScale;

        // transform.position += Vector3.forward * Time.deltaTime * moveSpeed;
        // transform.position = Vector3.Lerp(transform.position,Vector3.forward * 5 ,Time.deltaTime * moveSpeed);
    }
}

Input鍵盤輸入方法

在游戲中我們經(jīng)常要用到按某個鍵來執(zhí)行某件事,就比如按A鍵開炮,空格鍵跳躍等等。下面就來簡單介紹一下怎樣使用 鍵盤輸入方法

public class SimplePlayerMove : MonoBehaviour
{
    [Header("炮彈")]
    public GameObject bullet;
    
    public float moveSpeed = 3f;
    public float turnSpeed = 3f;

    private float hor, ver;
    
void OldUpdate(){
bool downA = Input.GetKeyDown(KeyCode.A);

        if (Input.GetKeyDown(KeyCode.A))
        {
            Debug.Log("按下了A鍵");
        }

        if (Input.GetKeyUp(KeyCode.A))
        {
            Debug.Log("松開了A鍵");
        }

        if (Input.GetKey(KeyCode.Space))
        {
            Debug.Log("按住了空格鍵");
        }
        
if(Input.GetKey(KeyCode.W))//前進
{
transform.position +=transform.forward * Time.deltaTime * moveSpeed;
}
if(Input.GetKey(KeyCode.S))//后退
{
transform.position -=transform.forward * Time.deltaTime * moveSpeed;
}
 if (Input.GetKey(KeyCode.A))//左轉(zhuǎn)
        {
            transform.eulerAngles -= Vector3.up * turnSpeed;
        }
  if (Input.GetKey(KeyCode.D))//右轉(zhuǎn)
        {
            transform.eulerAngles += Vector3.up * turnSpeed;
        }
}
----
void Update()
  {
    hor = Input.GetAxis("Horizontal");
    ver = Input.GetAxis("Vertical");
//transform.position += new Vector3(hor, 0, ver) *Time.deltaTime * moveSpeed;   
       //前后移動
        transform.position += ver * transform.forward * Time.deltaTime * moveSpeed;
        //左右轉(zhuǎn)身
        transform.eulerAngles += hor * Vector3.up * turnSpeed;
  }
}

Input鼠標輸入方法

說完了鍵盤輸入,自然還有鼠標輸入啦,那下面就來介紹一下 鼠標輸入方法


void KeyUpdate()
{

        if (Input.GetMouseButtonDown(0))
        {
            Debug.Log("按下了鼠標左鍵");
        }
        
        if (Input.GetMouseButtonUp(0))
        {
            Debug.Log("松開了鼠標左鍵");
        }
        
        if (Input.GetMouseButton(0))
        {
            Debug.Log("按住了鼠標左鍵");
        }
}
---
void Update()
{
float hor = Input.GetAxis("Horizontal");
//Debug。Log( if (Input.GetButtonDown("Fire"));
        {
            Debug.Log("按住了開火鍵");

            // GameObject crtPlayer = Instantiate(playerPrefab);
            GameObject crtPlayer = Instantiate(playerPrefab, Vector3.forward, Quaternion.identity);
        })
 if (Input.GetButtonDown("Fire"))
        {
            Debug.Log("按住了開火鍵");

            // GameObject crtPlayer = Instantiate(playerPrefab);
            GameObject crtPlayer = Instantiate(playerPrefab, Vector3.forward, Quaternion.identity);
        }
}



??Unity實現(xiàn)功能的三部曲

  1. 找到要操作的游戲?qū)ο蠡蛩慕M件
  2. 找到功能所對應(yīng)的組件
  3. 設(shè)置組件的屬性,或調(diào)用組件提供的方法,從而實現(xiàn)功能

注意

  1. 當程序出現(xiàn)異常,程序會自動暫停,后邊的代碼就不會執(zhí)行了
  2. 游戲運行時,所有的操作在停止游戲后,都會恢復
  3. 要真的去做某項操作時,不要在游戲運行時操作
在這里插入圖片描述

??總結(jié)

  • 好了,關(guān)于腳本方面呢我們已經(jīng)全部介紹完了,最后還簡單提了一下Unity實現(xiàn)功能的三部曲大家都學會了吧,不用順著網(wǎng)線來咬我了~
  • 其實整個游戲程序?qū)崿F(xiàn)功能的思路就是這樣,先找到這個游戲?qū)ο?,然后利用腳本寫代碼讓他做相應(yīng)的事情。
  • 所有的游戲?qū)ο笥袟l不紊的執(zhí)行他們該干的事情,那么一個游戲程序也就自然而然的運行起來了
  • 如果你是從之前寫的幾篇博客完整看到這里,那么我之前寫的那篇坦克大戰(zhàn)的小游戲也就可以自己做了

Unity中從倔強青銅上榮耀王者,看完這篇是不是有手就行~

  • 其實做一個小游戲也沒有那么難嘛~嘿嘿
  • 不過關(guān)于Unity中UI方面還沒有介紹,大家可以在網(wǎng)上搜一下大佬的文章看看呀,后續(xù)有時間會更UI方面的知識點的~

心動不如行動,還不趕緊一鍵三連,然后收藏夾吃灰?

祝大家早日上榮耀王者!

下篇再見啦~さようなら

    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多