第三十章 Unity角色控制器 Character Controller

news2024/11/16 13:00:35

在我们之前的章节中,我们已经了解了碰撞体和刚体。但是,对于刚体这个组件来讲,有两种使用方式。其一就是用它来模拟现实世界的移动或碰撞效果(例如,门的开关);其二就是使用代码来控制物体移动或碰撞(例如,角色的行走)。两种方式使用场景不同而已。

本章节要讲的角色控制器 Character Controller也是一个组件,它用来控制游戏对象的运行。需要注意的是,该组件具有碰撞特性(胶囊碰撞体),而没有刚体特性(不接受刚体的运动控制)。如果我们使用一个具有刚体组件的游戏对象A去碰撞具有角色控制器的游戏对象B的时候,我们的游戏对象B并不会因为碰撞而运动。角色控制器组件提供了Move和SimpleMove等方法进行移动控制。

接下来,我们就来创建一个“SampleScene6.unity”场景,向其中添加一个球体和胶囊体。

其中球体我们添加球体碰撞体组件和刚体组件,以及一个X轴正方向的力

然后就是我们的胶囊体,添加一个CharacterController组件。这里,我们需要注意的是,默认情况下,我们添加的胶囊体会自带“Capsule Collider”碰撞体组件,我们取消它即可。

然后我们Play运行我们整个工程,如下所示: 

我们发现,当球体碰撞到胶囊体的时候,两者都停止了运行,并且没有穿透模型。这说明我们的角色控制器组件具备碰撞体特性,但不具备刚体特性(如果具有刚体属性的话,它应该受到碰撞影响,向右边移动)。即使我们加上刚体,也不会有刚体特性的。角色控制器是专门用来控制角色移动的组件,区别于直接用Transform或者刚体,CharacterController有着更好的效果。接下来,我们就来简单介绍这个组件。

Slope Limit:坡度限制,设置角色可以走上的最大斜坡角度值(以度为单位)。

Step Offset:台阶高度,设置角色可以迈上的最大台阶高度值。

Skin width:皮肤厚度,决定两个碰撞体碰撞后相互渗透的程度。较大的皮肤宽度可减少抖动。较小的皮肤宽度可能导致角色卡住。合理设置是将此值设为半径的 10%。

Min Move Distance:最小移动距离,设置角色对象最小移动值。

Center:设置胶囊碰撞体在世界坐标中的位置。

Radius:设置胶囊碰撞体的横截面半径。

Height:设置胶囊碰撞体的高度。

前四个参数主要解决移动中遇到障碍时候的设置;后面三个参数则是设置碰撞形状的设置。CharacterController为我们提供了两种移动方法:Move 和 SimpleMove,两者都需要一个Vector3类型的参数。首先我们先试一试Move方法。我们取消Sphere游戏对象,增加一个平面来充当斜坡,如下所示:

 

接下来,我们创建一个“CharacterMove.cs”脚本来控制胶囊体移动。想到移动,大家肯定会联想到Translate方法,这个方法是我们之前学的,就是用来移动的。我们先使用它进行移动操作,代码如下:

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

public class CharacterMove : MonoBehaviour
{
    // 移动速度
    private float speed = 10.0f;

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

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKey(KeyCode.A))
        {
            transform.Translate(Vector3.left * speed * Time.deltaTime);
        }
        if (Input.GetKey(KeyCode.D))
        {
            transform.Translate(Vector3.right * speed * Time.deltaTime);
        }
    }
}

上面的代码非常简单,就是按下“A”和“D”键的时候,让胶囊体左右移动。

我们发现,胶囊体确实可以移动,但是它穿过了斜坡,并没有爬上斜坡。接下来,我们就是用CharacterController的Move方法来试试,代码修改如下:

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

public class CharacterMove : MonoBehaviour
{
    // 移动速度
    private float speed = 10.0f;

    // 角色控制器组件
    private CharacterController controller;

