终于斗胆离职,有全天的时间学习自己想做的游戏,想学的Unity了。
不过为了监督自己、真正吸收每次学习的内容,在这里做下总结
以下内容基于M_Studio的2D课程,都是自己的学习归纳

2D 编辑器中内容

2D TilePalette:Rule Tile

2D游戏的瓦片调色板中可以创建规则瓦片。通过创造规则瓦片,可以便捷生成需要的地形

生成方式

Project文件夹中创建。2021.3.8f1c1版本为2D-Tiles-RuleTile
RuleTile位置

编辑步骤

  1. 修改基础Sprite
  2. 增加规则瓦片样式
    RuleTile编辑步骤

2D TileMap

2D游戏瓦片工具

Sorting Layer

排序图层。通过修改不同GameObject的Sorting Layer, 确定位置关系

Order in Layer

组件在图层中的排序。值越大排在越前面

2D TileMap Collider

2D碰撞器, 如果是为平台设置碰撞器,需要添加Composite Collider, 并勾选used by composite, 使平台碰撞器合并在一起,而不是每个瓦片单独一个碰撞器

Composite Collider

设置为整块的碰撞体

Rigidbody 2D设置

如果是平台,需要将Body Type改成Static, 不然平台会下落

2D Rigidbody 2D

2D刚体

Mass

质量大小, 越大的势能越大

Collision Detection

碰撞检测, 如果有物体卡在墙壁等问题,设置成Continuous.
默认为discrete不连贯检测

2D Polygon Collider 2D

2D多边形碰撞器

Edit Collider

通过点击该按钮设置多边型具体样式
点击任意一个边增加一顶点、按住control选择删除一个顶点

2D Physics Materials

2D物理材质, 通过它来设置一个GameObject的摩擦力和弹力
放置到Player等GameObject的Collider中实现相应效果
PhysicsMaterials2D
Friction为设置摩擦力, Bounciness为设置弹力

Layer

图层,用于设置各图层碰撞关系

Project Setting中设置碰撞关系

Project Settings-Physics 2D-Layer Collision Matrix
底部设置各个图层碰撞关系

代码中实现碰撞检测

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 通过根据中心点画的圆是否与地面Layer接触判断是否在地上  
public LayerMask groundLayer;  
  
isGround = Physics2D.OverlapCircle(groundCheck.position, checkRadius, groundLayer);  
  
// 在Scene中通过Gizmos看到当前判断范围  
public void OnDrawGizmos()  
{  
    Gizmos.DrawWireSphere(groundCheck.position, checkRadius);  
}  

Animator

动画编辑器, 编辑各动画的状态切换

设置项关联

配置好Parameters后, 在代码中通过_anim.SetBool("test", False)等方式传递参数更新

代码相关

1
2
3
4
5
// 查看当前动画  
_anim.GetCurrentAnimatorStateInfo(layerIndex).IsName("animation_name");  
  
// 某一个动画的时长(秒)  
_gameObject.GetComponent<Animator>().GetCurrentAnimatorClipInfo(0)[0].clip.length  

Layers设置

  1. 基础Layer设定到最上方(最基础层), 从上到下为下覆盖上的关系
  2. 新Layer建好后把权重Weight设置为1, Blending改为Overrides
  3. 除基础Layer, 其他Layer均配置一个Empty State, 不带任何动画, 避免覆盖基础状态

Prefab

预制体

小技巧

  1. 在场景中修改了, 如果想要所有场景中的预制体均变化, 选择Overrides
    PrefabOverrides
  2. 想直接在预制体中修改, 选中场景中的预制体点Open
  3. 想去除GameObject与预制体的关联, 点击GameObject后按右键, Unpack Compeletly

GameObject

朝向修改

  1. Scale修改x为-1, 则为左右翻转GameObject
  2. Sprite Renderer挂载时, Flip勾选X, 即左右翻转. 但是这种情况下物理碰撞未修改

