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;//落地的話,當前跳躍次數清零
}
}
}