当前位置: 首页 > news >正文

虚幻C++基础 day3

常见的游戏机制

Actor机关门

  • 创建一个Actor类,添加两个静态网格与一个触发器

    • UBoxComponent
    • UStaticMeshComponent
  • 头文件:

    • #include “Components/BoxComponent.h”
    • #include “Components/StaticMeshComponent.h”

TriggerDoor.h

// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "TriggerDoor.generated.h"UCLASS()
class UEGAME_API ATriggerDoor : public AActor
{GENERATED_BODY()public:	// Sets default values for this actor's propertiesATriggerDoor();UPROPERTY(VisibleAnywhere, BlueprintReadWrite)class UBoxComponent* TriggerBox;UPROPERTY(VisibleAnywhere, BlueprintReadWrite)class UStaticMeshComponent* TriggerMesh;UPROPERTY(VisibleAnywhere, BlueprintReadWrite)UStaticMeshComponent* DoorMesh;protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;public:	// Called every framevirtual void Tick(float DeltaTime) override;};

TriggerDoor.cpp

// Fill out your copyright notice in the Description page of Project Settings.#include "TriggerDoor.h"
#include "Components/BoxComponent.h"
#include "Components/StaticMeshComponent.h"
// Sets default values
ATriggerDoor::ATriggerDoor()
{// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.PrimaryActorTick.bCanEverTick = true;TriggerBox = CreateDefaultSubobject<UBoxComponent>(TEXT("TriggerBox"));RootComponent = TriggerBox;TriggerMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("TriggerMesh"));TriggerMesh->SetupAttachment(GetRootComponent());DoorMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DoorMesh"));DoorMesh->SetupAttachment(GetRootComponent());}// Called when the game starts or when spawned
void ATriggerDoor::BeginPlay()
{Super::BeginPlay();}// Called every frame
void ATriggerDoor::Tick(float DeltaTime)
{Super::Tick(DeltaTime);}

设置材质上去

  • 直接采用场景里面的材质附着上去即可
    在这里插入图片描述

编写位置更新函数

  • 修好好位置后点击这个就可以实例同步到蓝图中
    在这里插入图片描述
    在这里插入图片描述

蓝图中的时间轴函数(Timeline)与UE多播委托机制

多播委托

  • 触发器中提供了两个与一个绑定宏用来判断组件是否被重叠,这两个函数是要参与UE反射系统的,我们需要使用UFUNCTION进行标明,UFUNCTION里面可以什么参数不要,我们称这个操作为多播委托
    • OnComponentBeginOverlap:事件,当某些内容开始与此组件重叠时调用,例如玩家进入触发器。
    • OnComponentEndOverlap:事件,当组件停止重叠时调用
  • AddDynamic宏:这个宏需要传入一个绑定函数,绑定函数参数格式如下UE源码,因为UE是把参数与参数类型都当做参数了,所以我们需要把逗号删除,一般是从开头数字乘2,从参数最后面开始选择,例如:SixParams(...),也就是6*2=12个参数,从函数尾部开始复制12个参数,注意UE4.23之后的版本可能参数不一样
/*** Delegate for notification of blocking collision against a specific component.  * NormalImpulse will be filled in for physics-simulating bodies, but will be zero for swept-component blocking collisions. */
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FiveParams( FComponentHitSignature, UPrimitiveComponent*, HitComponent, AActor*, OtherActor, UPrimitiveComponent*, OtherComp, FVector, NormalImpulse, const FHitResult&, Hit );
/** Delegate for notification of start of overlap with a specific component */
DECLARE_DYNAMIC_MULTICAST_DELEGATE_SixParams( FComponentBeginOverlapSignature, UPrimitiveComponent*, OverlappedComponent, AActor*, OtherActor, UPrimitiveComponent*, OtherComp, int32, OtherBodyIndex, bool, bFromSweep, const FHitResult &, SweepResult);
/** Delegate for notification of end of overlap with a specific component */
DECLARE_DYNAMIC_MULTICAST_DELEGATE_FourParams( FComponentEndOverlapSignature, UPrimitiveComponent*, OverlappedComponent, AActor*, OtherActor, UPrimitiveComponent*, OtherComp, int32, OtherBodyIndex);
/** Delegate for notification when a wake event is fired by physics*/
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FComponentWakeSignature, UPrimitiveComponent*, WakingComponent, FName, BoneName);
/** Delegate for notification when a sleep event is fired by physics*/
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FComponentSleepSignature, UPrimitiveComponent*, SleepingComponent, FName, BoneName);
/** Delegate for notification when collision settings change. */
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FComponentCollisionSettingsChangedSignature, UPrimitiveComponent*, ChangedComponent);DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam( FComponentBeginCursorOverSignature, UPrimitiveComponent*, TouchedComponent );
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam( FComponentEndCursorOverSignature, UPrimitiveComponent*, TouchedComponent );
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams( FComponentOnClickedSignature, UPrimitiveComponent*, TouchedComponent , FKey, ButtonPressed);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams( FComponentOnReleasedSignature, UPrimitiveComponent*, TouchedComponent, FKey, ButtonReleased);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams( FComponentOnInputTouchBeginSignature, ETouchIndex::Type, FingerIndex, UPrimitiveComponent*, TouchedComponent );
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams( FComponentOnInputTouchEndSignature, ETouchIndex::Type, FingerIndex, UPrimitiveComponent*, TouchedComponent );
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams( FComponentBeginTouchOverSignature, ETouchIndex::Type, FingerIndex, UPrimitiveComponent*, TouchedComponent );
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams( FComponentEndTouchOverSignature, ETouchIndex::Type, FingerIndex, UPrimitiveComponent*, TouchedComponent );
  • 声明两个绑定函数
public:	// Called every framevirtual void Tick(float DeltaTime) override;//自定义AddDynamic绑定的触发器函数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);
};
  • 将多播委托进行绑定

