Unity3D部分
一、3D坐标系
1. 2D坐标、屏幕坐标、3D坐标(世界坐标)
2D游戏时我们只考虑了X、Y的坐标,但是实际上这里的X和Y就是世界坐标中对应的X、Y。
屏幕坐标以左下角为原点(0,0),右上角坐标为(width,height),width为屏幕宽度,height为屏幕高度。
(ctrl + shift + F 相机快速对焦)
二、3D物理系统
1. 刚体
与2D的刚体类似
Rigidbody 组件:
- Is Kinematic:是否自己模拟物理效果,若是使用代码接管,可以勾上。
- Collision Detection:碰撞检测频率
2. 碰撞体
与2D的碰撞体类似
3. 触发
与2D的触发类似
4. 物理材质
与2D的物理材质类似
- Dynamic Friction:动态摩擦力
- Static Friction:静态摩擦力
- Bounciness:弹性
- Friction Combine:当两个物体发生摩擦时,摩擦力如何计算
- Bounce Combine:当两个物体碰撞时,弹性如何计算
三、物理射线
用于判断射击是否命中、点击地面建造建筑物等功能。
- Ray:射线类
- Physics Raycast:计算射线碰撞
- RaycastHit:射线检测信息类
- Debug.DrayLine:绘制线条(玩家无法看到,仅编辑器测试用)
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16void Update() { // 一条向上的射线,从(0,0,0)到(0,1,0) Ray ray1 = new Ray(Vector3.zero, new Vector3(0, 1, 0)); // 从屏幕中心点向鼠标位置射出的射线 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // 从ray方向上1000米距离内的发出射线是否能碰到物体 if (Physics.Raycast(ray, out RaycastHit hitinfo, 1000)) { // hitinfo 射线碰撞的相关信息 Debug.Log("射线碰到了物体"); Debug.Log(string.Format("射线碰到了{0},在位置{1}", hitinfo.collider.gameObject.name, hitinfo.point)); Debug.DrawLine(ray.origin, hitinfo.point, Color.red); } }
四、刚体移动
Rigidbody.MovePosition(Vector3 target);
刚体移动语句,target 是一个具体要到达的位置。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14// 固定更新 void FixedUpdate() { Move(); } private void Move() { // 获取输入 float h = Input.GetAxis("Horizontal"); float v = Input.GetAxis("Vertical"); Vector3 offset = new Vector3(h, 0, v) * 0.02f * 1.5f; rigidbody.MovePosition(transform.position + offset); }
偏移量 offset 应该等于 要移动的方向向量 * 画面更新时间 * 实际速度。
刚体移动方法中的target 应该等于 偏移量offset + 当前位置transform.position.
五、案例:方块保卫战
1. 案例介绍
- 敌人向玩家走来
- 玩家点击屏幕可以发射子弹
- 子弹击中敌人两次则敌人死亡销毁
- 敌人如果到达指定位置,则玩家失败,进行重新游玩
2. 案例分析
- 搭建基本场景和敌人外观
- 实现敌人自动移动
- 实现玩家发射子弹逻辑
- UI 显示当前得分
- 游戏结果,需要 UI 弹窗提醒结果
- 击毙所有敌人胜利
- 敌人进入指定位置触发失败
3. 场景搭建
4. 核心逻辑
- 实现敌人自动移动
- 实现玩家攻击敌人
- 敌人死亡逻辑
- 游戏胜利逻辑
- 游戏失败逻辑
5. UI 逻辑
- UI 显示当前得分
- 游戏结果面板(胜利与失败)
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67// 玩家逻辑 public class Player : MonoBehaviour { // 单例模式 public static Player instance; // 攻击力 private int AttackValue = 100; // 存储敌人 public List<Enemy> enemies; private int score = 0; private bool isOver = false; private void Awake() { instance = this; } void Update() { Shoot(); } private void Shoot() { if (Input.GetMouseButtonDown(0)) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out RaycastHit hitinfo, 100)) { Debug.DrawLine(ray.origin, hitinfo.point, Color.red); // 如果我射击到的是敌人,则附加伤害 if (hitinfo.collider.gameObject.tag == "Enemy") { // 附加伤害 Enemy enemy = hitinfo.collider.gameObject.GetComponent<Enemy>(); enemy.Hurt(AttackValue); } } } } public void EnemyDead(Enemy enemy) { score += 1; UI_Manager.instance.UpdateScoreText(score); enemies.Remove(enemy); if (enemies.Count == 0) { // 游戏胜利 Win(); } } private void Win() { UI_Manager.instance.GameResult(true); } private void Over() { isOver = true; UI_Manager.instance.GameResult(false); Time.timeScale = 0; } private void OnTriggerEnter(Collider other) { if (other.gameObject.tag == "Enemy" && isOver == false) { Over(); } } }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36// 敌人逻辑 public class Enemy : MonoBehaviour { private Rigidbody rbody; private float speed = 2.2f; private int HP = 100; void Start() { rbody = GetComponent<Rigidbody>(); } private void FixedUpdate() { Move(); } private void Move() { Vector3 offset = transform.forward * Time.fixedDeltaTime * speed; rbody.MovePosition(transform.position + offset); } public void Hurt(int damage) { HP -= damage; if(HP <= 0) { Dead(); } } private void Dead() { // 检查一下,还有没有其他敌人,如果没有则玩家胜利 Player.instance.EnemyDead(this); // 死亡 Destroy(gameObject); } }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29// UI管理器 public class UI_Manager : MonoBehaviour { public static UI_Manager instance; public Text ScoreText; public GameObject resultPanel; public Text resultText; private void Awake() { instance = this; } public void UpdateScoreText(int num) { ScoreText.text = num.ToString(); } public void GameResult(bool isWin) { resultPanel.SetActive(true); if(isWin) { resultText.text = "胜利"; } else { resultText.text = "失败"; } } }
最后
以上就是淡淡麦片最近收集整理的关于Unity基础笔记(4)—— Unity3D部分的全部内容,更多相关Unity基础笔记(4)——内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复