UE5 C++ 定时器控制Component持续旋转 和 动态加载模型

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
    • 在注册组件的过程中,引擎将组件与场景关联起来,使其可用于每帧更新,并运行以下功能
    • 重写OnRegister函数以添加代码。
    • 初始化渲染状态
    • 初始化物理状态
  • 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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值