type
status
date
slug
summary
tags
category
icon
password
fullWidth
fullWidth
【C++】代码设置TriggerVolume后视窗内未更新
问题描述
用代码设置了TriggerVolume的变换之后,视窗内Actor的形状和碰撞都没有更新,需要去面板上“点”一下才行(点哪都行);而面板上的数据已更新和代码设置的一致,由此判断是面板数据不回传导致。
问题分析
改动面板数据后,视窗内物体的属性发生变化,是由于调用了
PostEditChangeProperty
这个回调函数,在这里用Brush->BuildBound
重建形状并用GEditor->RebuildAlteredBSP()
更新碰撞。参考
Brush
类的PostEditChangeProperty
的实现:解决方法
在
BrushBuilder
类重写的PostEditChangeProperty
的方法里,仿照上述方法,调用BuildBound
以重新构建TriggerVolume的形状,调用RebuildAlteredBSP
以重新构建碰撞数据:- BuildBound:
- 用来重建Brush的边界(Bounding Box)的函数。
- 当Brush的形状或位置发生变化时,需要重新计算它的包围盒。
- RebuildAlteredBSP:
- 用来重建BSP(二叉空间分割)树的函数,BSP是UE用于空间分割和碰撞检测的数据结构。
- 当Brush的形状、位置或属性改变时,需要重建BSP以保证碰撞和渲染正确。
接口封装:
【C++】得到鼠标射线向量的接口
需求描述
编辑时用鼠标射线绘制地形、样条是非常实用的功能,考虑封装一个接口。
已有实现
UEditorLevelLibrary
类的GetLevelViewportCameraInfo
方法可以获取当前关卡编辑器的视口摄像机位置和旋转,但这不太有参考价值,这个需求要的是把鼠标的屏幕坐标映射成世界坐标和方位射线。解决方法
从别的模块抄(复制)一个
DeprojectScreenToWorld
方法来,把鼠标的屏幕坐标映射到世界坐标,并得到鼠标射线方向向量。方法实现:
接口封装:
【C++】根据端口号获取运行中进程的exe路径
需求描述
起服之前要查询服务器端口是否被引用进程占用,若被占用则杀死引用进程;因此需要一个接口,根据指定的端口号查找所有占用该端口的进程的可执行文件路径。
解决方法
- 调用
GetTcpTable2
函数获取当前系统的TCP连接表(第一次调用获取所需缓冲区大小,分配足够内存后再次调用获取实际数据)。
- 查找本地端口等于目标端口的连接(注意要将本地端口号从网络字节序转换为主机字节序),通过进程ID打开进程句柄,用
GetModuleFileNameEx
获取可执行文件路径。
MIB_TCPTABLE2
结构体仅包含dwOwningPid
(进程ID),没有直接存储进程的可执行文件路径,必须用OpenProcess
打开进程,才能进一步查询其路径。- 关闭进程句柄,释放TCP表内存。
- 使用
TSet
自动去重后转为TArray
返回。
【C++】输出参数模式(Output Parameter Pattern)
在虚幻引擎的C++代码中,许多API(如
DeprojectScreenToWorld
)采用通过参数传递并内部修改的设计模式。虚幻引擎中这类API通常遵循以下实现惯例:
- 参数命名:输出参数通常以
Out
前缀标识
- 返回值:通常返回
bool
或状态码表示操作是否成功
广泛使用输出参数模式主要出于以下考虑:
- 多返回值需求
- C++原生不支持直接返回多个值,因此通过引用或指针传递多个输出结果
- 性能优化
- 直接修改传入的引用或指针,避免了返回大型对象(如
FHitResult
)时的拷贝开销 - 允许调用者复用已分配的对象(如重复使用同一个
FHitResult
以减少动态内存分配)
- 状态反馈
- 许多函数需要返回
bool
表示操作是否成功,而实际结果通过参数传递 - 调用者可立刻检查
bool
值从而无需处理异常数据
【Python】Tkinter线程通信解决UI卡顿
问题描述
信息的获取要请求服务器,此过程耗时,会阻塞线程导致UI卡顿。而获取信息后要呈现在面板上,因此需要有一个回调到主线程的机制(Tkinter是单线程GUI工具包,所有GUI操作,包括更新界面、处理事件,必须在主线程中执行)。
解决方法
把耗时的信息获取操作做成异步,放在子线程中处理;得到的信息通过
Tkinter
的after
方法回到主线程,并呈现在UI上。after()
的工作原理——通过事件队列实现跨线程通信- 事件队列机制
Tkinter 的主线程运行一个事件循环(
mainloop()
),不断检查事件队列(如按钮点击、窗口重绘等)。after()
的作用是向这个队列插入一个自定义事件。
- 线程安全的通信
当其他线程调用
after(0, callback)
时,Tkinter会将callback
封装成一个事件,安全地插入主线程的事件队列。主线程在下次处理事件时,会执行这个回调。
- 主线程启动异步任务
__async_fetch_and_log
- 异步任务
__async_fetch_and_log
中获取版本信息
__log_results_on_main_thread
中log信息通过Tkinter
的after
方法回到主线程
【Python】使用watchdog库监听文件内容变化
问题描述
有一个业务场景:UE编辑器抛异常时会把异常信息写入到
error.txt
中,使用 Python 开发的工作小助手如果处于后台运行模式,需要监听 error.txt
文件的变化,若发生变化则弹出报错弹窗提示用户联系专人处理。解决方法
使用第三方库
watchdog
。watchdog
是一个 Python 库,用于监听文件系统事件(如创建、修改、删除、移动等),内部实现基于操作系统提供的底层文件监控机制:- Windows:
ReadDirectoryChangesW
- Linux:
inotify
- macOS:
FSEvents
以Window平台为例,WindowsApiEmitter将更底层的系统 API 封装其中:
watchdog
的核心组成:Observer
:启动监听线程,管理事件调度- 在后台运行,监听文件系统变化
- 使用
schedule()
方法注册要监听的目录和事件处理器 - 调用
start()
启动监听线程,stop()
停止监听
FileSystemEventHandler
:处理文件系统事件的基类,可以自定义回调方法on_modified(event)
→ 文件被修改on_created(event)
→ 文件被创建on_deleted(event)
→ 文件被删除on_moved(event)
→ 文件被移动/重命名on_any_event(event)
→ 所有事件都会触发
observer
监听文件变化并处理事件,调试面板新增两个子线程:- 主监控线程(
observer.start()
):由observer.start()
直接创建,管理文件系统事件的监听
- 事件分发线程(
emitter.start()
):watchdog
内部自动创建,用于解耦事件捕获和事件处理,将文件系统事件从内核传递到Python回调
BaseObserver.start()
内部实现:最小化到托盘后启动
observer
:从托盘恢复窗口后关闭
observer
:【Python】子进程执行.bat脚本并捕获输出
需求描述
在开发Git仓库部署工具时,需要执行一个.bat脚本,并实时捕获脚本的输出信息显示在GUI界面上,供使用者查看。这个需求可以拆解成两个问题:
- 子线程控制主线程的GUI变化
- 主进程捕获子进程的控制台输出内容
解决方法
主线程中启动一个子线程,里面用子进程跑.bat脚本:
threading
模块启动子线程,通过self.after()
将GUI更新回调到主线程。
subprocess
模块在子线程中启动子进程,利用管道(PIPE)捕获输出;在死循环中读取和处理数据。

