34. UE5 RPG实现鼠标点击移动

在前面,我们实现过使用键盘按键wasd去实现控制角色的移动,现在,我们实现了InputAction按键触发,后面,实现一下通过鼠标点击地面实现角色移动。
我们将实现两种效果的切换,如果你点击地面快速松开,角色将自动寻路到目标为止。如果你按住鼠标不放,角色将自动朝向鼠标所指向的位置移动。接下来,我们实现它吧!

首先在PlayerController(玩家控制器类)里面增加一些参数,用来记录一些信息,主要对应的是查询鼠标悬停的目标是否有敌人,按下的时间,以及自动寻路的参数。

	FVector CachedDestination = FVector::ZeroVector; //存储鼠标点击的位置float FollowTime = 0.f; // 用于查看按住了多久bool bAutoRunning = false; //当前是否自动移动bool bTargeting = false; //当前鼠标是否选中敌人UPROPERTY(EditDefaultsOnly)float ShortPressThreshold = 0.3f; //定义鼠标悬停多长时间内算点击事件UPROPERTY(EditDefaultsOnly)float AutoRunAcceptanceRadius = 50.f; //当角色和目标距离在此半径内时,将关闭自动寻路UPROPERTY(VisibleAnywhere)TObjectPtr<USplineComponent> Spline; //自动寻路时生成的样条线

在PlayerController构造函数,将Spline初始化

Spline = CreateDefaultSubobject<USplineComponent>("Spline");

我们之前在鼠标事件里面追踪鼠标悬停并给敌人描边的效果,能够获取到敌人
在这里插入图片描述
接下来就是在鼠标按下,悬停,抬起三个事件中去实现逻辑,我们之前在里面实现了对技能的触发
在这里插入图片描述
后面,我们将点击移动的功能融入进去。

实现长按角色跟随鼠标移动

首先,在鼠标按下事件中,判断传入的Tag是否为鼠标左键事件,在内部判断点击的是否为敌人,如果不是敌人,那就是地面,如果ThisActor有值,那就是点击到了敌人。
bTargeting为记录当前按下时,是否选中了敌人。
bAutoRunning 为是否自动寻路中,在鼠标按下,将自动关闭此项,在鼠标抬起时再重新计算是否需要自动移动。
FollowTime用于统计按下时间,来去顶当前操作为点击还是长按。

