该文来自学习chutianbo老师的笔记,链接b站第56P至71P
1.瓦片地图的制作
右键点击主界面Sence➡GameObject➡2D Object➡Tilemap➡Rectanglar(这样是创建了一个RPG式的视角)
创建tiles文件夹 将素材拖入右上角打开的紫色按键TIle Palette,将素材拖入
或者直接在文件夹中创建
2.素材过大需要分割怎么办
回到素材更改Sprite Mode为Multiple
进入Sprite Editor 选择左上角Slice 选择Grid By Cell Size
3.瓦片不符合边框
回到素材找到Pixels Per Unit将其改为64符合边框
4.关于瓦片盖住了角色
回到Hierarchy下的Grid下的tilemap找到右边的TIlemap Renderer更改order in layer为-10(图层放到后面去)
5.关于规则瓦片
在tile文件夹中右键Create➡2D➡Tiles➡Rule TIle(如果没有大概率是没有插件,直接寻找其他文章有教)
6.如何快速制作规则类似的瓦片
如上,选择rule Overring tile
7.如何使瓦片的碰撞体连在一起(原本我们制作好的瓦片都是单独的一个碰撞体)
在第四部中的tilemap中加入Composite Coillider 2D组件
在TIlemap Collider 2D中勾选 used by Compite即可;
8.关于规则类似瓦片的继承
直接继承规则类似瓦片的话,那么碰撞体是否也是继承的,所以如果存在碰撞体不同的情况下需要重新制作
9.伪透视的实现
在 2D 游戏中,场景里的 “前后” 是由 Y 轴决定的,需要让 Unity 根据游戏对象的 y 坐标来绘制游戏对象
Y 轴 y 坐标值越小,越靠前,应该遮挡 y 坐标值较大的游戏对象,也就是 y 坐标较小的游戏对象后绘制,就会位于上层
在游戏中,如果要设置 2D 伪透视试图,需要在项目设置中进行更改:
Edit > Project Settings > Graphics > Camera Settings > Transparency Sort Mode = Custom Axis > Transparency Sort Axis x = 0 / y = 1 / z = 0
所以我们使用的素材也要在Sprite Mode下的Sprite Edito中将轴心(个人认为是遮盖点)放在人物的脚底。
2 关于碰撞的实现
一个物体如果需要碰撞那么他一定拥有刚体组件即Rigidbody 2d(2d游戏中是这个)
同样的他如果需要和别的物件发生交互,那么他还需要碰撞体组件Box Collider 2D
2.1添加两个组件之后角色直接飞速下落
关闭刚体组件下的Gravity Scale(重力),将其设定为0即可;
2.2在2dRPG中为了透视效果最好将碰撞盒子设定在脚附近左右(大概身体1/3左右)
3为我们的角色增添生命系统
这十分的简单,在我们上节中为角色控制加入的脚本中加入
public int maxHealth = 5;
public int currentHealth;
void Start()
{
//获得当前游戏对象的刚体组件
rigidbody2d = GetComponent<Rigidbody2D>();
//初始化当前生命值
currentHealth = maxHealth;
}
3.1直接将我们游戏运行中重要的生命数值暴露出来是十分危险的,这种数值不应该直接被外部调用
所以我们需要对currentHealth进行封装。即用属性去保护其内部的字段
int currentHealth;
public int Currenthealth
{ get { return currentHealth; } }
//set { currentHealth = value; } }
这样我们就做好了简易的生命系统
4 世界的交互
在有了生命系统之后,生命会因为玩家的操作而进行变更,所以我们要加入玩家生命变更的函数
public void changehealth(int amount)
{
//限制生命值在0到maxhealth之间
currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth);
Debug.Log("当前生命值:" + currentHealth + "/" + maxHealth);
}
这里我们使用了unity自带的Math.Clamp函数,这样可以将血量限制在0到最大血量之间
链接官方文档:Math.Clamp
4.2那么在有了这个函数之后,我们就可以在创建的世界上设置血瓶或者掉血的陷阱了,那么下面的代码实现了吃掉一个血瓶为玩家回一滴血,同时在满血时不吃血瓶,以及吃掉血瓶之后血瓶消失的功能
public class Healthcollable : MonoBehaviour
{
//记录碰撞次数
int collideCount;
public int amount=1;
private void OnTriggerEnter2D(Collider2D other)
{
collideCount += 1;
Debug.Log($"和当前物体发生碰撞的是{other},第{collideCount}此碰撞");
//获取Ruby对象
RubyController rubyController = other.GetComponent<RubyController>();
//检测是谁碰撞了血瓶
if (rubyController != null)
{
//如果Ruby不是满血
if (rubyController.Currenthealth < rubyController.maxHealth) {
rubyController.changehealth(amount);
//消失血瓶
Destroy(gameObject);
}
else
{
Debug.Log("Ruby不需要加血");
Debug.Log("当前生命值:" + rubyController.Currenthealth + "/" + rubyController.maxHealth);
}
}
else
{
Debug.Log("非Ruby对象");
}
}
}
OntiggerEnter2D函数是进入时只触发一次的函数;
4.3那么同理我们在设置一个碰到会掉血的区域
public class Damageable : MonoBehaviour
{
//掉血量
public int DamageNum = -1;
//进入范围触发一次
private void OnTriggerStay2D(Collider2D collision)
{
RubyController rubyController = collision.GetComponent<RubyController>();
if (rubyController != null)
{
rubyController.changehealth(DamageNum);
}
else
{
Debug.Log("非Ruby对象");
}
}
//每一帧都会触发
}
OnTriggerStay2D是在碰撞体中每一帧都会触发的函数,这样子我们会发现角色掉血量太快了,几乎在瞬间血量就清空了。
所以我们给角色添加一个收到伤害后短暂无敌的功能
//设置无敌间隔
public float timelnvincible = 2.0f;
//设置是否无敌
bool islnvincible;
//定义变量,无敌进行时间(计时器)
float invincibleTimer;
在update中加入对无敌的检测(事实上个人认为每一帧都对这个函数进行检测好像不太合理)
void Update()
{
//无敌时刻进入倒计时
if (islnvincible)
{
invincibleTimer -= Time.deltaTime;
if (invincibleTimer < 0)
{
islnvincible = false;
}
}
}
在上面写的更改生命的函数中加入无敌的代码段文章来源:https://www.toymoban.com/news/detail-408718.html
//更改生命值
public void changehealth(int amount)
{
if (amount < 0)
{
//如果无敌,那么直接跳出函数,否则玩家进入无敌,计时开始
if (islnvincible)
{
return ;
}
islnvincible = true;
invincibleTimer = timelnvincible;
}
//限制生命值在0到maxhealth之间
currentHealth = Mathf.Clamp(currentHealth + amount, 0, maxHealth);
Debug.Log("当前生命值:" + currentHealth + "/" + maxHealth);
}
本文仅是个人记录初步学习unity所用
链接老师的文档:瓦片世界文章来源地址https://www.toymoban.com/news/detail-408718.html
到了这里,关于Unity初学2——瓦片的制作以及世界的交互(2d)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!