// Called when the game starts or when spawned
void ATriggerDoor::BeginPlay()
{Super::BeginPlay();//绑定事件TriggerBox->OnComponentBeginOverlap.AddDynamic(this, &ATriggerDoor::OnOverlapBegin);TriggerBox->OnComponentEndOverlap.AddDynamic(this, &ATriggerDoor::OnOverlapEnd);
}// Called every frame
void ATriggerDoor::Tick(float DeltaTime)
{Super::Tick(DeltaTime);}void ATriggerDoor::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
}void ATriggerDoor::OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
}

指定触发器只响应Pawn

	//设置TriggerBox碰撞的硬编码TriggerBox->SetCollisionEnabled(ECollisionEnabled::QueryOnly);//设置碰撞类型TriggerBox->SetCollisionObjectType(ECollisionChannel::ECC_WorldStatic);//设置对象移动时其应视为某种物体TriggerBox->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);//设置所有的碰撞响应为忽略TriggerBox->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Overlap);//设置Pawn碰撞响应为重叠

TriggerDoor.h

// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "TriggerDoor.generated.h"UCLASS()
class UEGAME_API ATriggerDoor : public AActor
{GENERATED_BODY()public:	// Sets default values for this actor's propertiesATriggerDoor();UPROPERTY(VisibleAnywhere, BlueprintReadWrite)class UBoxComponent* TriggerBox;UPROPERTY(VisibleAnywhere, BlueprintReadWrite)class UStaticMeshComponent* TriggerMesh;UPROPERTY(VisibleAnywhere, BlueprintReadWrite)UStaticMeshComponent* DoorMesh;protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;public:	// Called every framevirtual void Tick(float DeltaTime) override;//自定义AddDynamic绑定的触发器函数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);
};

TriggerDoor.cpp

