0%

FString ,FName,FText转换

FString ,FName,FText转换

From to
FName FString TestHUDString = TestHUDName.ToString();
FName FText TestHUDText = FText::FromName(TestHUDName);
FName -> FText 在一些情况下有效,但需注意 — FNames 内容不会从 FText 的”自动本地化”中受益。
FString FName TestHUDName = FName(*TestHUDString);
FString -> FName 不可靠。因为 FName 不区分大小写,所以转换存在损耗。
FString FText TestHUDText = FText::FromString(TestHUDString);
FString -> FText 在一些情况下有效,但需注意 — FString 内容不会从 FText 的”自动本地化”中受益。
FText FString TestHUDString = TestHUDText.ToString();
FText -> FString 不可靠。它在一些语言的转换中存在潜在损耗
FText FName FText 到 FName 的转换不存在。但可先转换到 FString,再转换到 FName。
FText -> FString -> FName 不可靠。因为 FName 不区分大小写,所以转换存在损耗。
FString int32 int32 TestInt = FCString::Atoi(*MyFString);
FString float float TestFloat = FCString::Atof(*MyFString);
int32 FString FString TestString = FString::FromInt(MyInt);
float FString FString TestString = FString::SanitizeFloat(MyFloat);
1
2
3
4
5
6
7
8
9
10
11
FName name = FName("this is a name");
FText::FromName(name);
name.ToString();

FString str = FString("this is a string");
FName name2 = FName(*str);
FText::FromString(str);

FText text = FText::FromString("this is a text");
text.ToString();
FName(*text.ToString());

总体而言,设置字符串变量文字时应使用 TEXT() 宏。如未指定 TEXT() 宏,将使用 ANSI 对文字进行编码,会导致支持字符高度受限。 传入 FString 的 ANSI 文字需要完成到 TCHAR 的转换(本地万国码编码),以便更高效地使用 TEXT()。

虚幻引擎中的字符串处理 | 虚幻引擎 5.4 文档 | Epic Developer Community

UE的几种输出方式

Log

1
2
3
4
5
6
UE_LOG(LogTemp, Log, TEXT("This is a log message."));
UE_LOG(LogTemp, Warning, TEXT("This is a warning message."));
UE_LOG(LogTemp, Error, TEXT("This is an error message."));

FString MyString = TEXT("Hello, World!");
UE_LOG(LogTemp, Log, TEXT("MyString: %s"), *MyString);

Debug Draw

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void DrawDebugSphere(UWorld* World, FVector Center, float Radius, int32 Segments, FColor Color, float LifeTime = 0.0f, uint8 DepthPriority = 0, bool bPersistentLines = false)
{
DrawDebugSphere(World, Center, Radius, Segments, Color, bPersistentLines, LifeTime, DepthPriority);
}

void DrawDebugLine(UWorld* World, FVector LineStart, FVector LineEnd, FColor Color, bool bPersistentLines = false, float LifeTime = 0.0f, uint8 DepthPriority = 0, float Thickness = 0.0f)
{
DrawDebugLine(World, LineStart, LineEnd, Color, bPersistentLines, LifeTime, DepthPriority, Thickness);
}

void DrawDebugPoint(UWorld* World, FVector Position, float Size, FColor Color, bool bPersistentLines = false, float LifeTime = 0.0f, uint8 DepthPriority = 0)
{
DrawDebugPoint(World, Position, Size, Color, bPersistentLines, LifeTime, DepthPriority);
}

输出到屏幕上

1
GEngine->AddOnScreenDebugMessage(-1, DisplayTime, Color, *Message);

委托-单播多播

帧同步和网络同步

定义

  • 帧同步:通过同步每一帧的操作指令,确保所有客户端在每一帧上执行相同的操作,从而保持游戏画面和逻辑的一致性。
  • 状态同步:通过服务器周期性地将游戏或系统的状态信息发送给所有客户端,以确保每个客户端上的游戏或系统状态保持一致。

工作原理

  • 帧同步
    1. 客户端在每一帧收集玩家操作并发送给服务器。
    2. 服务器汇总所有客户端的操作并广播给所有客户端。
    3. 客户端在同一帧上执行相同的输入操作。
  • 状态同步
    1. 客户端将操作发送到服务器。
    2. 服务器计算游戏行为的结果,并将结果广播给所有客户端。
    3. 客户端根据服务器发送的状态信息更新本地状态。

优缺点

  • 帧同步
    • 优点:延迟低,适合对实时性要求高的游戏;数据传输量小,服务器压力小;容易实现回放和观战功能。
    • 缺点:实现复杂,对网络延迟敏感;任何客户端的延迟或掉线都会影响整个游戏的同步。
  • 状态同步
    • 优点:安全性高,反外挂能力强;对网络延迟的适应性较高;适合复杂逻辑和物理交互的游戏。
    • 缺点:数据传输量大,可能导致带宽消耗高;延迟较大,响应速度慢。

区别

  1. 核心逻辑位置
    • 帧同步的战斗逻辑在客户端,状态同步的战斗逻辑在服务器。
  2. 数据传输量
    • 帧同步传输的是操作指令,数据量小;状态同步传输的是游戏状态,数据量大。
  3. 延迟适应性
    • 帧同步要求低延迟,状态同步对延迟的适应性更强。
  4. 安全性
    • 状态同步的安全性更高,因为所有逻辑都在服务器处理,帧同步更容易被篡改。
  5. 适用场景
    • 帧同步适用于动作快速、精确度要求高的游戏(如格斗游戏、MOBA游戏);状态同步适用于对复杂逻辑和物理交互要求高的游戏(如RPG、回合制游戏)

题目:

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

示例 1:

1
2
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

示例 2:

1
2
输入:nums = [0,1]
输出:[[0,1],[1,0]]

示例 3:

1
2
输入:nums = [1]
输出:[[1]]

代码:

1
2
3
4
5
6
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {

}
};

题目:

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 abc 使得 a + b + c = 0 ?请找出所有和为 0不重复 的三元组。

示例 1:

1
2
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]

示例 2:

1
2
输入:nums = []
输出:[]

示例 3:

1
2
输入:nums = [0]
输出:[]

代码:

1
2
3
4
5
6
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {

}
};

题目:

给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

请你设计并实现时间复杂度为 O(n) 的算法解决此问题。

示例 1:

1
2
3
输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。

示例 2:

1
2
输入:nums = [0,3,7,2,5,8,4,6,0,1]
输出:9

示例 3:

1
2
输入:nums = [1,0,1,2]
输出:3

代码:

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
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
unordered_set<int> num_set;
//去重,set集合元素唯一
for (const int& num : nums) {
num_set.insert(num);
}

int maxLength = 0;
int curNum = 0;
int curLength = 0;
for(const int& num:num_set)
{
//判断是否是开头的数字
// 100 99 5 7 6 2 1 (这里只有在遍历到99,5,1的时候才会进来)
if(!num_set.count(num-1))
{
curNum = num;
curLength = 1;
//找到最长的连续集合
while(num_set.count(++curNum))
{
curLength++;
}
maxLength = max(maxLength,curLength);
}
}
return maxLength;
}
};

考察的是对set集合的运用

题目:

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

字母异位词 是由重新排列源单词的所有字母得到的一个新单词。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
unordered_map<string, vector<string>> mp;
for (string& str: strs) {
string key = str;
sort(key.begin(), key.end());
mp[key].emplace_back(str);
}
vector<vector<string>> resultArr;
for (auto it = mp.begin(); it != mp.end(); ++it) {
resultArr.emplace_back(it->second);
}
return resultArr;
}
};

主要考察对哈希表的引用和排序