https://www.udemy.com/share/100YVuA0sbd1tXRng=/

 

이거보고 공부했읍니다.

가격도 매우 저렴합니다 언리얼 블로그에서 링크통해가면 더 할인도 되요(영어주의)

 

 

 

리플리케이트로 움직이는 액터의 

 

 

헤더파일

 

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Engine/StaticMeshActor.h"
#include "MovingPlatform.generated.h"

/**
 * 
 */
UCLASS()
class TEST_API AMovingPlatform : public AStaticMeshActor
{
	GENERATED_BODY()

public:
	AMovingPlatform();
	
	virtual void Tick(float DeltaTime) override;

	virtual void BeginPlay() override;

	UPROPERTY(EditAnywhere)//블프나 에디터상에서 모두 편집가능
		float Speed = 20;

	UPROPERTY(EditAnywhere, Meta = (MakeEditWidget = true))//에디터상 위젯에 나타냄
		FVector TargetLocation;

	void AddActiveTrigger(); //이동
	void RemoveActiveTrigger(); //해제

private:
	FVector GlobalTargetLocation;
	FVector GlobalStartLocation;

	UPROPERTY(EditAnywhere)
		int ActiveTriggers = 0; //트리거 발동조건
};

 

구현부

// Fill out your copyright notice in the Description page of Project Settings.

#include "MovingPlatform.h"

//움직이는 스태틱메쉬
AMovingPlatform::AMovingPlatform() {
	//틱 이벤트 사용
	PrimaryActorTick.bCanEverTick = true;

	//이물체가 이동성을 가지는지 설정 Enum형
	SetMobility(EComponentMobility::Movable);

}

void AMovingPlatform::BeginPlay()
{
	Super::BeginPlay();

	if (HasAuthority()) {
		//서버와 클라이언트를 동기화
		SetReplicates(true);
		SetReplicateMovement(true);
	}
	GlobalStartLocation = GetActorLocation();
	GlobalTargetLocation = GetTransform().TransformPosition(TargetLocation);
}

void  AMovingPlatform::Tick(float DeltaTime) {
	//부모로부터 가상함수를 재정의 하고있는지 확인
	Super::Tick(DeltaTime);

	if(ActiveTriggers >0 ) //트리거 발동되었을때.

	//참이면 서버, 거짓이면 단일 클라이언트일때를 분기
	if (HasAuthority()){
		//현재액터의 위치 변수저장하기
		FVector location = GetActorLocation();
	//틱마다 x축으로 델타시간*스피드 만큼 이동

	float JourneyLength = (GlobalTargetLocation - GlobalStartLocation).Size(); //목표지점과 첫지점의 거리
	float JourneyTravelled = (location - GlobalStartLocation).Size(); //현재내지점과 목표지점의 거리 

	if (JourneyTravelled >= JourneyLength) //목표지점 첫지점을 바꿈 
	{
		FVector Swap = GlobalStartLocation;
		GlobalStartLocation = GlobalTargetLocation;
		GlobalTargetLocation = Swap;
	}

	//방향벡터구하기
	FVector Direction = (GlobalTargetLocation - GlobalStartLocation).GetSafeNormal();
	//이동
	location += Speed * DeltaTime * Direction;
	SetActorLocation(location);
	
	
	
}
	
}

void AMovingPlatform::AddActiveTrigger()
{
	ActiveTriggers++;
}

void AMovingPlatform::RemoveActiveTrigger()
{
	if (ActiveTriggers > 0) {
		ActiveTriggers--;
	}
}

 

 

버튼이눌렸을때 액터가 움직이도록  하는 액터의 헤더파일 

 

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "PlatformTrigger.generated.h"

UCLASS()
class TEST_API APlatformTrigger : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	APlatformTrigger();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

private:
	UPROPERTY(VisibleAnywhere)
		class UBoxComponent* TriggerVolume;


	UFUNCTION() // 겹쳤을때 함수
		void OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

	UFUNCTION() // 나왔을대 함수
		void OnOverlapEnd(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

	UPROPERTY(EditAnywhere) //트리거가 발동되었을때 움직이는 플랫폼의 배열 
		TArray<class AMovingPlatform*> PlatformsToTrigger;

};

 

// Fill out your copyright notice in the Description page of Project Settings.

#include "PlatformTrigger.h"
#include "Components/BoxComponent.h"
#include "MovingPlatform.h"

// Sets default values
APlatformTrigger::APlatformTrigger()
{
 	// 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;

	TriggerVolume = CreateDefaultSubobject<UBoxComponent>(FName("TriggerVolume"));
	if(!ensure(TriggerVolume != nullptr)) return;
		RootComponent = TriggerVolume;

		TriggerVolume->OnComponentBeginOverlap.AddDynamic(this, &APlatformTrigger::OnOverlapBegin);
		TriggerVolume->OnComponentEndOverlap.AddDynamic(this, &APlatformTrigger::OnOverlapEnd);
}

// Called when the game starts or when spawned
void APlatformTrigger::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void APlatformTrigger::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

void APlatformTrigger::OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	UE_LOG(LogTemp, Warning, TEXT("Activated"));

	for (AMovingPlatform* Platform : PlatformsToTrigger) //배열에있는 트리거들 모두순회
	{//이동트리거발동
		Platform->AddActiveTrigger();
	}

}

void APlatformTrigger::OnOverlapEnd(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
	UE_LOG(LogTemp, Warning, TEXT("Deactivated"));

	
	for (AMovingPlatform* Platform : PlatformsToTrigger)
	{//이동트리거제거
		Platform->RemoveActiveTrigger();
	}
}

 

 

+ Recent posts