Python和UE4结合建立WebSocket通信

前言 最近在做一个直播中用到的小工具,需求是从斗鱼或者虎牙平台中拉去直播的数据(弹幕和礼物等等),并将这些数据实时推流到一个UE4客户端,在客户端中根据这些数据做一些业务逻辑。这里采用的模型是,使用python写数据推流服务器,UE4作为客户端持续接收数据。这里主要记录一下整个过程中遇到的问题。 为什么是WebSocket https://www.ruanyifeng.com/blog/2017/05/websocket.html PIP(python包管理工具) https://baike.baidu.com/item/PIP/20435212?fr=aladdin python配置环境变量 https://www.cnblogs.com/huangbiquan/p/7784533.html 在cmd中安装Python工具包(webSocket) https://jingyan.baidu.com/article/86f4a73ea7766e37d7526979.html 在PyCharm中安装Python工具包 https://blog.csdn.net/m0_37332816/article/details/81353659 https://zhuanlan.zhihu.com/p/314507897

二月 3, 2022 · Imrcao

解决UE4万向节锁(Gimbal Lock)的问题

一、问题描述 在开发类似飞行类游戏的时候往往需要将相机的旋转范围设置到[-180~180],但引擎默认会将pitch和roll两个轴向限定到[-90~90],这并不是一个bug,是引擎为了适配FPS游戏所做的限制,你可以垂直向上或者向下看,超过这个角度就没有意义了且会导致万向节锁的现象,为了避免这种现象我们可以采用四元数的方法。 二、解决步骤 使用的是飞行模板,创建自己的GameMode和Controller和pawn并在worldSettings中设置为我们的GameMode。如图示1.1(注意Pawn类中要加入Camera组件) 1 2 图示1.1 项目设置中添加输入,如图示1.2 1 2 图示1.2 接下来是主要的一步,使用四元数的方法解决万向节锁的现象。为了方便使用,我这里写成了一个插件。如图1.3所示,选择模板“BlueprintLibrary”,创建一个插件。 1 2 图示1.3 打开VS,将如下代码加入到.h和.cpp中。注意:在cpp中将函数名称“UMyFunctionName”替换为自己的类名称。如图1.4所示 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 public: // 旋转公式:将欧拉角的度数转换为四元数 UFUNCTION(BlueprintCallable, meta = (DisplayName = "Euler To Quaternion", Keywords = "rotation, quaterion"), Category = "Quaternion Rotation") static FQuat Euler_To_Quaternion(FRotator Current_Rotation); // 根据输入的四元数设置组件的世界坐标的旋转 UFUNCTION(BlueprintCallable, meta = (DisplayName = "Set World Rotation (Quaterion)", Keywords = "rotation, quaternion"), Category = "Quaternion Rotation") static void SetWorldRotationQuat(USceneComponent* SceneComponent, const FQuat& Desired_Rotation); // 根据输入的四元数设置组件的相对旋转 UFUNCTION(BlueprintCallable, meta = (DisplayName = "Set Relative Rotation (Quaterion)", Keywords = "rotation, quaternion"), Category = "Quaternion Rotation") static void SetRelativeRotationQuat(USceneComponent* SceneComponent, const FQuat& Desired_Rotation); // 添加本地旋转量 UFUNCTION(BlueprintCallable, meta = (DisplayName = "Add Local Rotation (Quaterion)", Keywords = "rotation, quaternion"), Category = "Quaternion Rotation") static void AddLocalRotationQuat(USceneComponent* SceneComponent, const FQuat& Delta_Rotation); // 根据输入的四元数设置Actor的世界坐标的旋转 UFUNCTION(BlueprintCallable, meta = (DisplayName = "Set Actor World Rotation (Quaternion)", Keywords = "rotation, quaternion"), Category = "Quaternion Rotation") static void SetActorWorldRotationQuat(AActor* Actor, const FQuat& Desired_Rotation); //根据输入的四元数设置Actor的相对旋转 UFUNCTION(BlueprintCallable, meta = (DisplayName = "Set Actor Relative Rotation (Quaternion)", Keywords = "rotation, quaternion"), Category = "Quaternion Rotation") static void SetActorRelativeRotationQuat(AActor* Actor, const FQuat& Desired_Rotation); // 添加本地旋转量 UFUNCTION(BlueprintCallable, meta = (DisplayName = "Add Actor Local Rotation (Quaternion)", Keywords = "rotation, quaternion"), Category = "Quaternion Rotation") static void AddActorLocalRotationQuat(AActor* Actor, const FQuat& Delta_Rotation); FQuat UQuaternoinsBPLibrary::Euler_To_Quaternion(FRotator Current_Rotation) { //声明输出四元数 FQuat q; //将度数转换为弧度 float yaw = Current_Rotation....

六月 13, 2021 · Imrcao

UE4的静态加载和动态加载(引用资源)

