日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

从零开始Unity引擎学习

發(fā)布時(shí)間:2023/12/10 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 从零开始Unity引擎学习 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

從零開(kāi)始Unity引擎學(xué)習(xí)

  • 簡(jiǎn)單說(shuō)明
    • 教程
    • 【Unity界面基礎(chǔ)認(rèn)識(shí)①】2021/12/13
    • 【Unity基礎(chǔ)界面認(rèn)識(shí)②】2021/12/14
    • 【Unity 腳本認(rèn)識(shí)①】2021/12/15
    • 【Unity 腳本認(rèn)識(shí)②】2021/12/16
    • 【Unity 腳本認(rèn)識(shí)③】2021/12/17
    • 【Unity 腳本認(rèn)識(shí)④】2021/12/19
    • 【Unity 腳本認(rèn)識(shí)⑤】2021/12/20
    • 【Unity 腳本認(rèn)識(shí)⑥】2021/12/21
    • 【Unity 腳本認(rèn)識(shí)⑦】2021/12/22~23
    • 【Unity 腳本認(rèn)識(shí)⑧】2021/12/26
    • 【做一個(gè)簡(jiǎn)單的飛機(jī)打怪獸小游戲①】簡(jiǎn)陋實(shí)現(xiàn)
    • 【做一個(gè)簡(jiǎn)單的飛機(jī)打怪獸小游戲②】進(jìn)行優(yōu)化
    • 【Unity腳本認(rèn)識(shí)⑨】2022/01/01

簡(jiǎn)單說(shuō)明

你好! 這是我從零開(kāi)始學(xué)習(xí)unity的博客。
每有空就會(huì)添加一個(gè)小標(biāo)題用于總結(jié)當(dāng)天所學(xué)的知識(shí)。

在小標(biāo)題下會(huì)用加粗字體一句話總結(jié)當(dāng)日學(xué)習(xí)的知識(shí)點(diǎn)。
剛開(kāi)始接觸unity什么都不懂,有錯(cuò)誤還請(qǐng)多多包涵( ゚Д゚)ノ

教程

unity核心類(lèi)圖
官方用戶(hù)手冊(cè)

【翻譯注釋文檔】
游戲蠻牛Unity 用戶(hù)文檔1.0

代碼調(diào)試和配置環(huán)境
調(diào)試C#代碼

【Unity界面基礎(chǔ)認(rèn)識(shí)①】2021/12/13

本日安裝了Unity 和 Unity Hub 。
學(xué)習(xí)到了:初步認(rèn)識(shí)了unity界面、學(xué)習(xí)了什么叫場(chǎng)景,如何新建場(chǎng)景、場(chǎng)景編輯器、如何添加資源、什么叫游戲?qū)ο?#xff0c;坐標(biāo)系。

1.unity界面初識(shí)
新建項(xiàng)目后安裝unity界面如圖所示。

Project項(xiàng)目面板:項(xiàng)目?jī)?nèi)的資源文件。圖中下方的面板。可在里面直接建立場(chǎng)景、文件夾、對(duì)象、腳本等等物品
Scene場(chǎng)景視圖:以可視化的形式展現(xiàn)游戲內(nèi)容。
面板內(nèi)部左上角一排工具分別為:抓取工具(可拖動(dòng)視圖)、旋轉(zhuǎn)平移工具、自由變換工具和拉伸工具。其中旋轉(zhuǎn)可進(jìn)行xyz軸的旋轉(zhuǎn)。
右上角工具為相機(jī)和將視圖畫(huà)面2D3D切換的可視化工具。
Game游戲視圖:對(duì)游戲進(jìn)行播放預(yù)覽。
Hierachy層級(jí)面板:以樹(shù)狀形式顯示游戲中的對(duì)象(左側(cè)面板)
inspector 組件面板:顯示一個(gè)游戲?qū)ο蟮娜拷M件
Console控制臺(tái):打印調(diào)試的

2.什么叫場(chǎng)景,如何新建
場(chǎng)景就是一個(gè)游戲里的關(guān)卡,或者某個(gè)畫(huà)面。
我個(gè)人理解,以找茬游戲?yàn)槔?#xff0c;應(yīng)該是一個(gè)解密里的一個(gè)關(guān)卡,在該關(guān)卡中進(jìn)行解密,到下一關(guān)就切換為下一個(gè)場(chǎng)景。

新建場(chǎng)景:在project面板中右鍵create新建場(chǎng)景就可以了。

3.場(chǎng)景編輯器
就是中間這個(gè)編輯窗口,可以用滾輪放大縮小,也可以平移。
其內(nèi)部可見(jiàn):
1.網(wǎng)格: 一個(gè)占屏幕上100像素、1個(gè)Unit(可自定義)
2.主攝像機(jī):攝像機(jī)的可視范圍
3.世界坐標(biāo)系:x,y軸

4.如何添加資源
方法:
①直接將素材拖拽進(jìn)project面板的Assets
②右鍵Assents區(qū)域選擇import導(dǎo)入

注:可直接右鍵素材Show In Explorer找到該素材所在的目錄,當(dāng)導(dǎo)入素材后會(huì)多出一個(gè)對(duì)應(yīng)的.meta文件。且刪除原有的素材項(xiàng)目?jī)?nèi)素材不會(huì)消失,因?yàn)閡nity導(dǎo)入規(guī)則是復(fù)制一份新的文件。
管理資源時(shí)可以添加子目錄來(lái)分類(lèi)管理。可以重命名素材,也可以刪除素材。

5.游戲?qū)ο?#xff0c;坐標(biāo)系的概念

游戲?qū)ο?/strong>就是場(chǎng)景中包含的內(nèi)容。
比如將某個(gè)圖片拖進(jìn)Scene窗口或是Hierarchy窗口中,就新增了一個(gè)游戲?qū)ο蟆?br /> 點(diǎn)擊該對(duì)象,右側(cè)會(huì)顯示該對(duì)象的屬性信息(名字,變換信息、組件,腳本情況等等)

