Unity教程2:保姆级教程.几行代码实现输入控制2D人物的移动

目录

人物的创建以及刚体的设置

图层渲染层级设置

角色碰撞箱设置

使用代码控制人物移动

创建脚本文件

 初始函数解释

控制移动代码

初始化变量

 获得键盘输入

 调用函数


手册链接在这:Unity User Manual (2019.3) - Unity 手册

没有控制人物移动的2D游戏就太说不过去了!那么接下来,这篇文章将会以简单的几行代码轻松的教会你实现2D人物的移动,不必担心看不懂代码,我将会查询API手册以保姆级教程来帮助你理解!那么我们开始吧!

人物的创建以及刚体的设置

 首先随便选择一个可用的人物素材当作我们的移动主人公,我这边就选用了一个胡桃夹子的形象当作主角。

 

 那么很显然这张图片素材需要切割,而且我们发现这张图片的命名为Idel,这是动画设置的常用名称,意思是人物待机时的动画,那么切割完也能方便我们实现人物的动画效果。

 切割的尺寸素材作者很贴心的标出来了,X16,Y24

 那么我们的素材已经切割好了,接下来就是把它放到场景里了,我们直接拖拽第一张角色的图片进入场景,然后将其重命名为Player。

然后为其添加两个组件,这两个组件就可以让我们简单的控制我们的人物移动了,不过还需要结合下文的代码实现。

我的设置如下

各参数设置缘由为下:

Gravity Scale设置为0,可以让我们的角色不再受到Unity默认的重力影响,而是可以上下左右进行平面移动,这是我们需要的功能。

Collision Detection 设置为Continuous 则能保证一直检测碰撞体间的碰撞,防止出现穿模卡墙的问题。

Freeze Rotation的Z轴 (冻结Z轴)则是防止我们的角色因为发生物理碰撞产生旋转,如下图GIF


图层渲染层级设置

因为我们制作的游戏带有RPG的要素,那么我希望我的人物能显示于背景以及建筑之前,那么我们新建一个图层,为其命名为Player,在Soritng Later选项中,下拉菜单选择Add Sorting Layer

 

 渲染层级的顺序以从下往上的优先级进行渲染,在新建完了Layer之后别忘了把我们Player的层级设置成Player。


角色碰撞箱设置

选择我们角色的碰撞箱组件,编辑其碰撞箱

 

将碰撞箱设置成这个大小

 为什么设置成这个大小呢?因为我们希望我们的角色能成功的遮挡到背景,也不要太过容易的碰撞到场景物体。

使用代码控制人物移动

 那么接下来就是重头戏了,如何利用代码控制我们人物的移动呢?

创建脚本文件

我们在项目文件夹中新建一个文件夹取名为Script,在这里面我们方便管理并存放我们的脚本,那么我们创建一个脚本文件命名为PlayerController

 然后拖拽我们的脚本文件挂载到我们的人物身上。


 初始函数解释

 每一个默认的C#脚本,Unity都会存放两个默认生成的函数

     // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        
    }

Strat函数会在游戏启动时调用,Update函数则是每一帧调用一次,它们跟深层次的使用方法我们暂不深究。


控制移动代码

初始化变量

我们之前已经在我们的人物身上挂载了刚体组件,控制移动的方法就需要利用刚体,那么我们怎么使用脚本来控制刚体组件呢?

Unity将每个组件的名称写成了一个类,借助类,我们可以生成一个空对象rb

//获取刚体组件
private Rigidbody2D rb;

 那么我希望我能借助变量控制速度的参数,使用Pubilc创建一个变量称之为Movespeed

    //人物移动速度
    public float Movespeed;

 既然我们能拿到Rigibody2D这个组件,那么拿到其他的组件也是可行的,比如Transform组件,在这里你可以自己试试使用Transform这个类型生成一个变量!

 private关键字意为私有,也就是将rb这个对象私有化了,即仅能在当前的这个类中访问到它。

public则是公有,也就是当前的变量在类外类内都可以被访问,以上面的Movespeed为例,保存代码后,我们也可以在Unity编辑器界面看到它。

  • GetComponent,既然每个组件变成了类,那么借助GetComponeent,将模板参数设置成相同类型即可得到当前代码挂载物体上的刚体组件,也就是以函数的方式获取了当前挂载物件上的组件对象我们在Start函数中写入这个代码
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }

 获得键盘输入

 实现移动,需要和键盘的输入进行联动,联动用的方法是调用Input类里面的函数GetAxis

Input.GetAxis

public static float GetAxis (string axisName); 

返回由 axisName 标识的虚拟轴的值,这个值的类型是一个float(浮点型)

axisName:对应绑定的键位的输入字符串名称

GetAxis的具体解释比较难懂,不过简单来说就是获得对应字符串绑定的键位输入,比如以左右移动为例,左右移动,我们习惯使用AD两个按键进行控制,那么对应这两个按键的字符串名字我们可以在Edit->Input Manager 中找到Hrizontal,这个就是我们想要的对应字符串名称

 为了实现移动,我们新建一个函数称为Movement,前文也提过,GetAxis的返回值是一个float类型的值,那么我们也定义一个float来存储它的返回值。