引言 在日常的开发中会遇到很多使用C++来加载资源的情况,例如我们要引用Content下的蓝图类和非蓝图类,那么在UE4中提供了很多机制来引用这些资源。从网上查到的很多资料来看,很多游戏开发者将这种机制称之为“静态加载”和“动态加载”,但是从官方文档上来看,我并没有搜到静态加载相关的词语,官方将这种机制称之为“硬性引用(HardRefernences)”和“软性应用(SoftReferences)”。在这篇文章中我会把网上的资料和官方资料整理一下,也方便以后查阅。 静态加载-硬性引用 我这里理解的是静态加载和硬性引用一个意思,对应的动态加载和软性引用一个意思。硬性应用由两种场景的情况。 (1)直接属性引用:这是最常见的资源引用情况,通过宏UPROPERTY暴露给蓝图,这样可以允许设计人员在编辑器中指定相关资源。示例代码如下: /** construction start sound stinger */ UPROPERTY(EditDefaultsOnly, Category=Building) USoundCue* ConstructionStartStinger; (2)构造时引用:在构造函数引用确切的资源,这里是使用特殊的类ConstructorHelpers完成的,这个类中有两个对应的方法:FObjectFinder()和FClassFinder(),它们分别加载的是非蓝图资产(动画、贴图、模型、音效等)和蓝图类(角色蓝图、Widget控件)资产。示例代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 static ConstructorHelpers::FClassFinder<AChatOnline_WFYCharacter> PlayerPawnBPClass(TEXT("/Game/ChatOnline/WFY_Blueprint/Core/WFY_Character")); static ConstructorHelpers::FClassFinder<AHUD> PlayerHUDBPClass(TEXT("/Game/ChatOnline/WFY_Blueprint/Core/ChatOnline_WFYHUD_BP")); //DefaultPawnClass = AChatOnline_WFYCharacter::StaticClass(); if (PlayerPawnBPClass.Class!=NULL) { DefaultPawnClass = PlayerPawnBPClass.Class; } if (PlayerHUDBPClass.Class!=NULL) { HUDClass = PlayerHUDBPClass.Class; } class UTexture2D* BarFillTexture; static ConstructorHelpers::FObjectFinder<UTexture2D> BarFillObj(TEXT("/Game/UI/HUD/BarFill")); BarFillTexture = BarFillObj.Object; (了解更多:在以上构造函数中,ConstructorHelpers 类将尝试在内存中查找该资源,如果找不到,则进行加载。请注意,使用资源的完整路径来指定要加载的内容。如果该资源不存在或者由于出错而无法加载,那么该属性将设置为 nullptr。发生这种情况时,尝试访问纹理的代码将崩溃。最好进行声明,指出资源已正确加载(如果后续代码假设引用有效)。 UPROPERTY 的声明与前面的硬性引用示例相同。它们的工作方式相同,只不过是最初的设置方式有所差别。有关硬性引用的一个注意事项是,当对象加载并实例化时,还将加载以硬性方式引用的资源。您必须仔细地进行考虑,否则内存使用量会因为同时加载许多资源而迅速增加。如果您希望推迟该加载或确定要在运行时加载的内容,那么下列各节可以帮助您完成这些任务。) 动态加载-软性引用 动态加载最常用的两个模板化方法是LoadObject<>()和LoadClass<>()。同样的前者加载非蓝图类资产后者加载蓝图类资产。需要注意的是使用LoadClass时,路径名必须带_C后缀,LoadObject不需要带后缀。示例代码如下: //加载Content目录下的资源文件 UTexture2D* SpeackCheck; UTexture2D* MicCheck; //方法一: SpeackCheck = LoadObject(nullptr, TEXT("/Game/ChatOnline/WFY_Textture/Icon/Speaker_Check"));...

六月 3, 2021 · Imrcao

20191004-UE4C++实现异步批量加载资源

目的:异步加载指定路径下的所有Texture2D资源,并将它们显示到WIdget的Image上,每隔一定时间更新一次图片。 知识点包括:1、获取UI组件,2、获得场景中的Actor,3、实现异步批量加载资源,4、UE4定时器使用 一、分别创建继承自UUserWidget和AActor的C++类,UWealthWidget和AWealthActor。 基于UWealthWidget创建一个蓝图UWealthWidget_BP,在蓝图控件中创建Image命名为TexImage。 二、回到VS中,UWealthWidget.h中代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #pragma once #include "CoreMinimal.h" #include "Blueprint/UserWidget.h" #include "WealthWidget.generated.h" class UImage; class UOverlay; UCLASS() class FRAMECOURSE_API UWealthWidget : public UUserWidget { GENERATED_BODY() public: //利用UE4反射机制获得UMG中的控件,这里的名字一定要和蓝图中创建的Image的名字一致。 UPROPERTY(Meta = (Bindwidget)) UImage* TexImage; public: //重载父类的初始化函数 virtual bool Initialize() override; //加载2D图片 void AssignTexture(UTexture2D* InTexture); }; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 UWealthWidget....

六月 4, 2019 · Imrcao