赞
踩
先笼统地将整个游戏分为两部分:UI 和游戏内容。
UI :即 User Interface,人机交互,操作界面,游戏中一般指血条、背包、注册登录等。
游戏内容:指场景、角色等实际游戏世界的展示。
一般我们所说的 2D/3D 是指游戏内容部分,绝大多数情况下 UI 本身都是 2D的。
(1)2D 素材和 2D 的渲染
(2)2D 物理系统
2D相机调整:
美术资源,在 Inspector 面板中的 Texture Type 属性选择**Sprite(2D and UI)**后,就可以正常使用。(scene面板可点击2D切换至2D开发视角)
Pixels Per Unit 属性:控制精灵sprite的比例,数值越大,精灵越小,精度越高。
Sprite Mode:精灵的模式
Single:精灵为单个类型,无需切割操作
Multiple:精灵是多个类型,可通过 Sprite Editor 对精灵进行切割 Slice操作。
Polygon
Sprite Editor:精灵编辑器,需安装2D Sprite包才能使用。
一般通过切割精灵自动生成 Sprite Sheets 精灵集。
SpriteRenderer 组件是一个用来显示 Sprite 的组件。
public class SpriteDemo : MonoBehaviour
{
private Spriterenderer spriteRenderer;
public Sprite sprite;
void Start()
{
spriteRenderer = GetComponent<SpriteRenderer>();
spriteRenderer.sprite = sprite;
spriteRenderer.color = new Color.black;
spriteRenderer.flipX = true;
}
}
Unity 的物理系统主要是对现实中的物理现象进行模拟,如重力等。
物理系统常用组件主要由 刚体 和 碰撞体 组成。
一个游戏如果希望具备重力,那么它一定需要有 RigidBody(刚体)组件。
Rigidbody 2D组件的属性:
BodyType:
Dynamic:动态,最仿真的。
Kinematic:运动,完全由代码控制。
Static:静态,不是为了移动而设计的,例如建筑物。
Simulated:是否模拟,不模拟的话,不会有重力、碰撞等。
Mass:质量。
Linear Drag:位置移动的阻力系数。
Angular Drag:旋转移动的阻力系数。
Gravity Scale:重力系数。
Collision Detection:碰撞检测,定义如何检测 2D 碰撞体之间的碰撞。
Constraints:定义对 2D 刚体运动的任何限制。
如果精灵Sprite需要运动就需要加刚体组件,但刚体组件只注重物体本身的物理特性,它不管物体周边的碰撞效果,要想让一个物体与其他物体接触需要使用碰撞体组件。
物理材质是一种资源,分为以下两个部分:
// 刚体组件示例代码 public class RigidbodyDemo : MonoBehaviour { private Rigidbody2D rigidbody2D; void Start() { rigidbody2D = GetComponent<Rigidbody2D>(); rigidbody2D.mass = 3; rigidbody2D.gravityScale = 0.5f; } void Update() { // 向指定坐标移动 rigidbody2D.MovePosition(new Vector2(0, 1) * 10); // 向指定方向一直移动 rigidbody2D.MovePosition(transform.position + new Vector3(0, 1, 0) * Time.deltaTime); // 改变速度向量,即施加一个任意方向任意大小的速度 rigidbody2D.velocity = new Vector2(0, 1); // 对刚体施加力 rigidbody2D.AddForce(Vector2.up); } }
碰撞体:指游戏中一个游戏物体的物理边缘,用来防止穿模、检测碰撞。
在Inspector面板中点击 Edit Collider,可以在 Scene 面板中编辑碰撞体尺寸。
很多时候,我们需要知道两个游戏物体发生碰撞产生的结果,比如车辆碰撞等。
如何进入碰撞事件?
碰撞事件代码示例:
// 碰撞进入 private void OnCollisionEnter2D(Collision2D collision) { // print("碰撞进入,碰撞的物体是:" + collision.gameObject.name); // 如果碰撞的物体的球,就表示被击中并销毁游戏物体 if(collision.gameObject.name == "Circle") { print("被击中"); GameObject.Destroy(collision.gameObject); } } // 碰撞退出 private void OnCollisionExit2D(Collision2D collision) { print("碰撞退出"); } // 碰撞中 private void OnCollisionStay2D(Collision2D collision) { print("碰撞过程中"); }
很多时候我们并不需要游戏物体发生碰撞,比如赛车游戏中,我们需要知道什么时候玩家到达了终点,用来作为胜利或计时的依据。或者传送门,玩家进入后可以传送,但这些游戏物体并不需要真的和玩家发生碰撞。
设置触发只需要在碰撞体上勾选 IsTrigger 即可。
注意:设置触发后这个游戏物体并不具备 “物理边缘” ,任何游戏物体都可以穿过它。
触发事件一般用于判断两个物体是否发生了碰撞交互,但不必有物理碰撞效果,比如通过特定地点触发剧情等。
如何进入触发事件?
游戏中的输入,就是指玩家的键盘按键、鼠标点击等行为。
一般会触发一些游戏行为,比如打开背包、角色移动等,其目的是为了让玩家交互。
PC端:基于键盘、鼠标、摇杆等硬件输入;
平板/手机:基于屏幕输入,游戏中实际响应的多为UI元素;
主机/其他:基于手柄、摇杆;
VR:基于VR眼镜、VR手柄等。
键盘输入的几种情况
Input.GetKeyDown(KeyCode.A)
Input.GetKeyUp(KeyCode.A)
Input.GetKey(KeyCode.A)
Input 方法示例:
public class KeyboardDemo : MonoBehaviour { private float attackValue = 0; void Update() { #region 按键检测 // 按下 // 只有第一次按下的那一帧有效 if (Input.GetKeyDown(KeyCode.A)) { print("A"); } // 弹起 // 只有第一次按下的那一帧有效 if (Input.GetKeyUp(KeyCode.W)) { print("W"); } // 按下中 // 在按下的过程中持续生效,每一帧都生效 if (Input.GetKey(KeyCode.S)) { print("S"); } // 蓄力:按下->按住->弹起 if(Input.GetKeyDown(KeyCode.J)) { print("开始蓄力"); attackValue = 0; } if(Input.GetKey(KeyCode.J)) { print("蓄力中"); attackValue += Time.deltaTime; } if(Input.GetKeyUp(KeyCode.J)) { print("蓄力结束,攻击力为 " + attackValue); } #endregion } }
鼠标输入的几种情况:
Input.GetMouseButtonDown(0);
Input.GetMouseButtonUp(0);
Input.GetMouseButton(0);
Input.mousePosition
0 代表鼠标左键,1 代表鼠标右键
鼠标输入示例:
public class MouseDemo : MonoBehaviour { void Update() { // 0:左键,1:右键 if(Input.GetMouseButtonDown(0)) { print("鼠标左键点击"); } if(Input.GetMouseButtonUp(0)) { print("鼠标左键弹起"); } if(Input.GetMouseButton(0)) { print("鼠标左键持续按下"); } // 鼠标位置 // 并不是游戏中的位置 // 而是以左下角为原点,横轴为屏幕宽度,纵轴为屏幕高度的平面直角坐标系 if (Input.GetMouseButtonDown(1)) { print(Input.mousePosition); } } }
InputManager 是 Unity 为开发者提供好的一个输入管理器,我们之前使用的鼠标、键盘检测,实际上都和这个脱离不了关系。
进入路径:Edit->ProjectSettings->InputManager
Input.GetAxis("Horizontal")
// 有平滑过渡
Input.GetAxis("Horizontal");
// 只能是 -1,0,1
Input.GetAxisRaw("Horizontal");
没有输入时默认为0,有输入时:
获取鼠标滚轮的输入:
// 向上滑滚轮为正,向下为负
float wheel = Input.GetAxis("Mouse ScrollWheel");
(1)案例介绍
让小球可以在平台上可以左右移动即可,A:向左移动,D:向右移动。
(2)案例实现
public class CircleMove : MonoBehaviour { // 每秒移动多少米(常规情况) public float Speed = 1; // 帧更新 void Update() { // 移动 Move(); } /// <summary> /// 移动 /// </summary> void Move() { // 获取玩家输入状况 float horizontal = Input.GetAxis("Horizontal"); //float vertical = Input.GetAxis("Vertical"); // 根据输入得到移动方向 Vector3 dir = new Vector3(horizontal, 0, 0); // 根据移动方向进行移动,帧率越高 需要 单帧移动速度越低 transform.Translate(dir * Time.deltaTime * Speed); } }
(1)功能介绍
基于移动的基础上,补充跳跃功能:a. 按空格后小球会跳起来,b. 落地会出现一定的回弹。
(2)功能实现
public class CircleJump : MonoBehaviour { // 跳跃基于刚体运动 private new Rigidbody2D rigidbody2D; // 跳跃给一个向上的力 public float JumpPower = 10; // 是否在地面上 private bool isOnGround = true; // 在Start()中初始化 private void Start() { rigidbody2D = GetComponent<Rigidbody2D>(); } void Update() { // 跳跃 Jump(); } /// <summary> /// 跳跃 /// </summary> void Jump() { // 如果按空格且在地面上就跳跃 // 防止跳跃给的力可以在空中进行而导致飞天 if (Input.GetKeyDown(KeyCode.Space) && isOnGround) { // 因为跳跃是一瞬间执行的和持续性的移动不同 // 所以不用 Time.deltaTime rigidbody2D.AddForce(Vector2.up * JumpPower); } } // 碰撞进入 private void OnCollisionEnter2D(Collision2D collision) { // 判断是否接触了地面 if(collision.gameObject.tag == "Floor") { isOnGround = true; } } // 碰撞退出 private void OnCollisionExit2D(Collision2D collision) { // 判断是否离开地面 if (collision.gameObject.tag == "Floor") { isOnGround = false; } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。