1 修复角色走路的卡顿
之前编写的游戏试玩中总会出现角色在Tilemap(非末端的瓦片)上移动会有卡顿,其实就是因为两个都是方形的碰撞器容易卡住。
解决方法:(3种)
- 修改角色碰撞器Edge Radius变成胶囊碰撞器:Edge Radius是角色Box Collider 2D里面的一个参数,当Edge Radius大于零时,每个边缘的作用类似于带有圆形末端的“胶囊”形状。
- 更换角色碰撞器为圆形的碰撞器:和上面的思路一样,把角色碰撞器的角变得有弧度。
- 为Tilemap添加Composite Collider 2D组件:让这些单独的盒子碰撞器合并起来,这样角色在上面走的时候就不会碰到非末端的碰撞器而停下。
添加Composite Collider 2D要注意的地方:添加后,会自动生成Rigidbody 2D刚体会产生重力,要把刚体的Body Type选择为static,要在Tilemap Collider 2D里面勾选好Used By Composite才会起作用。
2 设置二段跳
之前写代码,游戏中可以无限跳跃,但是大部分的游戏跳跃都不会无限,所以要给它的跳跃来点限制。除了设置跳跃只能跳二段以外,还要限制起跳必须只能从地面开始跳,这样游戏才自然。
代码思路:就是设置两个参数jumpMax(最大跳跃数量)和jumpNum(当前跳跃数),然后判断一下每次按下跳跃键后,如果jumpNum等于0表示是第一跳,那么第一跳必须要碰地才能跳;如果jumpNum不为0,则代表已经是多跳了,只有jumpNum小于jumpMax才能跳;在之气那的角色落地判断部分,加上jumpNum清零。此方法不但适合二段跳也适合有限制的多段跳,只需要改变jumpMax就行了。
代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour {
//左右移动,跳跃
private float moveSpeed;//移动速度
private float jumpForce;//跳跃力
private Rigidbody2D rig;//刚体
private Animator Anim;//角色的Animator
private Collider2D coll;//角色的碰撞器
public LayerMask ground;//用来开启layer
private bool falling=false;//用来标记是否是下落状态
private int jumpMax;//跳跃次数的上线
private int jumpNum;//当前跳跃的次数
// Use this for initialization
//初始化
void Start () {
rig = GetComponent<Rigidbody2D>();//获取主角刚体组件
Anim = GetComponent<Animator>();//获取主角动画组件
coll = GetComponent<Collider2D>();//获取角色碰撞器
ground = 1<<8;//开启Ground的layer层,Ground在layer8
jumpForce = 575f;
moveSpeed = 500f;
jumpMax = 2;//最多二段跳
jumpNum = 0;//初始跳跃数为0
}
//固定的时间间隔执行,不受游戏帧率的影响
void FixedUpdate()
{
Move();
changeAnimator();
}
//控制移动
void Move()
{
float moveMultiple = Input.GetAxis("Horizontal");
float faceDirection = Input.GetAxisRaw("Horizontal");
//角色左右移动
if (moveMultiple!=0)
{
rig.velocity = new Vector2(moveMultiple * moveSpeed * Time.deltaTime, rig.velocity.y);
}
//角色朝向修改
if(faceDirection!=0)
{
transform.localScale = new Vector2(faceDirection, 1);
}
//角色跳跃
if (Input.GetButtonDown("Jump"))
{
//rig.velocity = new Vector2(rig.velocity.x, jumpForce * Time.deltaTime);
//Anim.SetBool("ground", false);
if(jumpNum==0&& coll.IsTouchingLayers(ground))//第一跳要碰地才能跳
{
JumpChange();
}
else if (jumpNum > 0 && jumpNum < jumpMax)//第二跳判断
{
JumpChange();
}
}
}
//跳跃代码
void JumpChange()
{
rig.velocity = new Vector2(rig.velocity.x, jumpForce * Time.deltaTime);
Anim.SetBool("ground", false);
jumpNum++;
}
void changeAnimator()
{
Anim.SetFloat("speed", Mathf.Abs(rig.velocity.x));
if (Anim.GetBool("ground")==false&&rig.velocity.y<0)
{
falling = true;
}
else if (coll.IsTouchingLayers(ground)&&falling)
{
Anim.SetBool("ground", true);
falling = false;
jumpNum = 0;//落地的话,当前跳跃次数清零
}
}
}