UE C++ 实时加载模型的总结
一.总体思路:
如果实时加载UE模型,需要先将之前的模型删除。再生成出来,放在根节点,保持相对位置,相对的俯仰角。
void AAirForce::LoadWeapon(int ID, int Type, double X, double Y, double Z)
{//m_weaponMap.Empty();//生成工厂if (m_weaponMap.Contains(ID)){AActorBase* ab =Cast<AActorBase>(*m_weaponMap.Find(ID));if (ab != nullptr && ab->IsValidLowLevel() && !ab->IsPendingKill()){ab->Destroy();}m_weaponMap.Remove(ID);}ATargetFactory* TargetFactory = GetWorld()->SpawnActor<ATargetFactory>();//FString tmpWeaponPath = UKismetSystemLibrary::GetProjectDirectory() + "Plugins/HMSCore/Saved/Config/" + "AG_300M" + ".Json";FString tmpWeaponPath = UKismetSystemLibrary::GetProjectDirectory() + "Plugins/HMSCore/Saved/Config/" + m_WeaponType[Type] + ".Json";AActorBase* TargetActor = TargetFactory->TargetSpawn(ETargetType::WEAPON_TYPE, tmpWeaponPath);TargetActor->SetID(ID);TargetActor->AttachToComponent(Cast<USceneComponent>(RootComponent), FAttachmentTransformRules::KeepRelativeTransform);TargetActor->SetActorRelativeLocation(FVector(X, Y, Z));//UE_LOG(LogTemp, Warning, TEXT("%f, %f , %f"), it.PositionX, it.PositionY, it.PositionZ);TargetActor->SetActorRelativeRotation(FRotator(0, 0, 0));TargetActor->SetScale(FVector(1, 1, 1));m_weaponMap.Add(ID, TargetActor);TargetFactory->Destroyed;
}
二.管理Map
TMap<int, UObject*> m_weaponMap; //组件字典
首先看武器的Map里是否,包含之前加载的武器模型。如果包含这个ID的武器。找到并拿到它,销毁。然后在Map里移除这个指针。
if (m_weaponMap.Contains(ID)){AActorBase* ab =Cast<AActorBase>(*m_weaponMap.Find(ID));if (ab != nullptr && ab->IsValidLowLevel() && !ab->IsPendingKill()){ab->Destroy();}m_weaponMap.Remove(ID);}
重新生成,m_WeaponType在构造时初始化,工厂然后通过,工厂生成武器。
TMap<int32, FString> m_WeaponType; //武器字典2321F
ATargetFactory* TargetFactory = GetWorld()->SpawnActor<ATargetFactory>();
//FString tmpWeaponPath = UKismetSystemLibrary::GetProjectDirectory() + "Plugins/HMSCore/Saved/Config/" + "AG_300M" + ".Json";
FString tmpWeaponPath = UKismetSystemLibrary::GetProjectDirectory() + "Plugins/HMSCore/Saved/Config/" + m_WeaponType[Type] + ".Json";
AActorBase* TargetActor = TargetFactory->TargetSpawn(ETargetType::WEAPON_TYPE, tmpWeaponPath);
武器生成后,就可以了,然后销毁工厂。
设置ID,让它们绑定到组件上,将根组件变为USceneComponet组件,就有位置信息。
AttachToComponent(USeneComponnet,FAttachmentTransformRules::KeepRelativeTransform).
让后设置相对于根节点的相对位置。
TargetActor->SetID(ID);TargetActor->AttachToComponent(Cast<USceneComponent>(RootComponent), FAttachmentTransformRules::KeepRelativeTransform);TargetActor->SetActorRelativeLocation(FVector(X, Y, Z));//UE_LOG(LogTemp, Warning, TEXT("%f, %f , %f"), it.PositionX, it.PositionY, it.PositionZ);TargetActor->SetActorRelativeRotation(FRotator(0, 0, 0));TargetActor->SetScale(FVector(1, 1, 1));m_weaponMap.Add(ID, TargetActor);TargetFactory->Destroyed;
如果想要不在跟组件上,就使用如下代码。
int WeaponID = FCString::Atoi(*it.NodeID);TargetActor->SetID(WeaponID);if (m_childComponentMap.Contains(it.ParentName))TargetActor->AttachToComponent(Cast<USceneComponent>(m_childComponentMap[it.ParentName]), FAttachmentTransformRules::KeepRelativeTransform);elseTargetActor->AttachToComponent(Cast<USceneComponent>(RootComponent), FAttachmentTransformRules::KeepRelativeTransform);TargetActor->SetActorRelativeLocation(FVector(it.PositionX, it.PositionY, it.PositionZ));UE_LOG(LogTemp, Warning, TEXT("%f, %f , %f"), it.PositionX, it.PositionY, it.PositionZ);TargetActor->SetActorRelativeRotation(FRotator(it.RotationPitch, it.RotationYaw, it.RotationRoll));TargetActor->SetScale(FVector(it.ScaleX, it.ScaleY, it.ScaleZ));m_weaponMap.Add(WeaponID, TargetActor);
删除map,可以用for(auto& it:Map).逐个Destroy。再Reset重置。
void HMSTargetManager::RemoveTarget(int targetID)
{AActorBase* ab = *m_TargetMap.Find(targetID);if (ab != nullptr){ab->Destroy();}m_TargetMap.Remove(targetID);
}void HMSTargetManager::RemoveAllTarget()
{for (auto& it:m_TargetMap){AActorBase* ab = it.Value;if (ab != nullptr){ab->Destroy();}}m_TargetMap.Reset();
}