注:在場(chǎng)景中只是保存了游戲?qū)ο笠昧苏l(shuí),比如說(shuō)引用了某個(gè)圖片,該圖片的id是什么。

坐標(biāo)系可以在對(duì)象的Inspector屬性面板查看對(duì)象的坐標(biāo)xyz軸
坐標(biāo)的單位:一個(gè)方格是一個(gè)Unit(單位),一個(gè)單位在現(xiàn)實(shí)世界中都可以自行約定。
x軸:水平向右
y軸:垂直向上
z軸:垂直屏幕向內(nèi)
(可以用ae的攝像機(jī)來(lái)理解)

【Unity基礎(chǔ)界面認(rèn)識(shí)②】2021/12/14

今日學(xué)習(xí):認(rèn)識(shí)了游戲?qū)ο蟮母拍罴捌洳僮骱惋@示順序、攝像機(jī)、組件。

1.游戲?qū)ο?/strong>

基本操作
移動(dòng)(更改position值或者使用工具)
旋轉(zhuǎn)(x,y,z軸都可以作為旋轉(zhuǎn)軸)
縮放(x,y軸的縮放,中間的方塊可以不失去比例的縮放)
矩形工具:自由變換(按shit鍵可以等比例縮放)
隱藏和顯示:屬性中選擇active復(fù)選框

點(diǎn)擊 Sprite Editor打開(kāi)圖形編輯器,右下角顯示圖片的各個(gè)屬性

名稱(chēng)作用
name名字
Positioncentered 位置
Border
Pivot軸心(可選擇軸心位于哪里)
Pivot Unit Mode
Custom Pivot

圖片切割
打開(kāi)圖片編輯器后,打開(kāi)左上 第二個(gè)菜單:Slice,點(diǎn)擊Slice,會(huì)自動(dòng)剪裁圖片,分成相應(yīng)的多個(gè)圖片游戲?qū)ο?/p>

圖片與渲染器
Sprite:精靈
Sprint Renderer:圖片渲染器,用于顯示一個(gè)Sprite(一種組件)
將素材拖拽到Sprite的位置,替換當(dāng)前顯示的素材圖片。

顯示順序
-修改Order in Layer屬性
-修改Z坐標(biāo)

父子關(guān)系
與AE的父子關(guān)系同理,子對(duì)象隨父對(duì)象變換
:在樹(shù)狀管理器里拖拽就可以設(shè)置了

2.攝像機(jī)
點(diǎn)擊攝像機(jī)可查看其添加的組件
下面展示了部分了解到的組件

名稱(chēng)功能
Transform一種組件,表示:Position:位置 Rotation:旋轉(zhuǎn) Scale:縮放(每個(gè)游戲?qū)ο蠖加械慕M件)
Background背景,顯示區(qū)域外的填充是什么顏色
Size攝像機(jī)的范圍大小,默認(rèn)為5個(gè)單位,描述了攝像機(jī)可以拍攝多大的區(qū)域

Game窗口中可以跳調(diào)整其長(zhǎng)寬比例

3.組件
組件:用于實(shí)現(xiàn)一種功能。
在右側(cè)面板種可以添加一些組件

【Unity 腳本認(rèn)識(shí)①】2021/12/15

今日學(xué)習(xí):認(rèn)識(shí)了什么叫腳本、如何掛載腳本、學(xué)習(xí)查看手冊(cè)、認(rèn)識(shí)了腳本中的Start()和Update()