self.after()
是Tkinter
提供的一个核心方法,用于在主线程中延迟执行回调函数,允许从其他线程向主线程安全提交GUI操作请求。
代码:
【网络】本地回环地址和通配地址端口占用问题
问题描述
最近在调试一个本地游戏服务器时,发现一个有趣的现象:
- 先用 Python 启动一个 Socket 监听
127.0.0.1:9500
。
- 然后启动游戏服务器,默认监听
0.0.0.0:9500
。
- 结果发现两个服务都能正常运行,没有端口冲突。
控制台显示:
通配地址
0.0.0.0
和回环地址127.0.0.1
地址 | 0.0.0.0 | 127.0.0.1 (localhost) |
作用 | 监听所有网络接口(本机+外部) | 仅监听本地回环(本机内部通信) |
可访问性 | 外部设备可以访问(如手机、其他电脑) | 仅本机可以访问 |
典型用途 | Web 服务器、游戏服务器、数据库 | 本地开发调试、内部进程通信 |
原因分析
TCP套接字由
(IP, Port)
唯一标识,而不是单纯靠端口号。因此 Python 程序监听的127.0.0.1:9500
和游戏服务器监听的 0.0.0.0:9500
是两个不同的监听端点,不会冲突。但如果让Python程序的套接字绑定到 0.0.0.0:9500
再启动服务器,发现发生端口冲突,服务器无法启动。- Author:Yuki
- URL:http://shirakoko.xyz/article/work-note
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!
Relate Posts