UE-MotionMatchingInteraction架构分析
模块:PoseSearch。目前对于MotionMatchingInteraction,无任何官方文档,无任何官方示例(即便是写这篇文章时Epic发布的UE5.7的GASP项目),故仅作参考。
关键类分析
Availabilities
类声明在 PoseSearchInteractionAvailability.h 中:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051// input for MotionMatchInteraction_Pure: it declares that the associated character ("AnimContext" that could be an AnimInstance or an AnimNextCharacterComponent)// is willing to partecipate in an interaction described by a ...
Games104笔记-2-引擎架构分层
本文为课程Games104第二节课:Layered Architecture of Game Engine的个人笔记。
A Glance of Game Engine Layers
工具层
当我们第一次接触UE或者Unity时,映入眼帘的不是晦涩的代码,而是一个由许多工具组成的UI操作界面(在UE里叫做UE-Editor):
这一层是面对我们引擎用户的,叫做工具层,我们将其放在最顶层。
功能层
引擎的产品是游戏。为了能让游戏能够看的见、场景能够动态变化并且游戏能够和我们用户输入交互,我们肯定需要对这些需求提供相应的功能实现。在面试中经常被问到游戏中碰撞检测的原理,这涉及到的就是物理系统;另外即便是游戏客户端岗位也不可避免地被拷打图形学相关知识,而实时渲染领域则被应用于游戏引擎的渲染系统;另外游戏中玩法相关以及NPC人物也都离不开脚本、AI系统等。
这一层叫做功能层,它为上面的工具层提供支持。
资源层
游戏中有许多不同类型的资源,例如三维模型、骨骼、动画、声音、贴图等。它们需要在同一个引擎内进行统一管理,这就是资源层的职能。它为功能层提供操作对象。...
游戏客户端面经(自整理版)
岗位:游戏客户端开发
C++
1. 深拷贝和浅拷贝
深拷贝和浅拷贝的核心区别在于:拷贝时到底是只复制一层引用,还是把引用指向的内容也一起复制出一份新的。
浅拷贝是什么
定义 浅拷贝是指按字节或按成员逐个复制对象的值。对于指针类型的成员,只复制指针本身(即地址),而不复制指针所指向的内容。 在 C++ 中,如果用户没有显式定义拷贝构造函数和拷贝赋值运算符,编译器会自动生成默认版本,这些默认版本执行的就是浅拷贝。
特点
执行速度快,实现简单
多个对象共享同一份动态资源
容易引发重复释放(double free)或悬垂指针(dangling pointer)问题
深拷贝是什么
定义 深拷贝是指不仅复制对象的成员变量本身,对于指针类型的成员,还会重新分配内存,并将原指针所指向的内容复制到新分配的内存中。这样每个对象都拥有自己独立的资源副本,互不影响。
特点
避免了资源重复释放和意外共享
实现相对复杂,需要显式定义拷贝构造函数和拷贝赋值运算符
性能开销较大(涉及内存分配和数据复制)
2. 编译器默认生成的拷贝构造(拷贝赋值)的语义是什...
TArray
UE源码解析-TArray
这篇文章我们来分析UE里的变长数组的实现,对应模块为 Core 。
在 ContainersFwd.h 中罗列了很多容器模板的声明,里面包含 TArray : 1template<typename T, typename Allocator = FDefaultAllocator> class TArray;
Allocator
默认的分配器是 TSizedHeapAllocator ,在 ContainerAllocationPolicies.h 中声明: 12template <int IndexSize> class TSizedDefaultAllocator : public TSizedHeapAllocator<IndexSize> { public: typedef TSizedHeapAllocator<IndexSize> Typedef; };using FDefaultAllocator = TSizedDefaultAllocator<32>...
cpp3
cpp八股3
这里我们主要手撕一些面试里可能让你手撕的轮子(?
队列
首先看看环形队列,就是固定大小的缓冲区上维护两个指针:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051template<typename T>class CircleQueue{public: CircleQueue(int capacity=5) : cap(capacity), nxt(0), head(0) { buf.resize(cap); } T& Front() { if(Empty()) throw std::runtime_error("Queue is empty"); return buf[head]; } T& Back() ...
cpp2
cpp八股2
实现三个智能指针
首先是 UniquePtr,它是独占式的智能指针,不能被复制,只能被移动。
12345678910111213141516171819202122232425262728293031323334353637383940template<typename T>class UniquePtr{public: UniquePtr(T* p = nullptr) : ptr(p) {} UniquePtr(const UniquePtr&) = delete; UniquePtr& operator=(const UniquePtr&) = delete; UniquePtr(UniquePtr&& other) noexcept : ptr(other.ptr) { other.ptr = nullptr; } UniquePtr& operator=(UniquePtr...
AYS
关于AYShooter
AYShooter是一款使用UE5.7开发的多人在线FPS游戏。
参考游戏:APEX、TTF2、PUBG、CS2、三角洲等。
title
玩法简介
3C
角色采用FPP、TPP双重视角,FPP视角只在客户端渲染,TPP视角在除了自己以外的其他玩家身上渲染。
FPP采用传统状态机模型,TPP采用MotionMatch,考虑使用Lyra的动画作为Database。
扩展CMC,实现冲刺、滑铲、走墙等动作,实现运动状态网络同步以及客户端预测。
使用GAS建模核心玩法操作,例如 GA_Fire , GA_Reload 等。
实现基本的场景交互,例如攀爬、翻越。可以参考GASP的实现。
武器系统
GAS实现武器射击、换弹等功能。
目前先实现一把步枪,后续可以扩展更多武器。
AI
可以考虑使用比较新的StateTree和SmartObject系统。Demo阶段不用考虑。
UI
考虑采用MVC架构,具体用委托实现。这方面无需考虑网络同步。
DevLog1 AYRenderer
开发日志 AYRenderer
渲染Pass,VertexShader
模型矩阵与法线矩阵
在AYRenderer的UI界面中,用户可以自行设置渲染物体的 Transform :
Transform
这个 Transform 会形成所谓的 Model 矩阵,在顶点着色器(VertexShader)中会用到这个矩阵来对顶点进行变换。(即M变换)
当然所谓的顶点不只有位置和旋转的属性,还有法线属性,而法线的变换所对应的 Normal Matrix 则是 Model Matrix 的逆转置矩阵:
123Mat4 modelMatrix = object.transform.GetModelMatrix();// 法线矩阵是模型矩阵的逆转置矩阵Mat4 normalMatrix = modelMatrix.Inverse().Transpose();
我们来证明一下,首先假设模型空间中某顶点对应的切线为 t⃗,该切线可以由模型空间的两个顶点 A, B 表示: t⃗ = B − A.
经过模型变换后,对应的切线 $\vec{t'}$ 为: $$
\vec{t'}...
cpp八股1
cpp八股1
多态
什么是多态?C++中如何实现多态?
多态指的是同一个接口(在不同对象上)有着不同的行为。C++中多态分为编译时多态(静态多态)和运行时多态(动态多态)。
编译时动态顾名思义指的是在编译阶段就能决定哪个接口对应于哪个对象。
典型实现一:函数重载
注意返回值类型不参与重载判断
1234567891011121314151617#include <iostream>using namespace std;// 函数重载:同名函数根据参数不同实现不同行为int add(int a, int b) { return a + b;}double add(double a, double b) { return a + b;}int main() { cout << add(10, 20) << endl; // 调用 int 版本 cout << add(3.5, 2.7) << endl; // 调用 dou...
DesignPatterns
设计模式
资料来源于NJU研究生课程《高级软件设计》
设计模式指的是在软件工程中,针对特定问题的典型解决方案的一种标准化描述。
通常可分为三大类(Design Pattern Catalog): - 创建型模式:与对象创建有关:单例、工厂、抽象工厂等 - 结构型模式:将类或对象按某种布局组成更大的结构:装饰、适配器、外观、组合、代理等 - 行为型模式:类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务,以及怎样分配职责:策略、状态、观察者、迭代器、模板、命令等
本文给出以上14个常用设计模式的cpp实现示例。
设计原则
单一职责原则(SRP,Single Responsibility Principle):一个类只负责一项职责
开闭原则(OCP,Open-Closed Principle):软件实体应对扩展开放,对修改关闭
里氏替换原则(LSP,Liskov Substitution Principle):子类对象必须能够替换掉所有父类对象
依赖倒置原则(DIP,Dependency Inversion Principle):高层模块不应该依...
