UE4学习-添加机关并添加代码控制

    技术2022-07-11  99

    文章目录

    添加机关代码编写给密室添加屋顶打印日志控制系统角色创建一个新游戏模式替换DefaultPawn添加抓取组件获取起点和终点物体拾取,碰撞属性设置今日完整代码

    添加机关

    首先向场景里面添加一个聚光源

    添加聚光源以后,可以对其属性进行修改,如图: 然后需要给聚光源添加一个触发体积(TriggerVolume)。 然后调整触发体积的大小,按空格进行切换模式,移动旋转缩放

    代码编写

    所有引入的头文件都需要放在 #include “openDoor.generated.h” 之前。 定义ATriggerVolume的指针,添加UPROPERTY(EditAnywhere),这样表示可以在任意地方赋值。 所以可以在界面上进行赋值。

    #include <Engine/TriggerVolume.h> UPROPERTY(EditAnywhere) ATriggerVolume* trigger;

    赋值如图: 选中门,然后选中自定义的组件openDoor

    编译完成,会添加Trigger

    然后选中TriggerVolume即可。

    划重点: pawn = GetWorld()->GetFirstPlayerController()->GetPawn(); // 得到defaultPawn

    这句代码不能放到构造函数里面,否则编译会造成虚幻的崩溃。

    给密室添加屋顶

    这里使用玻璃作为屋顶。 添加玻璃,然后使用缩放工具进行调整,盖满整个房间即可。

    打印日志

    UE4里面日志,使用UE_LOG,第一个参数默认是LogTemp,第二个参数是日志类型,警告是Warning,字符串使用TEXT() 括起来。 UE_LOG(LogTemp, Warning, TEXT("%s begin openDoor()"), *owner->GetName());

    控制系统角色

    运行,然后F8弹出,能看到一个DefaultPawn,这个是系统默认角色。

    创建一个新游戏模式替换DefaultPawn

    创建以后,指定pawn为刚才创建的对象。 运行,F8,pawn就是我们自定义的pawn了。

    添加抓取组件

    获取起点和终点

    FVector start; FRotator viewRot; GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(start, viewRot); FVector end = start + viewRot.Vector() * 100; // 100cm DrawDebugLine(GetWorld(), start, end, FColor(255, 0, 0), false, 0.0f, 0, 10.0f);

    物体拾取,碰撞属性设置

    在检查碰撞的时候,只检测ECollisionChannel::ECC_PhysicsBody类别的物体。

    设置物体属性:

    今日完整代码

    openDoor.h

    // Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "Components/ActorComponent.h" #include "openDoor.generated.h" class AActor; class ATriggerVolume; UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) ) class MYPROJECT_API UopenDoor : public UActorComponent { GENERATED_BODY() public: // Sets default values for this component's properties UopenDoor(); protected: // Called when the game starts virtual void BeginPlay() override; public: // Called every frame virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; void openDoor(); void closeDoor(); private: AActor* owner; AActor* pawn; UPROPERTY(EditAnywhere) ATriggerVolume* trigger; float openTime = 0.4f; float lastTime = 0.0f; };

    openDoor.cpp

    // Fill out your copyright notice in the Description page of Project Settings. #include "openDoor.h" #include <GameFramework/Actor.h> #include <Engine/TriggerVolume.h> #include <Engine/World.h> // Sets default values for this component's properties UopenDoor::UopenDoor() { // Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features // off to improve performance if you don't need them. PrimaryComponentTick.bCanEverTick = true; } // Called when the game starts void UopenDoor::BeginPlay() { Super::BeginPlay(); /* openDoor();*/ owner = GetOwner(); pawn = GetWorld()->GetFirstPlayerController()->GetPawn(); // 得到defaultPawn UE_LOG(LogTemp, Warning, TEXT("%s begin openDoor()"), *owner->GetName()); } // Called every frame void UopenDoor::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); if (nullptr != trigger && trigger->IsOverlappingActor(pawn)) { openDoor(); lastTime = GetWorld()->GetTimeSeconds(); } if (GetWorld()->GetTimeSeconds() - lastTime > openTime) { closeDoor(); } } void UopenDoor::openDoor() { // pitch=y yaw=z roll=x /* FRotator newRotator = FRotator(0, 0, 0);*/ FRotator newRotator = FRotator(0, 180, 0); owner->SetActorRotation(newRotator); } void UopenDoor::closeDoor() { // pitch=y yaw=z roll=x FRotator newRotator = FRotator(0, 90, 0); owner->SetActorRotation(newRotator); }

    grabber.h

    // Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "Components/ActorComponent.h" #include "grabber.generated.h" UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) ) class MYPROJECT_API Ugrabber : public UActorComponent { GENERATED_BODY() public: // Sets default values for this component's properties Ugrabber(); protected: // Called when the game starts virtual void BeginPlay() override; public: // Called every frame virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; private: FVector getLineStart(); FVector getLineEnd(); AActor* lineTrace(); };

    grabber.cpp

    // Fill out your copyright notice in the Description page of Project Settings. #include "grabber.h" #include <Engine/World.h> #include <DrawDebugHelpers.h> // Sets default values for this component's properties Ugrabber::Ugrabber() { // Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features // off to improve performance if you don't need them. PrimaryComponentTick.bCanEverTick = true; // ... } // Called when the game starts void Ugrabber::BeginPlay() { Super::BeginPlay(); // ... } // Called every frame void Ugrabber::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); } FVector Ugrabber::getLineStart() { // 设置起点和终点,画射线 FVector start; FRotator viewRot; GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(start, viewRot); return start; } FVector Ugrabber::getLineEnd() { FVector start; FRotator viewRot; GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(start, viewRot); return start + viewRot.Vector() * 100; // 100cm } AActor* Ugrabber::lineTrace() { // 检查碰撞 FHitResult hit; GetWorld()->LineTraceSingleByObjectType(hit, getLineStart(), getLineEnd(), FCollisionObjectQueryParams(ECollisionChannel::ECC_PhysicsBody), FCollisionQueryParams(FName(TEXT(""), false, GetOwner())); AActor * act = hit.GetActor(); if (nullptr != act) { UE_LOG(LogTemp, Warning, TEXT(line hit : % s), *act->GetName()); } return act; }
    Processed: 0.011, SQL: 9