【Unity入门教程】 第十一章 二维游戏开发 【中国大学MOOC游戏引擎原理及应用】
以下均为来自中国大学mooc 游戏引擎原理及应用时的学习笔记,不含商用,仅供学习交流使用,如果侵权请联系作者删除。
11.1 二维游戏开发
游戏引擎可以对这些图片进行切换来达到模拟二维动画的效果。
在unity3D中选中2D视角,选择正交投影,即可进行2d游戏的开发
在unity商店中下载rougelike资源
直接导入一个叶子的图片,然后并且可以通过新建一个sprite的图片,然后将其扩大到覆盖整个屏幕并把其颜色修改,就可以生成一个背景
还有一种由多图片组成的大图片,例如下载资源包中的这个
可以选中这个类型
点击应用即可进入精灵编辑界面
然后可以选择左上角进行切片,切片有几种模式可供选择
看图我们可以将其切为7行8列
然后便可以看到切分好了的很多子图
点击apply即可看到其包含了很多子图
拖拽到场景中会发现被遮挡,这是因为存在一个优先级
layer决定层级
在同一层级则是由order in layer来决定,越大的话越在前面
实际上应该把背景层级放在最低的层级,这样就不会遮挡物体了
接下来调整精灵的大小,可以通过scale来实现,也可以通过精灵属性下的Pixels Per Unity来就决定,它代表的是每一个unity单位包含多少像素
默认是100,设置为10的话则会让这个显示的图片变大
接下来实现二维人物的动画:
这时候我们创建出这样的一个场景并且调出animation窗口,创建一个idle动画
接下来选中这六个,并且将其拖拽到窗口里
接下来创建一个animator,并把这个动画导入
然后为人物增加一个animator组件,并将刚才的那个导入
给子弹写一个脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Rigidbody2D))]
[RequireComponent(typeof(Collider2D))]
public class Bullet : MonoBehaviour
{
public float speed = 2f;
private Rigidbody2D body;
// Start is called before the first frame update
void Start()
{
body = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
body.MovePosition(transform.position + speed * transform.right * Time.deltaTime;)
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "enemy")
{
GameObject.Destroy(collision.gameObject);
GameObject.Destroy(gameObject);
}
}
}
给人物写一个发射子弹的脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Spawner : MonoBehaviour
{
public float timeInterval = 3f;
float timer = 0f;
public GameObject bullet;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (timer > timeInterval)
{
Instantiate(bullet, transform);
timer = 0;
}
timer += Time.deltaTime;
}
}
接下来用资源包里自带的图片为其创建一个子弹预制件,并为其添加上circle collider 2D组件,并将bullet脚本拖拽给它
接下来创建一个敌人并为其赋予动画,赋予动画的方式和之前一样,然后为其添加box collider以及添加tag
于是我们可以看到当子弹碰到敌人时,敌人会消失。
接下来介绍一种可以让二维物体也可以具有光照的方法:
创建一个新的材质,选择漫反射,并将这个材质给叶子
然后这时候会看到叶子是黑的,
如果我们在场景中添加一个点光源并把光源移动到叶子附近便可以看到这样的效果。
11.2 瓦片地图
比如说暗黑破坏神
如果需要表现斜45度的效果的话,在排列的地方则需要一些技巧
它是一个菱形的效果,我们可以通过透明的方式,把周围的图片像素弄成透明,通过这种方式来光得到菱形效果。
排列的时候,也是有上下交错这个排列就可以达到这种斜45度的效果。
创建一个tilemap
然后调出调色板窗口
然后可以将图片导入到调色板窗口里
然后就可以绘制地图了
这里可以调整grid的大小
这里还有吸取 擦掉 填充一片等功能
当有多个tilemap的时候这里可以选中
为瓦片地图添加一个tilemap collider2D
虽然添加了碰撞体但是这时候每个小方块都是单独的碰撞体,这里可以机进行优化
添加一个这个组件
并且为其添加上静态的属性,然后选中这个,
此时可以看到碰撞体变成一个整体了
此时给人物添加重力会发现人物会掉落到平台上面
11.3 二维角色
此时很多二维游戏也是用3D引擎开发的,只是限制了一个Z轴的*度
拖拽标准包中的机器人到场景中
为机器人编写一系列动作的代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Robot : MonoBehaviour
{
public float m_MaxSpeed = 10f;
public float m_JumpForce = 400f;
public LayerMask m_WhatIsGround;
public Transform m_GroundCheck;
const float k_GroundedRadius = 0.5f;//判断是否着地的冗余
public bool m_Grounded;
private Animator m_Anim;
private Rigidbody2D m_Rigidbody2D;
public bool m_FacingRight = true;//为了让物体一直往右走,当物体往左走的时候则让其反向
public bool m_Jump;
private void Awake()
{
m_GroundCheck = transform.Find("GroundCheck");
m_Anim = GetComponent<Animator>();
m_Rigidbody2D = GetComponent<Rigidbody2D>();
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
private void FixedUpdate()
{
m_Grounded = false;
Collider2D[] colliders = Physics2D.OverlapCircleAll(m_GroundCheck.position, k_GroundedRadius, m_WhatIsGround);
//检查一下在一个点周围做一个圆,在这个圆内是否有其他物体
//存在,如果是的话把其他物体的colliders返回回来
//第一个参数是中心点的位置,第二个是半径
//第三个是Layer,可以通过Layer遮罩来将特定的Layer纳入检查范围,不一定所有的物体都检查
for(int i = 0; i < colliders.Length; i++)
{
if (colliders[i].gameObject != gameObject)
{
m_Grounded = true;
//如果不是当前物体的话,说明撞到地面的物体了
}
}
m_Anim.SetBool("ground", m_Grounded);//将动画控制器中的参数设定为这个参数
float h = Input.GetAxis("Horizontal");
if (!m_Jump)
{
m_Jump = Input.GetKeyDown(KeyCode.Space);
}
Move(h, m_Jump);
m_Jump = false;
}
public void Move(float move,bool jump)
{
if (m_Grounded)
{
m_Anim.SetFloat("speed", Mathf.Abs(move));
//将move的值传递给动画控制器中的speed的参数
m_Rigidbody2D.velocity = new Vector2(move * m_MaxSpeed, m_Rigidbody2D.velocity.y);
if (move > 0 && !m_FacingRight)
{
Flip();//将人物身体反转一个方向的函数
}
else if (move < 0 && m_FacingRight)
{
Flip();
}
}
if (m_Grounded && jump && m_Anim.GetBool("ground"))
{
m_Grounded = false;
m_Anim.SetBool("ground", false);
m_Rigidbody2D.AddForce(new Vector2(0, m_JumpForce));
}
}
void Flip()
{
m_FacingRight = !m_FacingRight;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
接下来设定好这些状态变化的条件
然后将脚本拖拽给robot,然后what is ground这一栏按理来说应该创建一个layer ground给物体,这里方便起见先选择everything
注意到脚本中需要一个groundcheck组件,我们需要在场景中添加这个空物体来实现地面检测功能
添加这两个组件并调整碰撞体大小
但是这时候遇到了这样的问题,这是因为给瓦片地图虽然设置了刚体,但是的也得给刚体设置上静态的属性才可以。
设置完毕后,走路发现人物直接倒地,这是因为这是2D游戏,Z轴的晃动会使得人物倒地,我们需要给Z轴限制*度。
但是人物动作转换有延迟,我们可以这样:
需要取消这个
接下来实现跳上平台的功能
使其能从下部跳上去站在平台上 添加这个
这样即可实现从下方跳跃到上方。
11.4 二维角色骨架系统
关键帧动画需要保存的像素量很大,并且和周围的环境很难发生有效的交互,而且可能无法很好的实时生成动画。
接下来在unity中实现二维角色的骨骼动画。
导入2D animation包后
导入一个sprite,并进入sprite editor 为其添加骨骼(双击添加)
在这里插入图片描述
然后为其自动生成网格
下面可以自动赋权重
添加sprite skin组件并创建骨骼
创建动画并修改关键帧动画的位置,即可实现动画
本文地址:https://blog.csdn.net/weixin_43757333/article/details/110085317