묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결언리얼 엔진4 (Unreal Engine) 3D 횡스크롤 게임 만들기
exe 빌드할 시 컷씬 이후 화면 꺼짐
완성된 프로젝트 파일을 다운로드 받아 exe파일을 만들어 실행해보았는데, 컷씬 재생 이후 플레이어 체력 등 UI들만 출력되고 화면이 까맣게 되어 아무 것도 안보입니다. 어떻게 해결하나요?
-
미해결이득우의 언리얼 프로그래밍 Part2 - 언리얼 게임 프레임웍의 이해
delegate wrapper 사용 이유
안녕하세요 좋은 강의 정말 감사드립니다.다름이 아니라 delegate wrapper 사용 이유가 궁금하여 질문 드립니다.선생님께서 delegate를 다수 배열로 관리하기 해야 하는데 이 자체를 인자로 쓸 수 없다고 하신 부분이 잘 이해가 되지가 않습니다. 어느 부분을 인자로 쓸 수 없는지에 대해 구체적으로 말씀해주실 수 있나요?FTakeItemDelegateWrapper 랩퍼 구조체가 아닌 FOnTakeItemDelegate 델리게이트를 TArray 배열에 넣을 수도 있고이런 식으로 바인드도 되고, 실행도 되는데 왜 델리게이트 랩퍼 구조체를 따로 만들어야하는지가 궁금합니다.
-
미해결이득우의 언리얼 프로그래밍 Part2 - 언리얼 게임 프레임웍의 이해
enhanced input 키 동시입력
안녕하세요 교수님, void APACharacterPlayer::Move(const FInputActionValue& Value) { FVector2D MovementVector = Value.Get<FVector2D>(); const FRotator Rotation = Controller->GetControlRotation(); const FRotator YawRotation(0, Rotation.Yaw, 0); FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X); FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y); if (bIsRunning) { if (MovementVector.Y != 0) MovementVector.Y = 0; if (MovementVector.X == -1) MovementVector.X = 1; AddMovementInput(ForwardDirection, MovementVector.X); } else { if (MovementVector.Y != 0 || MovementVector.X == -1) bCanSprint = false; else bCanSprint = true; AddMovementInput(ForwardDirection, MovementVector.X); AddMovementInput(RightDirection, MovementVector.Y); UE_LOG(LogTemp, Log, TEXT("X = %f y = %f"),ForwardDirection.X, RightDirection.Y); } } 위 코드는 3인칭 게임플레이를 위해 강의 기반으로 작성한 코드입니다. bCanSprint 및 Running 로직은 무시하셔도 됩니다.발생한 문제는 키의 동시 입력을 받을 때 입니다. 왼쪽 방향키를 누른 채로 오른쪽 방향키를 누르면 MovementVector 값이 1.0 으로 변해서 오른쪽으로 잘 이동 하는데, 오른쪽 방향키를 누른 채로 왼쪽 방향키를 누르면 벡터 값이 변하지 않아 계속 오른쪽으로 갑니다. 똑같이 앞 방향키를 누른 채로 뒷 방향키를 누르면 뒤로 가지는데, 뒷 방향키를 누른채로는 앞으로 갈 수가 없습니다. 물론 따로따로 한 버튼씩 서로 역이 되는 방향키를 누를 때는 값이 알맞게 잘 변경됩니다. 원하는 로직은 두 가지 중에 하나입니다.동시입력이 들어왔을 경우 마지막 입력 방향으로 이동동시입력이 서로 반대 방향으로 들어왔을 경우 상쇄되어 정지 로직을 어떻게 수정해야 할까요? 동시입력(오른쪽 홀드+왼쪽이동, 뒤쪽홀드 + 앞쪽이동) 할 때만 벡터값이 제대로 변하지 않는 이유를 못 찾겠습니다..
-
미해결이득우의 언리얼 프로그래밍 Part3 - 네트웍 멀티플레이 프레임웍의 이해
리슨 서버 시 위젯 부착 관련
//CharacterBase.hif (!IsLocallyControlled()) { UE_LOG(LogTemp, Log, TEXT("LocallyControlled")); InfoBar = CreateDefaultSubobject<UWidgetComponent>(TEXT("Widget")); InfoBar->SetupAttachment(GetMesh()); InfoBar->SetRelativeLocation(FVector(0.0f, 0.0f, 210.0f)); static ConstructorHelpers::FClassFinder<UUserWidget> InfoBarWidgetRef(TEXT("/Script/UMGEditor.WidgetBlueprint'/Game/ProjectA/Blueprints/UI/WBP_InfoBar.WBP_InfoBar_C'")); if (InfoBarWidgetRef.Class) { InfoBar->SetWidgetClass(InfoBarWidgetRef.Class); InfoBar->SetWidgetSpace(EWidgetSpace::Screen); InfoBar->SetDrawSize(FVector2D(300.0f, 75.0f)); InfoBar->SetCollisionEnabled(ECollisionEnabled::NoCollision); } }안녕하세요 교수님, 리슨 서버로 동작 시킬 때 제가 만든 InfoBar 를 로컬의 캐릭터에는 부착하지 않고 로컬이 바라보는 프록시들에게만 부착을 하고 싶습니다. 그래서 제 생각에는 로컬로 컨트롤 되고 있다면 위젯을 생성하지 않는 방식으로 해결을 하려 했는데, 그럼에도 InfoBar 가 생성되어 부착됩니다.어떻게 하면 제가 의도한 대로 로컬에서는 프록시의 InfoBar 만 보이게 설계 할 수 있을까요?
-
미해결[입문자를 위한 UE5] Part1. 언리얼 엔진 블루프린트
이벤트 vs 함수 차이
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 이벤트 경우에 시작되는 지점은 알 수 있지만 끝나는 시기를 모른다는 의미를 잘 모르겠습니다. 일단 실행되면 끝날 때까지 이벤트 함수에 머무는 것이 아니라 비동기적으로 처리하는 건가요? 딜레이를 이벤트에서는 사용가능하지만 함수에서는 사용하지 못 하는 게 함수는 점유율을 100% 다 가져가서 다른 코드가 실행될 여지를 빼았기 때문인가요? 반대로 이벤트는 점유율이 왔다갔다 왕복하면서 실행이 되는 건가요?
-
미해결[왕기초] 후디니 게임 이펙트 만들기
export 오류에 관해 질문드립니
초심자에게 빛줄기와 같은 강의입니다 감사합니다 다만 문제가 생겼는데 export 따라하는 과정에서 vat abc fbx 방법들이 후디니 프리버전에선 지원하지 않는다고 오류(FBX export Apprenticeis not supported in houdini.)가 뜨는데 학생이나 인디버전 사용하면 해결 될까요?
-
미해결[입문자를 위한 UE5] Part3. 언리얼 엔진 3D 게임 개발 입문
애니메이션 커브 Rotation관련 질문드립니다.
섹션3 애니메이션 - 애니메이션 커브강의에서 궁금한점이 있느데요.Get Curve Value가 리턴하는 값을 print text 함수를 통해서 로그를 찍어보았는데, Right로 돌리는걸 기준으로 해서 제 예상에는 -90, -80, -70 ... 0 이렇게 될거라고 예상을 했는데, 실제로 로그를 찍어보니, -1, -10, -20, ... -80, -75, -70, .... 0 이런느낌으로 찍히는데, 이유를 잘 모르겠습니다.Right Animation에서 Rotation Curve는 -90~0으로 세팅되어있습니다.
-
미해결[입문자를 위한 UE5] Part4. 언리얼 엔진 C++
SimpleMoveToLocation() 작동 안함.
디아블로 방식의 컨트롤 강의중 PlayerController에서 클릭 했을 때 그 위치로 이동하는 SimpleMoveToLocation()함수가 작동을 안 하는데 네비메쉬 문제 일까요?
-
미해결언리얼5 액션 RPG 만들어봐요!! 파트1
강의자료 구글 드라이버가 끈겨습니다
언리얼 C++은 의지가 있어야 합니다. 저는 여러분들이 프로그래밍 언어와 언리얼 엔진에 대해서 많은 관심이 있어서 강의를 듣는다고 생각합니다. 여러분들의 미래를 위해서 시간 투자 많이 해주시고, 네이버 카페를 통해서 적극적으로 해 주셔서 언리얼 엔진에 푸짐하게 익숙해 지셔서 여러분들의 미래를 여러분들이 만들어 가기를 바랍니다.https://cafe.naver.com/insaneoops//구글드라이버가 끈겨습니다 ~ ;;;어디서 자료를 받아야하나요 ?아 2 번에 코드만 모아논건 살아있내요
-
미해결[입문자를 위한 UE5] Part4. 언리얼 엔진 C++
GamePlayAttribute & Protobuf
데디서버가 아닐때 protobuf 클래스를 그대로 사용하는 것을 상당히 좋은 방법이라고 생각했었는데, GameplayAttribute를 쓰면 앞의 방식을 포기하게 되는 경우가 있었나요? 아니면 사용하기는 하나 GameplayAttribute를 위해 protobuf에서 FGameplayAttributeData쪽에 복사를 해서 사용하려나요...
-
미해결이득우의 언리얼 프로그래밍 Part3 - 네트웍 멀티플레이 프레임웍의 이해
데디케이티드 서버 관련 질문
안녕하세요, 강의 관련 질문은 아니지만 궁금한 점이 생겨 질문 올립니다. 개인 프로젝트로 TPS 생존 게임을 제작하려 합니다. 한 경기에 10명 내외의 클라이언트가 접속할 예정입니다.언리얼 엔진에서 제공하는 리슨 서버와 데디케이티드 서버 중 어떤 방식이 알맞을까요?만약 데디케이티드 서버가 알맞다면 리슨 서버에서 구현했던 if(Hasauthority()) 등의 로직들은 제거해주면 되는 것인가요? 만약 데디케이티드 서버로 구성하면 어디서 클라이언트의 데이터 검증을 하게 되는지 등 리슨 서버와 어떻게 다르게 구성해야 하는지 잘 와닿지가 않습니다. characterplayer.cpp 등에 작성한 코드 자체가 서버 로직임과 동시에 클라이언트 로직인 것인지.. 인터넷에는 데디 서버를 구축하는 방법만 나와 있어서 여쭈어 봅니다. ++) 그리고 게임을 제작할 때 BP와 C++을 혼용해도 상관 없을까요? 강의는 전부 C++로 진행되어서 웬만하면 C++로 제작할 예정이지만, BP를 혼용하여 사용하는 것에 있어서 주의점 등이 있는지 궁금합니다.
-
미해결이득우의 언리얼 프로그래밍 Part1 - 언리얼 C++의 이해
Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0x0000000000000004
UE_LOG(LogTemp, Log, TEXT("%s 수업에 입장합니다.")); f로그에 %s등을 넣고 뒤에 *Name을 뺴먹고 Interface 호출시 잘못된 액세스 오류 발생하였습니다. %s를 지워주니까 잘 동작합니다!좋은 강의 해주셔서 감사합니다!
-
미해결이득우의 언리얼 프로그래밍 Part2 - 언리얼 게임 프레임웍의 이해
txt파일 삭제 시 빌드 오류
안녕하세요 강의 정말 잘 듣고 있습니다.다름이 아니라 마지막 32:13 쓸모 없는 파일을 삭제하는 부분에서 수업 자료에서 받은 파일 중 txt파일만 삭제하면 빌드 오류가 떠서 어떻게 없애야할지 궁금하여 질문 드립니다.위 사진처럼 삼인칭템플릿추가필요.txt 파일을 삭제하고 빌드를 하면 아래와 같이 빌드 오류가 뜨네요.Saved, Intermediate, DerivedDataCache, sin 파일을 지우고 txt파일도 지운 다음 Generate Visiual Studio를 실행했는데도 계속 똑같은 빌드 오류가 뜨네요. 어떻게 해결할 수 있을까요?
-
미해결이득우의 언리얼 프로그래밍 Part1 - 언리얼 C++의 이해
객체지향 설계에 대한 질문
안녕하세요, 9강 델리게이트 까지 들은 현재,제가 객체지향 설계에 대해 잘 이해를 한 것인지 잘 모르겠고 궁금한 것이 생겨서 질문 남깁니다. 9강에서 인터페이스를 사용해서 느슨한 결합으로 구현하는 것을 설명해주셨었습니다.강의에서 인터페이스를 구현할 때, 인터페이스를 사용해서 함수를 호출하기 위해서는 특정 클래스를 Cast하여 확인하고 호출했었습니다.그러면 예를 들어 캐릭터에서 아이템 사용 인터페이스를 사용한다고 해도 아이템 클래스 헤더를 include를 해야하는 상황이 발생하는데이 경우에는 인터페이스를 사용했음에도 결합? 의존이 발생한 것이라고 봐야할까요? 그리고 델리게이트 강의에서 중간에서 연결과 활동을 관리하는 주체 클래스가 필요하다고 하셨는데 이 클래스의 경우에는 모든 클래스를 include하여 사용하게 되는데 강한결합을 따지지 않나요? 그리고 강의를 따라가며 이해한 걸로 예시를 들어보았는데 제가 제대로 이해하고 있는 것인지 궁금합니다...좀 길지만 혹시 한번 봐주신다면 정말 감사하겠습니다===============================================================<6강 리플렉션 2>게임에서 다양한 아이템이 있습니다.아이템이라는 클래스를 만들어서 상속시켜 구현을 합니다.아이템 클래스에는 Use라는 가상 함수를 두고 이를 오버라이드 해서 각 아이템의 사용 시 효과를 구현합니다. <7강 인터페이스>사용가능한 아이템이 있고 패시브 효과를 가진 아이템이 있을 수 있기 때문에 Use라는 함수를 UsableItemInterface 등의 인터페이스로 구현하여 상속시켜 구현합니다. <8강 컴포지션>포함관계를 사용하여 복잡한 기능을 클래스를 쉽게 구현합니다.캐릭터 클래스에 아이템 클래스를 include하여 생성하여 아이템의 기능을 사용할 수 있게 합니다. <9강 델리게이트>include 된다면 강한 결합이기 때문에 안좋은 설계 방법이며 인터페이스를 활용하여 구현하여 느슨한 결합을 유지할 수 있습니다.예를 들어 아이템 자체를 include하기 보다는 아이템 사용 함수를 구현한 인터페이스에 의존하게 하여 해당 인터페이스를 구현한다면 다양한 종류의 아이템을 직접 캐릭터에 include하여 변경할 필요없이 사용이 가능하게 됩니다.하지만 매번 인터페이스를 만드는 것이 불편할 수 있으므로 델리게이트를 쓰면 편하고 안정적으로 관리가 가능합니다.캐릭터와 아이템의 의존을 없애기 위해 연결과 활동 주체 클래스를 만듭니다.주체 클래스에서 캐릭터와 아이템을 include하고 캐릭터에 onUse라는 델리게이트를 만들고 이게 호출되면 아이템의 Use가 호출되도록 bind합니다.그러면 캐릭터와 아이템이 의존하지 않고도 사용할 수 있게 되었습니다.===============================================================
-
미해결이득우의 언리얼 프로그래밍 Part3 - 네트웍 멀티플레이 프레임웍의 이해
데디케이티드 서버 개발 문의
현재는 리슨 서버로 개발하고 있어서 서버 클라 코드가 동시에 들어가지만데디케이티드 서버 개발은 서버 코드만 있으면 되기 때문에 더 편리하다 라고 하셨는데이게 머릿속에 잘 그려 지지가 않습니다 ㅠ 데디케이티드 서버 개발 방식이라는게아예 프로젝트를 분리해서 서버와 클라를 구분해서 개발 하는 것으로 생각 해야 할까요?(예를 들어 캐릭터 액터의 경우를 보면 같은 이름의 ABCharacter.h & cpp 파일이 있지만 안의 내용은 다르게 (어떤건 같은 내용) 되어 있다고 생각해야 할까요?)아니면 프로퍼티 리플리케이션의 경우는 콜백으로 OnRep_ 함수가 클라이언트 측에서만 실행 할 수 있는 걸로 나오는데, 이렇게 되면 애초에 서버 클라가 분리된 형태로 볼 수 있고, 이를 기반으로 프로퍼티를 바꾸는건 서버 코드, OnRep_ 콜백 함수는 클라이언트 코드 로 해서 각 파트가 개발 하는 방식이 데디케이티드 서버 개발 방식일까요?
-
미해결[입문자를 위한 UE5] Part2. 언리얼 엔진 2D 게임 개발 입문
State 패턴듣고 질문드립니다..
안녕하세요 루키스님저는 비전공자로서, 강의 너무 잘듣고있습니다.이해가 아주 쏙쏙됩니다.이때까지 제 자존심이 허락하지 않아뭐 안되는거있으면 구글링이나 chatgpt한테 물어봐가면서 아득바득해결했는데이건 도저히 이해가 안되네요... 제가 공격을 구현하는 코드에서 실수로 UpdateAnimation 부분을 빼고 연결해버렸습니다.나머지는 강의랑 동일한 코드로 작성하였습니다근데 요상하게도 나머지 기능은 정상적으로 작동하는데 공격시, 2회연속공격을 하더라구요??아니 공격키가 먹히는 것도 요상한데 2회연속공격도 요상합니다. 공격키가 먹히는 이유는 Event Tick에 걸어준 코드 때문에Update Input 함수에서 노란선방향으로 쭉 나가서 UpateAnimation쪽으로 가주면서공격키를 눌러주긴했으니까 EState가 Skill값으로 받아줘서 결과적으로 공격 모션을 취한것으로 예상을하고있는데근데 왜 2회연속공격으로 실행될까요??예전에 말씀하시길 Tick이 frame단위로 굉장히 짧은시간이니깐공격키가 눌린 찰나의 시간동안 저 과정이 2번 반복되서 그런걸까요??
-
미해결이득우의 언리얼 프로그래밍 Part2 - 언리얼 게임 프레임웍의 이해
3강에서 시점 변경 부분이요
시점 변경 전까지 정상 적으로 작동 되었는데 변경 후부터 움직임도 먹통이고 해서 이것저것 수정하다가 ACharacterPlayer::ACharacterPlayer() { // 카메라 붐 생성 (충돌이 있으면 플레이어 쪽으로 당겨짐) CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom")); CameraBoom->SetupAttachment(RootComponent); CameraBoom->TargetArmLength = 400.0f; // 카메라가 캐릭터 뒤에서 이 거리만큼 따라갑니다 CameraBoom->bUsePawnControlRotation = true; // 컨트롤러를 기반으로 암을 회전시킵니다 // 팔로우 카메라 생성 FollowCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FollowCamera")); FollowCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName); // 카메라를 붐 끝에 부착하고 붐이 컨트롤러 방향에 맞춰 조정되도록 합니다 FollowCamera->bUsePawnControlRotation = false; // 카메라는 암과 상대적으로 회전하지 않습니다 //Jump Input Action을 찾습니다. static ConstructorHelpers::FObjectFinder<UInputAction> InputActionJumpRef(TEXT("/Script/EnhancedInput.InputAction'/Game/KoreaSoul/Input/Actions/IA_Jump.IA_Jump'")); if (nullptr != InputActionJumpRef.Object) { JumpAction = InputActionJumpRef.Object; } static ConstructorHelpers::FObjectFinder<UInputAction> InputChangeActionControlRef(TEXT("/Script/EnhancedInput.InputAction'/Game/KoreaSoul/Input/Actions/IA_ChangeControl.IA_ChangeControl'")); if (nullptr != InputChangeActionControlRef.Object) { ChangeControlAction = InputChangeActionControlRef.Object; } // ShoulderMove Input Action static ConstructorHelpers::FObjectFinder<UInputAction> ShoulderMoveActionRef(TEXT("/Script/EnhancedInput.InputAction'/Game/KoreaSoul/Input/Actions/IA_ShoulderMove.IA_ShoulderMove'")); if (nullptr != ShoulderMoveActionRef.Object) { ShoulderMoveAction = ShoulderMoveActionRef.Object; } // ShoulderMoveLook Input Action static ConstructorHelpers::FObjectFinder<UInputAction> ShoulderMoveActionLookRef(TEXT("/Script/EnhancedInput.InputAction'/Game/KoreaSoul/Input/Actions/IA_ShoulderLook.IA_ShoulderLook'")); if (nullptr != ShoulderMoveActionLookRef.Object) { ShoulderLookAction = ShoulderMoveActionLookRef.Object; } // QuaterMove Input Action static ConstructorHelpers::FObjectFinder<UInputAction> QuaterMoveActionRef(TEXT("/Script/EnhancedInput.InputAction'/Game/KoreaSoul/Input/Actions/IA_QuaterMove.IA_QuaterMove'")); if (nullptr != QuaterMoveActionRef.Object) { QuaterMoveAction = QuaterMoveActionRef.Object; } CurrentCharacterControlType = ECharacterControlType::Quater; } void ACharacterPlayer::BeginPlay() { // 부모 클래스의 BeginPlay 함수를 호출합니다. Super::BeginPlay(); SetCharacterControl(CurrentCharacterControlType); } void ACharacterPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) { Super::SetupPlayerInputComponent(PlayerInputComponent); // PlayerInputComponent를 UEnhancedInputComponent로 캐스팅합니다. UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent); // 점프 액션을 트리거 이벤트에 바인딩합니다. // JumpAction이 발생하면 ACharacter의 Jump 함수를 호출합니다. EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Started, this, &ACharacter::Jump); EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Triggered, this, &ACharacter::StopJumping); EnhancedInputComponent->BindAction(ChangeControlAction, ETriggerEvent::Triggered, this, &ACharacterPlayer::ChangeCharacterControl); // MoveAction이 발생하면 ACharacterPlayer의 Move 함수를 호출합니다. EnhancedInputComponent->BindAction(ShoulderMoveAction, ETriggerEvent::Triggered, this, &ACharacterPlayer::ShoulderMove); EnhancedInputComponent->BindAction(ShoulderLookAction, ETriggerEvent::Triggered, this, &ACharacterPlayer::ShoulderLook); EnhancedInputComponent->BindAction(QuaterMoveAction, ETriggerEvent::Triggered, this, &ACharacterPlayer::QuaterMove); Controller = GetController(); // 컨트롤러 초기화 // 바인딩 확인용 로그 추가 UE_LOG(LogTemp, Warning, TEXT("InputComponent bound successfully")); } void ACharacterPlayer::ChangeCharacterControl() { UE_LOG(LogTemp, Warning, TEXT("ChangeCharacterControl called")); if (CurrentCharacterControlType == ECharacterControlType::Quater) { SetCharacterControl(ECharacterControlType::Shoulder); } else if (CurrentCharacterControlType == ECharacterControlType::Shoulder) { SetCharacterControl(ECharacterControlType::Quater); } // SetupPlayerInputComponent를 다시 호출하여 새로운 입력 맵핑을 적용합니다. SetupPlayerInputComponent(InputComponent); // 상태 변경 로그 추가 UE_LOG(LogTemp, Warning, TEXT("Control type changed to %s"), CurrentCharacterControlType == ECharacterControlType::Quater ? TEXT("Quater") : TEXT("Shoulder")); } void ACharacterPlayer::SetCharacterControl(ECharacterControlType NewCharacterControlType) { // CharacterControlManager 맵에서 NewCharacterControlType 키에 해당하는 값을 검색합니다. UCharacterControlData* NewCharacterControl = CharacterControlManager[NewCharacterControlType]; // 검색된 NewCharacterControl이 유효한 값인지 확인합니다. check(NewCharacterControl); // 가져온 CharacterControlData를 적용합니다. SetCharacterControlData(NewCharacterControl); APlayerController* PlayerController = CastChecked<APlayerController>(GetController()); if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer())) { Subsystem->ClearAllMappings(); UInputMappingContext* NewMappingContext = NewCharacterControl->InputMappingContext; if (NewMappingContext) { Subsystem->AddMappingContext(NewMappingContext, 0); } } // 현재 캐릭터 컨트롤 타입을 새로운 타입으로 설정합니다. CurrentCharacterControlType = NewCharacterControlType; UE_LOG(LogTemp, Warning, TEXT("Character control changed to %s"), NewCharacterControlType == ECharacterControlType::Quater ? TEXT("Quater") : TEXT("Shoulder")); } void ACharacterPlayer::SetCharacterControlData(const UCharacterControlData* CharacterControlData) { // 각 프로퍼티를 CharacterControlData 값으로 설정합니다. Super::SetCharacterControlData(CharacterControlData); CameraBoom->TargetArmLength = CharacterControlData->TargetArmLength; // 대상의 팔 길이를 설정합니다. CameraBoom->SetRelativeRotation(CharacterControlData->RelativeRotator); // 상대 각도를 설정합니다. CameraBoom->bUsePawnControlRotation = CharacterControlData->bUsePawnControlRotation; // 폰의 제어 회전을 사용하는지 설정합니다. CameraBoom->bInheritPitch = CharacterControlData->bInheritPitch; // Pitch 상속을 사용하는지 설정합니다. CameraBoom->bInheritYaw = CharacterControlData->bInheritYaw; // Yaw 상속을 사용하는지 설정합니다. CameraBoom->bInheritRoll = CharacterControlData->bInheritRoll; // Roll 상속을 사용하는지 설정합니다. CameraBoom->bDoCollisionTest = CharacterControlData->bDoCollisionTest; // 충돌 검사를 수행하는지 설정합니다. UE_LOG(LogTemp, Warning, TEXT("Character control data set")); } void ACharacterPlayer::ShoulderMove(const FInputActionValue& Value) { // 입력 값에서 2D 이동 벡터를 가져옵니다. FVector2D MovementVector = Value.Get<FVector2D>(); // 컨트롤러가 유효한지 확인합니다. if (Controller) { // 컨트롤러의 현재 회전값을 가져옵니다. const FRotator Rotation = Controller->GetControlRotation(); // Yaw(좌우 회전)만 사용하여 회전 값을 만듭니다. const FRotator YawRotation(0, Rotation.Yaw, 0); // 회전 매트릭스를 사용하여 전방 방향 벡터를 구합니다. const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X); // 회전 매트릭스를 사용하여 오른쪽 방향 벡터를 구합니다. const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y); // 입력 값에 따라 전방 방향으로 이동을 추가합니다. AddMovementInput(ForwardDirection, MovementVector.X); // 입력 값에 따라 오른쪽 방향으로 이동을 추가합니다. AddMovementInput(RightDirection, MovementVector.Y); } UE_LOG(LogTemp, Warning, TEXT("ShoulderMove called")); } void ACharacterPlayer::ShoulderLook(const FInputActionValue& Value) { // 입력 값에서 2D 회전 벡터를 가져옵니다. FVector2D LookVector = Value.Get<FVector2D>(); // 컨트롤러가 유효한지 확인합니다. if (Controller) { // 입력 값에 따라 컨트롤러의 회전 값을 변경합니다. AddControllerYawInput(LookVector.Y); AddControllerPitchInput(LookVector.X); } UE_LOG(LogTemp, Warning, TEXT("ShoulderLook called: Yaw=%f, Pitch=%f"), LookVector.X, LookVector.Y); } void ACharacterPlayer::QuaterMove(const FInputActionValue& Value) { // 이동 벡터를 생성합니다. 입력 값으로부터 FVector2D 타입을 가져옵니다. FVector2D MovementVector = Value.Get<FVector2D>(); // 입력 값의 제곱의 크기입니다. float InputSizeSquared = MovementVector.SquaredLength(); // 이동 벡터의 크기를 기본값 1로 설정합니다. float MovementVectorSize = 1.f; // 이동 벡터의 제곱 크기입니다. float MovementVectorSizeSquared = MovementVector.SquaredLength(); // 이동 벡터의 제곱 크기가 1을 초과하는 경우 if (MovementVectorSizeSquared > 1.0f) { // 이동 벡터를 정규화합니다. MovementVector.Normalize(); // 이동 벡터의 제곱 크기를 1로 설정합니다. MovementVectorSizeSquared = 1.f; } else { // 이동 벡터의 크기를 이동 벡터의 제곱 크기의 제곱근으로 설정합니다. MovementVectorSize = FMath::Sqrt(MovementVectorSizeSquared); } // 이동 방향을 설정합니다. 입력 벡터의 x, y를 사용하고 z를 0으로 설정합니다. FVector MoveDirection = FVector(MovementVector.X, MovementVector.Y, 0.0f); // 캐릭터 생성자의 컨트롤러에 이동 방향의 로테이터를 설정합니다. GetController()->SetControlRotation(FRotationMatrix::MakeFromX(MoveDirection).Rotator()); // 이동 입력을 추가합니다. 이동 방향과 이동 벡터의 크기를 인자로 사용합니다. AddMovementInput(MoveDirection, MovementVectorSize); UE_LOG(LogTemp, Warning, TEXT("QuaterMove called: X=%f, Y=%f"), MovementVector.X, MovementVector.Y); }일단 여기까지 고쳤는데 마우스 동작도 안되고 방향키는 전부 반대로 되어있고 v키를 눌러도 숄더로 돌아가서 다시 안돌아옵니다3시간동안 헤맸는데 도저히 모르겠어요
-
미해결이득우의 언리얼 프로그래밍 Part1 - 언리얼 C++의 이해
LogTemp 가 로그창에서 안보입니다 ㅠ
검색창에 LogTemp로 쳐봐도 안보이고 카테고리에도 없는데 따로 설정해야 할것이 있었나요?
-
미해결[입문자를 위한 UE5] Part4. 언리얼 엔진 C++
블루프린트 클래스 옮기는 과정 오류
평소 비주얼 스튜디오 코드 사용하고 있어서 환경바꾸기 귀찮아 그냥 그대로 쓰고 있었습니다.MainActor.cpp 에서 BP_R1Actor 찾는데는 성공했지만, ActorClass 에 대입이 안 되서 속 썩이다가 혹시나 하는 마음에 비주얼 스튜디오 2022로 옮기니 잘 되네요.비주얼 코드에서는 자꾸 타입 불일치로 Null 로 나려버리던데 이유는 아직도 찾지 못했습니다.저 같은 분 계실가봐 적어봅니다.
-
미해결이득우의 언리얼 프로그래밍 Part4 - 게임플레이 어빌리티 시스템
59:34 게임플레이 이펙트 cost 기능
cost로 지정된 값이 소모값보다 작으면 자동으로 GA를 실행시키지 않는것이 추가가 되있는건가요? 남아있는 에너지가 30보다 작으면 실행 할 수 없게 설계가 되어있는 걸까요?