    // Start is called before the first frame update
    void Start()
    {
        controller = GetComponent<CharacterController>();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKey(KeyCode.A))
        {
            //transform.Translate(Vector3.left * speed * Time.deltaTime);
            controller.Move(Vector3.left * speed * Time.deltaTime);
        }
        if (Input.GetKey(KeyCode.D))
        {
            //transform.Translate(Vector3.right * speed * Time.deltaTime);
            controller.Move(Vector3.right * speed * Time.deltaTime);
        }
    }
}

然后我们重新Play运行工程,如下:

 

我们发现,胶囊体可以顺利爬上斜坡,但是往回移动的时候,就会停留在空中继续移动。也就是说,Move方法并没有考虑重力的效果。那么SimpleMove方法呢?

        if (Input.GetKey(KeyCode.A))
        {
            //transform.Translate(Vector3.left * speed * Time.deltaTime);
            //controller.Move(Vector3.left * speed * Time.deltaTime);
            controller.SimpleMove(Vector3.left * speed);
        }
        if (Input.GetKey(KeyCode.D))
        {
            //transform.Translate(Vector3.right * speed * Time.deltaTime);
            //controller.Move(Vector3.right * speed * Time.deltaTime);
            controller.SimpleMove(Vector3.right * speed);
        }

请注意,SimpleMove方法的不需要Time.deltaTime时间了,简化了我们的代码书写。接下来,我们重新Play当前工程,效果如下:

这次我们发现,这次在进行移动的时候,就会受到重力的影响了。通过对比,我们可以很清楚的知道Translate,Move和SimpleMove三者的区别了。毫无疑问,我们肯定最终选择SimpleMove方法,它提供了碰撞检测以及重力效果。

另外,CharacterController由于没有直接的碰撞组件和刚体组件,因此OnCollisionXXX和OnTriggerXXX方法就不能使用了,但角色控制器专门提供了OnControllerColliderHit方法。接下来,我们就试试这个方法,它的参数为ControllerColliderHit对象,该对象有诸如gameObject,collider,rigidbody,controller等属性可以使用。

    void OnControllerColliderHit(ControllerColliderHit hit)
    {
        Debug.Log("碰撞物体为:" + hit.gameObject.name);
    }

增加以上代码后,重新运行当前工程。

请注意,“Plane”是我们的地面,而“Plane(1)”是我们的斜坡。由于碰撞检测非常快,会输出大量的Log信息,因此我们可以点击“Collapse”将重复内容折叠显示。另外,角色控制器Character controller 为我们提供了一个isGrounded属性,我们可以再脚本章通过该属性判断当前角色是否碰撞到地面。

接下来,我们总结刚体,碰撞体以及角色控制器三者的使用场景。

首先,刚体多用于场景中的“道具物体”,他们的运动通过Unity的物理系统来控制,我们要做的的就是使用代码给这些“道具物体”施加一个力即可,Rigidbody的AddForce()方法。

接下来就是碰撞体,它定义了游戏对象的“轮廓外形”,碰撞检测就是根据这个“轮廓外形”进行计算的。几乎场景中所有需要交互的游戏对象都需要碰撞体,即便是场景中“静止”的游戏物体,为了不发生“穿模”现象,我们也需要增加碰撞体(例如场景中的花草树木,建筑物等等)。碰撞体一般联合刚体一起使用,场景中能够“运动”的游戏对象,一般都会同时添加碰撞体和刚体。如果想让Unity的物理系统来控制“运动物体”的移动,就按照刚体默认属性即可(例如我们上面说的“道具物体”)。如果想要使用代码来控制“运动物体”的移动,则需要勾选刚体的Is Kinematic属性。两者的区别还体现在OnCollisionEnter 和 OnTriggerEnter 方法上面。另外,刚体的Is Kinematic属性还可以通过脚本来控制,从而可以在物理系统和脚本代码两者之间切换控制。

最后是角色控制器,多用于游戏中的“角色”,因为游戏角色要进行大量的交互控制,它的移动和旋转相对来说,比较复杂。他们的运动要么是玩家控制,要么是脚本控制,所以一般不需要由物理系统来控制。这个时候,我们使用CharacterController组件来控制“角色”就非常方便了。CharacterController组件的本质是“胶囊碰撞体”+“移动代码封装”,它没有刚体特性,不会受到力的作用效果,也不会产生力的作用效果。请注意,使用了CharacterController组件就不需要使用刚体和碰撞体了,也不要使用Translate()来移动了,要用它自己提供的SimpleMove ()方法来移动物体。如果需要使用CharacterController进行碰撞检测的话,使用它的OnControllerColliderHit即可。