什么是腳本
游戲?qū)ο蟮男袨橛筛郊拥腳_組件__控制。腳本可以理解就是在寫(xiě)一個(gè)自用組件(?

怎么掛載腳本
Assets窗口創(chuàng)建一個(gè)C#腳本
雙擊腳本啟動(dòng)VS

在VS頁(yè)面內(nèi)可以編輯該腳本,編輯腳本后退出到unity界面,可以直接將腳本拖拽至對(duì)象上掛載,然后點(diǎn)擊Game窗口中運(yùn)行。

①新建一個(gè)腳本和使用它
新建一個(gè)腳本后點(diǎn)開(kāi)腳本觀察其代碼。

using UnityEngine; using System.Collections;public class MainPlayer : MonoBehaviour {// 使用此函數(shù)進(jìn)行初始化void Start () {}// 每幀調(diào)用一次 Updatevoid Update () {} }

為了連接到 Unity 的內(nèi)部架構(gòu),腳本將實(shí)現(xiàn)一個(gè)類(lèi),此類(lèi)從稱(chēng)為 MonoBehaviour 的內(nèi)置類(lèi)派生而來(lái)。也就是說(shuō)MonoBehaviour是每一個(gè)腳本的基類(lèi)。

MonoBehaviour 是一個(gè)基類(lèi),所有 Unity 腳本都派生自該類(lèi)。
使用 C# 時(shí),必須顯式派生自 MonoBehaviour。(不太理解,找個(gè)例子來(lái)理解它)

——什么叫做顯式派生?
就是在派生類(lèi)的構(gòu)造函數(shù)中指定要調(diào)用的基類(lèi)的構(gòu)造函數(shù),
并將派生類(lèi)構(gòu)造函數(shù)的部分參數(shù)值傳遞給基類(lèi)構(gòu)造函數(shù)。
——什么叫做隱式派生?
隱式方式就是在派生類(lèi)的構(gòu)造函數(shù)中不指定對(duì)應(yīng)的基類(lèi)的構(gòu)造函數(shù),
這個(gè)時(shí)候調(diào)用的是基類(lèi)的默認(rèn)構(gòu)造函數(shù)。

monoBehaviour介紹及其函數(shù)

Component 菜單上的 Scripts 子菜單,其中包含項(xiàng)目中可用的所有腳本,包括自定義的腳本。

每當(dāng)創(chuàng)建一個(gè)腳本時(shí),自動(dòng)創(chuàng)建一個(gè)類(lèi).cs文件,文件名與類(lèi)名相同。
會(huì)由引擎自動(dòng)調(diào)用:

Start() :啟動(dòng)時(shí)調(diào)用
Update():每幀調(diào)用 (幀率不固定)

內(nèi)部執(zhí)行的順序:
1.創(chuàng)建對(duì)象
2.創(chuàng)建其調(diào)用的組件
3.Start()
4.定時(shí)執(zhí)行Update()

【Unity 腳本認(rèn)識(shí)②】2021/12/16

今日學(xué)習(xí):重新配置了環(huán)境、學(xué)習(xí)幀率的概念、如何獲取當(dāng)前對(duì)象和其他對(duì)象的組件

今早打開(kāi)腳本不知道為什么vs的自動(dòng)補(bǔ)全代碼又沒(méi)了,就把環(huán)境重新配置了一下。
查看vs2019的unity相關(guān)組件是否裝上。(查看發(fā)現(xiàn)明明已經(jīng)安裝好了T T)
然后打開(kāi)unity,點(diǎn)擊edit中的preference,找到自己安裝的編譯器,進(jìn)行一個(gè)選擇。

然后記得一定要重啟,再次打開(kāi)后雙擊腳本就能查看代碼的補(bǔ)全了。

②什么叫幀率,如何讓一個(gè)物體勻速移動(dòng)?
幀率就是指每秒鐘更新多少次。
FPS = 50 約每20ms 更新一次
FPS = 60 約每16.7ms更新一次

Debug.log("In Update() .." + Time.delaTime);

觀察間隔多久刷新一次

提問(wèn),什么叫做delaTime?
中文名稱(chēng)增量時(shí)間,含義是每經(jīng)過(guò)一幀所耗費(fèi)的時(shí)間。
Update()每幀執(zhí)行一次,那么經(jīng)歷過(guò)一幀耗費(fèi)的時(shí)間就是 增量時(shí)間(deltaTime)
1秒內(nèi)Update執(zhí)行的次數(shù),就是1秒內(nèi)執(zhí)行的總幀數(shù)

舉個(gè)例子

void Update(){transform.Translate(0, 0, Time.deltaTime * 10); //物體沿著自身Z軸方向,每秒移動(dòng)物體10米運(yùn)動(dòng)}

用增量時(shí)間*10,可以讓物體每一秒鐘移動(dòng)10米。而Update()每一秒刷新的次數(shù)都不同。

(Update執(zhí)行一次就是一幀,每秒的幀不同但每一幀移動(dòng)的距離都是速度 * 時(shí)間,最后相當(dāng)于再乘每秒鐘有幾幀,相當(dāng)于下面這個(gè)公式)

10米=(增量時(shí)間 * 1秒總幀數(shù)) *10米/秒

③如何獲取節(jié)點(diǎn)和組件?

-當(dāng)前游戲?qū)ο?/p> this.gameObject //當(dāng)前你這個(gè)游戲?qū)ο?/span>

取得當(dāng)前對(duì)象的全部組件

void Start(){//在當(dāng)前對(duì)象下尋找類(lèi)型為SpriteRenderer類(lèi)型的全部組件SpriteRenderer render = this.gameObject.GetComponent<SpriteRenderer>();//簡(jiǎn)寫(xiě):SpriteRenderer 自變量名稱(chēng) = this.GetComponent<獲取的類(lèi)型>();render.flipY = true; //對(duì)當(dāng)前對(duì)象進(jìn)行一個(gè)翻轉(zhuǎn)(X對(duì)稱(chēng)軸)}

運(yùn)行腳本后圖片翻轉(zhuǎn)了……

-獲取其他對(duì)象

GameObject obj = GameObject.Find("相應(yīng)對(duì)象的路徑");

【Unity 腳本認(rèn)識(shí)③】2021/12/17

今日學(xué)習(xí):父子節(jié)點(diǎn)關(guān)于transform的一些簡(jiǎn)單操作、組件的屬性如何增加修改,游戲?qū)ο笕绾胃淖冏鴺?biāo),旋轉(zhuǎn)。

今天又有問(wèn)題了。

找到這個(gè)用戶(hù)目錄下,刪除原有的許可證。

再重啟電腦,重新打開(kāi)unity hub申請(qǐng)?jiān)S可證就好了。

④父節(jié)點(diǎn)和子節(jié)點(diǎn)
左側(cè)樹(shù)狀文件結(jié)構(gòu)由Transform來(lái)管理。
常見(jiàn)操作:
1.取得父節(jié)點(diǎn),獲得父節(jié)點(diǎn)的名稱(chēng)

//取出當(dāng)前對(duì)象的父節(jié)點(diǎn)GameObject parentobj = this.transform.parent.gameObject;Debug.Log("rabbit的父節(jié)點(diǎn)" + parentobj.name);

2.遍歷全部子節(jié)點(diǎn)
遍歷當(dāng)前對(duì)象的全部子節(jié)點(diǎn)并打印出其名稱(chēng)。

//遍歷子節(jié)點(diǎn)foreach (Transform child in transform){Debug.log("子節(jié)點(diǎn)" + child.name);}

3.把一個(gè)節(jié)點(diǎn)移動(dòng)到另外一個(gè)位置。

將rabbit對(duì)象掛載到主攝像機(jī)對(duì)象下面。

//分別定義兩個(gè)對(duì)象GameObject obj = GameObject.Find("rabbit");GameObject target = GameObject.Find("Main Camera");//通過(guò)transform,先找到子節(jié)點(diǎn)的transform,將其掛到父節(jié)點(diǎn)的transform下面obj.transform.SetParent(target.transform);

未運(yùn)行前層級(jí)關(guān)系。

運(yùn)行后層級(jí)關(guān)系。

當(dāng)想將對(duì)象掛載到場(chǎng)景下面的時(shí)候,直接設(shè)置為null

obj.transform.SetParent(null);

游戲運(yùn)行時(shí),層級(jí)面板和組件面板都會(huì)顯示實(shí)時(shí)數(shù)據(jù)。

⑤組件的屬性定義
在組件面板中可以看到組件下面的一些屬性。

新建一個(gè)腳本,在腳本內(nèi)定義一個(gè)public的組件屬性,我們可以看到屬性面板中顯示了我們自己定義的屬性。

