C#初級編程
https://learn.u3d.cn/tutorial/beginner-gameplay-scripting
8 Update 和 FixedUpdate
Update(不是按固定時間調(diào)用的) 經(jīng)常用于
- 移動非物理特性的物體(不是物理對象)
- 簡單定時器
- 接收輸入
FixedUpdate(調(diào)用時間間隔相同)
- 進行任何必要的物理計算(任何物理對象)
- 最好使用力來定義移動
使用 IDE 的 Unity Event Functions 插入函數(shù)
9 點積、叉積
點積算出標量,如果點積為 0 則兩個向量互相垂直,飛機模擬例子:
- 點積 = 0,飛機前向 Z 軸 與 Y 軸垂直,此時阻力最小
- 點積 > 0,飛機在爬升,此時阻力變大
- 點積 < 0,飛機在俯沖
叉積算出新向量。使用左手坐標系根據(jù) A 、B 確定 C 的方向(中指)
- 為了確定圍繞哪個軸施加扭矩 來轉(zhuǎn)動坦克炮塔
- 如果知道炮塔目前朝向和目標朝向,則可以用叉積算出需要圍繞的軸的方向
10 啟用和禁用組件
private Light myLight;
private void Start()
{
myLight = GetComponent<Light>();
}
private void Update()
{
if (Input.GetKeyUp(KeyCode.Space))
myLight.enabled = !myLight.enabled;
}
11 激活游戲?qū)ο?/h2>
- 父節(jié)點無效后,子節(jié)點也會一同跟著無效,(不活躍節(jié)點在層次結(jié)構(gòu)中依舊可見)
- 利用父節(jié)點保持對對象群的控制
- 子節(jié)點由于父節(jié)點被禁用而禁用時,只針對子節(jié)點
setActive
不管用,想要重新激活子節(jié)點就必須重新激活父節(jié)點
- 要確認某個節(jié)點是否為活躍狀態(tài)
-
activeSelf 看節(jié)點本身
-
activeInHierarchy 看父子關(guān)系(父節(jié)點關(guān)則false;根節(jié)點自身為父節(jié)點)
Debug.Log(myObject.activeSelf);
Debug.Log(myObject.activeInHierarchy);
12 物體移動
- 默認移動,旋轉(zhuǎn)都是 Space.self
- 移動一個有碰撞體的對象(帶物理效果的物體),不能用 Translate 與 Rotate
public void Rotate(Vector3 axis, float angle) => this.Rotate(axis, angle, Space.Self);
13 LookAt
- 利用父節(jié)點保持對對象群的控制
- 子節(jié)點由于父節(jié)點被禁用而禁用時,只針對子節(jié)點
setActive
不管用,想要重新激活子節(jié)點就必須重新激活父節(jié)點
- activeSelf 看節(jié)點本身
- activeInHierarchy 看父子關(guān)系(父節(jié)點關(guān)則false;根節(jié)點自身為父節(jié)點)
Debug.Log(myObject.activeSelf);
Debug.Log(myObject.activeInHierarchy);
public void Rotate(Vector3 axis, float angle) => this.Rotate(axis, angle, Space.Self);
讓攝像機看向某一物體
public Transform target;
private void Update()
{
transform.LookAt(target);
}
14 Lerp
線性插值會在兩個給定值之間找到某個百分比的值。
float result = Mathf.Lerp (3f, 5f, 0.5f);
// Color.Lerp 和 Vector3.Lerp
Vector3 from = new Vector3 (1f, 2f, 3f);
Vector3 to = new Vector3 (5f, 6f, 7f);
// 此處 result = (4, 5, 6)
Vector3 result = Vector3.Lerp (from, to, 0.75f);
在對值進行平滑時,通常情況下最好使用 SmoothDamp 函數(shù)。想要實現(xiàn)特定效果時,才應使用 Lerp 進行平滑。
Unity - Scripting API: Mathf.SmoothDamp (unity3d.com)
Need help understanding the Mathf.SmoothDamp function - Unity Forum
ref velocity 存在的必要性
如果目標距離較遠,函數(shù)會嘗試加速你的位置,如果目標越來越近,則會減速。為了加速/減速,你需要知道你的速度有多快,這就是速度參數(shù)
16 GetButton、GetKey
- GetKey 需要使用 KeyCode 類型參數(shù)
- KeyCode 只與特定鍵相關(guān),建議使用 GetButton
- 參數(shù)是字符串,可以在 Project Settings | Input Manager 中設置,靈活性很大
- 兩種方式都有三種狀態(tài):Down、狀態(tài)、Up
private void Update()
{
if(Input.GetButtonDown("Jump"))
Debug.Log("按下了空格鍵");
if(Input.GetButtonDown("Fire1"))
Debug.Log("按下了鼠標左鍵");
}
17 GetAxis、GetAxisRaw
- GetButton、GetKey 只返回布爾值
- GetAxis 返回浮點值,介于-1到1之間
-
GetAxisRaw? 返回浮點值,僅返回 -1,0,1,不受平滑過濾參數(shù)影響
- 針對需要嚴格控制輸入的2D游戲非常有用
- Gravity 按鈕松開后歸零的速度(越高歸零越快)
- Sensitivity 按鈕按下后到達1或-1的速度有多快(越高越快)
- Dead 值針對手柄盲區(qū)(LS、RS輕微轉(zhuǎn)動不影響)(越大盲區(qū)越大)
private void Update()
{
float x = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
float x2 = Input.GetAxisRaw("Horizontal");
float v2 = Input.GetAxisRaw("Vertical");
Debug.Log($"{x} {v} {x2} {v2}");
}
void Movement ()
{
float forwardMovement = Input.GetAxis("Vertical") * speed * Time.deltaTime;
float turnMovement = Input.GetAxis("Horizontal") * turnSpeed * Time.deltaTime;
transform.Translate(Vector3.forward * forwardMovement);
transform.Rotate(Vector3.up * turnMovement);
}
18 OnMouseDown
用于檢測對 帶碰撞體組件的物體節(jié)點 或 GUI元素 鼠標點擊事件
以下代碼針對一個物理物體,每次鼠標點擊給予 forward 反方向的推力
private void OnMouseDown()
{
Debug.Log($"點擊 {gameObject.name}");
rb.AddForce(-transform.forward * 500f);
}
19 GetComponent
GetComponent 性能消耗大,應該盡量減少調(diào)用,最好是在 Awake,Start 調(diào)用
20 deltaTime
定時器功能與平滑移動(按速度移動)
public float speed = 8f;
public float countdown = 3.0f;
void Update ()
{
countdown -= Time.deltaTime;
if(countdown <= 0.0f)
light.enabled = true;
if(Input.GetKey(KeyCode.RightArrow))
transform.position += new Vector3(speed * Time.deltaTime, 0.0f, 0.0f);
}
21 值、引用
- 值類型對應的值被改變,只會影響特定變量
- 引用類型指向的值被改變,所有包含相同存儲地址的引用類型變量都會受到影響
void Start ()
{
//值類型變量
Vector3 pos = transform.position; // 值拷貝
pos = new Vector3(0, 2, 0);
//引用類型變量
Transform tran = transform;
tran.position = new Vector3(0, 2, 0);
}
22 類
- 拆分類的功能,不要全部寫在一起(單一職責原則)
- 如射擊類、移動類、庫存類
- 多用代碼段,比如 ctor 生成構(gòu)造函數(shù)
- 先全面仔細設計腳本結(jié)構(gòu),再開始編寫一個大類,將各種不同內(nèi)容囊括其中
23 Instantiate
Instantiate 用于動態(tài)生成預制體對象(創(chuàng)建預制件的克隆體)
?動態(tài)實例化生成的子彈預制體節(jié)點被強制轉(zhuǎn)型成了 RigidBody
public Rigidbody bulletPrefab; // 可以不是GameObject而是綁定的組件
public Transform firePosition;
public float bulletSpeed;
...
Rigidbody bulletInstance = Instantiate(bulletPrefab, firePosition.position, firePosition.rotation) as Rigidbody;
案例中用到了 as 關(guān)鍵字?!禖# 8.0本質(zhì)論》里沒有寫
- 按(Rigidbody)顯式轉(zhuǎn)換方式如果轉(zhuǎn)換不成功會拋出異常
- as 運算符類似于強制轉(zhuǎn)換操作;但是,如果轉(zhuǎn)換不可行,as 會返回 null 而不是引發(fā)異常
24 數(shù)組
使用 FindGameObjectsWithTag 初始化查找所有 Tag 為 Player 的節(jié)點存儲至數(shù)組中
C# 數(shù)組是從抽象的基類型Array派生的引用類型
public GameObject[] players;
void Start()
{
players = GameObject.FindGameObjectsWithTag("Player");
foreach (var player in players)
{
Debug.Log($"{player.name}");
}
}
25 Invoke
- Invoke 調(diào)用的函數(shù)必須 不包含參數(shù),且無返回值
其他內(nèi)容以前筆記有寫,略過
26 enum
用整數(shù)描述方向不易讀,可以建立 enum 類型(類內(nèi)類外都可創(chuàng)建)文章來源:http://www.zghlxwxcb.cn/news/detail-709762.html
enum Direction : short
{
North, // 0
East, // 1
South = 100, // 100
West // 101
};
void Start()
{
Direction myDirection;
myDirection = Direction.North;
var newDirection = ReverseDirection(myDirection);
}
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;
}
27 switch
跟 C++ 差不多文章來源地址http://www.zghlxwxcb.cn/news/detail-709762.html
public int intelligence = 5;
void Start()
{
switch (intelligence)
{
case 1:
break;
case 2:
break;
default:
break;
}
}
到了這里,關(guān)于Unity 游戲開發(fā)、03 基礎篇 | C#初級編程的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!