void APlayerControllerBase::AbilityInputTagPressed(const FGameplayTag InputTag)
{if(InputTag.MatchesTagExact(FMyGameplayTags::Get().InputTag_LMB)){bTargeting = ThisActor != nullptr; //ThisActor为鼠标悬停在敌人身上才会有值bAutoRunning = false;FollowTime = 0.f; //重置统计的时间}
}

接下来在鼠标悬停事件中,我们将实现角色跟随鼠标移动逻辑。
我们先实现之前的触发技能的逻辑,这里只需要判断一下是否鼠标左键的事件,如果是,将执行内部逻辑,不再运行后面的逻辑。

void APlayerControllerBase::AbilityInputTagHold(const FGameplayTag InputTag)
{if(!InputTag.MatchesTagExact(FMyGameplayTags::Get().InputTag_LMB)){if(GetASC()){GetASC()->AbilityInputTagHold(InputTag);}return;}

后面逻辑,我们先对bTargeting 进行布尔判断,如果它的值为true,证明点中了敌人,要执行攻击敌人逻辑,这个我们后面再实现
在另外的分支就是没有选中敌人,我们可以执行鼠标悬停角色跟随逻辑。
首先对悬停时间进行统计,如果悬停时间过短,我们后面将在鼠标抬起事件中去实现角色自动寻路功能。

FollowTime += GetWorld()->GetDeltaSeconds(); //统计悬停时间来判断是否为点击

接着,我们通过GetHitResultUnderCursor函数去获取鼠标拾取的位置
参数说明

  1. ECollisionChannel TraceChannel:这个参数决定了射线将与哪些类型的物体碰撞。例如,你可以设置射线只与静态网格体(ECC_StaticMesh)或角色(ECC_Pawn)等碰撞。

  2. bool bTraceComplex:这个布尔值决定了射线是否应该与复杂碰撞体(比如带有多边形碰撞体的网格体)进行碰撞检测。如果设置为 true,射线将与复杂碰撞体碰撞;如果设置为 false,则只会与简单的碰撞体(比如球体或盒体)碰撞。

  3. FHitResult& HitResult:这是一个引用参数,用于返回射线与场景中的物体碰撞的结果。如果射线没有碰撞到任何物体,这个参数将不会被修改。

将拾取到的位置缓存到变量内

		FHitResult Hit;if(GetHitResultUnderCursor(ECC_Visibility, false, Hit)){CachedDestination = Hit.ImpactPoint;}

有了目标位置后,我们通过目标位置减去角色所在位置,就可以得到一个朝向,GetSafeNormal()为归一化向量,然后使用AddMovementInput去移动角色

		if(APawn* ControlledPawn = GetPawn()){const FVector WorldDirection = (CachedDestination - ControlledPawn->GetActorLocation()).GetSafeNormal();ControlledPawn->AddMovementInput(WorldDirection);}

实现自动寻路

如果鼠标按下抬起的时间间隔比较小,我们将其定义为鼠标点击事件,并将执行自动寻路逻辑。这些内容我们将在鼠标抬起时的函数中进行实现。
在实现此逻辑之前,我们先将之前实现的技能函数实现,之前实现主要是一个触发技能鼠标抬起的回调,现在还未实现内容。
我们先判断传入的tag如果不是鼠标左键的tag,将执行此逻辑。

void APlayerControllerBase::AbilityInputTagReleased(const FGameplayTag InputTag)
{if(!InputTag.MatchesTagExact(FMyGameplayTags::Get().InputTag_LMB)){if(GetASC()){GetASC()->AbilityInputTagReleased(InputTag);}return;}
}

接着还要判断是否选中了敌人,选中敌人的话执行技能逻辑。

if(bTargeting){if(GetASC()){GetASC()->AbilityInputTagReleased(InputTag);}}else...

在else里面,我们就可以正式去实现自动寻路的功能了
首先判断一下,当前抬起时是否能够触发点击事件,ShortPressThreshold的值是我们可以自定义的,比如按下到抬起如果小于0.3s,我们将其定义为点击,那它的值我们就定义为0.3,FollowTime是在按下后,在Hold状态的间隔时间持续添加,来实现对按

if(FollowTime <= ShortPressThreshold)

接着我们去通过内置的插件去拾取自动寻路的路线,这个使用的UE引擎的方法,它需要三个值,当前世界上下文中的对象(传入自身即可),起始点,结束点,查询的到将返回一个UNavigationPath

if(UNavigationPath* NavPath = UNavigationSystemV1::FindPathToLocationSynchronously(this, ControlledPawn->GetActorLocation(), CachedDestination))

要使用寻路函数需要对应的模块,我们在官网看到它需要NavigationSystem模块
在这里插入图片描述
要使用此模块,我们需要在Build.cs里面将NavigationSystem加入,然后编译的时候将会将此模块自动编入

PrivateDependencyModuleNames.AddRange(new string[] { "GameplayTags", "GameplayTasks", "NavigationSystem" });

如果能够查询的到,我们首先将样条属性内的内容先清除

Spline->ClearSplinePoints(); //清除样条内现有的点

然后for循环找到路径里面的点,添加到样条中,为了防止错误,我们使用DrawDebugSphere函数在场景中debug测试。

for(const FVector& PointLoc : NavPath->PathPoints)
{Spline->AddSplinePoint(PointLoc, ESplineCoordinateSpace::World); //将新的位置添加到样条曲线中DrawDebugSphere(GetWorld(), PointLoc, 8.f, 8, FColor::Orange, false, 5.f); //点击后debug调试
}

添加完成后,我们还需要将记录在自动寻路状态的变量设置为true,在帧更新中,我们将通过这个变量进行角色移动

bAutoRunning = true; //设置当前正常自动寻路状态,将在tick中更新位置

接着可以编译测试是否能够实现在场景获取到路径点,我们要测试导航功能,需要在场景里面设置导航体积,只有在导航体积内,才能够触发此功能,先在场景添加一个此体积。
在这里插入图片描述
按快捷键P,可以显示可导航区域,我们可以调整体积范围来实现可导航范围。
在这里插入图片描述
顺便加几个遮挡物,导航体积会自动计算,将其可移动范围剔除掉。
在这里插入图片描述
然后测试点击地面,会发现生成了对应的点的位置
在这里插入图片描述

在帧循环实现自动移动

现在自动寻路的路径有了,我们要实现角色的自动移动,那么,需要在帧循环里面实现。

//帧更新
void APlayerControllerBase::PlayerTick(float DeltaTime)
{Super::PlayerTick(DeltaTime);//鼠标位置追踪是否悬停在敌人身上CursorTrace();}

首先我们获取并判断一下Pawn是否存在

if(APawn* ControlledPawn = GetPawn())

由于无法确保角色位置和样条曲线百分之百重合在一块,所以我们先获取一下角色距离样条最近的位置

const FVector LocationOnSpline = Spline->FindLocationClosestToWorldLocation(ControlledPawn->GetActorLocation(), ESplineCoordinateSpace::World);

然后通过此位置去获取在样条上的方向

const FVector Direction = Spline->FindDirectionClosestToWorldLocation(LocationOnSpline, ESplineCoordinateSpace::World);

让角色通过此方向去移动

ControlledPawn->AddMovementInput(Direction);

我们还需要在角色移动到终点时,设置它停止寻路,所以,我们还需要查询当前角色所在位置和终点位置的距离,如果小于我们设置的AutoRunAcceptanceRadius距离内,我们将停止自动寻路。

const float DistanceToDestination = (LocationOnSpline - CachedDestination).Length();
if(DistanceToDestination <= AutoRunAcceptanceRadius)
{bAutoRunning = false;
}

ps:这里还有一个问题,就是如果你点击位置为自动寻路无法到达的位置,导航还是会生成一条路径,但是我们无法达到最终点,这样无法停止自动寻路。所以,我们需要在鼠标抬起时,将路径的终点设置给CachedDestination,这也是自动寻路的最终点。
我们获取数组中的最后一个点,按照索引来算,就是数组的长度-1

CachedDestination = NavPath->PathPoints[NavPath->PathPoints.Num() - 1];

如果需要服务器,我们需要在导航系统设置运行客户端导航,这样,会在所有的客户端生成导航体积。
在这里插入图片描述
如果我们需要点击到柱子后面的地面,而不是忘柱子那里移动,我们需要修改柱子的碰撞预设为自定义
在这里插入图片描述
我们鼠标拾取地面位置是通过Visibility去拾取的,那么,将此相应通道关闭。
在这里插入图片描述
接下来,我们就可以测试了,查看是否有bug。
下面列出来PlayerController的完整代码

// 版权归暮志未晚所有。#pragma once#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "GameplayTagContainer.h"
#include "PlayerControllerBase.generated.h"class USplineComponent;
class UInputConfig;
class UInputMappingContext;
class UInputAction;
struct FInputActionValue;
class IEnemyInterface;
class UAbilitySystemComponentBase;/*** 玩家控制器*/
UCLASS()
class AURA_API APlayerControllerBase : public APlayerController
{GENERATED_BODY()public:APlayerControllerBase();virtual void PlayerTick(float DeltaTime) override;protected:virtual void BeginPlay() override; //游戏开始时触发virtual void SetupInputComponent() override; //在生成输入组件时触发private:UPROPERTY(EditAnywhere, Category="Input")TObjectPtr<UInputMappingContext> CharacterContext;UPROPERTY(EditAnywhere, Category="Input")TObjectPtr<UInputAction> MoveAction;void Move(const struct FInputActionValue& InputActionValue);void CursorTrace(); //鼠标位置追踪拾取IEnemyInterface* LastActor; //上一帧拾取到的接口指针IEnemyInterface* ThisActor; //这一帧拾取到的接口指针void AbilityInputTagPressed(FGameplayTag InputTag);void AbilityInputTagReleased(FGameplayTag InputTag);void AbilityInputTagHold(FGameplayTag InputTag);UPROPERTY(EditDefaultsOnly, Category="Input")TObjectPtr<UInputConfig> InputConfig;UPROPERTY()TObjectPtr<UAbilitySystemComponentBase> AbilitySystemComponentBase;UAbilitySystemComponentBase* GetASC();FVector CachedDestination = FVector::ZeroVector; //存储鼠标点击的位置float FollowTime = 0.f; // 用于查看按住了多久bool bAutoRunning = false; //当前是否自动移动bool bTargeting = false; //当前鼠标是否选中敌人UPROPERTY(EditDefaultsOnly)float ShortPressThreshold = 0.3f; //定义鼠标悬停多长时间内算点击事件UPROPERTY(EditDefaultsOnly)float AutoRunAcceptanceRadius = 50.f; //当角色和目标距离在此半径内时,将关闭自动寻路UPROPERTY(VisibleAnywhere)TObjectPtr<USplineComponent> Spline; //自动寻路时生成的样条线void AutoRun();
};
// 版权归暮志未晚所有。#include "Player/PlayerControllerBase.h"#include "AbilitySystemBlueprintLibrary.h"
#include "EnhancedInputSubsystems.h"
#include "MyGameplayTags.h"
#include "NavigationPath.h"
#include "NavigationSystem.h"
#include "AbilitySystem/AbilitySystemComponentBase.h"
#include "Components/SplineComponent.h"
#include "Input/InputComponentBase.h"
#include "Interaction/EnemyInterface.h"APlayerControllerBase::APlayerControllerBase()
{bReplicates = true; //是否将数据传送服务器更新LastActor = nullptr;ThisActor = nullptr;Spline = CreateDefaultSubobject<USplineComponent>("Spline");
}//帧更新
void APlayerControllerBase::PlayerTick(float DeltaTime)
{Super::PlayerTick(DeltaTime);//鼠标位置追踪是否悬停在敌人身上CursorTrace();//自动寻路AutoRun();
}void APlayerControllerBase::AutoRun()
{if(!bAutoRunning) return;if(APawn* ControlledPawn = GetPawn()){//找到距离样条最近的位置const FVector LocationOnSpline = Spline->FindLocationClosestToWorldLocation(ControlledPawn->GetActorLocation(), ESplineCoordinateSpace::World);//获取这个位置在样条上的方向const FVector Direction = Spline->FindDirectionClosestToWorldLocation(LocationOnSpline, ESplineCoordinateSpace::World);ControlledPawn->AddMovementInput(Direction);const float DistanceToDestination = (LocationOnSpline - CachedDestination).Length();if(DistanceToDestination <= AutoRunAcceptanceRadius){bAutoRunning = false;}}
}//鼠标位置追踪
void APlayerControllerBase::CursorTrace()
{FHitResult CursorHit;GetHitResultUnderCursor(ECC_Visibility, false, CursorHit); //获取可视的鼠标命中结果if(!CursorHit.bBlockingHit) return; //如果未命中直接返回LastActor = ThisActor;ThisActor = Cast<IEnemyInterface>(CursorHit.GetActor());/*** 射线拾取后,会出现的几种情况* 1. LastActor is null   ThisActor is null 不需要任何操作* 2. LastActor is null   ThisActor is valid 高亮ThisActor* 3. LastActor is valid   ThisActor is null 取消高亮LastActor* 4. LastActor is valid   ThisActor is valid LastActor != ThisActor 取消高亮LastActor 高亮ThisActor* 5. LastActor is valid   ThisActor is valid LastActor == ThisActor 不需要任何操作*/if(LastActor == nullptr){if(ThisActor != nullptr){//case 2ThisActor->HighlightActor();} // else case 1}else{if(ThisActor == nullptr){//case 3LastActor->UnHighlightActor();}else{if(LastActor != ThisActor){//case 4LastActor->UnHighlightActor();ThisActor->HighlightActor();} //else case 5}}}void APlayerControllerBase::AbilityInputTagPressed(const FGameplayTag InputTag)
{if(InputTag.MatchesTagExact(FMyGameplayTags::Get().InputTag_LMB)){bTargeting = ThisActor != nullptr; //ThisActor为鼠标悬停在敌人身上才会有值bAutoRunning = false;FollowTime = 0.f; //重置统计的时间}
}void APlayerControllerBase::AbilityInputTagReleased(const FGameplayTag InputTag)
{if(!InputTag.MatchesTagExact(FMyGameplayTags::Get().InputTag_LMB)){if(GetASC()){GetASC()->AbilityInputTagReleased(InputTag);}return;}if(bTargeting){if(GetASC()){GetASC()->AbilityInputTagReleased(InputTag);}}else{const APawn* ControlledPawn = GetPawn();if(FollowTime <= ShortPressThreshold && ControlledPawn){if(UNavigationPath* NavPath = UNavigationSystemV1::FindPathToLocationSynchronously(this, ControlledPawn->GetActorLocation(), CachedDestination)){Spline->ClearSplinePoints(); //清除样条内现有的点for(const FVector& PointLoc : NavPath->PathPoints){Spline->AddSplinePoint(PointLoc, ESplineCoordinateSpace::World); //将新的位置添加到样条曲线中// DrawDebugSphere(GetWorld(), PointLoc, 8.f, 8, FColor::Orange, false, 5.f); //点击后debug调试}//自动寻路将最终目的地设置为导航的终点,方便停止导航CachedDestination = NavPath->PathPoints[NavPath->PathPoints.Num() - 1];bAutoRunning = true; //设置当前正常自动寻路状态,将在tick中更新位置}}}
}void APlayerControllerBase::AbilityInputTagHold(const FGameplayTag InputTag)
{if(!InputTag.MatchesTagExact(FMyGameplayTags::Get().InputTag_LMB)){if(GetASC()){GetASC()->AbilityInputTagHold(InputTag);}return;}if(bTargeting){if(GetASC()){//点击敌人目标,将攻击敌人GetASC()->AbilityInputTagHold(InputTag);}}else{FollowTime += GetWorld()->GetDeltaSeconds(); //统计悬停时间来判断是否为点击FHitResult Hit;if(GetHitResultUnderCursor(ECC_Visibility, false, Hit)){CachedDestination = Hit.ImpactPoint;}if(APawn* ControlledPawn = GetPawn()){const FVector WorldDirection = (CachedDestination - ControlledPawn->GetActorLocation()).GetSafeNormal();ControlledPawn->AddMovementInput(WorldDirection);}}
}UAbilitySystemComponentBase* APlayerControllerBase::GetASC()
{if(AbilitySystemComponentBase == nullptr){AbilitySystemComponentBase = Cast<UAbilitySystemComponentBase>(UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(GetPawn()));}return AbilitySystemComponentBase;
}void APlayerControllerBase::BeginPlay()
{Super::BeginPlay();check(CharacterContext); //判断是否存在//从本地角色身上获取到它的子系统UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer());// check(Subsystem); //检查子系统是否存在 不存在会打断if(Subsystem){//将自定义的操作映射上下文添加到子系统中Subsystem->AddMappingContext(CharacterContext, 0); //可以存在多个操作映射,根据优先级触发}bShowMouseCursor = true; //游戏中是否显示鼠标光标DefaultMouseCursor = EMouseCursor::Default; //鼠标光标的样式FInputModeGameAndUI InputModeData;InputModeData.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock); //将鼠标锁定在视口内InputModeData.SetHideCursorDuringCapture(false); //鼠标被捕获时是否隐藏SetInputMode(InputModeData); //设置给控制器
}void APlayerControllerBase::SetupInputComponent()
{Super::SetupInputComponent();UInputComponentBase* EnhancedInputComponent = CastChecked<UInputComponentBase>(InputComponent); //获取到增强输入组件EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &APlayerControllerBase::Move); //绑定移动事件EnhancedInputComponent->BindAbilityAction(InputConfig, this, &ThisClass::AbilityInputTagPressed,&ThisClass::AbilityInputTagReleased, &ThisClass::AbilityInputTagHold);
}void APlayerControllerBase::Move(const FInputActionValue& InputActionValue)
{const FVector2D InputAxisVector = InputActionValue.Get<FVector2D>(); //获取输入操作的2维向量值const FRotator Rotation = GetControlRotation(); //获取控制器旋转const FRotator YawRotation(0.f, Rotation.Yaw, 0.f); //通过控制器的垂直朝向创建一个旋转值,忽略上下朝向和左右朝向const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X); //获取世界坐标系下向前的值,-1到1const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y); //获取世界坐标系下向右的值,-1到1if(APawn* ControlledPawn = GetPawn<APawn>()){ControlledPawn->AddMovementInput(ForwardDirection, InputAxisVector.Y);ControlledPawn->AddMovementInput(RightDirection, InputAxisVector.X);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/803618.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 289.生命游戏————2024 春招冲刺百题计划

根据 百度百科 &#xff0c; 生命游戏 &#xff0c;简称为 生命 &#xff0c;是英国数学家约翰何顿康威在 1970 年发明的细胞自动机。 给定一个包含 m n 个格子的面板&#xff0c;每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态&#xff1a; 1 即为 活细胞 &am…

鹅厂实习offer

#转眼已经银四了&#xff0c;你收到offer了吗# 本来都打算四月再投实习了&#xff0c;突然三月初被wxg捞了&#xff08;一年前找日常实习投的简历就更新了下&#xff09;&#xff0c;直接冲了&#xff0c;流程持续二十多天&#xff0c;结果是运气还不错&#xff0c;应该是部门比…

2024年光学通信和物联网、自动化控制和大数据国际会议(OCITACB2024)

2024年光学通信和物联网、自动化控制和大数据国际会议(OCITACB2024) 会议简介 2024年国际光通信与物联网、自动控制和大数据会议&#xff08;OCITACB2024&#xff09;的主要目标是促进光通信与物联网、自动管理和大数据领域的研发活动。另一个目标是促进研究人员、开发人员、工…

用three.js做一个3D汉诺塔游戏(下)

为桌台添加材质纹理 为物体添加适当的材质纹理,可以使其视觉效果产生质的飞跃。接下来,我们将为桌台添加一种木质纹理,用到的纹理贴图来自Pixabay.com。 我们使用 TextureLoader 来加载纹理贴图,其 load 方法第1个参数为贴图的 URL 字符串,该方法返回一个纹理对象,可直…

Linux服务器上搭建深度学习环境(安装anaconda、创建虚拟环境、安装pytorch)

Linux服务器的搭配 Linux服务器上安装anaconda创建虚拟环境linux上安装pytorchxshell连接服务器 Linux服务器上安装anaconda 链接 创建虚拟环境 参考教程&#xff1a;此处 linux上安装pytorch 链接 xshell连接服务器 链接

科技动态人工智能应用太空探索生物科技

根据最新的科技资讯&#xff0c;以下是一些值得关注的科技动态&#xff1a; 人工智能领域 智能体热潮 &#xff1a;随着大模型的研发热潮&#xff0c;AI智能体的发展迅速&#xff0c;它们被用作认知核心&#xff0c;具备强大的学习和迁移能力。智能体的架构和交互方式也在不断进…

python课后习题三

题目&#xff1a; 解题过程&#xff1a; 模式A&#xff1a; num int(input("&#xff08;模式A&#xff09;输入数字&#xff1a;")) for i in range(num): for j in range(num): if j < i 1: …

MQ的延迟队列

1&#xff0c;场景 1.定时发布文章 2.秒杀之后&#xff0c;给30分钟时间进行支付&#xff0c;如果30分钟后&#xff0c;没有支付&#xff0c;订单取消。 3.预约餐厅&#xff0c;提前半个小时发短信通知用户。 A -> 13:00 17:00 16:30 延迟时间&#xff1a; 7*30 * 60 * …

Excel·VBA考勤打卡记录整理

看到一个帖子《excel吧-考勤一天四次打卡&#xff0c;快速找出缺卡》&#xff0c;每个人每天有4次打卡记录&#xff0c;需要整理出所有缺少的打卡记录 与之前的文章《ExcelVBA考勤打卡记录统计结果》结果形式类似 与之前的文章《ExcelVBA考勤打卡记录数据整理》查找上下班打卡…

Linux、Docker、Brew、Nginx常用命令

Linux、Docker、Brew、Nginx常用命令 Linuxvi编辑器文件操作文件夹操作磁盘操作 DockerBrewNginx参考 Linux vi编辑器 Vi有三种模式。命令模式、输入模式、尾行模式&#xff0c;简单的关系如下&#xff1a; i -- 切换到输入模式&#xff0c;在光标当前位置开始输入文本。&a…

【go从入门到精通】初识struct结构体

作者简介&#xff1a; 高科&#xff0c;先后在 IBM PlatformComputing从事网格计算&#xff0c;淘米网&#xff0c;网易从事游戏服务器开发&#xff0c;拥有丰富的C&#xff0c;go等语言开发经验&#xff0c;mysql&#xff0c;mongo&#xff0c;redis等数据库&#xff0c;设计模…

虚拟网络设备性能优化

在现代网络架构中&#xff0c;虚拟网络设备扮演着越来越重要的角色&#x1f310;&#xff0c;特别是在云计算☁️和容器化技术&#x1f4e6;广泛应用的背景下。虚拟网络设备如虚拟以太网设备&#xff08;veth&#xff09;、虚拟交换机&#xff08;vSwitch&#xff09;、和虚拟路…

适用于 Mac 的 10 大数据恢复工具,具有优点、缺点

数据丢失很常见&#xff0c;并且可能由于许多不同的原因而发生。这种情况在我和我们团队的其他成员身上发生过很多次&#xff0c;即使我们格外小心我们的个人存储设备。 幸运的是&#xff0c;数据恢复软件在大多数情况下都可以工作。但是&#xff0c;由于数据丢失场景彼此之间…

【CKA模拟题】边车容器Shared-Volume的具体用法

Useful Resources: Persistent Volumes Claim , Pod to Use a PV 题干 For this question, please set this context (In exam, diff cluster name) kubectl config use-context kubernetes-adminkubernetes An existing nginx pod, my-pod-cka and Persistent Volume Claim…

macOS制作C/C++ app

C/C制作macOS .app 一、 .app APP其实是一个文件夹结构&#xff0c;只不过mac的界面中让它看起来像一个单独的文件。 在shell终端或者右键查看包结构即可看到APP的目录结构。 通常的app目录结构如下&#xff1a; _CodeSignature, CodeResources 一般为Mac APP Store上架程序…

【aws】在DBeaver上用终端节点连接Redshift

碎碎念 最近想要尝试redshift的一个叫做重新定位的功能&#xff0c;重新定位触发之后会停止当前的集群&#xff0c;转而在同一个区域的另一个可用区中启动一个一样的集群&#xff0c;这个过程视情况会花上10到60分钟不等。 但是目前项目中连接到redshift用的是私有ip&#xf…

保研线性代数复习4

一.范数&#xff08;Norms&#xff09; 1.什么是范数&#xff1f; 范数是一个向量空间V的函数&#xff0c;每一个属于向量空间V的向量x都匹配了一个实数&#xff08;它的长度&#xff09;&#xff1a; 2.范数的性质&#xff1f; 齐次性&#xff1a; 正定性&#xff1a; 三…

大创项目推荐 深度学习 机器视觉 车位识别车道线检测 - python opencv

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习 机器视觉 车位识别车道线检测 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满分5分) …

【Python】基础(专版提升1)

Python基础 1. 导学1.1 学习理念1.1.1 弱语法&#xff0c;重本质1.1.2 是技术&#xff0c;更艺术 1.2 学习方法1.2.1 当天知识必须理解 2. Python 简介2.1 计算机基础结构2.1.1 硬件2.1.2 软件 2.2 基础知识2.2.1 Python介绍2.2.1.1定义2.2.1.2优势2.2.1.3从业岗位 2.2.2 Pytho…

openGauss学习笔记-255 openGauss性能调优-使用Plan Hint进行调优-Hint的错误、冲突及告警

文章目录 openGauss学习笔记-255 openGauss性能调优-使用Plan Hint进行调优-Hint的错误、冲突及告警 openGauss学习笔记-255 openGauss性能调优-使用Plan Hint进行调优-Hint的错误、冲突及告警 Plan Hint的结果会体现在计划的变化上&#xff0c;可以通过explain来查看变化。 …