本课程涉及的内容已经共享到百度网盘:https://pan.baidu.com/s/1e1jClK3MnN66GlxBmqoJWA?pwd=b2id

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/487231.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【网络进阶】HTTP服务器(一)

文章目录 1. HTTP简介2. HTTP工作原理3. HTTP注意事项4. HTTP消息结构5. 客户端请求消息6. 服务器响应消息7. GET传递数据实例8. HTTP请求方法9. HTTP响应头信息 1. HTTP简介 HTTP&#xff08;超文本传输协议&#xff0c;Hypertext Transfer Protocol&#xff09;是一种用于传…

Spring Cloud的五大组件你知道多少

前言 Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发&#xff0c;如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等&#xff0c;都可以用Spring Boot的开发风格做到一键启动和部署。 Spring Clo…

瑞萨e2studio(25)----电容触摸配置(2)

瑞萨e2studio.24--电容触摸配置1 概述初始配置监控检测电容按键显示和测量标准差显示多个触摸按键曲线 概述 篇文档将在上篇文章基础上修改电容触摸配置。 初始配置 需要进入Debug模式才可以进行电容触摸配置。 监控检测电容按键 从电容触摸主界面&#xff08;QE&#xf…

解决Xshell安装时错误代码-1603的问题

安装流程 官网下载&#xff1a;家庭/学校免费 - NetSarang Website 填写姓名&#xff0c;邮箱&#xff0c;申请下载&#xff0c;就能在邮箱收到下载链接 点击链接即可自动开始下载&#xff1b; 下载完成后进行安装即可 问题描述 安装进行到最后一步时&#xff0c;出现下图…

CCED2000后,中文编程软件再次脱颖而出,系出金山

WPS抗衡微软&#xff0c;CCEDE却被淹没&#xff1f; DOS代&#xff0c;我们用WPS来进行文字编辑&#xff0c;CCED来做表格&#xff0c;两者在那个时代可以称得上是国产办公领域的“必装软件”。 如今&#xff0c;30年过去了&#xff0c;WPS一步一步成长为抗衡微软office的国产…

4d毫米波雷达聚类检测和追踪

待整理和写代码&#xff0c;准备先用dbcan聚类&#xff0c;用激光那一套做做看看效果 流程 4D雷达毫米波聚类跟踪流程如下图&#xff1a; 预处理主要包括标定、坐标转换和动静分离。 标定使用水平仪、角反&#xff0c;采集数据分析&#xff0c;得到水平和俯仰偏角。 坐标转…

nssctf web (3)

[HUBUCTF 2022 新生赛]checkin <?php show_source(__FILE__); #将当前文件的代码显示到页面 $username "this_is_secret"; #给username赋值 $password "this_is_not_known_to_you"; #给password赋值 include("flag.php");//here I ch…

MySQL数据管理

一、MySQL数据库管理 1、库和表 行&#xff08;记录&#xff09;&#xff1a;用来描述一个对象的信息 列&#xff08;字段&#xff09;&#xff1a;用来描述对象的一个属性 2、常用的数据类型 int &#xff1a;整型 float &#xff1a;单精度浮点 4字节32位 double &…

《网络安全审查办法》

1发展历程 2020年4月27日&#xff0c;12部门联合发布《网络安全审查办法》&#xff0c;2020年6月1日起实施。 2021年7月10日&#xff0c;国家互联网信息办公室发布关于《网络安全审查办法&#xff08;修订草案征求意见稿&#xff09;》公开征求意见的通知。11月16日国家互联网信…

【C++入门】你知道为什么C++有函数重载而C语言没有函数重载吗?

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;C航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1…

《最强Android书 架构大剖析》读书笔记

