UE5 C++ TPS开发 学习记录(五)

news2025/1/15 13:01:39

这节课创建了新的游戏关卡Lobby,制作了属于自己的游戏名字"Match Type",制作了加入游戏会话的委托和函数,最后可以用IP就可以把客户端链接到服务端

.h

// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "GameFramework/Character.h" #include "Logging/LogMacros.h" #include "OnlineSubsystem.h" #include "Interfaces/OnlineSessionInterface.h" #include "MenuCharacter.generated.h" class USpringArmComponent; class UCameraComponent; class UInputMappingContext; class UInputAction; struct FInputActionValue; DECLARE_LOG_CATEGORY_EXTERN(LogTemplateCharacter, Log, All); UCLASS(config=Game) class AMenuCharacter : public ACharacter { GENERATED_BODY() /** Camera boom positioning the camera behind the character */ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true")) USpringArmComponent* CameraBoom; /** Follow camera */ UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true")) UCameraComponent* FollowCamera; /** MappingContext */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true")) UInputMappingContext* DefaultMappingContext; /** Jump Input Action */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true")) UInputAction* JumpAction; /** Move Input Action */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true")) UInputAction* MoveAction; /** Look Input Action */ UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true")) UInputAction* LookAction; public: AMenuCharacter(); protected: /** Called for movement input */ void Move(const FInputActionValue& Value); /** Called for looking input */ void Look(const FInputActionValue& Value); protected: // APawn interface virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override; // To add mapping context virtual void BeginPlay(); public: /** Returns CameraBoom subobject **/ FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; } /** Returns FollowCamera subobject **/ FORCEINLINE class UCameraComponent* GetFollowCamera() const { return FollowCamera; } public: //Pointer to the online session interface void _MyDebugLog(int32 Key, float TimeToDisplay, FColor DisplayColor, const FString& DebugMessage); IOnlineSessionPtr OnlineSessionInterface; protected: //创建会话 UFUNCTION(BlueprintCallable,Category="My") void CreateGameSession(); //创建会话成功 void OnCreateSessionComplete(FName SessionName, bool bWasSuccess); //加入会话 UFUNCTION(BlueprintCallable,Category="My") void JoinSession(); //查找会话成功 void FindSessionComplete(bool bWasSuccess); // void JoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result); private: //创建会话的委托 FOnCreateSessionCompleteDelegate OnCreateSessionCompleteDelegate; //查找会话的委托 FOnFindSessionsCompleteDelegate OnFindSessionsCompleteDelegate; //查找会话设置 TSharedPtr<FOnlineSessionSearch> SessionSearch; //加入会话 FOnJoinSessionCompleteDelegate OnJoinSessionCompleteDelegate; };

.cpp

