【Unity】2D角色跳跃控制器-CSDN博客

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

最近加了学校的Nova独游社本文是社团出的二面题后续有时间优化下可能会做成一个二维冒险小游戏。本文主要涉及相关代码参考教程《勇士传说》横版动作类游戏开发教程

效果演示

【Unity】2D角色跳跃模拟器

主要实现功能

  • 角色移动翻转
  • 地图周围空气墙
  • 角色跳跃与长按连跳
  • 地面判断与连跳限制
  • 滑块控制速度与弹跳力

人物素材

人物素材选用的是童年游戏《死神VS火影》中黑崎一护卍解形态动作分帧图如下进行扣绿处理后可以导入到unity中进行自动切图。

在这里插入图片描述
本项目目前只用到前三个动作待机动作、奔跑动作和跳跃动作。

动画关系

动画状态图如图所示首先进入idol待机状态播放待机动画根据角色的速度切换奔跑状态。

在这里插入图片描述

任意状态按下空格键则切换到跳跃状态。跳跃状态使用了混合树细分成四个状态jump1为起跳动作jump2为上升动作jump3为滞空动作jump4为落地动作。

在这里插入图片描述

角色移动和翻转

角色的移动主要通过读取用户的输入对刚体的位置进行调整如果输入为反方向则沿x轴对人物进行翻转代码如下

void Movement()
  {
      float horizontalmove;//定义变量当horizontalmove等于-1时向左等于1时向右等于0时不动
      horizontalmove = Input.GetAxis("Horizontal");//绑定输入
      if (horizontalmove != 0)
      {
          rb.velocity = new Vector2(horizontalmove * speed, rb.velocity.y);//更新速度变量
      }

      float faceDir = transform.localScale.x;

      if (horizontalmove > 0)
          faceDir = (float)0.5;
      if (horizontalmove < 0)
          faceDir = (float)-0.5;

      // 人物翻转
      transform.localScale = new Vector3(faceDir, (float)0.5, (float)0.5);
  }

角色跳跃与长按连跳

角色蓄力跳主要通过计时器实现按下空格时倒计时启动如果秒松开isJumping设为False执行普通跳跃直接调整角色y轴位置。如果按住不松手则持续执行跳跃倒计时结束再执行普通跳跃从而跳的更高代码如下

void Jump()
{   
    // 普通跳
    if (Input.GetKeyDown(KeyCode.Space) && physicscheck.isGround)
    {
        isJumping = true;
        jumpTimeCounter = jumpTime;
        rb.velocity = new Vector2(rb.velocity.x, jumpForce);
    }
    // 蓄力跳
    if (Input.GetKey(KeyCode.Space) && isJumping == true)
    {
        if(jumpTimeCounter > 0)
        {
            rb.velocity = new Vector2(rb.velocity.x, jumpForce);
            jumpTimeCounter -= Time.deltaTime;
        }
        else
        {
            isJumping = false;
        }
    }
    if (Input.GetKeyUp(KeyCode.Space))
    {
        isJumping = false;
    }
}

地面判断相关代码

public void Check()
{
    isGround = Physics2D.OverlapCircle(transform.position, checkRaduis, groundLayer);
}

滑块控制

滑块传参只需要在游戏的Canvas中设置Slider在参数面板中绑定相关方法

在这里插入图片描述

相关代码

public void OnChangeSpeed(float newSpeed)
{
    speed = newSpeed * maxSpeed;
}

public void OnChangeJumpForce(float newJumpForce)
{
    jumpForce = newJumpForce * maxJumpForce;
}

完整代码

PlayerController.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public Rigidbody2D rb;  //添加Rigidbody

    [Header("基本属性")]
    public float speed = 10;  //速度
    public float jumpForce = 4; //跳跃力度

    private float jumpTimeCounter;
    public float jumpTime;
    private bool isJumping;

    // Slider相关
    private float maxSpeed = 50;
    private float maxJumpForce = 30;

    private PhysicsCheck physicscheck;

    private void Awake()
    {
        physicscheck = GetComponent<PhysicsCheck>();
    }

    // Update is called once per frame
    void Update()
    {
        Movement();//移动
        Jump();
    }

    void Movement()
    {
        float horizontalmove;//定义变量当horizontalmove等于-1时向左等于1时向右等于0时不动
        horizontalmove = Input.GetAxis("Horizontal");//绑定输入
        if (horizontalmove != 0)
        {
            rb.velocity = new Vector2(horizontalmove * speed, rb.velocity.y);//更新速度变量
        }

        float faceDir = transform.localScale.x;

        if (horizontalmove > 0)
            faceDir = (float)0.5;
        if (horizontalmove < 0)
            faceDir = (float)-0.5;

        // 人物翻转
        transform.localScale = new Vector3(faceDir, (float)0.5, (float)0.5);

    }

    void Jump()
    {   
        // 普通跳
        if (Input.GetKeyDown(KeyCode.Space) && physicscheck.isGround)
        {
            isJumping = true;
            jumpTimeCounter = jumpTime;
            rb.velocity = new Vector2(rb.velocity.x, jumpForce);
        }
        // 蓄力跳
        if (Input.GetKey(KeyCode.Space) && isJumping == true)
        {
            if(jumpTimeCounter > 0)
            {
                rb.velocity = new Vector2(rb.velocity.x, jumpForce);
                jumpTimeCounter -= Time.deltaTime;
            }
            else
            {
                isJumping = false;
            }
        }
        if (Input.GetKeyUp(KeyCode.Space))
        {
            isJumping = false;
        }
    }
    public void OnChangeSpeed(float newSpeed)
    {
        speed = newSpeed * maxSpeed;
    }

    public void OnChangeJumpForce(float newJumpForce)
    {
        jumpForce = newJumpForce * maxJumpForce;
    }
}

拓展

对于2D平面游戏来说有的游戏会做更多优化比如

  • 跳跃缓冲Jump Buffer当玩家即将落地前按下跳跃键时该次跳跃命令将被缓存玩家落地后会直接执行缓存的跳跃命令包含可以调整大小的 缓存时间
  • 野狼时间Coyote Time当玩家刚刚离开地面几帧时玩家按下跳跃键仍然可以起跳包含可以调整大小的野狼时间

实测发现只要移动速度和弹跳值合适手感本身就还不错因此就没去实现这些有些花哨的设计不过可以纳入之后拓展的一个考虑范畴。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6