1.定时器
#include "TimerManager.h"
2.拿到静态网格组件,并定时让他旋转到一定角度,清空定时器。
void AAirForce::TurnOnLeg() //起落架放下
{
/*UStaticMeshComponent* FrontLeg = Cast<UStaticMeshComponent>(m_childComponentMap["FLeg"]);
FrontLeg->SetRelativeRotation(FRotator(0,0,0));*/
if (m_childComponentMap.Contains("FLeg"))
{
FrontLeg = Cast<UStaticMeshComponent>(m_childComponentMap["FLeg"]);
}
if (m_childComponentMap.Contains("LLeg"))
{
LeftLeg = Cast<UStaticMeshComponent>(m_childComponentMap["LLeg"]);
}
if (m_childComponentMap.Contains("RLeg"))
{
RightLeg = Cast<UStaticMeshComponent>(m_childComponentMap["RLeg"]);
}
if (LegTime.IsValid())
{
GetWorld()->GetTimerManager().ClearTimer(LegTime);
}
GetWorld()->GetTimerManager().SetTimer(LegTime, this, &AAirForce::MinueValue, 0.1, true); //时间句柄 Time //时间句柄 Time
}
void AAirForce::MinueValue()
{
if (FrontLeg->IsValidLowLevel())
{
if (FLegRot.Roll > 0)
{
FLegRot.Roll -= 1;
}
else
{
FLegRot.Roll = 0;
if (LegTime.IsValid())
{
GetWorld()->GetTimerManager().ClearTimer(LegTime);
}
}
FrontLeg->SetRelativeRotation(FLegRot);
}
if (LeftLeg->IsValidLowLevel())
{
if (LLegRot.Roll > 0)
{
LLegRot.Roll -= 1;
}
else
{
LLegRot.Roll = 0;
if (LegTime.IsValid())
{
GetWorld()->GetTimerManager().ClearTimer(LegTime);
}
}
LeftLeg->SetRelativeRotation(LLegRot);
}
if (RightLeg->IsValidLowLevel())
{
if (RLegRot.Roll > 0)
{
RLegRot.Roll -= 1;
}
else
{
RLegRot.Roll = 0;
if (LegTime.IsValid())
{
GetWorld()->GetTimerManager().ClearTimer(LegTime);
}
}
RightLeg->SetRelativeRotation(RLegRot);
}
}
3.使用管理者拿到每一个目标,如果高于一定高度,并且之前在地面上,才收。这样一个Bool就可以让这个动作有唯一性。
case EMSG_OPER::UPDATE:
{
AActorBase* ab = HMSTargetManager::GetInstance().GetTargetByID(tg.TargetId);
//if (ab ->IsValidLowLevel()) //每一个置位
if (ab->IsValidLowLevel())
{
ab->MoveToPlace(tg.TargetLat, tg.TargetLon, tg.TargetAlt);
ab->SetEulerAngle(tg.TargetHeading, tg.TargetPitch, tg.TargetRoll);
ab->SetScale(FVector(tg.TargetScaleX, tg.TargetScaleY, tg.TargetScaleZ)); //2321G
if (tg.TargetAlt > 500 && ab->m_OnGround == true)
{
ab->TurnOffLeg(); //收起落架
ab->m_OnGround = false;
}
if (tg.TargetAlt < 500 && ab->m_OnGround == false)
{
ab->TurnOnLeg(); //放起落架
ab->m_OnGround = true;
}
//m_TargetFactory;
}
5.动态加载模型.以下部分个人觉得结合大钊的InisideUE4里,第一章Actor与Component关系理解会更深。
泛型加载各种组件
template< class T >
FUNCTION_NON_NULL_RETURN_START
T* NewObject(UObject* Outer, FName Name, EObjectFlags Flags = RF_NoFlags, UObject* Template = nullptr, bool bCopyTransientsFromClassDefaults = false, FObjectInstancingGraph* InInstanceGraph = nullptr)
附着节点,再设置相对父节点的位置。
bool AttachToComponent(USceneComponent* InParent, const FAttachmentTransformRules& AttachmentRules, FName InSocketName = NAME_None );
很简单,设置创建方法类型,并将组件添加到实例组件列表中
AddInstanceComponet
/** Adds a component to the instance components array */
void AddInstanceComponent(UActorComponent* Component);
可得UActorComponent的三个流程
- NewObject UObject相关略过
- Register
- Initialize 是一个在BeginPlay前调用的自定以的扩展接口
ConfigData 是读取到JSON文件并解析的数据,通过这段代码就可以拼接一个车,飞机,轮船等模型
if (ConfigData->StaticMeshInfo.Num() <= 0) return;
//加载各个组件。。MeshName绝不能重名,否则NewObject和TMap结构都会出问题
for (auto& it : ConfigData->StaticMeshInfo)
{
//UClass* baseClass = FindObject<UClass>(ANY_PACKAGE, TEXT("StaticMeshComponent"));
UStaticMeshComponent* tmpComp = NewObject<UStaticMeshComponent>(Cast<UObject>(this), *it.NodeID); //UObject,申请后转化为UStaticMeshComponent
if (m_childComponentMap.Contains(it.ParentName)) //如果 子节点字典里的包括了它的父节点的名字,就把它附着在父节点的相对位置
tmpComp->AttachToComponent(Cast<USceneComponent>(m_childComponentMap[it.ParentName]), FAttachmentTransformRules::KeepRelativeTransform);
else //否则附着在根节点的相对位置
tmpComp->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
tmpComp->RegisterComponent(); //注册
AddInstanceComponent(tmpComp);
tmpComp->SetRelativeLocation(FVector(it.PositionX, it.PositionY, it.PositionZ));
tmpComp->SetRelativeRotation(FRotator(it.RotationPitch, it.RotationYaw, it.RotationRoll));
UStaticMesh* tmpMesh = nullptr;
tmpMesh = GetStaticMeshAssets(it.MeshName); //动态加载这个UStaticMesh
tmpComp->SetStaticMesh(tmpMesh);
FVector tmpscale = tmpComp->GetRelativeScale3D(); //设置组件伸缩
tmpComp->SetRelativeScale3D(FVector(tmpscale.X * (it.ScaleX), tmpscale.Y * (it.ScaleY), tmpscale.Z * (it.ScaleZ)));
m_childComponentMap.Add(it.NodeID, tmpComp); //把NodeID,作为键值管理
m_childComponentTypeMap.Add(it.NodeID, EComType::MESH_TYPE);
UStaticMesh* AAirForce::GetStaticMeshAssets(const FString MeshName)
{
FString tmpPath = m_ResourcesPath + m_AircraftName + TEXT("/") + MeshName + TEXT(".") + MeshName + TEXT("'");
// /Script/Engine.StaticMesh'/Game/AirForceModels/J16/J_16_1_JiSheng.J_16_1_JiSheng'
// /Script/Engine.StaticMesh'/Game/AirForceModels/J10/J10_Normal.J10_Normal'
return LoadObject<UStaticMesh>(nullptr, *tmpPath);
}