IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【UE4 C++】实现自动门 -> 正文阅读

[C++知识库]【UE4 C++】实现自动门

前言

本文章将会教你用C++如何实现自动门。
我们任务踩到开关上面门就会升起来,我们离开门之后,两秒后门会降下来。

创建C++文件

右键创建C++文件,继承Actor类。

.h文件内容

<声明门和开关的静态网格体>
静态网格体在哪里都可以看到,并且在蓝图中可以读写。

UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
	class UStaticMeshComponent* FloorSwitch;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
	class UStaticMeshComponent* Door;

<声明触发开关的感应器>
盒子组件在哪里都可以看到,并且在蓝图中可以读写。

UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
		class UBoxComponent* TriggerBox;

<声明储存初始位置的变量>
有了门和开关的初始位置,之后确定门移动到什么位置就很好计算。

UPROPERTY(BlueprintReadWrite)
		FVector InitialDoorLocation; // 储存门的初始位置
UPROPERTY(BlueprintReadWrite) 
	FVector InitialSwitchLocation; // 储存开关的初始位置

<声明组件重合的触发反应的函数>
我们人物触碰到开关后做出的反应的实现就在这两个函数之中,一个是开始重叠的时候,一个是重叠结束的时候。

UFUNCTION()
		void OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,  UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

UFUNCTION()
	void OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

这个函数这样声明不是凭空得出来的,因为我们要和我们的开关组件联系起来,那么联系起来的函数是有规定的。

首先我们看如何将他们联系起来:

TriggerBox->OnComponentBeginOverlap.AddDynamic(this, &AAFloorSwitch::OnOverlapBegin);
TriggerBox->OnComponentEndOverlap.AddDynamic(this, &AAFloorSwitch::OnOverlapEnd);

他们之间的联系就需要用上面这个来搭建联系,
我们点进去查看他的实现:

UPROPERTY(BlueprintAssignable, Category="Collision")
	FComponentBeginOverlapSignature OnComponentBeginOverlap;

我们看到他前面有一段声明,应该是他的类型声明吧?
我们找到他:
DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_SixParams( FComponentBeginOverlapSignature, UPrimitiveComponent, OnComponentBeginOverlap, UPrimitiveComponent*, OverlappedComponent, AActor*, OtherActor, UPrimitiveComponent*, OtherComp, int32, OtherBodyIndex, bool, bFromSweep, const FHitResult &, SweepResult);
特别长,其实看不太懂,只知到这个函数的第一个和第三个对应着我们刚刚看到那个变量?,从第四个开始到后面的所有就是我们函数构建要填写的数据类型和名字,(数据类型和变量名之间的逗号要记得去掉。)
重叠结束函数也类似。

<声明存储时间变量>
FTimerHandle TimerHandle; 这里出现了一个新东西,FTimerHandle感觉就是储存对应时间的一个变量。

<声明离开之后关门时间变量>

UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float SwitchTime;

<声明关门函数>

UFUNCTION()
	void CloseDoor();

<声明门的开关操作实现函数>
这个函数和我们之前见到的不一样,因为他的属性标签是BlueprintImplementableEvent,这个的意思就是这个函数在C++中声明,蓝图中实现,待会我们会知道如何去实现这个函数。

UFUNCTION(BlueprintImplementableEvent) // 蓝图实现函数
	void RaiseDoor(); // 门上升函数

UFUNCTION(BlueprintImplementableEvent)
	void LowerDoor();// 门下降函数

UFUNCTION(BlueprintImplementableEvent)
	void RaiseFloorSwitch(); // 开关上升

UFUNCTION(BlueprintImplementableEvent)
	void LowerFloorSwitch(); // 开关下降

<声明更新函数>

UFUNCTION(BlueprintCallable)
	void UpdateDoorLocation(float Z);

UFUNCTION(BlueprintCallable)
	void UpdateSwitchLocation(float Z);

.cpp 文件实现

<构造函数>

  • TriggerBox的初始化

创建实例,并且设他为根组件

TriggerBox = CreateDefaultSubobject<UBoxComponent>(TEXT("TriggerBox"));
RootComponent = TriggerBox;

设置开关盒子的碰撞类型:

它有四种类型:
NoCollision 无碰撞
QueryOnly 仅响应踪迹碰撞,无物理碰撞
PhysicsOnly 仅响应物理碰撞,无踪迹碰撞
QueryAndPhysics 同时响应物理碰撞和踪迹碰撞

在因为我们是站在开关上面,需要他做出一些其他的反应,而不是阻挡,所以我们选第二种是最合适的。
TriggerBox->SetCollisionEnabled(ECollisionEnabled::QueryOnly);

接下来设置的就是下图所展示的部分,
设置当前Mesh的对象类型(用于区别场景的Mesh类型,以便进行不同的碰撞响应)。
TriggerBox->SetCollisionObjectType(ECollisionChannel::ECC_WorldStatic);

我们只需要对人物做出反应,其他的不用考虑,所以先将所有通道都设置为忽略状态,再单独设置响应pawn类的重叠。

TriggerBox->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);
TriggerBox->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Overlap); 

在这里插入图片描述
设置盒子的大小:TriggerBox->SetBoxExtent(FVector(64, 64, 32));

  • 门开关的初始化
    创建门开关的实例,附在根组件上。
FloorSwitch = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("FloorSwitch"));
FloorSwitch->SetupAttachment(RootComponent);
  • 门的初始化

创建门的实例,附在根组件上。

Door = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Door"));
Door->SetupAttachment(RootComponent);
  • 设置人离开开关后们停留的时间

SwitchTime = 2;

<BeginPlay()>
获得门和门开关的初始位置

InitialDoorLocation = Door->GetComponentLocation();
InitialSwitchLocation = FloorSwitch->GetComponentLocation();

将开关盒子与角色的重叠情况进行绑定

TriggerBox->OnComponentBeginOverlap.AddDynamic(this, &AAFloorSwitch::OnOverlapBegin);
TriggerBox->OnComponentEndOverlap.AddDynamic(this, &AAFloorSwitch::OnOverlapEnd);

<OnOverlapBegin自定义函数实现>
在开始重叠的时候,我们要把我们的时间手柄置为空,让门升起来,开关降下去。

GetWorldTimerManager().ClearTimer(TimerHandle);
RaiseDoor();
LowerFloorSwitch();

<OnOverlapEnd自定义函数实现>
GetWorldTimerManager().SetTimer(TimerHandle, this, &AAFloorSwitch::CloseDoor, SwitchTime);
设置时间,SwitchTime秒后执行关门操作。

<CloseDoor函数实现>
门降下去,开关升起来。

LowerDoor();
RaiseFloorSwitch();

<UpdateDoorLocation函数实现>
更新门的位置

FVector NewLocation = InitialDoorLocation;
NewLocation.Z += Z;
Door->SetWorldLocation(NewLocation);

<UpdateSwitchLocation更新门开关的位置>

FVector NewLocation = InitialSwitchLocation;
NewLocation.Z += Z;
FloorSwitch->SetWorldLocation(NewLocation);

创建蓝图

右键我们刚创建的C++类,创建蓝图。
给我们的组件挑选Mesh:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-28 00:10:58  更:2021-07-28 00:11:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/29 4:37:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码