該值也可以修改

⑥游戲?qū)ο筮\(yùn)動(dòng)計(jì)算

Vector3,用于表示一個(gè)3維向量(x,y,z),也稱(chēng)為3元數(shù)。

定義一個(gè)三維的坐標(biāo),坐標(biāo)表示為浮點(diǎn)數(shù),所以在其后必須要加f

Vector3 pos = new Vector3(0, 0.1f, 0);

節(jié)點(diǎn)坐標(biāo)、旋轉(zhuǎn)都可以用Vector3表示

transform.position = new Vector3(0, 0.1f, 0); //設(shè)置位置 //eulerAngles 歐拉角 用來(lái)旋轉(zhuǎn)的 旋轉(zhuǎn)了45度 transform.eulerAngles = new Vector3(0, 0, 45f);

世界坐標(biāo) World Space Position 絕對(duì)坐標(biāo),以世界坐標(biāo)系計(jì)算
本地坐標(biāo) Local Space Position 以父節(jié)點(diǎn)的坐標(biāo)系計(jì)算

控制游戲?qū)ο笤谝欢ǚ秶鷥?nèi)移動(dòng),當(dāng)碰到上下邊界的時(shí)候就調(diào)轉(zhuǎn)自己的方向。

private bool upward = true;//飛行的方向,向上// Update is called once per framevoid Update(){if(upward && transform.position.y > 5){upward = false;transform.localEulerAngles = new Vector3(0, 0, 180);}if (!upward && transform.position.y < -5){upward = true;transform.localEulerAngles = new Vector3(0, 0, 0);}float step = 1.6f * Time.deltaTime;transform.Translate(0, step, 0, Space.Self);}

【Unity 腳本認(rèn)識(shí)④】2021/12/19

今日學(xué)習(xí):向量的概念,向量標(biāo)準(zhǔn)化,向量算數(shù),屏幕坐標(biāo)的概念

⑦向量的概念,向量標(biāo)準(zhǔn)化,向量算數(shù)

求向量長(zhǎng)度的API
float len = v.magnitude

標(biāo)準(zhǔn)化:將向量的長(zhǎng)度縮放為單位向量(長(zhǎng)度為1的向量)

Vector3 b = a.normalized;

幾個(gè)常用標(biāo)準(zhǔn)向量:

Vector3.right,即Vector3(0, 1, 0) x軸
Vector3.up,即Vector3(1, 0, 0) y軸
Vector3.foward ,即Vector3(0, 0, 1) z軸

兩物體間距離:求兩物體位置表示出的向量,然后計(jì)算向量長(zhǎng)度,就可以得出物體間距離。

Vector3 direction = p2 - p1; direction.magnitude//物體間的距離Vector3.SignedAngle(b,a,Vector3.forward);//計(jì)算a到b的角度,旋轉(zhuǎn)軸為z

使一個(gè)對(duì)象跟隨另外一個(gè)對(duì)象的移動(dòng)而轉(zhuǎn)移自己的朝向。

void Start(){Vector3 face = this.transform.up; // 獲取朝向GameObject target = GameObject.Find("音符");Vector3 direction = target.transform.position - this.transform.position;//計(jì)算兩對(duì)象間的向量float angle = Vector3.SignedAngle(face, direction, Vector3.forward);//計(jì)算向量與當(dāng)前對(duì)象的角度this.transform.Rotate(0, 0, angle); //旋轉(zhuǎn)這個(gè)角度}

⑧屏幕坐標(biāo)
就是游戲?qū)ο箫@示在當(dāng)前屏幕上的位置。

Screen.width(像素)
Screen.height(像素)

獲得一個(gè)物體的屏幕坐標(biāo)(將世界坐標(biāo)變成屏幕坐標(biāo))

Vector3 worldpos = transform.position;
Vector3 screenPos = Camera.main.WorldToScreenPoint(worldPos);
屏幕的邊界(可以用屏幕坐標(biāo)來(lái)控制游戲?qū)ο蟛怀銎聊坏倪吔?#xff09;

【Unity 腳本認(rèn)識(shí)⑤】2021/12/20

今日學(xué)習(xí):獲取鼠標(biāo)事件,游戲?qū)ο蟾S鼠標(biāo),鼠標(biāo)拖拽功能的實(shí)現(xiàn)*

⑨獲取鼠標(biāo)事件,游戲?qū)ο蟾S鼠標(biāo)

Input.GetMouseButtonDown(0)//獲取鼠標(biāo)左鍵是否按下 Input.mousePosition;//獲取鼠標(biāo)當(dāng)前的位置

0表示左鍵,1表示滾輪,2表示右鍵


探測(cè)鼠標(biāo)位置在哪里,先取其屏幕位置,再轉(zhuǎn)換為世界位置。

// 探測(cè) ‘鼠標(biāo)左鍵按下’ 事件是否發(fā)生if (Input.GetMouseButtonDown(0)){Debug.Log("鼠標(biāo)按下,pos=" + Input.mousePosition);Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);Debug.Log("世界坐標(biāo): " + pos);pos.z = 0; // 把Z坐標(biāo)置0,放到2D平面上來(lái)}

跟隨鼠標(biāo)移動(dòng),并改變自己的方向

void Start(){Application.targetFrameRate = 60;}// Update is called once per framevoid Update(){if (Input.GetMouseButton(0)) //檢測(cè)鼠標(biāo)位置{//獲取當(dāng)前鼠標(biāo)的屏幕坐標(biāo)轉(zhuǎn)換為世界坐標(biāo)Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);pos.z = 0;//改變方向SetDirection(pos);}//控制移動(dòng)float step = 5f * Time.deltaTime;transform.Translate(0, step, 0, Space.Self);}//變換其方向void SetDirection(Vector3 targetPos){Vector3 face = transform.up; //記錄當(dāng)前游戲?qū)ο笪恢?/span>Vector3 direction = targetPos - transform.position;//算出兩向量位置間的向量float angle = Vector3.SignedAngle(face, direction, Vector3.forward);//計(jì)算其夾角transform.Rotate(0, 0, angle);//改變當(dāng)前游戲?qū)ο蟮姆较?/span>}