// Copyright Epic Games, Inc. All Rights Reserved. #include "MenuCharacter.h" #include "Engine/LocalPlayer.h" #include "Camera/CameraComponent.h" #include "Components/CapsuleComponent.h" #include "GameFramework/CharacterMovementComponent.h" #include "GameFramework/SpringArmComponent.h" #include "GameFramework/Controller.h" #include "EnhancedInputComponent.h" #include "EnhancedInputSubsystems.h" #include "OnlineSessionSettings.h" #include "InputActionValue.h" #include "Online/OnlineSessionNames.h" DEFINE_LOG_CATEGORY(LogTemplateCharacter); // // AMenuCharacter AMenuCharacter::AMenuCharacter(): OnCreateSessionCompleteDelegate(FOnCreateSessionCompleteDelegate::CreateUObject(this,&ThisClass::OnCreateSessionComplete)), OnFindSessionsCompleteDelegate(FOnFindSessionsCompleteDelegate::CreateUObject(this,&ThisClass::FindSessionComplete)), OnJoinSessionCompleteDelegate(FOnJoinSessionCompleteDelegate::CreateUObject(this,&ThisClass::JoinSessionComplete)) { // Set size for collision capsule GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f); // Don't rotate when the controller rotates. Let that just affect the camera. bUseControllerRotationPitch = false; bUseControllerRotationYaw = false; bUseControllerRotationRoll = false; // Configure character movement GetCharacterMovement()->bOrientRotationToMovement = true; // Character moves in the direction of input... GetCharacterMovement()->RotationRate = FRotator(0.0f, 500.0f, 0.0f); // ...at this rotation rate // Note: For faster iteration times these variables, and many more, can be tweaked in the Character Blueprint // instead of recompiling to adjust them GetCharacterMovement()->JumpZVelocity = 700.f; GetCharacterMovement()->AirControl = 0.35f; GetCharacterMovement()->MaxWalkSpeed = 500.f; GetCharacterMovement()->MinAnalogWalkSpeed = 20.f; GetCharacterMovement()->BrakingDecelerationWalking = 2000.f; GetCharacterMovement()->BrakingDecelerationFalling = 1500.0f; // Create a camera boom (pulls in towards the player if there is a collision) CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom")); CameraBoom->SetupAttachment(RootComponent); CameraBoom->TargetArmLength = 400.0f; // The camera follows at this distance behind the character CameraBoom->bUsePawnControlRotation = true; // Rotate the arm based on the controller // Create a follow camera FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera")); FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName); // Attach the camera to the end of the boom and let the boom adjust to match the controller orientation FollowCamera->bUsePawnControlRotation = false; // Camera does not rotate relative to arm // Note: The skeletal mesh and anim blueprint references on the Mesh component (inherited from Character) // are set in the derived blueprint asset named ThirdPersonCharacter (to avoid direct content references in C++) //添加访问Steam会话系统 IOnlineSubsystem* OnlineSubsystem = IOnlineSubsystem::Get(); if(OnlineSubsystem) { //获得当前会话的指针 OnlineSessionInterface = OnlineSubsystem->GetSessionInterface(); _MyDebugLog(-1,15.f,FColor::Blue,FString::Printf(TEXT("Now Subsystem %s"),*OnlineSubsystem->GetSubsystemName().ToString())); } } void AMenuCharacter::_MyDebugLog(int32 Key, float TimeToDisplay, FColor DisplayColor, const FString& DebugMessage) { if(GEngine) { GEngine->AddOnScreenDebugMessage(Key,TimeToDisplay,DisplayColor,DebugMessage); } } void AMenuCharacter::CreateGameSession() { //Called when pressing the 1 key //检测IOnlineSessionPtr是否有效 if(!OnlineSessionInterface.IsValid()) { return; } //获得当前会话名字并且放在变量内 auto ExistingSession = OnlineSessionInterface->GetNamedSession(NAME_GameSession); //当存在会话的时候,删除会话 if(ExistingSession!=nullptr) { OnlineSessionInterface->DestroySession(NAME_GameSession); } OnlineSessionInterface->AddOnCreateSessionCompleteDelegate_Handle(OnCreateSessionCompleteDelegate); //创建智能指针会话设置 TSharedPtr<FOnlineSessionSettings> SessionSettings = MakeShareable(new FOnlineSessionSettings()); //非局域网 SessionSettings->bIsLANMatch = false; //最多4人 SessionSettings->NumPublicConnections =4; //允许其他玩家加入 SessionSettings->bAllowJoinInProgress = true; //允许好友加入 SessionSettings->bAllowJoinViaPresence = true; //线上公开 SessionSettings->bShouldAdvertise = true; //显示用户状态 SessionSettings->bUsesPresence = true; //使用第三方 SessionSettings->bUseLobbiesIfAvailable = true; //设置会话搜索设置,Name是"MatchType",值是"FreeForAll" SessionSettings->Set(FName("MatchType"),FString("FreeForAll"),EOnlineDataAdvertisementType::ViaOnlineServiceAndPing); const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController(); OnlineSessionInterface->CreateSession(*LocalPlayer->GetPreferredUniqueNetId(), NAME_GameSession , *SessionSettings); } void AMenuCharacter::OnCreateSessionComplete(FName SessionName, bool bWasSuccess) { if(bWasSuccess) { _MyDebugLog(-1,15.f,FColor::Blue,FString::Printf(TEXT("Create Session Success : %s"), *SessionName.ToString())); UWorld* World = GetWorld(); if(World) { World->ServerTravel("/Game/ThirdPerson/Maps/Lobby?listen"); } } else { _MyDebugLog(-1,15.f,FColor::Red,FString(TEXT("Faild to Create Session"))); } return; } void AMenuCharacter::JoinSession() { /*找到会话*/ if(!OnlineSessionInterface.IsValid()) { return; } //添加查询委托 OnlineSessionInterface->AddOnFindSessionsCompleteDelegate_Handle(OnFindSessionsCompleteDelegate); //设置查找 SessionSearch = MakeShareable(new FOnlineSessionSearch()); SessionSearch->MaxSearchResults = 10000; SessionSearch->bIsLanQuery=false; //设置查询设置 SessionSearch->QuerySettings.Set(SEARCH_PRESENCE,true,EOnlineComparisonOp::Equals); //获得本地的第一个玩家 const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController(); //使用本地的第一个玩家的URL和查找设置进行查找 OnlineSessionInterface->FindSessions(*LocalPlayer->GetPreferredUniqueNetId(),SessionSearch.ToSharedRef()); } void AMenuCharacter::FindSessionComplete(bool bWasSuccess) { if(!OnlineSessionInterface.IsValid()) { return; } for(auto Result : SessionSearch->SearchResults) { FString Id = Result.GetSessionIdStr(); FString User = Result.Session.OwningUserName; FString MatchType; //找到所有Key是"MatchType"类型的房间 Result.Session.SessionSettings.Get("MatchType",MatchType); _MyDebugLog(-1,15.f,FColor::Cyan,FString::Printf(TEXT("Id : %s , Name : %s"),*Id,*User)); if(MatchType == "FreeForAll") { _MyDebugLog(-1,15.f,FColor::Cyan,FString::Printf(TEXT("Join Match Type : %s"),*MatchType)); //绑定加入委托 OnlineSessionInterface->AddOnJoinSessionCompleteDelegate_Handle(OnJoinSessionCompleteDelegate); const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController(); //调用JoinSession,并且加入的时候调用OnJoinSessionCompleteDelegate这个委托 OnlineSessionInterface->JoinSession(*LocalPlayer->GetPreferredUniqueNetId(),NAME_GameSession,Result); } } } void AMenuCharacter::JoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result) { if(!OnlineSessionInterface.IsValid()) { return; } FString Address; // if(OnlineSessionInterface->GetResolvedConnectString(NAME_GameSession,Address)) { _MyDebugLog(-1,15.f,FColor::Yellow,FString::Printf(TEXT("Connect String : %s"),*Address)); APlayerController* PlayerController = GetGameInstance()->GetFirstLocalPlayerController(); if(PlayerController) { PlayerController->ClientTravel(Address,ETravelType::TRAVEL_Absolute); } } } void AMenuCharacter::BeginPlay() { // Call the base class Super::BeginPlay(); //Add Input Mapping Context if (APlayerController* PlayerController = Cast<APlayerController>(Controller)) { if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer())) { Subsystem->AddMappingContext(DefaultMappingContext, 0); } } } // // Input void AMenuCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) { // Set up action bindings if (UEnhancedInputComponent* EnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent)) { // Jumping EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Started, this, &ACharacter::Jump); EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Completed, this, &ACharacter::StopJumping); // Moving EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AMenuCharacter::Move); // Looking EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &AMenuCharacter::Look); } else { UE_LOG(LogTemplateCharacter, Error, TEXT("'%s' Failed to find an Enhanced Input component! This template is built to use the Enhanced Input system. If you intend to use the legacy system, then you will need to update this C++ file."), *GetNameSafe(this)); } } void AMenuCharacter::Move(const FInputActionValue& Value) { // input is a Vector2D FVector2D MovementVector = Value.Get<FVector2D>(); if (Controller != nullptr) { // find out which way is forward const FRotator Rotation = Controller->GetControlRotation(); const FRotator YawRotation(0, Rotation.Yaw, 0); // get forward vector const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X); // get right vector const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y); // add movement AddMovementInput(ForwardDirection, MovementVector.Y); AddMovementInput(RightDirection, MovementVector.X); } } void AMenuCharacter::Look(const FInputActionValue& Value) { // input is a Vector2D FVector2D LookAxisVector = Value.Get<FVector2D>(); if (Controller != nullptr) { // add yaw and pitch input to controller AddControllerYawInput(LookAxisVector.X); AddControllerPitchInput(LookAxisVector.Y); } }