注意!字符串内的对应名称一定一定要与Input Manager的名称相同!不然这个函数会调用失败!也就是我们Horizontal一定要打对!

 void Movement()
    {
        
        float InputSpeedX = Input.GetAxis("Horizontal");
    }
  • 那么借助这个函数,我们成功获得了键盘输入的值,拿到了当前输入的速度之后,使用成员函数对当前对象的位置进行位移。
  • 使用刚体类中的成员变量velocity即刚体的线性速度,即可控制刚体的左右移动
  • 官方的API手册中,给予了操控velocity值的方法,将一个new出来的vector2类型的变量进行赋值
  • 官方的使用范例如下:Rigidbody-velocity - Unity 脚本 API

  •  vector2 是一个类,使用new创建一个Vector2对象,Vector2对象的初始化是传入两个浮点类型的变量。一个是x,一个是y,那么前面设置的两个float变量即可在这里使用达到控制效果,单纯的实现水平移动,不需要获得Y值
 rb.velocity = new Vector2(InputSpeedX * Movespeed, rb.velocity.y);

 调用函数

那么我们的movement函数的大概样式如下

    void Movement()
    {
        float InputSpeedX = Input.GetAxisRaw("Horizontal");
        rb.velocity = new Vector2(InputSpeedX * Movespeed, rb.velocity.y);
    }

为了能让GetAxis无时无刻的检测键盘上的输入,我们需要借助一个函数来调用它 FixedUpdate

 FixedUpdate

实现了移动函数需要不断的调用,使用Update函数也可以,但是不稳定,由于不同的机器每秒中能生成的帧数并不是恒定的,每一帧调用一次函数会导致一些问题从而使得Update不稳定

而FixedUpdate  每个固定帧率帧调用该函数,调用之间的默认时间为 0.02 秒(50 次调用/秒 


    private void FixedUpdate()
    {
        Movement();
    }

 那么将Movespeed设置为5,保存我们的代码返回Unity,启动游戏,我们的人物就可以移动了!

 但是手感还是怪怪的,平滑的移动感觉让人很不舒服,当然如果你喜欢可以保留,不过我就不用了,如果你也不喜欢,可以将GetAxis换成GetAxisRaw,这样就不是平滑移动了。

整体代码如下:

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

public class PlayerControler : MonoBehaviour
{

    private Rigidbody2D rb;
    public float Movespeed;
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }
    void Update()
    {  
    }
    private void FixedUpdate()
    {
        Movement();
    }
    void Movement()
    {

        float InputSpeedX = Input.GetAxisRaw("Horizontal");

        rb.velocity = new Vector2(InputSpeedX * Movespeed, rb.velocity.y);

    }

}

怎么样?是不是很简单?当然,我们还没有实现上下移动的方法,不过相信如上的过程实现上下移动对于你肯定不是问题!这里就留个小挑战!希望你能实现出来!

当然你也可能是一位代码苦手,所以我这边还是写在下面了!不要偷看哦!

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

public class PlayerControler : MonoBehaviour
{

    private Rigidbody2D rb;
    public float Movespeed;
    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }
    void Update()
    {  
    }
    private void FixedUpdate()
    {
        Movement();
    }
    void Movement()
    {

        float InputSpeedX = Input.GetAxisRaw("Horizontal");
        float InputSpeedY = Input.GetAxis("Vertical");

        rb.velocity = new Vector2(InputSpeedX * Movespeed, rb.velocity.y);
        rb.velocity = new Vector2(rb.velocity.x,InputSpeedY * Movespeed);

    }

}

第二种方法实现移动

那么实现移动的方法也不止使用刚体组件内部的velocity,我们还可以通过控制刚体组件的Positon来实现人物的移动控制。

不同于我们分别控制组件的X,Y轴的值,我们可以声明一个Vector2类型的变量来控制。Vector2内部有两个成员变量,一个X,一个Y,那么同理,Vector3里面就有X,Y,Z

 Vector2 movement;

 那么我们就使用movement这个对象内部的X,Y来分别接受键盘输入的信息

 movement.x = Input.GetAxisRaw("Horizontal");
 movement.y=  Input.GetAxisRaw("Vertical");

然后我们使用刚体组件的函数MovePositon来实现

那么这个函数需要传入的是一个Vector2类型的值,那么我们将当前组件的Positon 加上 获得输入的Vector2类型的movement乘上设置好的速度值以及每秒钟的时间(位移=速度*时间)而因为我们在FixedUpdate中调用这个函数,那么时间也应该是FixedDeltaTime

rb.MovePosition(rb.position + movement * Movespeed*Time.fixedDeltaTime);

这种方法也同样能实现移动,也是不错的方法。


那么到这就结束了!接下来就是接入帧动画!让我们的游戏人物变得更加生动!希望对你有点帮助!感谢阅读!

猜你喜欢

转载自blog.csdn.net/m0_53607711/article/details/129485116