效果如圖所示

⑩鼠標(biāo)拖拽功能的實(shí)現(xiàn)
鼠標(biāo)點(diǎn)擊拖動(dòng)游戲?qū)ο蟆?/p> private bool drag = false; //是否被拖拽private Vector3 lastMousePos;//鼠標(biāo)的相對(duì)位移// Start is called before the first frame updatevoid Start(){Application.targetFrameRate = 60;}// Update is called once per framevoid Update(){//當(dāng)鼠標(biāo)按下的時(shí)候if (Input.GetMouseButtonDown(0)){Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);pos.z = 0; // 把Z坐標(biāo)置0,放到2D平面上來(lái)//判定鼠標(biāo)離游戲的點(diǎn)有多遠(yuǎn)float distance = (pos - transform.position).magnitude;//求出兩者之間的距離if (distance < 1.5f)//如果該距離小于1.5的時(shí)候{drag = true;lastMousePos = pos;//使游戲?qū)ο蟾S鼠標(biāo)移動(dòng)(拖拽)}}//沒(méi)有按下的時(shí)候就不移動(dòng)if (Input.GetMouseButtonUp(0)){drag = false;}// 當(dāng)拖拽的時(shí)候if (drag){//先查找鼠標(biāo)在世界坐標(biāo)中的位置Vector3 pos = Camera.main.ScreenToWorldPoint(Input.mousePosition);pos.z = 0; //計(jì)算現(xiàn)在鼠標(biāo)位置相對(duì)于之前鼠標(biāo)位置的距離Vector3 delta = pos - lastMousePos;//根據(jù)相對(duì)移動(dòng)距離進(jìn)行一個(gè)加法的計(jì)算(移動(dòng))transform.position += delta; lastMousePos = pos;//更新鼠標(biāo)的新位置}}

實(shí)現(xiàn)效果

【Unity 腳本認(rèn)識(shí)⑥】2021/12/21

今日學(xué)習(xí):什么是事件函數(shù),腳本參數(shù),認(rèn)識(shí)預(yù)制體

?事件函數(shù)(Event Fuction),腳本執(zhí)行順序

由系統(tǒng)主動(dòng)調(diào)用的
Awake(),Start(),Update(),FixedUpdate()

相應(yīng)事件的回調(diào)函數(shù)On開(kāi)頭的
OnEnable(), OnDisable(), OnGUI()…

Awake()→OnEnable→Start()→…
可以把初始化放在Awake或者Startl里面。

多個(gè)附加腳本的游戲?qū)ο笸瑫r(shí)執(zhí)行(是無(wú)序的,優(yōu)先級(jí)均為0)
可以用 Execution Order來(lái)判定腳本的執(zhí)行順序 : 優(yōu)先級(jí)
順序值越小,優(yōu)先級(jí)越高。
一個(gè)腳本優(yōu)先于其他腳本,執(zhí)行順序?yàn)?1;
一個(gè)腳本晚于其他腳本,執(zhí)行順序1;

腳本的參數(shù):就是在腳本里的函數(shù)定義的變量,定義后可在組件面板看到定義的參數(shù)。

值類(lèi)型(C#中的struct,也就是Vector3),不可以初始化為null。

小練習(xí):點(diǎn)擊切換圖片

public Sprite sprite0;public Sprite sprite1;private int index = 0;void Start(){}void Update(){if (Input.GetMouseButtonDown(0)){DoChange();}}void DoChange(){//使用這個(gè)Render組件SpriteRenderer renderer = GetComponent<SpriteRenderer>();if(index == 0){index = 1;renderer.sprite = this.sprite1;}else{index = 0;renderer.sprite = this.sprite0;}}

?預(yù)制體

預(yù)制體:Prefab, 預(yù)先制作好的物體(模板),一般用于游戲?qū)ο蟮膭?dòng)態(tài)創(chuàng)建。
預(yù)制體實(shí)例:Prefab instance

建立預(yù)制體后,可通過(guò)拖拽新增預(yù)制體的實(shí)例。
雙擊點(diǎn)擊要修改的預(yù)制體進(jìn)入預(yù)制體編輯界面,可給預(yù)制體掛載腳本,同時(shí)預(yù)制體的實(shí)例也會(huì)受到該腳本控制。
點(diǎn)擊某一預(yù)制體后,右上角面板如圖所示。

Open為編輯預(yù)制體
Select找到當(dāng)前預(yù)制體實(shí)例的預(yù)制體
Override 是否將預(yù)制體實(shí)例的修改反過(guò)來(lái)修改到預(yù)制體上。

如何使預(yù)制體實(shí)例與其預(yù)制體斷開(kāi)關(guān)聯(lián)?
右鍵該對(duì)象,選擇Unpack Prefab

?動(dòng)態(tài)創(chuàng)建與銷(xiāo)毀預(yù)制體
當(dāng)鼠標(biāo)點(diǎn)擊時(shí),miku創(chuàng)建一個(gè)預(yù)制體音符,音符飄出去,并在超出屏幕范圍時(shí)銷(xiāo)毀自身。

mikumove.cs

public GameObject myPrefab;void Update(){if (Input.GetMouseButtonDown(0)){Sing();}}private void Sing(){GameObject music = Instantiate(myPrefab);music.transform.position = transform.position + new Vector3(0, 1f, 0);}

在界面中將音符對(duì)象掛載到miku的預(yù)制體對(duì)象實(shí)例上。

// Update is called once per framevoid Update(){float step = 1.5f * Time.deltaTime;transform.Translate(0, step, 0, Space.Self);Vector3 sp = Camera.main.WorldToScreenPoint(transform.position);if(sp.y > Screen.height){Destroy(this.gameObject);}}

【Unity 腳本認(rèn)識(shí)⑦】2021/12/22~23

今日學(xué)習(xí):定時(shí)器、認(rèn)識(shí)Unity中重要的類(lèi)

