赞
踩
学习 ue4 的一些笔记记录, 记录各种踩坑, 也是一种不归路的写照. 持续更新中…
之前也有写过点,这里做个汇总,顺便补上漏记得东东,持续更新……
这里以 MyTest 项目名说明。
包含引擎类。如果需要扩展或使用引擎类,都在项目模块的预编译头文件 MyTest.h 中包含进来。自己创建的头文件都会包含这个 MyTest.h 头文件。
#ifndef __MYTEST_H__
#define __MYTEST_H__
#include "EngineMinimal.h"
#include "EngineGlobals.h"
#include "Engine/Engine.h"
#include "GameFramework/GameMode.h"
包含自己创建的类。
#pragma once
//#include "MyUtil.h"
#include "MyGameMode.generated.h"
UCLASS()
class MYTEST_API AMyGameMode : public AGameMode
#include "MyTest.h"
#include "MyGameMode.h"
//#include "MyUtil.h"
AMyGameMode::AMyGameMode() : Super()
安装 企业版 vs_enterprise.exe , 激活秘钥 VS2017序列号|Visual Studio 2017 激活码 序列号
下载 企业版: https://visualstudio.microsoft.com/zh-hans/downloads/
参考官方文档要求: https://docs.unrealengine.com/en-us/Programming/Development/VisualStudioSetup 中的 Options for a New Visual Studio Installation, 如果缺少组件, 可以再次双击 vs_enterprise.exe 安装缺少的组件.
安装视频教程: Setting up Visual Studio with UE4 - https://www.youtube.com/watch?v=4yQTGwuFm1w
edit->project settings->platforms->android
配置 sdk,ndk,java,ant 的目录
默认打包会分成 apk 安装包 和 obb 数据包, 如果不想要分包, 全都打在一个 apk 中, 可以在 edit->project settings->platforms->android 中勾选上 package game data inside .apk
参考: Unreal Engine 4:编译时出现中文乱码问题 - https://blog.csdn.net/netyeaxi/article/details/81206896
实测, 只有把 visual studio 的语言换成 英语, 才能解决问题. 在vs中 工具 -> 选项 -> 环境 -> 区域设置 -> 语言 中选择 English. (如果没有该语言, 可以通过 vs_enterprise.exe 安装语言包)
class类,在类的头上加上标记 Blueprintable 和 Blueprintable
UCLASS(Blueprintable, BlueprintType)
class MYTEST_API UCoolDownComp : public UActorComponent
enum枚举,加上 BlueprintType 即可,一般不用来继承使用
UENUM(BlueprintType)
enum class CharState : uint8 //动画状态
{
xxx.exe -MyFlagPresent 1
,获取到这个 MyFlagPresent 的值为 1其实就是使用ubt工具+参数
先cd到这个目录中,再使用命令生成vs2013的解决方案,默认是2015,没有安装的话会报错
I:\UnrealEngine_4.10\Engine\Binaries\DotNET>UnrealBuildTool.exe -projectfiles -project="F:/workplace_ue4/ShooterGame_4.10/data/ShooterGame.uproject" -game -rocket -progress -2013
vs工程就蹦出了
两者必须在同一帧同时替换,因为一个模型对应一个动画
bool UMyBpFuncLib::TestChangeCharAnimInstance(AMyChar* _myChar, FString _pathMesh, FString _pathAnim)
{
FStreamableManager* stream = new FStreamableManager();
FStringAssetReference ref1(*_pathMesh);
USkeletalMesh* TmpMesh = Cast<USkeletalMesh>(stream->SynchronousLoad(ref1));
_myChar->GetMesh()->SetSkeletalMesh(TmpMesh);
FStringAssetReference ref2(*_pathAnim);
UAnimBlueprint* TmpMeshAnim = Cast<UAnimBlueprint>(stream->SynchronousLoad(ref2));
_myChar->GetMesh()->SetAnimInstanceClass((UClass*)TmpMeshAnim->GetAnimBlueprintGeneratedClass());
delete stream;
return true;
}
真相
UObject* AMyText::TestLoadBPObject(FString _path) { auto cls = StaticLoadObject(UObject::StaticClass(), nullptr, *_path); if (!cls) { //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("Failed to load UClass ")); return nullptr; } else { //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("UClass LOADED!!!!")); UBlueprint* bp = Cast<UBlueprint>(cls); if (!bp) { //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("Failed to load UClass 2 ")); } else { //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Green, TEXT("UClass LOADED!!!! 2 " + bp->GetName())); TSubclassOf<class UObject> MyItemBlueprint; MyItemBlueprint = (UClass*)bp->GeneratedClass; UWorld* const World = GWorld->GetWorld(); if (World){ FActorSpawnParameters SpawnParams; //SpawnParams.Instigator = this; UObject* DroppedItem = World->SpawnActor<UObject>(MyItemBlueprint, GetActorLocation(), { 0, 0, 0 }, SpawnParams); } } return cls; } }
(只能传递string 和 int 两种类型参数)
CallFunctionByNameWithArguments 是 Uobject 的方法,所以只要是继承自Uobject的类都可以使用
UCLASS()
class UCoolDownMgr : public UObject, public FTickableGameObject, public USingleton<UCoolDownMgr>
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
UCoolDownMgr();
virtual ~UCoolDownMgr();
// Begin FTickableGameObject Interface.
virtual void Tick(float DeltaTime) override;
virtual bool IsTickable() const override;
virtual TStatId GetStatId() const override;
// End FTickableGameObject Interface.
};
void UMyBpFuncLib::TestNSLocatext(int32 _dayCount, int32 _hp) { FFormatNamedArguments Args; //命名式参数 Args.Add("DayCount", _dayCount); Args.Add("Hp", _hp); FText txt1 = FText::Format(NSLOCTEXT("Solus", "Day", "--- Day1 {DayCount}"), Args); FText txt2 = FText::Format(NSLOCTEXT("Solus", "HP", "--- HP1 {Hp}"), Args); FFormatOrderedArguments Args2; //索引式参数 Args2.Add(_dayCount); Args2.Add(_hp); FText txt3 = FText::Format(NSLOCTEXT("Solus", "Day", "--- Day2 {0}"), Args2); FText txt4 = FText::Format(NSLOCTEXT("Solus", "HP", "--- HP2 {1}"), Args2); FString str = txt1.ToString() + TEXT("\n") + txt2.ToString() + TEXT("\n") + txt3.ToString() + TEXT("\n") + txt4.ToString(); GEngine->AddOnScreenDebugMessage(0, 5.0f, FColor::Green, str); }
#define TCHAR_TO_ANSIANSI_TO_TCHAR(str) (TCHAR*)StringCast<TCHAR>(static_cast<const ANSICHAR*>(str)).Get()
#define TCHAR_TO_UTF8(str) (ANSICHAR*)FTCHARToUTF8((const TCHAR*)str).Get()
#define UTF8_TO_TCHAR(str) (TCHAR*)FUTF8ToTCHAR((const ANSICHAR*)str).Get()
/// This function is designed to be overridden by a blueprint. Do not provide a body for this function in C++; 不要给BlueprintImplementableEvent声明的方法提供c++方法实现,由蓝图实现
UFUNCTION(BlueprintImplementableEvent)
void CountDownHasFinished();
如果形参是fstring,就必须是引用类型,一般不需要蓝图修改的都加const,需要修改的就加引用声明
UFUNCTION(BlueprintImplementableEvent, Category = "MyBehavior")
void OnDeath(const FString& _str, int32 _num);
UFUNCTION(BlueprintImplementableEvent, Category = "MyBehavior")
void OnDeath(UPARAM(ref) FString& _str, int32 _num);
c++ 返回 多个值 给蓝图
如果需要返回多个值,就不需要再c++中 return,使用 形参引用 就行。
UFUNCTION(BlueprintCallable, Category = "UMyGameInstance")
void MyMerge(AActor* PlayerPawn, TArray<USkeletalMesh*> SrcMeshList, AActor*& retActor, USkeletalMeshComponent*& retSkeletalComp);
BlueprintNativeEvent,
UFUNCTION(BlueprintNativeEvent)
void CountDownHasFinished();
virtual void CountDownHasFinished_Implementation();
void AMyText::CountDownHasFinished_Implementation()
{ ... }
UCLASS(ClassGroup="MyCustom", meta=(BlueprintSpawnableComponent))
class UMyComp : public UActorComponent
{ ... };
->
void AMyBullet::Tick(float DeltaSeconds) { Super::Tick(DeltaSeconds); //每帧修正到目标的飞行方向 if (mTargetActor != nullptr) { FVector targetLoc = mTargetActor->GetActorLocation(); if ( mLastTargetLoc != targetLoc) { FVector bulletLoc = GetActorLocation(); FRotator rota = UKismetMathLibrary::FindLookAtRotation(bulletLoc, targetLoc); SetActorRotation(rota); MovementComp->Velocity = MovementComp->InitialSpeed * (targetLoc - bulletLoc).GetSafeNormal(); //子弹移动方向归一化,然后再乘以速度就成了速度矢量 mLastTargetLoc = targetLoc; } } }
重写父类这两个方法
virtual void OnInstanceCreated(UBehaviorTreeComponent& OwnerComp) override;
virtual void OnInstanceDestroyed(UBehaviorTreeComponent& OwnerComp) override;
因为有些数据不能再类的构造方法中初始化,涉及到引擎必须用引擎提供的 初始化方法,如:
void UBTDecorateMyBase::OnInstanceCreated(UBehaviorTreeComponent& OwnerComp)
{
//初始化成员都放在这个方法
if (!mOwnerChar)
mOwnerChar = GetMyChar();
if (!mBTComp)
mBTComp = &OwnerComp;
}
需要打开父类UBTAuxiliaryNode的开关,构造里默认设置为false
/** if set, OnTick will be used */
uint8 bNotifyTick : 1;
需要在子类中的构造中把这个开关打开
UBTDecorateMyBase::UBTDecorateMyBase()
: Super()
{
//设置tick 开关
bNotifyTick = true;
}
关卡中新建个自定义时间 moveCube
控制执行这个事件,输入命令:ce moveCube
如果在 ./Config/DefaultGameUserSettings.ini 不存在,这新建一个或者从 ./Saved/Config/Windows/GameUserSettings.ini 拷贝一份命名为 DefaultGameUserSettings.ini,保留自己想要的配置部分
[/Script/Engine.GameUserSettings]
bUseVSync=True
ResolutionSizeX=700
ResolutionSizeY=400
LastUserConfirmedResolutionSizeX=700
LastUserConfirmedResolutionSizeY=400
WindowPosX=-1
WindowPosY=-1
bUseDesktopResolutionForFullscreen=False
FullscreenMode=2
LastConfirmedFullscreenMode=2
Version=5
参考:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。