// Fill out your copyright notice in the Description page of Project Settings.#include "TriggerDoor.h"
#include "Components/BoxComponent.h"
#include "Components/StaticMeshComponent.h"
#include "Characters/Player/MainPlayer.h"
// Sets default values
ATriggerDoor::ATriggerDoor()
{// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.PrimaryActorTick.bCanEverTick = true;TriggerBox = CreateDefaultSubobject<UBoxComponent>(TEXT("TriggerBox"));RootComponent = TriggerBox;TriggerBox->SetBoxExtent(FVector(60.f, 60.f, 30.f));//设置TriggerBox碰撞的硬编码TriggerBox->SetCollisionEnabled(ECollisionEnabled::QueryOnly);//设置碰撞类型TriggerBox->SetCollisionObjectType(ECollisionChannel::ECC_WorldStatic);//设置对象移动时其应视为某种物体TriggerBox->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);//设置所有的碰撞响应为忽略TriggerBox->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Overlap);//设置Pawn碰撞响应为重叠TriggerMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("TriggerMesh"));TriggerMesh->SetupAttachment(GetRootComponent());DoorMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DoorMesh"));DoorMesh->SetupAttachment(GetRootComponent());}// Called when the game starts or when spawned
void ATriggerDoor::BeginPlay()
{Super::BeginPlay();TriggerBox->OnComponentBeginOverlap.AddDynamic(this, &ATriggerDoor::OnOverlapBegin);TriggerBox->OnComponentEndOverlap.AddDynamic(this, &ATriggerDoor::OnOverlapEnd);
}// Called every frame
void ATriggerDoor::Tick(float DeltaTime)
{Super::Tick(DeltaTime);}void ATriggerDoor::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{AMainPlayer* Player = Cast<AMainPlayer>(OtherActor);if (Player){}
}void ATriggerDoor::OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{AMainPlayer* Player = Cast<AMainPlayer>(OtherActor);if (Player){}
}

BlueprintImplementableEvent参数的使用

  • 新建几个函数用来升起降下门,关闭打开门
  • BlueprintImplementableEvent:会把函数变成一个事件,把函数提升为事件后,就不能去初始化函数了,因为这个是在蓝图调用的事件
    在这里插入图片描述
    在这里插入图片描述

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

编写更新函数在蓝图中使用

  • 新建两个用于更新的函数在蓝图中调用,新建两个变量用来获取当前门与触发器的offset,用于更新函数中去进行位置移动
//获取门与触发器位置
UPROPERTY(BluerprintReadWrite,Category = "Trigger Door|Trigger Properties")
FVector InitTriggerLoction;
UPROPERTY(BluerprintReadWrite,Category = "Trigger Door|Door Properties")
FVector InitDoorLocation;
UFUNCTION(BlueprintCallable,Category="Triggerable Door | Triggerable Switch")
void UpdateTriggerLocation(FVector offset);
UFUNCTION(BlueprintCallabel,Category= "Triggerable Door | Door Switch")
void UpdateDoorLocation(FVector offset);
  • 在BeginPlay中初始化门和触发器的位置
// Called when the game starts or when spawned
void ATriggerDoor::BeginPlay()
{Super::BeginPlay();TriggerBox->OnComponentBeginOverlap.AddDynamic(this, &ATriggerDoor::OnOverlapBegin);TriggerBox->OnComponentEndOverlap.AddDynamic(this, &ATriggerDoor::OnOverlapEnd);//获取到门和触发器的位置InitTriggerLoction = TriggerMesh->GetComponentLocation();InitDoorLocation = DoorMesh->GetComponentLocation();
}
  • 然后去更新函数中更新门与触发器的位置
void ATriggerDoor::UpdateTriggerLocation(FVector offset)
{//新位置=初始位置+移动后的位置FVector newLocation = InitTriggerLoction + offset;TriggerMesh->SetWorldLocation(newLocation);
}void ATriggerDoor::UpdateDoorLocation(FVector offset)
{//新位置=初始位置+移动后的位置FVector newLocation = InitDoorLocation + offset;DoorMesh->SetWorldLocation(newLocation);
}
  • 然后去蓝图中连接更新函数
    在这里插入图片描述

采用定时器关门

  • 采用定时器关门的两种思路:
    • 思路一:我们可以在人物踩上触发器的时候开启定时器进行关门,当人物离开定时器的时候就关闭定时器
    • 思路二:我们可以定义一个bool变量(默认为false)进行判断定时器是否开启,当人物踩上触发器的时候就让变量为true,当人物离开触发器的时候就为false也就不执行定时器
  • 定时器头文件:#include “TimerManager.h”
  • FTimerHandleCloseDoorTimerHandle: 创建一个时间句柄
  • SetTimer的六个重载函数
/*** Sets a timer to call the given native function at a set interval.  If a timer is already set* for this handle, it will replace the current timer.** @param InOutHandle			If the passed-in handle refers to an existing timer, it will be cleared before the new timer is added. A new handle to the new timer is returned in either case.* @param InObj					Object to call the timer function on.* @param InTimerMethod			Method to call when timer fires.* @param InRate				The amount of time between set and firing.  If <= 0.f, clears existing timers.* @param InbLoop				true to keep firing at Rate intervals, false to fire only once.* @param InFirstDelay			The time for the first iteration of a looping timer. If < 0.f inRate will be used.*/template< class UserClass >FORCEINLINE void SetTimer(FTimerHandle& InOutHandle, UserClass* InObj, typename FTimerDelegate::TUObjectMethodDelegate< UserClass >::FMethodPtr InTimerMethod, float InRate, bool InbLoop = false, float InFirstDelay = -1.f){InternalSetTimer(InOutHandle, FTimerUnifiedDelegate( FTimerDelegate::CreateUObject(InObj, InTimerMethod) ), InRate, InbLoop, InFirstDelay);}template< class UserClass >FORCEINLINE void SetTimer(FTimerHandle& InOutHandle, UserClass* InObj, typename FTimerDelegate::TUObjectMethodDelegate_Const< UserClass >::FMethodPtr InTimerMethod, float InRate, bool InbLoop = false, float InFirstDelay = -1.f){InternalSetTimer(InOutHandle, FTimerUnifiedDelegate( FTimerDelegate::CreateUObject(InObj, InTimerMethod) ), InRate, InbLoop, InFirstDelay);}/** Version that takes any generic delegate. */FORCEINLINE void SetTimer(FTimerHandle& InOutHandle, FTimerDelegate const& InDelegate, float InRate, bool InbLoop, float InFirstDelay = -1.f){InternalSetTimer(InOutHandle, FTimerUnifiedDelegate(InDelegate), InRate, InbLoop, InFirstDelay);}/** Version that takes a dynamic delegate (e.g. for UFunctions). */FORCEINLINE void SetTimer(FTimerHandle& InOutHandle, FTimerDynamicDelegate const& InDynDelegate, float InRate, bool InbLoop, float InFirstDelay = -1.f){InternalSetTimer(InOutHandle, FTimerUnifiedDelegate(InDynDelegate), InRate, InbLoop, InFirstDelay);}/*** Version that doesn't take a delegate */FORCEINLINE void SetTimer(FTimerHandle& InOutHandle, float InRate, bool InbLoop, float InFirstDelay = -1.f){InternalSetTimer(InOutHandle, FTimerUnifiedDelegate(), InRate, InbLoop, InFirstDelay);}/** Version that takes a TFunction */FORCEINLINE void SetTimer(FTimerHandle& InOutHandle, TFunction<void(void)>&& Callback, float InRate, bool InbLoop, float InFirstDelay = -1.f ){InternalSetTimer(InOutHandle, FTimerUnifiedDelegate(MoveTemp(Callback)), InRate, InbLoop, InFirstDelay);}

思路一

  • Trigger.h
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "TriggerDoor.generated.h"UCLASS()
class UEGAME_API ATriggerDoor : public AActor
{GENERATED_BODY()public:	// Sets default values for this actor's propertiesATriggerDoor();UPROPERTY(VisibleAnywhere, BlueprintReadWrite)class UBoxComponent* TriggerBox;UPROPERTY(VisibleAnywhere, BlueprintReadWrite)class UStaticMeshComponent* TriggerMesh;UPROPERTY(VisibleAnywhere, BlueprintReadWrite)UStaticMeshComponent* DoorMesh;//获取门与触发器位置UPROPERTY(BlueprintReadWrite,Category = "Trigger Door|Trigger Properties")FVector InitTriggerLoction;UPROPERTY(BlueprintReadWrite,Category = "Trigger Door|Door Properties")FVector InitDoorLocation;//延时时间UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Trigger Door|Trigger Properties")float DelayTimer;//创建一个时间句柄FTimerHandle CloseDoorTimerHandle;protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;public:	// Called every framevirtual void Tick(float DeltaTime) override;//自定义AddDynamic绑定的触发器函数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);//将函数提升为事件UFUNCTION(BlueprintImplementableEvent, Category = "Triggerable Dorr|Trigger Switch")void RaiseTrigger();UFUNCTION(BlueprintImplementableEvent, Category = "Triggerable Dorr|Trigger Switch")void LowerTrigger();UFUNCTION(BlueprintImplementableEvent, Category = "Triggerable Dorr|Trigger Switch")void OpenDoor();UFUNCTION(BlueprintImplementableEvent, Category = "Triggerable Dorr|Trigger Switch")void CloseDoor();UFUNCTION(BlueprintCallable,Category="Triggerable Door | Triggerable Switch")void UpdateTriggerLocation(FVector offset);UFUNCTION(BlueprintCallable,Category= "Triggerable Door | Door Switch")void UpdateDoorLocation(FVector offset);
};
  • Trigger.cpp
// Fill out your copyright notice in the Description page of Project Settings.#include "TriggerDoor.h"
#include "Components/BoxComponent.h"
#include "Components/StaticMeshComponent.h"
#include "Characters/Player/MainPlayer.h"
#include "TimerManager.h"// Sets default values
ATriggerDoor::ATriggerDoor()
{// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.PrimaryActorTick.bCanEverTick = true;TriggerBox = CreateDefaultSubobject<UBoxComponent>(TEXT("TriggerBox"));RootComponent = TriggerBox;TriggerBox->SetBoxExtent(FVector(60.f, 60.f, 30.f));//设置TriggerBox碰撞的硬编码TriggerBox->SetCollisionEnabled(ECollisionEnabled::QueryOnly);//设置碰撞类型TriggerBox->SetCollisionObjectType(ECollisionChannel::ECC_WorldStatic);//设置对象移动时其应视为某种物体TriggerBox->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);//设置所有的碰撞响应为忽略TriggerBox->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Overlap);//设置Pawn碰撞响应为重叠TriggerMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("TriggerMesh"));TriggerMesh->SetupAttachment(GetRootComponent());DoorMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DoorMesh"));DoorMesh->SetupAttachment(GetRootComponent());//延迟时间设为2秒DelayTimer = 2.0f;}// Called when the game starts or when spawned
void ATriggerDoor::BeginPlay()
{Super::BeginPlay();TriggerBox->OnComponentBeginOverlap.AddDynamic(this, &ATriggerDoor::OnOverlapBegin);TriggerBox->OnComponentEndOverlap.AddDynamic(this, &ATriggerDoor::OnOverlapEnd);//获取到门和触发器的位置InitTriggerLoction = TriggerMesh->GetComponentLocation();InitDoorLocation = DoorMesh->GetComponentLocation();
}// Called every frame
void ATriggerDoor::Tick(float DeltaTime)
{Super::Tick(DeltaTime);}void ATriggerDoor::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{AMainPlayer* Player = Cast<AMainPlayer>(OtherActor);if (Player){//清除定时器GetWorldTimerManager().ClearTimer(CloseDoorTimerHandle);OpenDoor();LowerTrigger();}
}void ATriggerDoor::OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{AMainPlayer* Player = Cast<AMainPlayer>(OtherActor);if (Player){RaiseTrigger();//开启定时器进行关门GetWorldTimerManager().SetTimer(CloseDoorTimerHandle, this, &ATriggerDoor::CloseDoor, DelayTimer);}
}void ATriggerDoor::UpdateTriggerLocation(FVector offset)
{//新位置=初始位置+移动后的位置FVector newLocation = InitTriggerLoction + offset;TriggerMesh->SetWorldLocation(newLocation);
}void ATriggerDoor::UpdateDoorLocation(FVector offset)
{//新位置=初始位置+移动后的位置FVector newLocation = InitDoorLocation + offset;DoorMesh->SetWorldLocation(newLocation);
}

思路二

  • 定义一个bool变量用来检测角色是否踩到触发器
  • 我们采用Lambda表示来进行操作,使用Lambda表达式操作,SetTimer函数传入参数会不一样
GetWorldTimerManager().SetTimer(CloseDoorTimerHandle, FTimerDelegate::CreateLambda(CloseDoorLambda), DelayTimer, false);

在这里插入图片描述

  • Trigger.h
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "TriggerDoor.generated.h"UCLASS()
class UEGAME_API ATriggerDoor : public AActor
{GENERATED_BODY()public:	// Sets default values for this actor's propertiesATriggerDoor();UPROPERTY(VisibleAnywhere, BlueprintReadWrite)class UBoxComponent* TriggerBox;UPROPERTY(VisibleAnywhere, BlueprintReadWrite)class UStaticMeshComponent* TriggerMesh;UPROPERTY(VisibleAnywhere, BlueprintReadWrite)UStaticMeshComponent* DoorMesh;//获取门与触发器位置UPROPERTY(BlueprintReadWrite,Category = "Trigger Door|Trigger Properties")FVector InitTriggerLoction;UPROPERTY(BlueprintReadWrite,Category = "Trigger Door|Door Properties")FVector InitDoorLocation;//延时时间UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Trigger Door|Trigger Properties")float DelayTimer;bool bIsPlayerOnTrigger;//创建一个时间句柄FTimerHandle CloseDoorTimerHandle;protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;public:	// Called every framevirtual void Tick(float DeltaTime) override;//自定义AddDynamic绑定的触发器函数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);//将函数提升为事件UFUNCTION(BlueprintImplementableEvent, Category = "Triggerable Dorr|Trigger Switch")void RaiseTrigger();UFUNCTION(BlueprintImplementableEvent, Category = "Triggerable Dorr|Trigger Switch")void LowerTrigger();UFUNCTION(BlueprintImplementableEvent, Category = "Triggerable Dorr|Trigger Switch")void OpenDoor();UFUNCTION(BlueprintImplementableEvent, Category = "Triggerable Dorr|Trigger Switch")void CloseDoor();UFUNCTION(BlueprintCallable,Category="Triggerable Door | Triggerable Switch")void UpdateTriggerLocation(FVector offset);UFUNCTION(BlueprintCallable,Category= "Triggerable Door | Door Switch")void UpdateDoorLocation(FVector offset);
};
  • Tirgger.cpp
// Fill out your copyright notice in the Description page of Project Settings.#include "TriggerDoor.h"
#include "Components/BoxComponent.h"
#include "Components/StaticMeshComponent.h"
#include "Characters/Player/MainPlayer.h"
#include "TimerManager.h"// Sets default values
ATriggerDoor::ATriggerDoor()
{// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.PrimaryActorTick.bCanEverTick = true;TriggerBox = CreateDefaultSubobject<UBoxComponent>(TEXT("TriggerBox"));RootComponent = TriggerBox;TriggerBox->SetBoxExtent(FVector(60.f, 60.f, 30.f));//设置TriggerBox碰撞的硬编码TriggerBox->SetCollisionEnabled(ECollisionEnabled::QueryOnly);//设置碰撞类型TriggerBox->SetCollisionObjectType(ECollisionChannel::ECC_WorldStatic);//设置对象移动时其应视为某种物体TriggerBox->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);//设置所有的碰撞响应为忽略TriggerBox->SetCollisionResponseToChannel(ECollisionChannel::ECC_Pawn, ECollisionResponse::ECR_Overlap);//设置Pawn碰撞响应为重叠TriggerMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("TriggerMesh"));TriggerMesh->SetupAttachment(GetRootComponent());DoorMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("DoorMesh"));DoorMesh->SetupAttachment(GetRootComponent());//延迟时间设为2秒DelayTimer = 2.0f;bIsPlayerOnTrigger = false;
}// Called when the game starts or when spawned
void ATriggerDoor::BeginPlay()
{Super::BeginPlay();TriggerBox->OnComponentBeginOverlap.AddDynamic(this, &ATriggerDoor::OnOverlapBegin);TriggerBox->OnComponentEndOverlap.AddDynamic(this, &ATriggerDoor::OnOverlapEnd);//获取到门和触发器的位置InitTriggerLoction = TriggerMesh->GetComponentLocation();InitDoorLocation = DoorMesh->GetComponentLocation();
}// Called every frame
void ATriggerDoor::Tick(float DeltaTime)
{Super::Tick(DeltaTime);}void ATriggerDoor::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{AMainPlayer* Player = Cast<AMainPlayer>(OtherActor);if (Player){//判断主角踩到触发器,就为真if (bIsPlayerOnTrigger == false){bIsPlayerOnTrigger = true;}OpenDoor();LowerTrigger();}
}void ATriggerDoor::OnOverlapEnd(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{AMainPlayer* Player = Cast<AMainPlayer>(OtherActor);//判断主角没踩到触发器,就为假if (bIsPlayerOnTrigger == true){bIsPlayerOnTrigger = false;}//Lambda表达式auto CloseDoorLambda = [this](){//主角没有踩到触发器就关门if (bIsPlayerOnTrigger == false){CloseDoor();}};if(Player){RaiseTrigger();//开启定时器进行关门GetWorldTimerManager().SetTimer(CloseDoorTimerHandle, FTimerDelegate::CreateLambda(CloseDoorLambda), DelayTimer, false);}
}void ATriggerDoor::UpdateTriggerLocation(FVector offset)
{//新位置=初始位置+移动后的位置FVector newLocation = InitTriggerLoction + offset;TriggerMesh->SetWorldLocation(newLocation);
}void ATriggerDoor::UpdateDoorLocation(FVector offset)
{//新位置=初始位置+移动后的位置FVector newLocation = InitDoorLocation + offset;DoorMesh->SetWorldLocation(newLocation);
}

Actor创建一个随机生成空间

  • 新建一个Actor类用来随机随机生成Actor,添加触发器与一个模版变量(专门用来存储AActor)
public:	// Sets default values for this actor's propertiesASpawnVolume();//触发器UPROPERTY(VisibleAnywhere, BlueprintReadOnly)class UBoxComponent* SpawnBox;//模版类,用来添加AActorUPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Spawn Volume")TArray<TSubclassOf<AActor>> SpawnClass;

获取Actor随机位置与随机种类

  • 新建两个函数用来获取种类与位置
  • 头文件#include “Kismet/KismetMathLibrary.h” 中会有很多数学函数
  • 例如:RandomPointInBoundingBox:随机点在边界框
public:	// Called every framevirtual void Tick(float DeltaTime) override;//获取随机位置UFUNCTION(BlueprintCallable, Category = "Spawn Volume")FVector GetSpawnRandomLocation();UFUNCTION(BlueprintCallable, Category = "Spawn Volume")TSubclassOf<AActor> GetSpawnClass();
};
FVector ASpawnVolume::GetSpawnRandomLocation()
{FVector OriginPoint = SpawnBox->GetComponentLocation();FVector Extent = SpawnBox->GetScaledBoxExtent();return UKismetMathLibrary::RandomPointInBoundingBox(OriginPoint,Extent);
}TSubclassOf<AActor> ASpawnVolume::GetSpawnClass()
{if (SpawnClass.Num() > 0){int index = FMath::RandRange(0, SpawnClass.Num() - 1);return SpawnClass[index];}else{return nullptr;}
}

随机生成区域与蓝图本地事件机制

  • BlueprintPure参数:可以把函数变成纯净函数没有执行线
  • BlueprintNativeEvent参数一般要与BlueprintCallable一起使用,在蓝图中声明的本地事件使用BlueprintNativeEvent关键词进行标记。它告诉Unreal Engine系统该事件可以在C++中进行实现,并且可以在蓝图中被重写或使用。一旦在蓝图中声明了本地事件,就可以在C++中编写实现该事件的代码。通过继承蓝图类的C++类,可以对该本地事件进行重写或添加额外的逻辑。这样,当在蓝图中调用该本地事件时,将执行C++中实现的代码逻辑。总之,BlueprintNativeEvent关键词允许在Unreal Engine蓝图中声明本地事件,并通过C++进行实现和扩展。这样的设计模式提供了蓝图和C++之间的灵活交互,允许开发人员在保持蓝图的简洁性和可视化优势的同时,利用C++的强大功能来实现高级逻辑和性能优化
  • 在C++中实现一个蓝图本地事件时,通常需要在函数名后添加_Implementation作为后缀。例如,如果在蓝图中声明了一个本地事件函数MyEvent,那么在C++中实现它的函数名将是MyEvent_Implementation。这是因为在Unreal Engine中,蓝图本地事件的实现通常是通过虚函数重写机制来完成的。当蓝图中调用本地事件时,底层引擎会查找与事件函数同名的_Implementation函数,然后执行该函数中的代码逻辑。使用_Implementation作为后缀是一种约定,用于将原始的虚函数和其实现函数进行区分。这样做可以保持函数名的一致性,并且使代码更易于理解和维护。另外,_Implementation函数是在C++类中实现蓝图本地事件的默认方法。你也可以在自定义C++类中以其他的名字实现蓝图本地事件,只需在蓝图中指定相应的函数即可。
    总结起来,为了实现蓝图本地事件函数,需要在函数名后添加_Implementation作为后缀。这是为了区分虚函数和其实现函数,并保持代码的一致性和清晰度
  • GetWorld()->SpawnActor<AActor>(SpawnClasses, SpawnLocation, FRotator(0.0f)):生成Actor在世界中
  • SpawnActor:函数源码
	/** Templated version of SpawnActor that allows you to specify a class type via the template type */template< class T >T* SpawnActor( const FActorSpawnParameters& SpawnParameters = FActorSpawnParameters() ){return CastChecked<T>(SpawnActor(T::StaticClass(), NULL, NULL, SpawnParameters),ECastCheckedType::NullAllowed);}/** Templated version of SpawnActor that allows you to specify location and rotation in addition to class type via the template type */template< class T >T* SpawnActor( FVector const& Location, FRotator const& Rotation, const FActorSpawnParameters& SpawnParameters = FActorSpawnParameters() ){return CastChecked<T>(SpawnActor(T::StaticClass(), &Location, &Rotation, SpawnParameters),ECastCheckedType::NullAllowed);}/** Templated version of SpawnActor that allows you to specify the class type via parameter while the return type is a parent class of that type */template< class T >T* SpawnActor( UClass* Class, const FActorSpawnParameters& SpawnParameters = FActorSpawnParameters() ){return CastChecked<T>(SpawnActor(Class, NULL, NULL, SpawnParameters),ECastCheckedType::NullAllowed);}/** *  Templated version of SpawnActor that allows you to specify the rotation and location in addition*  class type via parameter while the return type is a parent class of that type */template< class T >T* SpawnActor( UClass* Class, FVector const& Location, FRotator const& Rotation, const FActorSpawnParameters& SpawnParameters = FActorSpawnParameters() ){return CastChecked<T>(SpawnActor(Class, &Location, &Rotation, SpawnParameters),ECastCheckedType::NullAllowed);}/** *  Templated version of SpawnActor that allows you to specify whole Transform*  class type via parameter while the return type is a parent class of that type */template< class T >T* SpawnActor(UClass* Class, FTransform const& Transform,const FActorSpawnParameters& SpawnParameters = FActorSpawnParameters()){return CastChecked<T>(SpawnActor(Class, &Transform, SpawnParameters), ECastCheckedType::NullAllowed);}
SpawnVolume.h
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "SpawnVolume.generated.h"UCLASS()
class UEGAME_API ASpawnVolume : public AActor
{GENERATED_BODY()public:	// Sets default values for this actor's propertiesASpawnVolume();//触发器UPROPERTY(VisibleAnywhere, BlueprintReadOnly)class UBoxComponent* SpawnBox;//模版类,用来添加AActor的子类UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Spawn Volume")TArray<TSubclassOf<AActor>> SpawnClass;protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;public:	// Called every framevirtual void Tick(float DeltaTime) override;//获取随机位置UFUNCTION(BlueprintPure, Category = "Spawn Volume")FVector GetSpawnRandomLocation();UFUNCTION(BlueprintPure, Category = "Spawn Volume")TSubclassOf<AActor> GetSpawnClass();//蓝图本地事件机制UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Spawn Volue")void SpawnActor(UClass* SpawnClasses, FVector SpawnLocation);
};
SpawnVolume.cpp
// Fill out your copyright notice in the Description page of Project Settings.#include "SpawnVolume.h"
#include "Components/BoxComponent.h"
#include "Kismet/KismetMathLibrary.h"
// Sets default values
ASpawnVolume::ASpawnVolume()
{// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.PrimaryActorTick.bCanEverTick = true;SpawnBox = CreateDefaultSubobject<UBoxComponent>(TEXT("SpawnBox"));RootComponent = SpawnBox;}// Called when the game starts or when spawned
void ASpawnVolume::BeginPlay()
{Super::BeginPlay();}// Called every frame
void ASpawnVolume::Tick(float DeltaTime)
{Super::Tick(DeltaTime);}FVector ASpawnVolume::GetSpawnRandomLocation()
{FVector OriginPoint = SpawnBox->GetComponentLocation();FVector Extent = SpawnBox->GetScaledBoxExtent();return UKismetMathLibrary::RandomPointInBoundingBox(OriginPoint,Extent);
}TSubclassOf<AActor> ASpawnVolume::GetSpawnClass()
{if (SpawnClass.Num() > 0){int index = FMath::RandRange(0, SpawnClass.Num() - 1);return SpawnClass[index];}else{return 0;}
}
//生成Actor
void ASpawnVolume::SpawnActor_Implementation(UClass* SpawnClasses, FVector SpawnLocation)
{GetWorld()->SpawnActor<AActor>(SpawnClasses, SpawnLocation, FRotator(0.0f));
}
  • 蓝图中去调用写好的这个机制
    在这里插入图片描述
  • 运行结果
    在这里插入图片描述

Actor创建移动浮空平台

创建移动平台与EditWidget工具

  • 创建一个Actor类,这个Actor需要一个静态网格,两个变量(一个表示起点一个表示终点)
  • meta = (EditWidget = “true”):这是一个可选的元标记(Metadata),用于添加额外的属性信息。在这种情况下,MakeEditWidget 被设置为 “true”,这表示该属性可以在编辑器中作为一个小部件进行编辑。这通常用于自定义编辑器小部件以提供更直观的属性编辑体验。
public:	// Sets default values for this actor's propertiesAFloatingPlatform();UPROPERTY(VisibleAnywhere,BlueprintReadOnly)class UStaticMeshComponent* PlatformMesh;UPROPERTY(VisibleAnywhere, Category = "Floating Platform")FVector StartPoint{};UPROPERTY(EditAnywhere, Category = "Floating Platform", meta = (MakeEditWidget = "true"))FVector EndPoint{};
  • 运行结果
    在这里插入图片描述

使用VInterpTo进行插值

  • 新建一个变量PlatformSpeed用来设置上升速度
public:	// Sets default values for this actor's propertiesAFloatingPlatform();UPROPERTY(VisibleAnywhere,BlueprintReadOnly)class UStaticMeshComponent* PlatformMesh;UPROPERTY(VisibleAnywhere, Category = "Floating Platform")FVector StartPoint{};UPROPERTY(EditAnywhere, Category = "Floating Platform", meta = (MakeEditWidget = "true"))FVector EndPoint{};UPROPERTY(EditAnywhere, Category = "Floating Platform")float PlatformSpeed;
  • 使用VInterpTo进行移动
  • VInterpTo 源码
CORE_API FVector FMath::VInterpTo( const FVector& Current, const FVector& Target, float DeltaTime, float InterpSpeed )
{// If no interp speed, jump to target valueif( InterpSpeed <= 0.f ){return Target;}// Distance to reachconst FVector Dist = Target - Current;// If distance is too small, just set the desired locationif( Dist.SizeSquared() < KINDA_SMALL_NUMBER ){return Target;}// Delta Move, Clamp so we do not over shoot.const FVector	DeltaMove = Dist * FMath::Clamp<float>(DeltaTime * InterpSpeed, 0.f, 1.f);return Current + DeltaMove;
}
  • VInterpConstantTo:匀速运动源码
CORE_API FVector FMath::VInterpConstantTo(const FVector Current, const FVector& Target, float DeltaTime, float InterpSpeed)
{const FVector Delta = Target - Current;const float DeltaM = Delta.Size();const float MaxStep = InterpSpeed * DeltaTime;if( DeltaM > MaxStep ){if( MaxStep > 0.f ){const FVector DeltaN = Delta / DeltaM;return Current + DeltaN * MaxStep;}else{return Current;}}return Target;
}
  • FloatingPlatform.cpp
// Fill out your copyright notice in the Description page of Project Settings.#include "FloatingPlatform.h"
#include "Components/StaticMeshComponent.h"
// Sets default values
AFloatingPlatform::AFloatingPlatform()
{// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.PrimaryActorTick.bCanEverTick = true;PlatformMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Platform"));RootComponent = PlatformMesh;PlatformSpeed = 2.f;
}// Called when the game starts or when spawned
void AFloatingPlatform::BeginPlay()
{Super::BeginPlay();//获取Actor的世界位置StartPoint = GetActorLocation();EndPoint += StartPoint;
}// Called every frame
void AFloatingPlatform::Tick(float DeltaTime)
{Super::Tick(DeltaTime);FVector CurrentLocation = GetActorLocation();FVector NewLocation = FMath::VInterpTo(CurrentLocation, EndPoint, DeltaTime, PlatformSpeed);SetActorLocation(NewLocation);//移动到新位置
}

使用定时器进行平台来回移动

  • 新建一个bool变量bInterping用来判断是否要开启定时器,新建一个DelayTime用来规定延时时间几秒后开启定时器,新键一个用来记录当前位置的变量Distance
  • 思路:bInterping默认为true,Distance获取到移动到目标点的位置,在移动过程中,新建一个NewDistace获取当前世界位置减去开始位置的值,判断Distance要是减去NewDistance的值大于等于一个很小的值,就说明到最终位置了,此时的bInterping为false了,该开启定时器返回起点,2秒后定时器中函数表达式bInterping为真,互换起点与终点位置,又进行新一轮平台移动
FloatingPlatform.h
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "FloatingPlatform.generated.h"UCLASS()
class UEGAME_API AFloatingPlatform : public AActor
{GENERATED_BODY()public:	// Sets default values for this actor's propertiesAFloatingPlatform();UPROPERTY(VisibleAnywhere,BlueprintReadOnly)class UStaticMeshComponent* PlatformMesh;UPROPERTY(VisibleAnywhere, Category = "Floating Platform")FVector StartPoint{};UPROPERTY(EditAnywhere, Category = "Floating Platform", meta = (MakeEditWidget = "true"))FVector EndPoint{};UPROPERTY(EditAnywhere, Category = "Floating Platform")float PlatformSpeed;UPROPERTY(EditAnywhere, Category = "Floating Platform")float DelayTime;FTimerHandle InterpTimerHandle;bool bInterping;float Distance;
protected:// Called when the game starts or when spawnedvirtual void BeginPlay() override;public:	// Called every framevirtual void Tick(float DeltaTime) override;};
FloatingPlatform.cpp
// Fill out your copyright notice in the Description page of Project Settings.#include "FloatingPlatform.h"
#include "Components/StaticMeshComponent.h"
#include "TimerManager.h"
// Sets default values
AFloatingPlatform::AFloatingPlatform()
{// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.PrimaryActorTick.bCanEverTick = true;PlatformMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("PlatformMesh"));RootComponent = PlatformMesh;PlatformSpeed = 200.f;DelayTime = 2.0f;bInterping = true;
}// Called when the game starts or when spawned
void AFloatingPlatform::BeginPlay()
{Super::BeginPlay();//获取Actor的世界位置StartPoint = GetActorLocation();Distance = EndPoint.Size();EndPoint += StartPoint;}// Called every frame
void AFloatingPlatform::Tick(float DeltaTime)
{Super::Tick(DeltaTime);if (bInterping){FVector CurrentLocation = GetActorLocation();FVector NewLocation = FMath::VInterpConstantTo(CurrentLocation, EndPoint, DeltaTime, PlatformSpeed);SetActorLocation(NewLocation);//移动到新位置float NewDistance = (GetActorLocation() - StartPoint).Size();if (Distance - NewDistance <= 0.5f){bInterping = !bInterping;//Lambda表达式auto ToggleInterpState = [this](){bInterping = !bInterping;};//开启定时器GetWorldTimerManager().SetTimer(InterpTimerHandle, FTimerDelegate::CreateLambda(ToggleInterpState), DelayTime, false);//交换起点与终点FVector temp = StartPoint;StartPoint = EndPoint;EndPoint = temp;}}}
  • 运行结果
    请添加图片描述

相关文章:

虚幻C++基础 day3

常见的游戏机制 Actor机关门 创建一个Actor类&#xff0c;添加两个静态网格与一个触发器 UBoxComponentUStaticMeshComponent 头文件&#xff1a; #include “Components/BoxComponent.h”#include “Components/StaticMeshComponent.h” TriggerDoor.h // Fill out your …...

第26期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大型语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以…...

(动手学习深度学习)第7章 稠密连接网络---DenseNet

目录 DenseNetDenseNet的优点&#xff1a;DenseNet的改进思路总结 DenseNet代码实现 DenseNet DenseNet的优点&#xff1a; 省参数。在 ImageNet 分类数据集上达到同样的准确率&#xff0c;DenseNet 所需的参数量不到 ResNet 的一半。对于工业界而言&#xff0c;小模型可以显著…...

UART编程(寄存器)

1. 串口编程步骤 1.1 看原理图确定引脚 有很多串口&#xff0c;使用哪一个&#xff1f;看原理图确定 1.2 配置引脚为UART功能 至少用到发送、接收引脚&#xff1a;txd、rxd 需要把这些引脚配置为UART功能&#xff0c;并使能UART模块 1.3 设置串口参数 有哪些参数&#xf…...

事务码增删查改表数据

常用事务码 SE11 SE14 SE16 SE16N SM30 SE11:查看数据库表/修改表中字段数量_类型/查看表中数据/设置表为可维护或不可维护 SE14:查看数据库表的创建日期创建用户名/查看表中字段/删除表中全部数据(只能全部删) SE16:查看数据库表/对可维护数据库表进行数据维护/SE16通过调试…...

vue开发环境搭建部署(mac版)

前言 目前后端工作越来越少了&#xff0c;年底了&#xff0c;为了先过验收。项目负责人、产品、需求制定的方案就是先做假页面&#xff0c;所以前端的活多点。 其实现在不喜欢搞前端&#xff0c;原因很多&#xff0c;但是感觉现在似乎流行的码林绝学又是九九归一的瓶颈期…...

Java【算法 05】通过时间获取8位验证码(每两个小时生成一个)源码分享

通过时间获取验证码 1.需求2.代码实现2.1 依赖2.2 时间参数处理方法2.3 截取验证码方法2.4 验证方法 3.总结 1.需求 要求是很简单的&#xff0c;每个验证码的有效时间是2小时&#xff0c;这个并不是收到验证码开始计时的&#xff0c;而是每个两小时的时间段使用的是相同的验证…...

微服务 Spring Cloud 5,一图说透Spring Cloud微服务架构

目录 一、域名系统DNS二、LVS&#xff08;Linux Virtual Server&#xff09;,Linux虚拟服务器三、CDN静态资源四、Nginx反向代理服务器1、Nginx的主要作用体现在以下几个方面&#xff1a;2、Nginx静态资源服务和CDN静态资源服务&#xff0c;如何选择&#xff1f; 五、Gateway网…...

conda清华源安装cuda12.1的pytorch

使用pytorch官方提供的conda command奇慢无比&#xff0c;根本装不下来&#xff08;科学的情况下也这样&#xff09; 配置一下清华源使用清华源装就好了 清华源&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/ 配置方法&#xff1a;conda config --…...

安徽首届道医传承十八绝技发布会在合肥成功举办

近日&#xff0c;在安徽合肥举行了首届道医传承十八绝技发布会&#xff0c;本次会议由安徽渡罗门生物科技有限公司、北京道武易医文化传播有限公司、楼观台道医文化研究院联合举办。现场吸引了来自全国各地民族医学领域的专家学者参与讨论与交流。本次会议旨在促进道医的交流与…...

一款功能强大的web目录扫描器专业版

dirpro 简介 dirpro 是一款由 python 编写的目录扫描器&#xff0c;操作简单&#xff0c;功能强大&#xff0c;高度自动化。 自动根据返回状态码和返回长度&#xff0c;对扫描结果进行二次整理和判断&#xff0c;准确性非常高。 已实现功能 可自定义扫描线程 导入url文件进…...

【Linux网络】网卡配置与修改主机名,做好基础系统配置

目录 一、网络配置命令 1、查看网卡信息ifconfig Linux永久修改ip地址 2、主机名修改 ①hostname 临时修改主机名 ②永久修改主机名 第一种&#xff0c;使用命令修改 第二种&#xff1a;修改配置文件 3、路由信息 再来拓展一下&#xff0c;永久修改路由表信息 4、检查…...

三大基础排序 -选择排序、冒泡排序、插入排序

排序算法 文章目录 冒泡排序算法步骤动图代码优化总结 选择排序算法步骤动图代码总结 插入排序算法步骤动图代码总结 排序算法&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。一般默认排序是按照由小到大即…...

el-form添加自定义校验规则校验el-input只能输入数字

0 效果 1 代码 {1,5}是用来限制小数点后几位的 addFormRules: {investAmount: [{ validator: checkInvestAmount, trigger: blur }], }, const checkInvestAmount (rule, value, callback) > {if (value ! && value ! null && value ! undefined) {if (/…...

ios 开发问题小集 [持续更新]

文章目录 一、如何给列表上的UITableViewCell添加手势二、获取NSIndexPath的方式2.1 根据row, section 来创建2.2 根据point 的位置来找到 indexPath三、tableView在Grouped样式下,设置表头表尾空白一、如何给列表上的UITableViewCell添加手势 给cell添加手势,大家都会这么做…...

idea Plugins 搜索不到插件

Settings — System Settings — HTTP Proxy&#xff0c;打开HTTP Proxy 页面&#xff0c;设置自动发现代理&#xff1a; 勾选Atuto-detect proxy settings&#xff0c;勾选Automatic proxy configuration URL&#xff0c;输入&#xff1a; https://plugins.jetbrains.com/id…...

三相电机的某些实测特性曲线

三相电机参数&#xff1a; 0.75KW&#xff0c;额定电流是2A&#xff0c;功率因数0.71&#xff0c;效率78.9%。制式S1. 1.负载不变时的线电压与线电流的关系 1.1相关数据与python代码&#xff1a; 这里记录了一系列的实验&#xff1a; 第一组实验&#xff1a;近乎空载&#xf…...

Essential C++ 面向对象4.1 ~ 5.4

个人认为&#xff0c;结合网上对《Essential c》的评论&#xff0c;它不适合初学者&#xff1a; &#xff08;1&#xff09;过于精炼&#xff0c;很多内容不会细讲 &#xff08;2&#xff09;中文版翻译较生硬&#xff0c;逻辑不够连贯清晰 &#xff08;3&#xff09;课后作业有…...

数组【数据结构与算法】

什么是线性表&#xff1f;什么是非线性表&#xff1f;什么是数组&#xff1f;数组如何实现根据下标随机访问数组元素&#xff1f;为什么数组从下标0开始&#xff0c;不从下标1开始&#xff1f; 什么是线性表&#xff1f; 数据结构元素只有前后关系。 线性表包括&#xff1a;数…...

Python克隆单个网页

网上所有代码都无法完全克隆单个网页&#xff0c;不是Css&#xff0c;Js下载不下来就是下载下来也不能正常显示&#xff0c;只能自己写了&#xff0c;记得点赞~ 效果如图&#xff1a; 源码与所需的依赖&#xff1a; pip install requests pip install requests beautifulsoup4…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

WebRTC从入门到实践 - 零基础教程

WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC&#xff1f; WebRTC&#xff08;Web Real-Time Communication&#xff09;是一个支持网页浏览器进行实时语音…...