前言

模型的边缘高光应该是老生常谈的话题了, 不过还是有必要详细记录一下各种主流的两个实现方案, 同样的, 这个问题也经常在TA或者客户端面试中被问到

后期方案

先看效果动图

录制_2020_12_15_16_03_11_453

阅读全文 »

前言

对于很多情况下, 我们都希望我们可以在游戏运行状态下自定义UE4的按键映射, 目前的UE已经支持多数平台的按键在蓝图中实时的更改按键设置, 直接保存到 EngineInput.ini文件

写了一个案例插件,提供了几个解决方案的Demo和几个方便蓝图使用的库函数

RuntimeInputMapping

API

我们项目设置里的Input栏的内容其实是封装在一个UObjectUInputSettings中, 他其实就是一个配置类, 有一个静态方法可以直接获取该类

1
static UInputSettings* GetInputSettings();
阅读全文 »

使用静态博客有些日子了, 前阵子博客文件被手残折腾没了(还好文章有备份), 重新部署一下有点生疏了.

于是还是决定写一篇部署博客的文章重新记录一下部署流程

准备工作

  • 手动百度搜索node.js下载并安装
  • 下载并安装git
  • 注册github账户

关于git和github的使用在另外一篇博客里有详细说明,点击这里

  • 创建你的用户名.github.io的仓库,此仓库是用来保存博客文件的
    • 虽然非绝对必要但是强烈将以注册一个自己的域名,如阿里云;否则可能导致访问速度过慢或者无效
    • 在setting中的GitHubPages栏填写自己的域名

image-20201204094746007

安装Hexo

GitBash模式下输入安装hexo

1
$ npm install -g hexo

选择一个博客文件夹,输入如下代码初始化hexo环境

1
$ hexo init

初始化后在文件内会生成若干文件和文件夹,大致如下

image-20201204095336780

阅读全文 »

image-20201203141501722

image-20201203141518954

image-20201203141549721

需要打开源码版引擎,找到目录Engine\Extras\VisualStudioSnippets,里面有很多后缀是snippet的文件. 或者点击这里下载

如果是非源码版需要使用代码片段可以把这个文件夹复制对应的目录

  • VS导入UE代码片段

在VS中打开Tools(工具)-Code Snippets Manager(代码片段管理器)

image-20201203141902771

点击上图中的导入,找到之前所有snippet文件选择导入

然后在VS中按下组合键Ctrl+K然后Ctrl+X就可以选择所有代码片段了

Pure MVC是在基于模型、视图和控制器的MVC模式建立的一个轻量级的应用框架.

目前已经广泛应用于各类平台,常见用的语言如C#,Java等

本文尝试根据标准的C++PureMVC框架魔改成UE4版本方便使用的UnrealPureMVC(UPM)框架插件

github:UnrealPureMVC

阅读全文 »

有的时候我们需要对当前工程下的特定资源进行一些操作,比如找到所有图片资源或者所有静态模型资源,然后把这些资源信息发到某个UI上进行操作等等

本文对UE4资源注册模块AssetRegistry进行简单的分析

目前蓝图已经封装了相应的库,可以非常方便的调用

Asset Registry模块负责处理引擎下的资源信息(收集/检索*.uasset),从这个模块中可以读取到所有资源信息(FAssetData)

FAssetData

主要参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*Obj的具体路径,比如 /Game/ThirdPersonCPP/Blueprints/ThirdPersonCharacter.ThirdPersonCharacter*/
FName ObjectPath;
//比如/Game/ThirdPersonCPP/Blueprints/ThirdPersonCharacter
FName PackageName;
//比如: /Game/ThirdPersonCPP/Blueprints/
FName PackagePath;
//资源名称
FName AssetName;
//资源class的名称,如果是蓝图则是Blueprint
FName AssetClass;
/*
UProperty的名称和值的键值对
可以从此获取一些描述信息,比如蓝图资源的BlueprintType等
*/
FAssetDataTagMapSharedView TagsAndValues;
//ChunkID
TArray<int32> ChunkIDs;

在获取Asset的时候需要填充一个结构体参数FARFilter,里面的参数部分类似上述参数,之后再看

FARFilter

对资源进行检索的时候的过滤参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//参考FAssetData
TArray<FName> PackageNames;
//参考FAssetData
TArray<FName> PackagePaths;
//参考FAssetData
TArray<FName> ObjectPaths;
//参考FAssetData
TArray<FName> ClassNames;
//白名单,蓝图不可见
TMultiMap<FName, TOptional<FString>> TagsAndValues;
//黑名单
RecursiveClassesExclusionSet;
//是否递归查找路径
bool bRecursivePaths;
//是否递归查找类继承
bool bRecursiveClasses;
//是否只查询磁盘上的资源
bool bIncludeOnlyOnDiskAssets;

