實作效果
還是很好玩的,大家可以看看
思路
跳躍和走路大家應該都知道了,這裡簡單介紹一下蹬牆跳的實作辦法,函數主體
if (isSliding)
{
rb.velocity = new Vector2(rb.velocity.x,-wallSlidingSpeed);
if(Input.GetKeyDown(KeyCode.Space))
{
wallJumping = true;
Invoke("setWallJumpingFalse", wallJumpTime);
}
if(wallJumping)
{
rb.velocity = new Vector2(xwallJumpForce * -x, ywallJumpForce);
}
return;
}
void setWallJumpingFalse()
{
wallJumping = false;
}
首先必須確定角色在牆壁上滑行,這部分可以看後續代碼,相信大家一下就能看懂;
然後當按下空格時,我們将會施加一個斜向上的速度(與角色朝向相反)------角色将會斜着跳起來,持續一小段時間以後再消失,這時候玩家可以朝向牆移動,也就是回到牆面。
代碼
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerControl : MonoBehaviour
{
public float speed;
private Rigidbody2D rb;
[SerializeField]private float x;//角色橫軸方向速度
[SerializeField] private bool Right;//角色面向
[SerializeField]private bool isGround;//是否在地面
[SerializeField]private bool isFront;//是否接觸牆壁
[SerializeField] private bool isSliding;//玩家是否在滑行
[SerializeField] private bool wallJumping;//玩家正在牆上跳躍
public LayerMask groundMask;//地面對應的層級
public LayerMask wallMask;//牆壁對應的層級
public Transform groundCheck;//檢測是否面對地面
public Transform frontCheck;//檢測是否面對牆壁
public float jumpForce;
public float xwallJumpSpeed;//跳躍的x速度
public float ywallJumpSpeed;//跳躍的y速度
public float wallSlidingSpeed;
public float checkRadius;//檢測的半徑
public float wallJumpTime;//跳躍的時間
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody2D>();
Right = true;
}
// Update is called once per frame
void Update()
{
x = Input.GetAxisRaw("Horizontal");
checkPosition();
move();
}
void setWallJumpingFalse()
{
wallJumping = false;
}
void move()
{
if (!isSliding && !wallJumping)
{
rb.velocity = new Vector2(x * speed, rb.velocity.y);
}
if (isSliding)
{
rb.velocity = new Vector2(rb.velocity.x, -wallSlidingSpeed);
}
if(isSliding && Input.GetKeyDown(KeyCode.Space))
{
wallJumping = true;
Invoke("setWallJumpingFalse", wallJumpTime);
}
if(wallJumping)
{
rb.velocity = new Vector2(xwallJumpSpeed * -x, ywallJumpSpeed);
}
if ((x > 0 && !Right) || (x < 0 && Right))
{
flip();
}
}
void checkPosition()
{
isGround = Physics2D.OverlapCircle(groundCheck.position, checkRadius, groundMask);
if(Input.GetKeyDown(KeyCode.Space) && isGround == true)
{
rb.velocity = Vector2.up * jumpForce;
}
isFront = Physics2D.OverlapCircle(frontCheck.position, checkRadius, wallMask);
if(isFront == true && isGround == false)
{
if((Right && x > 0) || (!Right && x < 0))
isSliding = true;
else
{
isSliding = false;
}
}
else
{
isSliding = false;
}
}
//實作角色的轉身
void flip()
{
transform.localScale = new Vector3(-transform.localScale.x, transform.localScale.y, transform.localScale.z);
Right = !Right;
}
}
代碼細節
由于各種位置的判斷有先後關系,并且移動的方式也不同,我嘗試着在update中的不同位置改變代碼順序,隻有上述代碼能夠實作我們想要的全部效果。
比如嘗試把
rb.velocity = new Vector2(x * speed, rb.velocity.y);
放在攀牆跳的後面,并且沒有套在if中,一旦跳躍時間上調,就會出現很鬼畜的效果,大家可以試試 = =。同樣的,如果它沒有在if裡面而是放在update一開始,那麼角色将不會滑行, 就算isSilding變量為true也隻會停在牆上。
變量指派
- GroundMask: 作為地面的layer,如果需要在牆壁最上面跳躍,那麼需要把牆壁也添加進去
- WallMask:作為牆壁的layer
- GroundCheck:放在角色身下判斷是否和地面接觸的點
- FrontCheck:放在角色前方判斷是否和牆壁接觸的點
- 其他:自行調參
參考