//創(chuàng)建一個(gè)預(yù)制體資源音符public GameObject myPrefab;private float interval = 0.4f; //每隔0.4秒發(fā)射一顆private float count = 0;void Update(){//計(jì)時(shí)count += Time.deltaTime;if(count >= interval)//如果當(dāng)前累計(jì)的事件到了0.4秒{count = 0;//清零Sing();//進(jìn)行一個(gè)歌的唱}}private void Sing(){Vector3 pos = transform.position + new Vector3(0, 1f, 0);GameObject bullet = Instantiate(myPrefab, pos, transform.rotation);}

效果如圖

最近幾天學(xué)學(xué)校的項(xiàng)目比較忙,所以看了一點(diǎn)別的,這里列一下unity中比較重要的類(lèi),復(fù)習(xí)一下之前學(xué)的一些方法和語(yǔ)句。

類(lèi)名描述
GameObject表示可以存在于場(chǎng)景中的對(duì)象的類(lèi)型。
MonoBehaviour基類(lèi),默認(rèn)情況下,所有 Unity 腳本都派生自該類(lèi)。
ObjectUnity 可以在編輯器中引用的所有對(duì)象的基類(lèi)。
Transform提供多種方式來(lái)通過(guò)腳本處理游戲?qū)ο蟮奈恢谩⑿D(zhuǎn)和縮放,以及與父和子游戲?qū)ο蟮膶蛹?jí)關(guān)系。
Vectors用于表達(dá)和操作 2D、3D 和 4D 點(diǎn)、線和方向的類(lèi)。
Quaternion表示絕對(duì)或相對(duì)旋轉(zhuǎn)的類(lèi),并提供創(chuàng)建和操作它們的方法。
ScriptableObject可用于保存大量數(shù)據(jù)的數(shù)據(jù)容器。
Time(以及幀率管理)Time 類(lèi)用于測(cè)量和控制時(shí)間,并管理項(xiàng)目的幀率。
Mathf一組常見(jiàn)的數(shù)學(xué)函數(shù),包括三角函數(shù)、對(duì)數(shù)函數(shù)以及游戲和應(yīng)用開(kāi)發(fā)中常用的其他函數(shù)。
Random提供簡(jiǎn)便的方法來(lái)生成各種常用類(lèi)型的隨機(jī)值。
Debug用于可視化編輯器中的信息,這些信息可以幫助您了解或調(diào)查項(xiàng)目運(yùn)行時(shí)發(fā)生的情況。

Quaternmion中常用尤拉角(以下概念理解來(lái)自別人的博客)

歐拉角代表一系列的三維基本旋轉(zhuǎn), 也就是圍繞一個(gè)坐標(biāo)系的各軸的一系列旋轉(zhuǎn)。例如,首先繞Z軸旋轉(zhuǎn)一個(gè)α角,然后繞x軸做一個(gè)β角的旋轉(zhuǎn),最后再繞Z軸來(lái)一個(gè)γ角的旋轉(zhuǎn)。這些旋轉(zhuǎn)都是從一個(gè)已知的標(biāo)準(zhǔn)方向上進(jìn)行的。在物理中,

這個(gè)初始化的標(biāo)準(zhǔn)方向通常是一個(gè)靜止的坐標(biāo)系,在線性幾何中,通常是一個(gè)標(biāo)準(zhǔn)基。

歐拉角的使用:(此處有待理解。。。比如萬(wàn)向鎖)

// 正確使用歐拉角的旋轉(zhuǎn)腳本。 // 將歐拉角存儲(chǔ)在一個(gè)類(lèi)變量中,并僅使用 // 該變量作為歐拉角進(jìn)行應(yīng)用,但從不依賴(lài)于讀回歐拉值。float x; void Update () {x += Time.deltaTime * 10;transform.rotation = Quaternion.Euler(x,0,0); }

錯(cuò)誤使用:

// 旋轉(zhuǎn)腳本錯(cuò)誤 #1 // 此處的錯(cuò)誤在于我們正在修改四元數(shù)的 x 值 // 此值不表示角度,不會(huì)產(chǎn)生所需的結(jié)果void Update () {var rot = transform.rotation;//這里rot定義為var對(duì)象,不可以用在旋轉(zhuǎn)角度上(?rot.x += Time.deltaTime * 10;transform.rotation = rot; } // 旋轉(zhuǎn)腳本錯(cuò)誤 #2 // 從四元數(shù)讀取、修改并寫(xiě)入歐拉值。 // 因?yàn)檫@些值是從四元數(shù)計(jì)算的, // 所以每個(gè)新的旋轉(zhuǎn)可能會(huì)返回非常不同的歐拉角,而這可能會(huì)受到萬(wàn)向鎖的影響。void Update () {var angles = transform.rotation.eulerAngles;angles.x += Time.deltaTime * 10;transform.rotation = Quaternion.Euler(angles); }

【Unity 腳本認(rèn)識(shí)⑧】2021/12/26

今日學(xué)習(xí):認(rèn)識(shí)鍵盤(pán)事件、認(rèn)識(shí)unity里的剛體、碰撞檢測(cè)的組件使用

鍵盤(pán)事件

Input.GetKeyDown(key) 按下事件
Input.GetKeyUp(key) 抬起事件
Input.GetKey(key) 狀態(tài)檢查是否被按下

物理系統(tǒng)
可以給游戲?qū)ο笤黾右粋€(gè)Physic 2D組件 RigidBody 2D,然后可以設(shè)置為物理學(xué)剛體還是運(yùn)動(dòng)學(xué)剛體

剛體:
Dynamic 普通剛體 有質(zhì)量、有速度
Static 靜態(tài)剛體,質(zhì)量無(wú)窮大、無(wú)速度
Kinematic 運(yùn)動(dòng)學(xué)剛體,無(wú)質(zhì)量

剛體的碰撞
1)Dynamic 物理學(xué)碰撞檢測(cè)
可以添加Box Collider 2D(碰撞組件),兩個(gè)剛體會(huì)計(jì)算其碰撞。
可以編輯剛體的范圍