比较需要注意的是ClassNames这个参数,这个类型并不是我们场景中对象的类型,打个比方,我们场景里的玩家一般是ACharacter,但是我们的资源其实就是Blueprint,所以在填充这个结构体的时候并不能用*.::StaticClass()来给与Class类型

一般情况资源的创建类型就是用右键创建出来的名称或类似的名称,并且都是继承自Object

FAssetRegistryState

储存了读取asset后的相关信息,用作磁盘内容的cache数据,用于描述asset registry当前的状态,可以由IAssetRegistry进行使用和维护。把这些数据单独组成一个FAssetRegistryState类,是为了减少耦合性,因为引擎中除asset registry外的其他模块 也需要用到这些数据。

主要方法

我们可以通过static TScriptInterface<IAssetRegistry> GetAssetRegistry();获取单例

蓝图亦可以

image-20201127165818065

1
static UObject* GetAsset(const FAssetData& InAssetData);

通过上述方法可以自定义的根据FARFliter参数来获取所需的资源数据

如果不清楚每个参数的含义,可以反向的通过下面方法来查看

1
static FAssetData CreateAssetData(const UObject* InAsset, bool bAllowBlueprintClass = false);

1
2
3
bool GetAssetsByPackageName(FName PackageName, TArray<FAssetData>& OutAssetData, bool bIncludeOnlyOnDiskAssets = false) const;
bool GetAssetsByPath(FName PackagePath, TArray<FAssetData>& OutAssetData, bool bRecursive = false, bool bIncludeOnlyOnDiskAssets = false) const;
bool GetAssetsByClass(FName ClassName, TArray<FAssetData>& OutAssetData, bool bSearchSubClasses = false) const;

上面三个方法根据不同方式来获取对应的资源

1
void GetSubPaths(const FString& InBasePath, TArray<FString>& OutPathList, bool bInRecurse) const;

基于一个基础路径获取子路径,比较有用


1
2
bool GetReferencers(FName PackageName, TArray<FName>& OutReferencers, EAssetRegistryDependencyType::Type InReferenceType = EAssetRegistryDependencyType::Packages) const;
bool GetDependencies(FName PackageName, TArray<FName>& OutDependencies, EAssetRegistryDependencyType::Type InDependencyType = EAssetRegistryDependencyType::Packages) const;

获取引用和依赖关系,也很有用


1
2
3
4
	void SearchAllAssets(bool bSynchronousSearch);
void ScanFilesSynchronous(const TArray<FString>& InFilePaths, bool bForceRescan = false);
void ScanPathsSynchronous(const TArray<FString>& InPaths, bool bForceRescan = false);
//等等

扫描/搜索文件,不需要返回值,因为扫描以后文件就保存在FAssetRegistryState内了

录制_2020_10_31_14_52_47_579~2

上一篇留下了一个镜头抖动问题,实际上ALS项目是通过自定义CameraManager实现的,本篇就此来展开一下

AdvancedLocomotionSysemV4分析(一):移动和脚步IK

AdvancedLocomotionSystem分析(二):攀爬系统

AdvancedLocomotionSystemV4分析(三):动作叠加

AdvancedLocomotionSystemV4分析(四):布娃娃和起身

阅读全文 »

接下来就是布娃娃系统,对应的就有从布娃娃恢复成正常状态的起身动作。

这里还同时分析了一下站立和下蹲姿势的切换,因为起身动作会涉及到这一块

AdvancedLocomotionSysemV4分析(一):移动和脚步IK

AdvancedLocomotionSystem分析(二):攀爬系统

AdvancedLocomotionSystemV4分析(三):动作叠加

阅读全文 »

AdvancedLocomotionSysemV4分析(一):移动和脚步IK

AdvancedLocomotionSystem分析(二):攀爬系统

AdvancedLocomotionSystemV4分析(四):布娃娃和起身

AdvancedLocomotionSystemV4分析(五):镜头


本片主要分析一下ALS项目的动作叠加部分,主要用到各类姿势的切换,如受伤状态、持枪、持弓状态等,另外一种一般项目会用到的AnimOffset在这里没有用到,头部转向用了另外一种方式制作

录制_2020_10_29_16_42_10_43

阅读全文 »

ALS系统的攀爬系统思路比较简单,播放蒙太奇配合位置的刷新。缺点是没有中间状态,意味着无法打断或者做平移等

后面我打算尝试改成加入中间过程的攀爬系统

AdvancedLocomotionSysemV4分析(一):移动和脚步IK

AdvancedLocomotionSystemV4分析(三):动作叠加

AdvancedLocomotionSystemV4分析(四):布娃娃和起身

AdvancedLocomotionSystemV4分析(五):镜头

阅读全文 »