因为一个Steam只能同时链接一个Address,所以我没有测试成功.第一个链接上了Steam,第二个就会出现链接Null

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

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

相关文章

pytest如何在类的方法之间共享变量?

在pytest中&#xff0c;setup_class是一个特殊的方法&#xff0c;它用于在类级别的测试开始之前设置一些初始化的状态。这个方法会在类中的任何测试方法执行之前只运行一次。 当你在setup_class中使用self来修改类属性时&#xff0c;你实际上是在修改类的一个实例属性。在Pyth…

高频面试题整理(二)

文章目录 索引相关问题优化你的索引 密集索引和稀疏索引如何定位并优化慢查询sqlMyISAM与InnoDB 关于锁方面的区别是什么&#xff1f;MyISAMInnoDB事务隔离级别 多线程并发的相关问题Thread中的start和run方法的区别Thread和Runnable是什么关系&#xff1f;如何处理线程的返回值…

【Java程序设计】【C00307】基于Springboot的基Hadoop的物品租赁管理系统(有论文)

基于Springboot的基Hadoop的物品租赁管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的基于 Hadoop的物品租赁系统的设计与实现&#xff0c;本系统有管理员、用户二种角色权限&#xff1b; 前台首页&#…

Xcode与Swift开发小记

引子 鉴于React Native目前版本在iOS上开发遇到诸多问题&#xff0c;本以为搞RN只需理会Javascript开发&#xff0c;没想到冒出CocoaPod的一堆编译问题。所以横下一条心&#xff0c;决定直接进攻iOS本身。不管你是用React Native&#xff0c;还是用Flutter&#xff0c;iOS下的…

