shift 跟随移动
alt 复制移动
end 落地
shift 跟随移动
alt 复制移动
end 落地
在 内容浏览器 窗口下
新建文件夹 和 导入资源
点击即可预览声音
在SM_Door_Blueprint 时间轴 添加事件轨迹
Play Sound at Location 播放音乐在某个位置
GetActorLocation 获取当前物体的位置:
Play Music只会在 事件关键帧 调用
// 总结
//所有#inclde 的头文件需要在 #include "XXXXX.generated.h"的上方
//使用 AActor* 需要使用的头文件是:GameFramework/Actor.h
//使用 ATriggerVolume* 需要引入的头文件是:Engine/TriggerVolume.h
//使用 GetWorld() 需要引入的头文件是:Engine/World.h
//使用 DrawDebugLine(GetWorld(),Start,End,FColor(255,0,0),false,0,0,10); 需要引入的头文件是:DrawDebugHelpers.h
//使用 UInputComponent* 需要引入的头文件是:Components/InputComponent.h
//使用 UPhysicsHandleComponent* 需要引入的头文件:PhysicsEngine/PhysicsHandleComponent.h
//使用 UPrimitiveComponent* 需要引入的头文件按是:Components/PrimitiveComponent.h
//通过拖拽实现的字段,需要添加 UPROPERTY(EditAnyWhere) 标识
//通过蓝图可以监听到事件,需要添加 UPROPERTY(BlueprintAssignable) 标识
// 添加事件
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FDoorEvent);
// 打印输出日志
UE_LOG(LogTemp,Warning,TEXT("Hello World!"));
UE_LOG(LogTemp,Waring,TEXT("Hello %s am in OpenDoor!"), *Owner->GetName());
UE_LOG(LogTemp,Warning,TEXT("Total Mass is %f!"),TotalMass);
蓝图:
SetActorRotation
Make Rotator
按住 Ctrl 可以移动线
X(Roll)
Y(Pitch)
Z(Yaw)
代码里面是:pitch,yaw,roll 的顺序
Reverse 回播,动画倒着播放
小bug:DefaultPawn和其他物体发生碰撞,导致DefaultPawn不受控制的移动旋转
勾选DefaultPawn_Blueprint 下的 Physics 下的 约束 锁定旋转X Y Z 勾选
需要选中 CollisionComponent(继承)下找
void UOpenDoor1::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
//if (TriggerVolume != nullptr && TriggerVolume->IsOverlappingActor(DefaultPawn))
if (TriggerVolume && GetTotalMassInTrigger() > 25)
{
OnOpen.Broadcast();
}
else
{
OnClose.Broadcast();
}
}
在SM_Door的蓝图
添加上OnClose()
添加时间轴
中间的白线,表示,从OnOpen函数执行到 时间轴_0
双击时间轴,可以编辑时间轴:
添加浮点型轨迹(float类型的时间轴)
添加向量型轨迹(Vector类型的时间轴)
添加事件轨迹:
添加颜色轨迹:
0-90度 的变化,可以添加浮点型轨迹
更改时间轴名称为:Angle
在第0帧,添加关键帧,右键0.00,0.00位置,添加关键帧到CurveFloat_0
添加后,多了一个黄色的菱形小点
时间从 0 开始,修改成 0
再添加关键帧,时间为1,值为90
点击这2个,使得界面融合
滚动滚轮,可以放大缩小时间轴的显示范围:
长度(时间的长度)改为:1.00
添加完了时间轴的曲线后,在事件图表上多了Angle和Test的显示
白线是流程,其他的线是数值
中间为什么会有这个东西,因为Angle是float 类型,Print String是 String类型,把float转换成string,自动完成的
单独删除某个线,按住 Alt 键,点击线即可删除
删除中间的转换图标,选中后,可以用BackSpace或者Delete
蓝图移动:
按住鼠标右键拖动,
滚动滑轮,放大缩小
做动画效果,使用蓝图/代码
蓝图实现简单
使得自身进入机关,也触发开门效果
Simulate Physics
MassInKg
蓝图---转换选择的Actor为蓝图类:
转换成蓝图类后,世界大纲视图中的名字也变了,加上了_Blueprint
编辑蓝图类:
①:双击内容浏览器中的蓝图类(SM_Door_Blueprint)
②:在世界大纲视图中的文件后面,点击编辑 SM_Door_Blueprint
蓝图下的窗口:
视口(Viewport) 用于观看模型是怎么样子的
事件图表 (Event Graph)
事件图表(Event Graph)下,可以按住鼠标左键框选,右键对应的图标删除,
改成蓝图类后,上面的属性就会丢失掉:
比如下图中Trigger Volume ,需要拖拽的引用
在C++代码里面定义事件,蓝图也可以监听到
需要开门的时候,去触发事件,蓝图可以监听到事件,然后做一些事情
OpenDoor.h 头文件中
// DECLARE声明,DYNAMIC动态,MULTICAST多个,DELEGATE委托 (C# delegate 委托,Event 事件)
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FDoorEvent); // 事件加F,需要加“;”号
UPROPERTY(BlueprintAssignable) // 使用这个“注释”,可以使得下面2个在蓝图可以识别到
FDoorEvent OnOpen;
FDoorEvent OnClose;
代码定义好了,蓝图 添加事件才会有对于的OnOpen
添加了,事件就在我的蓝图窗口---图表显示了,OnOpen(OpenDoor)
取消添加,再添加引用,解决没有问题的报错
箭头可以拖出来
Print String 打印字符串
C++代码触发,蓝图监听
蓝图也要编译和保存
蓝图也可以播放
//OpenDoor.h 文件
// DECLARE声明,DYNAMIC动态,MULTICAST多个,DELEGATE委托 (C# delegate 委托,Event 事件)
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FDoorEvent); // 事件加F,需要加“;”号
public:
UOpenDoor();
UPROPERTY(BlueprintAssignable) // 使用这个“注释”,可以使得下面2个在蓝图可以识别到,蓝图可编辑的意思
FDoorEvent OnOpen;
UPROPERTY(BlueprintAssignable)
FDoorEvent OnClose;
// UOpenDoor.cpp 文件
void UOpenDoor::OpenDoor()
{
// 得到所在的Actor 设置这个Actor的属性
// pitch=y yaw=z roll=x
FRotator NewRotator = FRotator(0, 90, 0);
Owner->SetActorRotation(NewRotator);
OnOpen.Broadcast(); // C++触发这个事件,蓝图监听事件
}
设置椅子和桌子的质量
细节面板上的Physics---MassInKg打勾并设置质量
报错是因为没有引入 UPrimitiveComponent 所需要的头文件
#include "Components/PrimitiveComponent.h"
TotalMass += Actor->FindComponentByClass<UPrimitiveComponent>()->GetMass();
UE_LOG(LogTemp, Warning, TEXT("Total Mass is %f!"), TotalMass);// 加 * 号是取指针的数据,%f 对于小数类型,直接写小数就行,和C语言printf()一样
为什么显示还是质量0,因为没有勾选上 Generate Overlap Events
检测方式要一致:代码:TriggerVolume->GetOverlappingActors(OUT Actors) 与 Generater Overlap Events 对应
主角没有重力,勾选上 Simulate Physics
Physics---Simulate Physics,勾选上就会有重力的效果
#include "Components/PrimitiveComponent.h"
void UOpenDoor1::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
//if (TriggerVolume != nullptr && TriggerVolume->IsOverlappingActor(DefaultPawn))
if (TriggerVolume && GetTotalMassInTrigger() > 25)
{
OpenDoor();
LastDoorOpenTime = GetWorld()->GetTimeSeconds();
}
if (GetWorld()->GetTimeSeconds() - LastDoorOpenTime > DoorOpenDuration)
{
CloseDoor();
}
}
float UOpenDoor1::GetTotalMassInTrigger()
{
TArray<AActor*> Actors;
if (TriggerVolume == nullptr)
return 0.0f;
TriggerVolume->GetOverlappingActors(OUT Actors);// OUT 在语法上没有任何影响,方便阅读代码的
float TotalMass = 0;
for (AActor* Actor : Actors)// for(const auto& Actor : Actors)
{
TotalMass += Actor->FindComponentByClass<UPrimitiveComponent>()->GetMass();
}
UE_LOG(LogTemp, Warning, TEXT("Total Mass is %f!"), TotalMass);// 加 * 号是取指针的数据,%f 对于小数类型,直接写小数就行,和C语言printf()一样
return TotalMass;
}
一直抓取着,在TickComponent中
// Called every frame
void UGrabber::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if (PhysicsHandle&&PhysicsHandle->GrabbedComponent)
{
PhysicsHandle->SetTargetLocation(GetLineEnd());
}
}
void UGrabber::Grab()
{
UE_LOG(LogTemp, Warning, TEXT("Grab action is pressed!"));
FHitResult Hit = LineTrace();
UPrimitiveComponent* ComponentToGrab = Hit.GetComponent();
if (Hit.GetActor() && PhysicsHandle)
{
UE_LOG(LogTemp, Warning, TEXT("Grab!"));
//PhysicsHandle->GrabComponent(ComponentToGrab, NAME_None, ComponentToGrab->GetOwner()->GetActorLocation(), true);
PhysicsHandle->GrabComponentAtLocationWithRotation(ComponentToGrab, NAME_None, ComponentToGrab->GetOwner()->GetActorLocation(), GetOwner()->GetActorRotation());
}
}
void UGrabber::Release()
{
UE_LOG(LogTemp, Error, TEXT("Grab action is released!"));
if (PhysicsHandle)
{
PhysicsHandle->ReleaseComponent();
}
}
给 DefaultPawn_Blueprint 添加组件 Phusics Handle
(对蓝图做的修改都要保存和编译)添加完组件后,需要 Save 和 编译
使用Physics Handle 需要引入的头文件 #include "PhysicsEngine/PhysicsHandleComponent.h"
不知道用头文件,使用谷歌搜索一下,看官方的文档里面找
使用 UPhysicsHandleComponent* ,需要引入头文件 #include "PhysicsEngine/PhysicsHandleComponent.h"
没有引入组件导致的报错:
引入#include "Components/PrimitiveComponent.h"
使用UPrimitiveComponent* 需要引入 #include "Components/PrimitiveComponent.h"
没有抓起来,Actor是 可移动的
// Grabber.h
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "Components/InputComponent.h"
#include "PhysicsEngine/PhysicsHandleComponent.h"
#include "Grabber.generated.h"
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class UNREALENGINEPROJECT_API UGrabber : public UActorComponent
{
GENERATED_BODY()
public:
UGrabber();
protected:
virtual void BeginPlay() override;
public:
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
private:
FVector GetLineStart();
FVector GetLineEnd();
FHitResult LineTrace();
UInputComponent* InputComponent = nullptr;
UPhysicsHandleComponent* PhysicsHandle = nullptr;
void Grab();
void Release();
};
// Grabber.cpp
#include "Grabber.h"
#include "Engine/World.h"
#include "DrawDebugHelpers.h"
#include "Components/PrimitiveComponent.h"
UGrabber::UGrabber()
{
PrimaryComponentTick.bCanEverTick = true;
}
void UGrabber::BeginPlay()
{
Super::BeginPlay();
PhysicsHandle = GetOwner()->FindComponentByClass<UPhysicsHandleComponent>();
InputComponent = GetOwner()->FindComponentByClass<UInputComponent>();
if (InputComponent)// 使用指针需要判断不为空
{
UE_LOG(LogTemp, Warning, TEXT("Input Component is founded!"));
InputComponent->BindAction("Grab", IE_Pressed, this, &UGrabber::Grab);
InputComponent->BindAction("Grab", IE_Released, this, &UGrabber::Release);
}
else
{
UE_LOG(LogTemp, Error, TEXT("Input Component is not founded!"));
}
}
void UGrabber::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
}
FVector UGrabber::GetLineStart()
{
FVector Start;
FRotator ViewRotator;
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(Start, ViewRotator);
return Start;
}
FVector UGrabber::GetLineEnd()
{
FVector Start;
FRotator ViewRotator;
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(Start, ViewRotator);
return (Start + ViewRotator.Vector() * 100); // ViewRotator.Vector() 视野的正中心 前方 100cm
}
FHitResult UGrabber::LineTrace()
{
//DrawDebugLine(GetWorld(), Start, End, FColor(255, 0, 0), false, 0, 0, 10);
FHitResult Hit;
GetWorld()->LineTraceSingleByObjectType(
Hit,
GetLineStart(),
GetLineEnd(),
FCollisionObjectQueryParams(ECollisionChannel::ECC_PhysicsBody),
FCollisionQueryParams(FName(TEXT("")), false, GetOwner())
);
AActor* Actor = Hit.GetActor();
if (Actor != nullptr)
{
UE_LOG(LogTemp, Warning, TEXT("Line Hit:%s"), *Actor->GetName());
}
return Hit;
}
void UGrabber::Grab()
{
UE_LOG(LogTemp, Warning, TEXT("Grab action is pressed!"));
FHitResult Hit = LineTrace();
UPrimitiveComponent* ComponentToGrab = Hit.GetComponent();
if (Hit.GetActor() && PhysicsHandle)
{
UE_LOG(LogTemp, Warning, TEXT("Grab!"));
//PhysicsHandle->GrabComponent(ComponentToGrab, NAME_None, ComponentToGrab->GetOwner()->GetActorLocation(), true); // 已弃用
PhysicsHandle->GrabComponentAtLocation(ComponentToGrab, NAME_None, ComponentToGrab->GetOwner()->GetActorLocation());
}
}
void UGrabber::Release()
{
UE_LOG(LogTemp, Error, TEXT("Grab action is released!"));
}
编辑---项目设置---引擎--输入
Bindings
Action Mappings(某个键的按下)
Axis Mappings(某个轴的按下)
2个大步骤:
(1)在编辑---项目设置---引擎--输入-Bindings-Action Mappings(某个键的按下),添加事件再添加需要触发的按键
(2)写代码
添加上以后,运行场景系统在DefaultPawn_Blueprint的细节面板上有PawnInputComponent(继承):
#include "Components/InputComponent.h"
#include "Grabber.generated.h" // 引入的头文件需要再这个头文件的前面
UInputComponent* InputComponent = nullptr;
使用 UInputComponent* 需要引入 #include "Components/InputComponent.h"
// Grabber.h
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "Components/InputComponent.h"
#include "Grabber.generated.h"
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class UNREALENGINEPROJECT_API UGrabber : public UActorComponent
{
GENERATED_BODY()
public:
UGrabber();
protected:
virtual void BeginPlay() override;
public:
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
private:
FVector GetLineStart();
FVector GetLineEnd();
AActor* LineTrace();
UInputComponent* InputComponent = nullptr;
void Grab();
void Release();
};
// Grabber.cpp
#include "Grabber.h"
#include "Engine/World.h"
#include "DrawDebugHelpers.h"
UGrabber::UGrabber()
{
PrimaryComponentTick.bCanEverTick = true;
}
void UGrabber::BeginPlay()
{
Super::BeginPlay();
InputComponent = GetOwner()->FindComponentByClass<UInputComponent>();
if (InputComponent)// 使用指针需要判断不为空
{
UE_LOG(LogTemp, Warning, TEXT("Input Component is founded!"));
InputComponent->BindAction("Grab", IE_Pressed, this, &UGrabber::Grab);
InputComponent->BindAction("Grab", IE_Released, this, &UGrabber::Release);
}
else
{
UE_LOG(LogTemp, Error, TEXT("Input Component is not founded!"));
}
}
void UGrabber::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
}
FVector UGrabber::GetLineStart()
{
FVector Start;
FRotator ViewRotator;
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(Start, ViewRotator);
return Start;
}
FVector UGrabber::GetLineEnd()
{
FVector Start;
FRotator ViewRotator;
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(Start, ViewRotator);
return (Start + ViewRotator.Vector() * 100); // ViewRotator.Vector() 视野的正中心 前方 100cm
}
AActor * UGrabber::LineTrace()
{
//DrawDebugLine(GetWorld(), Start, End, FColor(255, 0, 0), false, 0, 0, 10);
FHitResult Hit;
GetWorld()->LineTraceSingleByObjectType(
Hit,
GetLineStart(),
GetLineEnd(),
FCollisionObjectQueryParams(ECollisionChannel::ECC_PhysicsBody),
FCollisionQueryParams(FName(TEXT("")), false, GetOwner())
);
AActor* Actor = Hit.GetActor();
if (Actor != nullptr)
{
UE_LOG(LogTemp, Warning, TEXT("Line Hit:%s"), *Actor->GetName());
}
return Actor;
}
void UGrabber::Grab()
{
UE_LOG(LogTemp, Warning, TEXT("Grab action is pressed!"));
}
void UGrabber::Release()
{
UE_LOG(LogTemp, Error, TEXT("Grab action is released!"));
}
if(Actor != nullptr)
和
if(Actor)
效果一样
指针、对象 也好,都可以这样判断不为空执行if语句
#include "Grabber.h"
#include "Engine/World.h"
#include "DrawDebugHelpers.h"
UGrabber::UGrabber()
{
PrimaryComponentTick.bCanEverTick = true;
}
void UGrabber::BeginPlay()
{
Super::BeginPlay();
}
void UGrabber::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
}
FVector UGrabber::GetLineStart()
{
FVector Start;
FRotator ViewRotator;
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(Start, ViewRotator);
return Start;
}
FVector UGrabber::GetLineEnd()
{
FVector Start;
FRotator ViewRotator;
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(Start, ViewRotator);
return (Start + ViewRotator.Vector() * 100); // ViewRotator.Vector() 视野的正中心 前方 100cm
}
AActor * UGrabber::LineTrace()
{
//DrawDebugLine(GetWorld(), Start, End, FColor(255, 0, 0), false, 0, 0, 10);
FHitResult Hit;
GetWorld()->LineTraceSingleByObjectType(
Hit,
GetLineStart(),
GetLineEnd(),
FCollisionObjectQueryParams(ECollisionChannel::ECC_PhysicsBody),
FCollisionQueryParams(FName(TEXT("")), false, GetOwner())
);
AActor* Actor = Hit.GetActor();
if (Actor != nullptr)
{
UE_LOG(LogTemp, Warning, TEXT("Line Hit:%s"), *Actor->GetName());
}
return Actor;//Actor 可能为空,需要校验
}
射线检测:有起点有方向有距离
ECC_PhysicsBody 物理物体
细节面板上的 Physics ,勾选 Simulate Physics 才会触发碰撞,
射线触发一定要勾选上 细节面板上的Physics下的 Simulate Physics 才会触发
Grabber.cpp
#include "Grabber.h"
#include "Engine/World.h"
#include "DrawDebugHelpers.h"
UGrabber::UGrabber()
{
PrimaryComponentTick.bCanEverTick = true;
}
void UGrabber::BeginPlay()
{
Super::BeginPlay();
}
void UGrabber::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
FVector Start;
FRotator ViewRotator;
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(Start, ViewRotator);
FVector End = Start + ViewRotator.Vector() * 100; // ViewRotator.Vector() 视野的正中心 前方 100cm
//DrawDebugLine(GetWorld(), Start, End, FColor(255, 0, 0), false, 0, 0, 10);
FHitResult Hit;
GetWorld()->LineTraceSingleByObjectType(
Hit,
Start,
End,
FCollisionObjectQueryParams(ECollisionChannel::ECC_PhysicsBody),
FCollisionQueryParams(FName(TEXT("")), false, GetOwner())
);
AActor* Actor = Hit.GetActor();
if (Actor != nullptr)
{
UE_LOG(LogTemp, Warning, TEXT("Line Hit:%s"), *Actor->GetName());
}
}
添加抓取功能:
在DefaultPawn_Blueprint文件中:
添加组件---新建C++组件...
第二步,选择Actor Component :
第三步,名称改称为Grabber,抓取器:
创建类
Unreal Engine 4 中的坐标/向量 FVector
FVector Start;
获取PlayerController()
#include "Engine/World.h"
GetWorld()->GetFirstPlayerController()
PlayerController : 控制Player的移动的
使用DrawDebugLine
需要引用 #include "DrawDebugHelpers.h"
DrawDebugLine(GetWorld(), Start, End, FColor(255, 0, 0), false, 0, 0, 10);
API
void DrawDebugLine()
{
const UWorld * InWorld,
FVector const & LineStart,
FVector const & LineEnd,
FColor const & Color,
bool bPersistentLines;
float LifeTime,
uint8 DepthPriority,
float Thickness
}
编译没看到线,先保存一下蓝图类DefaultPawn_Blueprint !!!
#include "Grabber.h"
#include "Engine/World.h"
#include "DrawDebugHelpers.h"
UGrabber::UGrabber()
{
PrimaryComponentTick.bCanEverTick = true;
}
void UGrabber::BeginPlay()
{
Super::BeginPlay();
}
void UGrabber::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
FVector Start;
FRotator ViewRotator;
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(Start, ViewRotator);
FVector End = Start + ViewRotator.Vector()*100; // ViewRotator.Vector() 视野的正中心 前方 100cm
DrawDebugLine(GetWorld(), Start, End, FColor(255, 0, 0), false, 0, 0, 10);
}
选中物体后,
工具栏---蓝图---转换选择的Actor为蓝图类
Toolbar
Blueprints---Convert Selected Actor to Blueprint Class
创建的DefaultPawn_Blueprint
编辑---项目设置---地图和模式
Edit---Project Settings---Maps & Modes
Create New Blueprints
选择我们自定义的DefaultPawn_Blueprint
内容浏览器下有NewGameMode
// 日志输出:临时日志,警告级别,文字,%s,替换,加 * 表示取得数据
UE_LOG(LogTemp, Warning, TEXT("Hello %s am in OpenDoor! "), *Owner->GetName());
// GetName() 取得是ID名称
输出日志 窗口:
窗口---开发者工具---输出日志
使用指针前,需要判断指针不能为空,否则容易崩溃
TriggerVolume != nullptr
指针:
指针!=nullptr
private:
AActor* Owner;
UPROPERTY(EditAnyWhere)
ATriggerVolume* TriggerVolume;
AActor* DefaultPawn;
float DoorOpenDuration = 0.5f;
float LastDoorOpenTime = 0;
void UOpenDoor1::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if (TriggerVolume != nullptr && TriggerVolume->IsOverlappingActor(DefaultPawn))
{
OpenDoor();
LastDoorOpenTime = GetWorld()->GetTimeSeconds();
}
if (GetWorld()->GetTimeSeconds() - LastDoorOpenTime > DoorOpenDuration)
{
CloseDoor();
}
}
运行时:
白色:本来存在的
黄色:运行时候生成的
DefaultPawn 默认创建的角色
Shift + F1 鼠标脱离场景
F8 弹出:同玩家控制器分离,允许正常的编辑器控制
每次修改完代码要编译一下
使用GetWorld()需要引入库:#include “Engine/World.h”
使用ATriggerVolume需要引入库:#include "Engine/TriggerVolume.h"
这三个文件夹不能删除:Config、Content、Source
这些文件夹及文件都能删除:.vs、Binaries、Intermediate、Saved、UnrealEngineProject.sln
重新打开,需要重新生成,点“是”
Content、Source不能删除
属性的初始化放在BeginPlay()
Actor的相关的,都是A开头的
AAcotr*
ATriggerVolume*
所有的引入的,需要放在generated.h的上方
由于这个报错:
所以添加引用:
通过拖拽的方法实现:
需要加入UPROPERTY(EditAnyWhere)
锁定 图标的用处,便于拖拽
光照---聚光灯
Lights---Spot Light
Light:
Inner Core Angle
Outer Cone Angle
体积--Trigger Volume
Volumes---Trigger Volume:
LIGHTING NEEDS TO BE REBUILT(1 unbuilt object)
Build---Build Light Only
构建---仅构建光照