ue4总结八

1、宏

#define MAX  1000

(1)宏名一般用大写

(2)宏定义末尾不加分号;

(3)可以用#undef命令终止宏定义的作用域

为了理解#define的作用,了解一下对C语言源程序的处理过程经过了预处理、编译、汇编

预处理: 
(1)   把源程序中的#include 扩展为文件正文,即把包含的.h文件找到并展开到#include 所在处。 
(2)   根据#if和#ifdef等编译命令将源程序中的某部分包含进来或排除在外
(3)    预处理器将源程序文件中出现的对宏的引用展开成相应的宏 定义,即本文所说的#define的功能,由预处理器来完成。 

2、ue4引擎中在编辑器中选中一个物体,按ctrl+b就可以自动定位到文件中
 

3、一个变量StreetlightScalar如果设置为RepNotify会自动产生一个函数,该函数再变量的值变化时自动调用

扫描二维码关注公众号,回复: 2906188 查看本文章

4、如果是子弹打到敌人用LineTraceByChannel射线判断,如果是投个渔网或者投个呼啦圈,用BoxTraceByChannel设置范围

5、在c++中写武器的Overlap事件

先要拿到武器的胶囊体,再调用OnComponentBeginOverlap函数,用一个委托,第二个参数绑定回调函数,对于这个函数,比如有很多按钮,需要写一个init方法放置许多按钮的这种函数,初始化时候调用init函数绑定按键和触发事件

如果这个回调函数是自己写的,参数要和OnComponentBeginOverlap的参数一样,可以在蓝图中查看这个函数,看每个参数

在回调函数中写这几个参数

 生成程序,可能会报错提示你正确的函数原型是什么样的,修改好参数就把Overlap和函数绑定好了

像按钮点击,overlap触发都是先拿到组件,然后调用事件.AddDynamic来接一个函数回调触发的

6、一个actor不生成看下是不是actor在生成的时候是否和其他物体已经碰撞所以看不到

在actor中某函数没触发可以看下是否该actor掉落到地上或者其他形式销毁了,所以没触发函数

7、设置人物动画无敌时间

在播放人物动画中Play Montage设置节点触发事件

在动画中添加Notify,这里有两个,应该添加Montage Notify而不是新建通知

8、在动画蓝图中某个动画创建了notify,触发某个事件

9、武器是否戳到敌人,在武器的boxCollision组件中发现box collision的框没了,解决方法,在Rendering中勾选visible,如果勾选就找基类是否没勾选

10、用c++编写AI

11、将一个sphere转换成static mesh,选择一个sphere拖到场景中,右键选择Conver Sphere To Static mesh

12、蓝图中的事件、函数和宏的区别

                                             事件 | 函数 | 宏
输入参数                              | O   |    O   | O
在网络上复制                      | O   |    X   | X
被其他蓝图调用                  | O   |    O   | X
输出参数(或返回值)      |  X  |    O    | O
被子类覆盖                          |  O  |    O   | X

Delay和Timeline节点,这些节点都只能在事件中去调用,而不能在函数中进行调用

函数和事件最本质的区别。函数的调用系统一定会等函数执行结束返回结果后,才会有后续动作,而事件的调用只是触发了事件的开始,系统就继续往下执行了,也即函数的执行都是在同一个线程,而事件的执行则是在多线程

13、GameMode不会复制到加入多人游戏的远程客户端;它只存在于服务器上

Game mode 只存在于服务器上,而 Game State 存在于服务器上且会被复制到所有客户端

14、虚幻则将潜在的物理碰撞和潜在的可视效果组合到了 PrimitiveComponent 中。任何在世界中具有形状的物体,要么就是能够被渲染显示,要么就是能作物理交互,它们都继承于 PrimitiveComponent。

15、火药桶爆炸时如何让周围的人或物体也受伤并把人炸飞?

(1)先调用SphereOverLapActor,在半径范围内拿到所有类型为CharacterMesh类型的Actor,遍历并对里面继承有Take Damage接口的Actor进行操作

(2)给这些Actor的Take Damage接口赋一个伤害,计算人和火药桶的向量,并给人一个速度,把人炸飞

16、在c++中写UButton的时候需要导入头文件,在文档查找UButton,可以看到最下面显示

那么在c++中这样导入就行,记住.generated.h要放在所有头文件的下面

#include "Components/Button.h"
#include "StartUserWidget.generated.h"