记录一些mac电脑重装mysql和pgsql的坑

为什么要重装,是想在mac电脑 创建data目录…同事误操作,导致电脑重启不了.然后重装系统后,.就连不上数据库了.mysql和pgsql两个都连不上.网上也查了很多资料.实在不行,.就重装了… 重装mysql. 1.官网下载 https://www.mysql.com/downloads/ 滑到最下面 选择 选择对应的芯片版本…

python-产品篇-游戏-开心消消乐

文章目录 准备代码效果 准备 安装对应环境库 代码 import pygame import random from pygame.locals import *class SoundPlay:game_bgm "sound/GameSceneBGM.ogg"world_bgm sound/WorldSceneBGM.oggeliminate (sound/eliminate1.ogg, sound/eliminate2.ogg, s…

MATLAB环境下基于洗牌复杂演化的图像分割算法

智能优化算法因其较强的搜索解能力而得到了大量的应用&#xff0c;在这些计算智能算法中&#xff0c;群体智能优化算法因其高效性、有效性以及健壮性等优点而得到了科研人员的青睐。这类算法借鉴生物群体的合作特性&#xff0c;主要解决大规模复杂的分布式问题&#xff0c;研究…

YOLO算法改进Backbone系列之:EfficientViT

EfficientViT: Memory Effificient Vision Transformer with Cascaded Group Attention 摘要&#xff1a;视觉transformer由于其高模型能力而取得了巨大的成功。然而&#xff0c;它们卓越的性能伴随着沉重的计算成本&#xff0c;这使得它们不适合实时应用。在这篇论文中&#x…

深入理解 JavaScript 中的绑定机制(上)

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Orange3数据预处理(列选择组件)数据角色及类型描述

在Orange3的文件组件中&#xff0c;datetime、categorical、numeric以及text代表不同种类的数据类型&#xff0c;具体如下&#xff1a; datetime&#xff1a;代表日期和时间类型的数据。通常用于时间序列分析、生存分析和其他需要考虑时间因素的机器学习任务中。例如&#xff0…

k8s-kubeapps部署 20

部署kubeapps应用&#xff0c;为Helm提供web UI界面管理&#xff1a; 下载最新版本的kubeapps并修改其values.yaml文件 下载并拉取所需镜像&#xff1a; 部署应用 添加解析 修改svc暴露方式为LoadBalancer 得到分配地址 访问http://192.168.182.102 授权并获取token 1.24前的…

密码学及其应用(应用篇15)——0/1背包问题

1 问题背景 背包问题是一个经典的优化问题&#xff0c;在计算机科学和运筹学中有着广泛的应用。具体到你提到的这个问题&#xff0c;它是背包问题中的一个特例&#xff0c;通常被称为0/1背包问题。这里&#xff0c;我们有一系列的正整数 &#xff0c;以及一个正整数&#xff0c…

TCP/IP协议栈:模拟器实现基本的L2和L3功能

在C中实现的TCPI/IP网络堆栈模拟器。该模拟器实现基本的第2层&#xff08;MAC地址&#xff0c;Arp&#xff09;和第3层&#xff08;路由&#xff0c;IP&#xff09;功能。 TCP/IP协议栈是一个网络通信的基础架构&#xff0c;包含了多层次的协议和功能。在模拟实现基本的L2和L3…

LabVIEW和Python开发微细车削控制系统

LabVIEW和Python开发微细车削控制系统 为满足现代精密加工的需求&#xff0c;开发了一套基于LabVIEW和Python的微细车削控制系统。该系统通过模块化设计&#xff0c;实现了高精度的加工控制和G代码的自动生成&#xff0c;有效提高了微细车削加工的自动化水平和编程效率。 项目…

【JavaEE】 spring boot的配置文件详解

spring boot的配置文件详解 文章目录 spring boot的配置文件详解常用配置spring boot的配置文件1. properties 文件2. YAML 文件3. 多环境配置4. 配置文件优先级5. 配置属性注入特殊说明 properties配置文件基本语法 例子peoperties文件的缺点 YML配置文件YML使用yml 配置不同数…

【PyQt5桌面应用开发】3.Qt Designer快速入门(控件详解)

一、Qt Designer简介 Qt Designer是PyQt程序UI界面的实现工具&#xff0c;可以帮助我们快速开发 PyQt 程序的速度。它生成的 UI 界面是一个后缀为 .ui 的文件&#xff0c;可以通过 pyiuc 转换为 .py 文件。 Qt Designer工具使用简单&#xff0c;可以通过拖拽和点击完成复杂界面…

mini-spring|向虚拟机注册钩子,实现Bean对象的初始化和销毁方法

目标 当我们的类创建的 Bean 对象&#xff0c;交给 Spring 容器管理以后&#xff0c;这个类对象就可以被赋予更多的使用能力。我们还希望可以在 Bean 初始化过程&#xff0c;执行一些操作。比如帮我们做一些数据的加载执行&#xff0c;链接注册中心暴漏RPC接口以及在Web程序关…

vSphere高可用架构---HA简介

1.高可用性 2.不同级别的高可用&#xff1a; 1&#xff09;应用程序级别&#xff0c;2&#xff09;操作系统级别&#xff0c;3&#xff09;虚拟化级别&#xff0c;4&#xff09;物理层级别 不同级别的高可用举例&#xff1a; 应用程序级别的高可用性。例如&#xff1a;Oracl…

高温应用中GaN HEMT大信号建模的ASM-HEMT

来源&#xff1a;An ASM-HEMT for Large-Signal Modeling of GaN HEMTs in High-Temperature Applications&#xff08;JEDS 23年&#xff09; 摘要 本文报道了一种用于模拟高温环境下氮化镓高电子迁移率晶体管&#xff08;GaN HEMT&#xff09;的温度依赖性ASM-HEMT模型。我…

机器学习.线性回归

斯塔1和2是权重项&#xff0c;斯塔0是偏置项&#xff0c;在训练过程中为了使得训练结果更加精确而做的微调&#xff0c;不是一个大范围的因素&#xff0c;核心影响因素是权重项 为了完成矩阵的运算&#xff0c;在斯塔0后面乘x0&#xff0c;使得满足矩阵的转换&#xff0c;所以在…