2)Kinematic 運(yùn)動(dòng)學(xué)剛體
碰撞檢測(cè)過(guò)程:
a. 添加兩個(gè)物體,‘飛機(jī)’ 和 ‘小球’
b .添加剛體組件 Rigidbody 2D
設(shè)為 Kinematic

c.添加 碰撞組件 Box Collider2d
勾選 Is Trigger ( 碰撞觸發(fā)器 )

d.添加腳本組件 , 重寫(xiě)事件函數(shù)OnTriggerEnter2D()
void OnTriggerEnter2D(Collider2D collision)
{
Debug.Log("飛機(jī):探測(cè)到了碰撞 … ");
}

當(dāng)系統(tǒng)檢測(cè)到碰撞的時(shí)候,會(huì)觸發(fā)碰撞事件的回調(diào)

OnTriggerEnter2D: 兩個(gè)碰撞體開(kāi)始相遇
OnTriggerStay2D: 兩個(gè)碰撞體接觸中
OnTriggerExit2D: 兩個(gè)碰撞體分開(kāi)

碰撞事件的參數(shù):

collision.gameObject 對(duì)方碰撞體
collision.transform 對(duì)方的Transform組件
collision.name 對(duì)方的節(jié)點(diǎn)名稱(chēng)
collision.tag 對(duì)方節(jié)點(diǎn)的Tag(身份) 用于識(shí)別碰撞對(duì)象的身份(很重要)

Project setting中
a.可以設(shè)置當(dāng)前項(xiàng)目的tag和layer,隨后點(diǎn)開(kāi)某一游戲?qū)ο蟮慕M件面板時(shí),可以看到當(dāng)前游戲?qū)ο蟮腡ag。
b.Physics 2D中查看Layer Collision Matrix可以設(shè)置不同層才會(huì)碰撞,相同層的游戲?qū)ο蟛话l(fā)生碰撞(區(qū)別友軍和敵軍) 使用這個(gè)可以減低資源的消耗,因?yàn)橄嗤瑢拥膶?duì)象不會(huì)檢測(cè)碰撞,而上面那個(gè)區(qū)分對(duì)象的方法不管什么tag(身份)都會(huì)進(jìn)行碰撞的檢測(cè)。

【做一個(gè)簡(jiǎn)單的飛機(jī)打怪獸小游戲①】簡(jiǎn)陋實(shí)現(xiàn)

①將界面改為豎屏模式
Window→Layout→Tall(豎屏)
分辨率設(shè)置為9:16

②添加主控腳本
添加空節(jié)點(diǎn)“游戲主控”
新建主控腳本MyGame.cs

主控腳本內(nèi)設(shè)置一些全局變量,比如幀率就在主控腳本內(nèi)設(shè)置。

③制作子彈和飛機(jī)

將子彈素材制作為預(yù)制體,并掛載相應(yīng)的腳本,并添加碰撞有關(guān)組件,當(dāng)子彈碰上怪物時(shí),使怪物被消滅