17、重写初始化方法的时候,由于先要实现父类的方法,可以先判断父类是否返回False,如果是,直接返回,再写后面的逻辑

18、在C++的Widget类中拿到某个控件

.h中:UButton* StartBtn;

首先在Widget的c++类有个Initialize方法用于初始化控件,在该函数中

.cpp中:StartBtn=Cast<UButton>(GetWidgetFromName(Text("Button_Start")));

注意Cast强转后面的也要用括号括起来

左边类型是UButton*然而经过Cast<>里面是UButton

19、如果函数小于4行,最好用FORCEINLINE

20、C++中typename和class的区别 :

在c++Template中很多地方都用到了typename与class这两个关键字,而且好像可以替换,是不是这两个关键字完全一样呢?
class用于定义类,在模板引入c++后,最初定义模板的方法为: template<class T>...... 
这里class关键字表明T是一个类型,后来为了避免class在这两个地方的使用可能给人带来混淆,所以引入了typename这个关键字,它的作用同class一样表明后面的符号为一个类型,这样在定义模板的时候就可以使用下面的方式了: template<typename T>......
在模板定义语法中关键字class与typename的作用完全一样。
typename难道仅仅在模板定义中起作用吗?其实不是这样,typename另外一个作用为:使用嵌套依赖类型(nested depended name),如下

class MyArray 
{ 
public:
typedef int LengthType;
.....
}

template<class T>
void MyMethod( T myarr ) 
{ 
typedef typename T::LengthType LengthType; 
LengthType length = myarr.GetLength; 
}

这个时候typename的作用就是告诉c++编译器,typename后面的字符串为一个类型名称,而不是成员函数或者成员变量,这个时候如果前面没有 typename,编译器没有任何办法知道T::LengthType是一个类型还是一个成员名称(静态数据成员或者静态函数),所以编译不能够通过。 
 

Typename的用法:

template <class T> 
class simpleTest
{
 public: 
    typename T::myint a; 
}; 
struct Node
{ 
    typedef int myint; 
}; 
int main()
{
     simpleTest<Node> s;
}

摘自:https://blog.csdn.net/pizzq/article/details/1487004

21、调试的时候在屏幕上输出信息

GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Red, FString(TEXT("dfsdfsdf")));

22、

在GameMode中负责对界面的切换,因此在BeginPlay中的所有页面的创建和绑定Button的Click事件的函数都写在这里:

startWidget=CreateWidget<UStartUserWidget>(GetGameInstance(),LoadClass<UStartUserWidget(this,TEXT("WidgetBlueprint'/Game/StarterContent/HDRI/UI/BP_StartUserWidget.BP_StartUserWidget_C'")));
加载一个类的时候,找到蓝图类,右键,复制引用,在TEXT中粘贴,最后要加_C

23、对于按钮的回调事件处理,在Widget的Initialize函数中除了拿到控件,还要对按钮的点击事件进行绑定

bool UStartUserWidget::Initialize()
{
	if (!Super::Initialize())
	{
		return false;
	}
	//初始化退出游戏按钮
	QuitBtn = Cast<UButton>(GetWidgetFromName(TEXT("Button_Quit")));
	QuitBtn->OnClicked.AddDynamic(this, &UStartUserWidget::QuitBtnOnClickEvent);
	return true;
}

//退出按钮点击事件
void UStartUserWidget::QuitBtnOnClickEvent()
{
	GEngine->AddOnScreenDebugMessage(-1,2.0f,FColor::Red,TEXT("dsfsd"));
}

24、进行页面切换

但是没有空指针判断,还是空指针判断比较好

startWidget->RemoveFromViewport();
if (registerWidget)
{
    registerWidget->AddToViewport();
}

25、创建组件

CreateDefaultSubObject

26、在GameMode中指定默认的pawn,通过ConstructorHelpers::FClassFinder来查找某个蓝图类,如果找某个c++类通过类名::Static方法

//构造方法
AStartGameMode::AStartGameMode()
{
    //设置默认Pawn
	ConstructorHelpers::FClassFinder<ACharacter> CharacterFinder(TEXT("/Game/StarterContent/Blueprints/Character/BP_XCharacter.BP_XCharacter_C"));
	DefaultPawnClass = CharacterFinder.Class;
	//设置PlayerController
	PlayerControllerClass=AAXPlayerController::StaticClass();
}

猜你喜欢

转载自blog.csdn.net/zhangxiaofan666/article/details/81199674