天天看點

Unity3d實作簡單2D角色控制

實作效果

還是很好玩的,大家可以看看

Unity3d實作簡單2D角色控制

思路

跳躍和走路大家應該都知道了,這裡簡單介紹一下蹬牆跳的實作辦法,函數主體

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:放在角色前方判斷是否和牆壁接觸的點
  • 其他:自行調參

參考

Unity3d實作簡單2D角色控制
Unity3d實作簡單2D角色控制

繼續閱讀