}
// 左右转向
void AMyPlayer::LookYaw(float val) {
AddControllerYawInput(val); }
// 上下转向
void AMyPlayer::LookPitch(float val) {
// 注意方向相反
AddControllerPitchInput(val); }
// 按 E 键与激活对象进行交互 void AMyPlayer::Use() {
AInteractableActor* Interactable = FindFocusedActor(); if (Interactable) {
// OnInteract_Implementation Interactable->OnInteract(this); } }
AInteractableActor* AMyPlayer::FindFocusedActor() {
if (!Controller) {
return nullptr; }
FVector Location; FRotator Rotation;
FHitResult Hit(ForceInit);
Controller->GetPlayerViewPoint(Location, Rotation);
FVector Start = Location;
FVector End = Start + (Rotation.Vector() * InteractionDistance);
// 通过 “射线拾取” 选定对象
GetWorld()->LineTraceSingleByChannel(Hit, Start, End, ECC_Camera, TraceParams); if (Hit.bBlockingHit) // 击中
{
// 获取当前被击中的对象的引用
AInteractableActor* MyCastActor = Cast(Hit.GetActor()); if (MyCastActor) {
return MyCastActor; } }
return nullptr; }
void AMyPlayer::HandleHighlight() {
AInteractableActor* NewHighlight = FindFocusedActor(); if (NewHighlight) {
// 如果当前描边和新激活的对象不是同一个 if (FocusedActor != NewHighlight) {
if (FocusedActor) {
// 当前描边对象取消描边 FocusedActor->OnEndFocus(); }
// 描边新激活对象
NewHighlight->OnBeginFocus(); FocusedActor = NewHighlight; } } else {
if (FocusedActor) {
// 取消描边
FocusedActor->OnEndFocus(); FocusedActor = nullptr; } } }
InteractableActor.h
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include \ #include \
#include \
UCLASS()
class OUTLINECPLUSPLUS_API AInteractableActor : public AActor {
GENERATED_BODY() public:
// Sets default values for this actor's properties AInteractableActor();
// Called when the game starts or when spawned virtual void BeginPlay() override;
// Called every frame
virtual void Tick( float DeltaSeconds ) override;
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = Interaction) void OnInteract(AActor* Caller) ;
virtual void OnInteract_Implementation(AActor* Caller);
void OnBeginFocus(); void OnEndFocus();
private:
UPROPERTY(EditDefaultsOnly)
uint32 bCawww.whfengjun.comnInteract : 1; TArray
EStencilColor Color = EStencilColor::SC_Green; };
InteractableActor.cpp
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片
// Fill out your copyright notice in the Description page of Project Settings.
#include \
#include \
// Sets default values
AInteractableActor::AInteractableActor() {
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't nwww.edu800.cneed it.
PrimaryActorTick.bCanEverTick = true; }
// Called when the game starts or when spawned void AInteractableActor::BeginPlay() {
Super::BeginPlay();
for (UActorComponent* Mesh : GetComponentsByClass(UMeshComponent::StaticClass())) {
UMeshComponent* thisMesh = Cast
Meshes.Push(thisMesh); } } }
// Called every frame
void AInteractableActor::Tick( float DeltaTime ) {
Super::Tick( DeltaTime ); }
void AInteractableActor::OnInteract_Implementation(AActor* Caller) {
AMyPlayer* Player = Cast(Caller);
if (Player) {
GEngine->AddOnScreenDebugMessage(-1, 5.f,
FColor::Red,
FString::Printf(TEXT(\ \ );
// 销毁自己 Destroy(); } }
void AInteractableActor::OnBeginFocus() {
if (bCanInteract) {
for (UMeshComponent* Mesh : Meshes) {
Mesh->SetRenderCustomDepth(true);
Mesh->SetCustomDepthStencilValue((uint8)Color); } } }
void AInteractableActor::OnEndFocus() {
if (bCanInteract) {
for (UMeshComponent* Mesh : Meshes) {
Mesh->SetRenderCustomDepth(false); } } }
颜色 的 Enum
[cpp] view plain copy 在CODE上查看代码片派生到我的代码片 UENUM(BlueprintType)
enum class EStencilColor : uint8 {
SC_Green = 250 UMETA(DisplayName = \ SC_Blue = 251 UMETA(DisplayName = \ SC_Red = 252 UMETA(DisplayName = \ SC_White = 253 UMETA(DisplayName = \ };