public class bullet : MonoBehaviour {public float speed = 5.5f;void Start(){}void Update(){float dy = speed * Time.deltaTime;transform.Translate(0, dy, 0, Space.Self);Vector3 sp = Camera.main.WorldToScreenPoint(transform.position);if(sp.y > Screen.height){Destroy(this.gameObject);}}//當(dāng)private void OnTriggerEnter2D(Collider2D collision){if(collision.tag.Equals("Monster")){Destroy(collision.gameObject);Destroy(this.gameObject);}} }

飛機(jī)相關(guān)代碼下所示,通過(guò)wasd鍵可以操控飛機(jī)移動(dòng)(尚未優(yōu)化屏幕邊界問(wèn)題)
將子彈作為預(yù)制體,由飛機(jī)發(fā)射,標(biāo)簽為Bullet。

public class MyJet : MonoBehaviour {public GameObject bulletPrefab;public float moveSpeed = 2.5f;private float interval = 0.4f;private float count = 0;void Start(){Application.targetFrameRate = 60;}void Update(){count += Time.deltaTime;if (count >= interval){count = 0;Fire();}//控制飛機(jī)移動(dòng)Vector3 jp = Camera.main.WorldToScreenPoint(transform.position);if (Input.GetKey(KeyCode.A) && jp.x > 0) {transform.Translate(-0.05f,0, 0, Space.Self);}if (Input.GetKey(KeyCode.D) && jp.x < (Screen.width )){transform.Translate(0.05f, 0, 0, Space.Self);}if (Input.GetKey(KeyCode.S) && jp.y > 0){transform.Translate( 0, -0.05f, 0, Space.Self);}if (Input.GetKey(KeyCode.W) && jp.y < (Screen.height )){transform.Translate(0, 0.05f, 0, Space.Self);}}private void Fire(){Vector3 pos = transform.position + new Vector3(0, 1f, 0); //子彈出現(xiàn)的位置GameObject bullet = Instantiate(bulletPrefab, pos, transform.rotation);} }

⑤制作怪物,隨機(jī)生成怪物
怪物代碼如下,讓怪物像子彈一樣沿著屏幕y軸移動(dòng),制作為預(yù)制體,標(biāo)簽為Monster。

public class Monster : MonoBehaviour {public float speed = 1.0f;void Start(){}void Update(){float dy = speed * Time.deltaTime;transform.Translate(0, -dy, 0, Space.Self);} }


由主控腳本隨機(jī)生成怪物:Monster_control,建立了一個(gè)頭像數(shù)組,錄入后通過(guò)改變預(yù)制體的圖像來(lái)隨機(jī)生成不同的怪物。

public class Monster_control : MonoBehaviour {public GameObject monsterPrefab;public Sprite[] images; //頭像的數(shù)組void Start(){//反射機(jī)制:輸入名字找到方法//參數(shù)的名字(字符串) 多少時(shí)間后執(zhí)行第一次 每隔幾秒執(zhí)行一次InvokeRepeating("CreateMonster", 0.1f, 2f); }void Update(){}void CreateMonster(){//隨機(jī)float x = Random.Range(-2, 2);//限定生成怪物的范圍float y = 5;//初始化怪物GameObject monster = Instantiate(monsterPrefab);monster.transform.position = new Vector3(x, y, 0);int index = Random.Range(0, images.Length);//不會(huì)包含后一個(gè)數(shù),會(huì)顯示0到length-1//隨機(jī)選擇一個(gè)怪物SpriteRenderer renderer =monster.GetComponent<SpriteRenderer>();renderer.sprite = this.images[index];} }


⑥實(shí)現(xiàn)效果

最近學(xué)校事情比較多,封校做項(xiàng)目和課設(shè)T T,不是每天都有時(shí)間總結(jié)學(xué)東西,但該寫(xiě)還是會(huì)寫(xiě)一點(diǎn)。

【做一個(gè)簡(jiǎn)單的飛機(jī)打怪獸小游戲②】進(jìn)行優(yōu)化

①使每個(gè)怪物大小一致

//將頭像的大小設(shè)置為100px(寬度)Sprite sprite = this.images[index];float imgWidth = images[index].rect.width; //取得的圖像實(shí)際寬度float scale = 100 / imgWidth; //縮放比例monster.transform.localScale = new Vector3(scale, scale, scale);

②怪物離開(kāi)屏幕時(shí)銷(xiāo)毀

//判斷當(dāng)前怪物是否離開(kāi)頁(yè)面,離開(kāi)則銷(xiāo)毀Vector3 sp = Camera.main.WorldToScreenPoint(transform.position);if(sp.y < 0){Destroy(this.gameObject);}

③增加游戲背景并使其滾動(dòng)
新建兩個(gè)圖片,放置一個(gè)節(jié)點(diǎn)下。

編寫(xiě)圖片讓圖片向下移動(dòng),當(dāng)一定位置時(shí)返回初始位置,使得圖片無(wú)限循環(huán)的移動(dòng)。(背景滾動(dòng)效果)
bg_control.cs 掛載到游戲主控下

public class bg_control : MonoBehaviour {Transform bg1;Transform bg2;public float speed = 1.0f;// Start is called before the first frame updatevoid Start(){bg1 = GameObject.Find("/background/bg1").transform;bg2 = GameObject.Find("/background/bg2").transform;bg1.position = new Vector3(0, 0, 0);bg2.position = new Vector3(0, 10, 0);}// Update is called once per framevoid Update(){//設(shè)定速度和移動(dòng)float dy = speed * Time.deltaTime;bg1.Translate(0, -dy, 0);bg2.Translate(0, -dy, 0);//當(dāng)離開(kāi)屏幕后滾動(dòng)回到初始位置。if(bg1.position.y <= -10){bg1.Translate(0, 20, 0);}if (bg2.position.y <= -10){bg2.Translate(0, 20, 0);}} }

【Unity腳本認(rèn)識(shí)⑨】2022/01/01

1.添加音效
unity內(nèi)的音頻:支持2D/3D音效
3D:空間感,有近大遠(yuǎn)小的效果
支持格式:mp3/wav/ogg/aiff,可以在Inspector中試聽(tīng)
添加腳本時(shí)可把play onwake勾選掉

可以調(diào)用AudioSource的API進(jìn)行播放
clip / mute / loop / volume / isPlaying
play() 播放 :正在播放時(shí)播放,就會(huì)停止當(dāng)前播放,重新開(kāi)始播放
Stop() 停止
Pause () 暫停
isplaying 判斷是否在播放
PlayOneShot(clip) 新開(kāi)一個(gè)播放

2.Invoke

Invoke 延時(shí)調(diào)用,過(guò)一會(huì)兒再調(diào)用

eg.Invoke(“SomeJob” , 3)
表示在3秒之后調(diào)用SomeJob方法

在每一幀Update后,系統(tǒng)都會(huì)檢查待執(zhí)行的Invoke,
連續(xù)調(diào)用多次Invoke之后,會(huì)添加多個(gè)延時(shí)調(diào)用
使用IsInvoking(name) 可以判定當(dāng)前是否存在同名的延時(shí)調(diào)用

定時(shí)調(diào)用
InvokeRepeating(methodName, delay, interval):延時(shí)調(diào)用、并重復(fù)執(zhí)行,實(shí)現(xiàn)了一個(gè)定時(shí)器的邏輯

3.消息調(diào)用
判斷鼠標(biāo)是否點(diǎn)擊到相應(yīng)物體

//判斷鼠標(biāo)是否點(diǎn)中了當(dāng)前物體if (Input.GetButtonDown(0)){//獲取鼠標(biāo)在屏幕上的位置Vector3 mousePos = Camera.main.ScreenToViewportPoint(Input.mousePosition);mousePos.z = 0;//兩個(gè)向量相減并記錄下減后向量的大小float distance = (mousePos - transform.position).magnitude;//判斷向量大小是否在一個(gè)范圍內(nèi)if(distance < 2){//打中了}}

將該main節(jié)點(diǎn)下面的所有腳本遍歷一遍,尋找AddScore方法并調(diào)用它。
方法1:(簡(jiǎn)單,短)

GameObject main = GameObject.Find("游戲主控"); main.SendMessage("AddScore", 1);

方法2:

GameObject main = GameObject,Find("游戲主控") MyGame myGame = main GetComponent<MyGame>(); myGame.AddScore();

SendMessage():查找目標(biāo)方法并立即執(zhí)行
1.遍歷該對(duì)象上的所有MonoBehaviour組件
2.檢查該組件上有沒(méi)有xxx方法
3.若有此方法,則執(zhí)行該方法
沒(méi)有找到目標(biāo)方法的時(shí)候,提示:SendMessae xxx has no receiver!

SendMessage()是同步調(diào)用,而不是異步調(diào)用。在目標(biāo)對(duì)象上,查找目標(biāo)方法并立即執(zhí)行

4.交互界面UI

unity中的UI叫做UGUI
(1)添加Canvas(畫(huà)布)
添加的同時(shí)會(huì)添加一個(gè)EvenSystem (事件系統(tǒng))

總結(jié)

以上是生活随笔為你收集整理的从零开始Unity引擎学习的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。