文章目录 第一章 Android 体系结构的变革之路1.2 Android系统源码目录与Linux的异同Android的框架原生二进制可执行文件Android 的原生库核心(core)库用以支持框架的库硬件抽象层Linux内核不带上层 UI界面的Android 第二章 Android 的分区和文件系统2.1 分区架构实验:从设备中获…

ffmpeg学习日记513-源码-configure_filtergraph()函数分析及功能

Date: 12/04/2023 Hours: Details:template_tags 文章目录 源码版本实现文件函数原型参数释义函数功能函数分析filtergraph_is_simple函数 总结参考 源码版本 ffmpeg-4.1.10 实现文件 fftools/ffmpeg_filter.c 函数原型 int configure_filtergraph(FilterGraph *fg)参数释…

重识三只松鼠:“二次创业”的新变革,“深蹲起跳”的新动能

“羚羊明白它必须跑得比狮子快&#xff0c;不然它会被狮子吃掉&#xff1b;每天早晨狮子醒来&#xff0c;狮子也明白它必须赛过跑得最慢的羚羊&#xff0c;不然它会活活饿死。不论你是狮子还是羚羊&#xff0c;都不重要……重要的是每天旭日东升&#xff0c;你就得开始奔跑&…

突破经典网格特征?AutoFocusFormer: Image Segmentation off the Grid 论文阅读笔记

突破经典网格特征&#xff1f;AutoFocusFormer: Image Segmentation off the Grid 论文阅读笔记 一、Abstract二、引言三、相关工作视觉 Transformer Backbones基于聚类的注意力自适应下采样点云网络 四、方法4.1 聚类和区域4.1.1 平衡聚类4.1.2 聚类的区域 写在前面 这一周赶上…

【五一创作】Visual Studio常用调试技巧的温习

当你在编写C程序时&#xff0c;难免会遇到代码出现错误的情况。这时候就需要用调试工具来定位问题并解决它。以下是一些在Visual Studio中使用调试器时常用的技巧&#xff0c;权当作温故总结罢~ 1. 断点 断点是调试中最为基本但也最常用的技巧之一。通过在需要定位的代码行上打…

一文搞懂 x64 IA-64 AMD64 Inte64 IA-32e 架构之间的关系

想要搞清楚 x64、IA64、AMD64 指令集之间的关系&#xff0c;就要先了解 Intel 和 AMD 这两家公司在生产处理器上的发展历史。 x86 处理器 1978年 Intel 生产了它的第一款 16bit 处理器8086&#xff0c;之后几款处理器名字也都以86结尾&#xff0c;包括80186&#xff0c;80286&a…

五一长假暴露了电动爹的真面目,而新能源汽车市场似乎也到了转折点

4月份国内市场汽车销量数据已经出炉&#xff0c;同比来说仍然保持了很高的增长&#xff0c;不过环比数据却显示出新能源汽车市场似乎已到了转折点&#xff0c;繁荣期似乎已经结束&#xff0c;淘汰赛开始了。 一、五一长假再次暴露了电动爹的真面目 新能源汽车长途旅行首先就是怕…

部署LVS-DR集群

引言 一、LVS-DR工作原理 LVS-DR&#xff08;Linux Virtual Server Director Server&#xff09;工作模式&#xff0c;是生产环境中最常用的一 种工作模式。 LVS-DR 模式&#xff0c;Director Server 作为群集的访问入口&#xff0c;不作为网关使用节点 Director Server 与 …

推荐算法实战项目:DeepFM 原理以及案例实战(附完整 Python 代码)

本文要介绍的是由哈尔滨工业大学联合华为发表论文《DeepFM: A Factorization-Machine based Neural Network for CTR Prediction》中提出的DeepFM模型。其实根据名字可以看出来&#xff0c;此模型包含Deep和FM两个部分。其中Deep部分就是普通的深度神经网络&#xff0c;FM是因子…

【图像处理】墨西哥小波和带通滤波

一、说明 在连续小波的家族当中&#xff0c;埃尔米特小波是个非常特别的存在&#xff08;应用在连续小波转换称作埃尔米特转换&#xff09;。Ricker子波计算电动力学的广谱源项。它通常只在美国才会被称作墨西哥帽小波&#xff0c;因为在作为核函数处理2维图像时&#xff0c;形…