代码还是参考自Epic官方的塔防项目:StrategyGame
看了下C++的API,现成的API中貌似只支持单点触碰检测,用法如下:
注册:
// support touch devices InputComponent->BindTouch(EInputEvent::IE_Pressed, this, &ATD_MobilePlayerController::MoveToTouchLocation); InputComponent->BindTouch(EInputEvent::IE_Repeat, this, &ATD_MobilePlayerController::MoveToTouchLocation);
触发回调:
void ATD_MobilePlayerController::MoveToTouchLocation(const ETouchIndex::Type FingerIndex, const FVector Location) { FVector2D ScreenSpaceLocation(Location); // Trace to see what is under the touch location FHitResult HitResult; GetHitResultAtScreenPosition(ScreenSpaceLocation, CurrentClickTraceChannel, true, HitResult); if (HitResult.bBlockingHit) { // We hit something, move there SetNewMoveDestination(HitResult.ImpactPoint); } }
如果要实现多点触碰检测,比如实现两个手指捏动来缩放屏幕,StrategyGame项目自己实现了一套算法来实现多点屏幕检测,具体做法如下:
StrategyPlayerController.h
1,先重写StrategyPlayerController的ProcessPlayerInput()和SetupInputComponent()函数
protected: /** update input detection */ virtual void ProcessPlayerInput(const float DeltaTime, const bool bGamePaused) override; virtual void SetupInputComponent() override;
在SetupInputComponent()函数中绑定事件(这个事件机制也是自己写的),其中BIND_1P_ACTION和BIND_2P_ACTION是自己定义的宏:
void AStrategyPlayerController::SetupInputComponent() { Super::SetupInputComponent(); InputHandler = NewObject<UStrategyInput>(this); BIND_1P_ACTION(InputHandler, EGameKey::Tap, IE_Pressed, &AStrategyPlayerController::OnTapPressed); BIND_1P_ACTION(InputHandler, EGameKey::Hold, IE_Pressed, &AStrategyPlayerController::OnHoldPressed); BIND_1P_ACTION(InputHandler, EGameKey::Hold, IE_Released, &AStrategyPlayerController::OnHoldReleased); BIND_1P_ACTION(InputHandler, EGameKey::Swipe, IE_Pressed, &AStrategyPlayerController::OnSwipeStarted); BIND_1P_ACTION(InputHandler, EGameKey::Swipe, IE_Repeat, &AStrategyPlayerController::OnSwipeUpdate); BIND_1P_ACTION(InputHandler, EGameKey::Swipe, IE_Released, &AStrategyPlayerController::OnSwipeReleased); BIND_2P_ACTION(InputHandler, EGameKey::SwipeTwoPoints, IE_Pressed, &AStrategyPlayerController::OnSwipeTwoPointsStarted); BIND_2P_ACTION(InputHandler, EGameKey::SwipeTwoPoints, IE_Repeat, &AStrategyPlayerController::OnSwipeTwoPointsUpdate); BIND_2P_ACTION(InputHandler, EGameKey::Pinch, IE_Pressed, &AStrategyPlayerController::OnPinchStarted); BIND_2P_ACTION(InputHandler, EGameKey::Pinch, IE_Repeat, &AStrategyPlayerController::OnPinchUpdate); FInputActionBinding& ToggleInGameMenuBinding = InputComponent->BindAction("InGameMenu", IE_Pressed, this, &AStrategyPlayerController::OnToggleInGameMenu); ToggleInGameMenuBinding.bExecuteWhenPaused = true; }
ProcessPlayerInput()来检测触碰点变化,这是一个连续执行的函数,大概逻辑是:每次执行时都会把当前的屏幕触碰信息和上次的触碰信息做对比,检测是单点触碰,还是按住不放,还是多点触碰或多点按住不放等等,具体逻辑在InputHandler->UpdateDetection(DeltaTime);中。
void AStrategyPlayerController::ProcessPlayerInput(const float DeltaTime, const bool bGamePaused) { if (!bGamePaused && PlayerInput && InputHandler && !bIgnoreInput) { InputHandler->UpdateDetection(DeltaTime); } Super::ProcessPlayerInput(DeltaTime, bGamePaused); if (!bIgnoreInput ) { const ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(Player); AStrategySpectatorPawn* StrategyPawn = GetStrategySpectatorPawn(); if(( StrategyPawn != NULL ) && ( LocalPlayer != NULL )) { // Create the bounds for the minimap so we can add it as a 'no scroll' zone. AStrategyHUD* const HUD = Cast<AStrategyHUD>(GetHUD()); AStrategyGameState const* const MyGameState = GetWorld()->GetGameState<AStrategyGameState>(); if( (MyGameState != NULL ) && ( MyGameState->MiniMapCamera.IsValid() == true ) ) { if( LocalPlayer->ViewportClient != NULL ) { const FIntPoint ViewportSize = LocalPlayer->ViewportClient->Viewport->GetSizeXY(); const uint32 ViewTop = FMath::TruncToInt(LocalPlayer->Origin.Y * ViewportSize.Y); const uint32 ViewBottom = ViewTop + FMath::TruncToInt(LocalPlayer->Size.Y * ViewportSize.Y); FVector TopLeft( HUD->MiniMapMargin, ViewBottom - HUD->MiniMapMargin - MyGameState->MiniMapCamera->MiniMapHeight, 0 ); FVector BottomRight( (int32)MyGameState->MiniMapCamera->MiniMapWidth, MyGameState->MiniMapCamera->MiniMapHeight, 0 ); FBox MiniMapBounds( TopLeft, TopLeft + BottomRight ); StrategyPawn->GetStrategyCameraComponent()->AddNoScrollZone( MiniMapBounds ); StrategyPawn->GetStrategyCameraComponent()->UpdateCameraMovement( this ); } } } } }
StrategyInput.cpp
void UStrategyInput::UpdateDetection(float DeltaTime) { UpdateGameKeys(DeltaTime); ProcessKeyStates(DeltaTime); } void UStrategyInput::UpdateGameKeys(float DeltaTime) { AStrategyPlayerController* MyController = CastChecked<AStrategyPlayerController>(GetOuter()); // gather current states uint32 CurrentTouchState = 0; for (int32 i = 0; i < ARRAY_COUNT(MyController->PlayerInput->Touches); i++) { if (MyController->PlayerInput->Touches[i].Z != 0) { CurrentTouchState |= (1 << i); } } // detection FVector2D LocalPosition1 = FVector2D(MyController->PlayerInput->Touches[0]); FVector2D LocalPosition2 = FVector2D(MyController->PlayerInput->Touches[1]); DetectOnePointActions(CurrentTouchState & 1, PrevTouchState & 1, DeltaTime, LocalPosition1, TouchAnchors[0], Touch0DownTime); DetectTwoPointsActions((CurrentTouchState & 1) && (CurrentTouchState & 2), (PrevTouchState & 1) && (PrevTouchState & 2), DeltaTime, LocalPosition1, LocalPosition2); // save states PrevTouchState = CurrentTouchState; } void UStrategyInput::ProcessKeyStates(float DeltaTime) { for (const FActionBinding1P& AB : ActionBindings1P) { const FSimpleKeyState* KeyState = KeyStateMap.Find(AB.Key); if (KeyState && KeyState->Events[AB.KeyEvent] > 0) { AB.ActionDelegate.ExecuteIfBound(KeyState->Position, KeyState->DownTime); } } for (const FActionBinding2P& AB : ActionBindings2P) { const FSimpleKeyState* KeyState = KeyStateMap.Find(AB.Key); if (KeyState && KeyState->Events[AB.KeyEvent] > 0) { AB.ActionDelegate.ExecuteIfBound(KeyState->Position, KeyState->Position2, KeyState->DownTime); } } // update states for (TMap<EGameKey::Type,FSimpleKeyState>::TIterator It(KeyStateMap); It; ++It) { FSimpleKeyState* const KeyState = &It.Value(); if (KeyState->Events[IE_Pressed]) { KeyState->bDown = true; } else if (KeyState->Events[IE_Released]) { KeyState->bDown = false; } FMemory::Memzero(KeyState->Events, sizeof(KeyState->Events)); } }
相关推荐
总的来说,UE4和UE5为开发者提供了丰富的工具和API,以支持在触摸屏设备上实现移动、旋转和缩放等交互操作。通过理解和熟练运用这些功能,可以创建出更加直观和自然的用户体验。在实际项目中,应根据具体需求进行...
能够实现单指旋转双指缩放,控制相机远近,点击事件按钮,适合UE4学习触摸屏的同学,移动开发,或者触摸屏开发
在UE4(Unreal Engine 4)中,触控屏手势输入是移动设备和触控设备游戏开发的关键组成部分。UE4触控屏手势输入SDK提供了一整套解决方案,以支持不同类型的触摸操作,如单指点击、双指缩放等,从而丰富用户的交互体验...
在UE4(Unreal Engine 4)中,触摸输入是一种常见的交互方式,特别是在移动设备或支持触控的桌面系统上。"UE4项目触摸输入两点缩放" 是一个专为实现这种交互方式而设计的项目,它允许用户通过在屏幕上同时触摸两个点...
在UE4(Unreal Engine 4)中,开发者经常需要集成各种自定义功能,其中之一就是通过C++代码在蓝图中实现打开外部exe程序。这个功能对于游戏中的交互性或者工具集成非常有用,例如启动辅助编辑器、执行数据分析脚本等...
Visual Assist X是一款强大的Visual Studio(VS)插件,专为提升C++开发效率而设计,尤其在使用Unreal Engine 4(UE4)时效果显著。这款插件提供了丰富的代码补全、重构、高亮显示、智能感知等功能,极大地提高了...
在UE4(Unreal Engine 4)中,UI系统基于UMG(Unreal Motion Graphics),它提供了一种可视化的方式去创建用户界面,并且可以与C++代码深度集成。本示例"UE4 UI简单例子 C++"展示了如何利用C++编程语言在UE4中创建一...
毕业设计基于C++的一款UE4射击游戏源码。一款UE4射击游戏Demo,包含UE4游戏框架及整套联网射击游戏功能。一款UE4射击游戏Demo,包含UE4游戏框架及整套联网射击游戏功能。一款UE4射击游戏Demo,包含UE4游戏框架及整套...
UE4 socket 数据接收以及发送,功能示例
4. 汽车与工业控制:汽车导航系统、工业自动化设备等也开始采用多点触摸屏,提升操作的直观性和便捷性。 5. 医疗与科研:医疗设备、实验室仪器通过多点触摸屏提供更精细的操作控制。 总的来说,多点触摸屏技术以其...
在UE4(Unreal Engine 4)中,开发者可以结合蓝图和C++代码来构建游戏逻辑,这提供了灵活性和性能的平衡。本工程分享主要关注如何在蓝图中调用C++函数,分为两种主要方式:一是通过继承C++类的蓝图类直接调用,二是...
在UE4(Unreal Engine 4)中,游戏对象的行为和交互主要通过C++或蓝图实现。本笔记将深入探讨如何使用C++编程语言来控制球体的运动,并结合移动粒子效果来提升游戏视觉体验。以下是你需要了解的关键知识点: 1. **...
在UE4(Unreal Engine 4)中,C++是一种主要的编程语言,用于实现游戏逻辑和自定义功能。在3D图形处理中,多边形的三角化是一个关键步骤,因为大多数现代图形硬件和软件都支持三角形作为基本渲染单元。本教程将深入...
实现了通过蓝图把场景中的AStaticMeshActor和两个动态材质实例UMaterialInstanceDynamic 传给c++ 自定义函数参数。 并在自定义函数里面实现两张材质的动态交替变更,其中一张材质还动态加载了本地1.png图片,使得能...
UE4 C++教程 虚幻四C++教程
在UE4(Unreal Engine 4)开发过程中,有时候我们需要获取电脑的唯一标识符或硬件信息,例如在实现用户认证、设备绑定等场景时。在UE4 4.25及之后的版本中,蓝图系统不再支持直接获取这些信息,这给开发者带来了一定...
虚幻引擎4(UE4)提供了两种主要的编程方式,即C++和蓝图。C++是一种通用的文本编程语言,适合进行底层逻辑和性能敏感的代码编写,而蓝图则是一种图形化编程工具,更适合快速原型设计和游戏逻辑的可视化表达。 在UE...
"UE4vs代码段.zip" 文件集合就是这样一个实用资源,它包含了一些预定义的代码片段,可以帮助开发者快速实现特定功能,提高开发效率。 首先,让我们详细了解一下这些代码段的具体内容: 1. **快捷创建碰撞事件的三...
4. **物理模拟**:UE4内置了强大的物理引擎,学习如何使用C++控制物体的运动、碰撞检测和刚体行为,对于创建真实感的游戏至关重要。 5. **图形渲染**:理解材质、着色器和光照模型,以及如何通过C++接口调整它们,...
UE4 C++ 离线API 下载直接使用 无障碍