hi, every devs.
im ue5 beginner.
I am writing a program that generates a mesh in Unreal from vertex information.
First, upload an image of the phenomenon.
If you look at MESH_{idx}, it is a mesh I created, but no matter how much I change the ㅣㅐLocation value of Transform, it cannot be moved.
Even if you give a value to Tick(), only the Location value of Transform increases and the actual mesh object does not move.
Since it is a Static Mesh and does not move, I allowed
ProcecduralMesh->SetMobility(EComponentMobility::Movable);,
but it does not move.
I don’t know why.
I upload the entire code below. thank you
Actor header code:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
include “CoreMinimal.h”
include “GameFramework/Actor.h”
include “ProceduralMeshComponent.h”
include “MyMeshActor.generated.h”
UCLASS()
class SQLITETEST_API AMyMeshActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor’s properties
AMyMeshActor();
// 프리미티브 큐브 생성
UPROPERTY()
UStaticMeshComponent* CubeComponent;
// 프리미티브 실린더 생성
UPROPERTY()
UStaticMeshComponent* CylinderComponent;
// 필요한 메시 생성 및 설정 함수
void CreateCylinder(float Width, float Height, float Length, FVector Position, float Rotx, float Roty, float Rotz);
void CreateCylinder(UStaticMeshComponent* InCubeComponent, float Width, float Height, float Length, FVector Position);
void CreateCube(float Width, float Height, float Length, FVector Position, float Rotx, float Roty, float Rotz);
void CreateCube(UStaticMeshComponent* InCubeComponent, float Width, float Height, float Length, FVector Position);
void CreateMeshByVertex(TArray<FVector> Vertices, TArray<int32> Triangles);
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
private:
UStaticMesh* CubeMesh;
UStaticMesh* CylinderMesh;
UStaticMeshComponent* MeshComponent;
UPROPERTY(VisibleAnywhere, Category = “Mesh”)
UProceduralMeshComponent* ProceduralMesh;
actor cpp:
// Fill out your copyright notice in the Description page of Project Settings.
include “MyMeshActor.h”
include “Components/StaticMeshComponent.h”
include “KismetProceduralMeshLibrary.h”
include “UObject/ConstructorHelpers.h”
// Sets default values
AMyMeshActor::AMyMeshActor()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don’t need it.
PrimaryActorTick.bCanEverTick = true;
MeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComponent"));
ProceduralMesh = CreateDefaultSubobject<UProceduralMeshComponent>(TEXT("GeneratedMesh"));
RootComponent = MeshComponent;
// 메시 로드 및 저장
static ConstructorHelpers::FObjectFinder<UStaticMesh> CubeMeshFinder(TEXT("/Game/StarterContent/Shapes/Shape_Cube.Shape_Cube"));
if (CubeMeshFinder.Succeeded())
{
CubeMesh = CubeMeshFinder.Object;
}
static ConstructorHelpers::FObjectFinder<UStaticMesh> CylinderMeshFinder(TEXT("/Game/StarterContent/Shapes/Shape_Cylinder.Shape_Cylinder"));
if (CylinderMeshFinder.Succeeded())
{
CylinderMesh = CylinderMeshFinder.Object;
}
}
void AMyMeshActor::CreateMeshByVertex(TArray Vertices, TArray Triangles)
{
TArray Normals;
TArray UV0;
TArray VertexColors; // FColor 대신 FLinearColor 사용
TArray Tangents;
// 메쉬 생성
ProceduralMesh->CreateMeshSection(0, Vertices, Triangles, Normals, UV0, VertexColors, Tangents, true);
// 이동,회전 허용
ProceduralMesh->SetMobility(EComponentMobility::Movable);
// 법선 및 탄젠트 계산
UKismetProceduralMeshLibrary::CalculateTangentsForMesh(Vertices, Triangles, UV0, Normals, Tangents);
}
gamemode.cpp:
include “MyGameMode.h”
include “Engine/World.h”
include “MyActor.h”
include “MyMeshActor.h”
AMyGameMode::AMyGameMode()
{
PlayerControllerClass = AMyPlayerController::StaticClass();
}
void AMyGameMode::StartPlay()
{
Super::StartPlay();
FString FilePath = TEXT("C:\\sqlite\\rvtobjs.txt"); // 적절한 파일 경로
TArray<StackMeshVertexInfo> LoadedData = ParseMEPMeshes(FilePath);
if (GetWorld())
{
int idx = 0;
for (const StackMeshVertexInfo& MeshInfo : LoadedData)
{
// 위치 및 회전값 설정
FVector Location(0.0f, 0.0f, 0.0f); // 예제에서는 임시값 사용, 실제 사용시 MeshInfo에서 적절한 값을 가져와야 함
FRotator Rotation(0.0f, 0.0f, 0.0f);
// 스폰 파라미터 설정
FActorSpawnParameters SpawnParams;
SpawnParams.Owner = this;
// AMyMeshActor 스폰
AMyMeshActor* SpawnedMeshActor = GetWorld()->SpawnActor<AMyMeshActor>(AMyMeshActor::StaticClass(), Location, Rotation, SpawnParams);
if (SpawnedMeshActor != nullptr)
{
FString LabelName = FString::Printf(TEXT("MESH_%d"), idx++);
SpawnedMeshActor->SetActorLabel(LabelName);
// 스폰된 메쉬 액터에 대한 추가 설정 (예: 메쉬 데이터 설정)
SpawnedMeshActor->CreateMeshByVertex(MeshInfo.Vertex, MeshInfo.Indices);
//// 정적으로 생성 된 메쉬를 동적 메쉬로 변환
//UStaticMeshComponent* MeshComponent = SpawnedMeshActor->FindComponentByClass<UStaticMeshComponent>();
//if (MeshComponent)
//{
// // 메쉬 컴포넌트를 동적으로 설정
// MeshComponent->SetMobility(EComponentMobility::Movable);
// UE_LOG(LogTemp, Warning, TEXT("Mobility set to Movable for: %s"), *LabelName);
//}
// 새로운 위치로 이동
FVector NewLocation = FVector(100.0f, 100.0f, 100.0f);
bool bSuccess = SpawnedMeshActor->SetActorLocation(Location);
UE_LOG(LogTemp, Warning, TEXT("Actor moved: %s"), bSuccess ? TEXT("True") : TEXT("False"));
idx++;
}
}
}
}