小技巧

  1. 配置角色/敌人等角色时, 创建空物体然后在其内部编辑Sprite等较好. 可以平级设置特效/巡逻点等的其他组件

代码

接口 Interface

编写interface, 各继承的Class需实现其方法
主要用于通用逻辑在各个待实现Class中实现

协程 IEnumerator

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 启动  
StartCorontine(xxx())  
  
// 编写  
IEnumerator xxx()  
{  
	// do sth...  
	yield return new WaitForSeconds(xxx);  
	// do sth...  
}  

有限状态机 Finite States Machine

抽象类继承编写
后续新增状态时, 编写抽象类即可, 更方便扩展
FSM

常用方法

编写时常用方法有

  1. 进入状态时的方法 e.g EnterState()
  2. 一直在当前状态时的方法 e.g OnUpdate()
  3. 退出状态时的方法 e.g ExitState()

虚方法 Virtual

父类包含虚方法时, 子类可以重新实现该方法, 也可以不更改原有实现

观察者模式

观察者模式是Manager常用的模式, 其他调用方向Manager进行汇报, 调用其方法

单例模式

部分脚本需要有且只有一个实例的情况下使用单例模式, 是Manager常用的模式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public void Awake()  
{  
    if (Instance == null)  
    {  
        Instance = this;  
    }  
    else  
    {  
        Destroy(gameObject);  
    }  
}  

SceneManager

Unity自带class, 控制场景切换

1
2
3
4
5
// 加载场景(通过index, 在Unity-File-Build Setting中设置)  
SceneManager.LoadScene(PlayerPrefs.GetInt("sceneIndex"));  
  
// 当前场景名  
SceneManager.GetActiveScene().name  

PlayerPrefs

Unity自带class, 存储玩家数据

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 存储数据  
PlayerPrefs.SetFloat("playerHealth", _player.health);  
  
// 存储到文件中, 下次打开游戏时可继续使用  
PlayerPrefs.Save();  
  
// 删除Key  
PlayerPrefs.DeleteKey("playerHealth");  
  
// 是否有该Key  
PlayerPrefs.HasKey("sceneIndex");  

Update, FixdUpdate

Update用于逻辑执行, 每一帧执行一次
FixUpdate用于物理检测等,固定时间执行一次

移动相关

横向移动

1
2
3
4
5
6
7
// 获取横向输入.有渐变  
float horizontalInput = Input.GetAxis("Horizontal");  
// 获取横向输入.无渐变,只有-1,0,1  
float horizontalInput = Input.GetAxisRaw("Horizontal");  
  
  
rb.velocity = new Vector2(Input.GetAxis("Horizontal") * speed, rb.velocity.y);  

跳跃

1
_rb.velocity = new Vector2(_rb.velocity.x, jumpForce);  

是否在地面的检测

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 通过根据中心点画的圆是否与地面Layer接触判断是否在地上  
public LayerMask groundLayer;  
  
isGround = Physics2D.OverlapCircle(groundCheck.position, checkRadius, groundLayer);  
  
// 在Scene中通过Gizmos看到当前判断范围  
public void OnDrawGizmos()  
{  
    Gizmos.DrawWireSphere(groundCheck.position, checkRadius);  
}  

重力惯性

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 在跳起和地面两种不同情况时修改不同的地面引力/地面惯性, 实现角色跳跃快速下落/上升, 但地面时不要这么大的地面惯性  
if (isGround)  
{  
    isJump = false;  
    _rb.gravityScale = 1;  
}  
else  
{  
    _rb.gravityScale = 4;  
}  

开发过程中显示Debug图像

Gizmo

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// 显示Gizmo圆形, 辅助显示攻击范围等
public void OnDrawGizmos()
{
    Gizmos.DrawWireSphere(groundCheck.position, checkRadius);
}

// 只在选中当前GameObject时画Gizmos
private void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.cyan;
        Gizmos.DrawWireSphere(transform.position, sightRadius);
    }