반응형

 

 

 

MyOnBeginOverp 을 OnAAA 로 생각하고 보시면 됩니다

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
UCLASS(abstract)
class AAA : public UPageWidget
{
 
UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "what the")
void OnAAA(UElem* _Elem);
}
 
 
 
void UTabPanel::OnAAA_Implementation(UElem* _Elem)
{
}
 
cs

 

 

 

BlueprintNativeEvent 만 있다면

 

1. C++ 에서 OnAAA 를 호출 할 수있는데 BP 에 OnAAA event 노드가 없다면 C++ 의  OnAAA_Impl... 은 호출된다

2. 하지만 BP 에 OnAAA event 노드가 있다면 C++ 의 OnAAA_Impl... 은 호출되지 않는다

3. 이때 BP 에 OnAAA event 노드에 대한 부모 OoAAA  노드 가 있다면 이 노드가 호출될때 C++ 의 OnAAA_Impl... 이 호출되게 된다

 

이벤트에 오른쪽 버튼을 눌러 부모의 OnAAA 이벤트를 추가하면 됨

 

 

그런데 이때는 이벤트 자체를 함수처럼 BP에서 호출 할 수가 없는데 그러고 싶을 때는

BlueprintCallable 를 같이 넣어주게 되면 이벤트를 함수처럼 호출 할 수 있다

이때 BP에서 함수로 이벤트를 호출 하면 호출 되는 대상은 BP의 이벤트 OnAAA 가 된다

 

 

반응형

'게임엔진(GameEngine) > Unreal4' 카테고리의 다른 글

SLATE_ATTRIBUTE 와 TAttribute  (0) 2017.05.14
Unreal Engine4 Build process  (0) 2017.05.13
언리얼 안드로이드 빌드 오류  (0) 2017.04.06
Generate Visual Studio project files  (0) 2017.03.31
PBR 자세한 샘플 예시  (0) 2017.03.31
반응형

언리얼 안드로이드 빌드 오류

언리얼 엔진을 사용하면서 안드로이드 웍스라는 패키지를 알게 되었고 이 패키지를 통해 쉽게 Android SDK 부터 JDK 까지 설치할 수 있었습니다.

안드로이드 퀵 스타트 문서를 참고 하시면 됩니다.

너무도 당연히 안드로이드 빌드를 하면 자연스럽게 되는 줄 알았는데 바로 에러에 직면하게 되더군요.


처음 오류는 스크린샷을 찍어두진 않았지만 경로가 제대로 지정되어 있지 않아 발생하는 오류 였습니다.

프로젝트 설정을 열어보니 경로 정보가 하나도 입력되어 있지 않더군요.
위 이미지와 같이 경로 이미지를 입력해 주었더니 해결 되었습니다.

하지만 그렇게 끝나면 간단했겠지만 실제로는 아래와 같은 에러가 다시 발생하더군요.

ERROR: SWT folder 'lib\x86_64' does not exist.



경로 설정도 다 했고 뭐가 문제일까? 역시나 구글링을 해보니 해결 방법이 보이더군요.

https://answers.unrealengine.com/questions/213886/cant-launch-and-build-for-android.html

이 글의 답변처럼 PATH를 지정해 줬더니 .... 안되더군요.



결국 한참을 헤매다가 재부팅을 했더니 해결되네요. -ㅅ-;
같은 삽질을 겪으시는 분들을 위해 해결 과정을 남겨 놓습니다.


참고자료

안드로이드 퀵 스타트
언리얼 빌드 시스템 가이드
https://answers.unrealengine.com/questions/213886/cant-launch-and-build-for-android.html




출처 : https://indiegd.blogspot.kr/2016/11/blog-post_8.html

반응형
반응형

Generate Visual Studio project files






uproject 파일에서 오른쪽 버튼을 누르면 Generate Visual Studio project files  이 메뉴를 볼 수 있는데 이 명령어가 하는 역할은


.sin 과 .vcxproj 파일들을 자동으로 생성해 준다는 것이다


즉 모든 프로젝트 파일을 자동으로 저 명령어로 만들어진다는 것


이 말은 버전관리 대상이 될 필요는 없다는 뜻과도 같음


vcxproj.filters 와 vcxproj.user 파일도 마찬가지

반응형
반응형

물리 기반 머티리얼


이 글은 언리얼 엔진 4 의 물리 기반 머티리얼 시스템을 빠르게 익히고자 하는 이를 돕기 위해 디자인된 문서입니다. 최소한 언리얼 엔진 3 이상, 언리얼 엔진에서의 머티리얼 생성에 어느정도는 익숙한 분들을 대상으로 합니다. 언리얼에서의 머티리얼이 완전 처음이신 경우, 핵심 머티리얼 개념 문서부터 먼저 참고해 보시는 편이 나을 것입니다.

여기서의 목표는 이 시스템을 사용하여 표준 머티리얼을 제작하는 방식을 "평이한 언어로 요점정리" 해 드리기 위함으로, 기존 버전의 언리얼 엔진 작업방식에 익숙한 분들에게도 헛갈릴 수 있기 때문입니다. 물리 기반 접근법에 관련해서 오직 머티리얼 관련된 부분에만 초점을 맞춰 보겠습니다. 사용가능한 입력 전체에 대한 설명은, 머티리얼 입력 문서를 참고해 주세요.

물리 기반이란?

Physically based, 물리 기반 셰이딩이란, 빛의 작용이 이래야 할 것이다 하고 직관적으로 추정하기 보다는, 실제로 어떠한 작용을 하는지 추정하는 것을 뜻합니다. 그 결과 좀 더 정확하고 자연스러운 외양을 얻을 수 있습니다. 물리 기반 머티리얼은 라이팅 환경에서도 똑같이 잘 작동합니다. 게다가 머티리얼 값도 덜 복잡해지고 상호의존적이 되어, 좀 더 직관적인 인터페이스가 가능해 졌습니다. 이러한 장점은 픽사와 [4] 디즈니의 [3] 최근작에서 명확히 볼 수 있듯이, 비실사 렌더링에도 적용 가능합니다.

이런 저런 이유로 인해, 언리얼 엔진 4 에서는 새로운 물리 기반 머티리얼 및 셰이딩 모델을 채택했습니다. UE4 의 물리 기반 머티리얼 및 셰이딩 모델 관련해서 기술적으로 자세한 내용은, 시그래프 프리젠테이션을 [2] 참고해 주시기 바랍니다.


아래 링크가 이 글의 원글인데 슬라이드를 움직이면서 각각 PBR속성별 자세한 결과들을 볼 수가 있습니다

https://docs.unrealengine.com/latest/KOR/Engine/Rendering/Materials/PhysicallyBased/index.html

반응형
반응형




인터페이스 선언

인터페이스 클래스 선언은 일반 언리얼 클래스 선언과 비슷하나, 크게 두 가지 차이점이 있습니다. 첫째, 인터페이스 클래스는 UCLASS 매크로 대신 UINTERFACE 매크로를 사용하며, UObject 를 직접 상속하는 대신 UInterface 를 상속합니다.

UINTERFACE([specifier, specifier, ...], [meta(key=value, key=value, ...)])
class UClassName : public UInterface
{
    GENERATED_BODY()
};

둘째, UINTERFACE 클래스는 실제 인터페이스가 아닙니다. 언리얼 엔진의 리플렉션 시스템에 보이도록 하기 위해서만 존재하는 공백 클래스입니다. 다른 클래스에서 상속하게 되는 실제 인터페이스는 같은 클래스 이름에 첫 글자만 "U" 에서 "I" 로 바뀝니다.

.h 파일에서 (예: ReactToTriggerInterface.h):

#pragma once

#include "ReactToTriggerInterface.generated.h"

UINTERFACE(Blueprintable)
class UReactToTriggerInterface : public UInterface
{
    GENERATED_BODY()
};

class IReactToTriggerInterface
{    
    GENERATED_BODY()

public:
    /** 이 오브젝트를 활성화시키는 트리거 볼륨에 반응합니다. 반응에 성공하면 true 를 반환합니다. */
    UFUNCTION(BlueprintCallable, BlueprintCallable, Category="Trigger Reaction")
    bool ReactToTrigger() const;
};

함수를 .h 파일에 직접 작성할 수 있는데, 기본적으로 아무 것도 하지 않는 함수이거나 false, 0, 공백 스트링 반환처럼 사소한 동작을 하는 함수의 경우 종종 그렇게 합니다. 보다 복잡한 함수는 .cpp 파일에 작성하여 컴파일 시간을 줄일 수 있습니다. 순수 가상 (pure virtual) 함수가 지원됩니다. 여기 샘플 함수는 .h 파일에 작성해도 될만큼 간단하긴 하지만, .cpp 파일에 작성하도록 하겠습니다. (ReactToTriggerInterface.cpp 와 같은) cpp 파일에 이제 다음과 같은 부분이 있을 것입니다:

#include "ReactToTriggerInterface.h"

bool IReactToTriggerInterface::ReactToTrigger() const
{
    return false;
}

접두사가 "U" 인 클래스는 생성자나 기타 다른 함수가 필요치 않은 반면, "I" 인 클래스는 모든 인터페이스 함수를 포함하며, 다른 클래스에 실제로 상속되는 클래스이기도 합니다.

블루프린트가 이 인터페이스를 구현할 수 있도록 하려면 Blueprintable 지정자가 필요합니다.





C++ 로 인터페이스 구현

새 클래스에서 인터페이스를 사용하려면, 단순히 (사용중인 UObject 기반 클래스에 추가로) 접두사가 "I" 인 인터페이스 클래스를 상속하기만 하면 됩니다.

class ATrap : public AActor, public IReactToTriggerInterface
{
    GENERATED_BODY()

public:
    virtual bool ReactToTrigger() const override;
};

주어진 클래스의 인터페이스 구현 여부 확인

인터페이스를 구현하는 두 C++ 와 블루프린트 클래스 사이의 호환을 위해서는, 다음 함수 중 하나를 사용하면 됩니다:



// OriginalObject 가 UReactToTriggerInterface 를 구현한다면 bIsImplemented 는 true 가 됩니다.

bool bIsImplemented = OriginalObject->GetClass()->ImplementsInterface(UReactToTriggerInterface::StaticClass()); 


// OriginalObject 가 UReactToTriggerInterface 를 구현한다면 ReactingObject 는 null 이외의 값이 됩니다.

IReactToTriggerInterface* ReactingObject = Cast<IReactToTriggerInterface>(OriginalObject); 



U 접두사 클래스에 Cast 를 사용하려고 하면 실패하는 반면, StaticClass 함수는 I 접두사 클래스에 구현되어 있지 않아 컴파일되지 않습니다.

다른 언리얼 유형으로의 형 변환

언리얼 엔진의 형변환 시스템은 한 인터페이스에서 다른 인터페이스로, 또는 인터페이스에서 적합한 경우 언리얼 유형으로 형 변환을 지원합니다.


// 인터페이스가 구현된 경우 ReactingObject 는 null 이외의 값이 됩니다.

IReactToTriggerInterface* ReactingObject = Cast<IReactToTriggerInterface>(OriginalObject); 


// ReactingObject 가 null 이외의 값이고 ISomeOtherInterface 를 구현하는 경우 DifferentInterface 는 null 이외의 값이 됩니다.

ISomeOtherInterface* DifferentInterface = Cast<ISomeOtherInterface>(ReactingObject); 


// ReactingObject 가 null 이외의 값이고 OriginalObject 는 AActor 또는 AActor 파생 클래스인 경우, Actor 는 null 이외의 값이 됩니다.

AActor* Actor = Cast<AActor>(ReactingObject); 


블루프린트 구현가능 클래스

블루프린트가 이 인터페이스를 구현할 수 있도록 하려면, Blueprintable 메타데이터 지정자를 사용해야 합니다. 블루프린트 클래스가 덮어쓰려는 모든 인터페이스 함수는 BlueprintNativeEvent 또는 BlueprintImplementableEvent 여야 합니다. BlueprintCallable 마킹된 함수는 여전히 호출은 가능할 것이나, 덮어쓰기는 불가능합니다. 다른 모든 함수는 블루프린트에서 접근할 수 없을 것입니다.




출처 : https://docs.unrealengine.com/latest/KOR/Programming/UnrealArchitecture/Reference/Interfaces/index.html



반응형
반응형


UUserWidget 클래스에서 SynchronizeProperties 함수가 있는데 


//~ Begin UWidget Interface

virtual void SynchronizeProperties() override;


이 클래스를 상속받아 함수를 오버라이드 해서 관련 코드를 작성하면 해당 결과를 에디터 상에서 실행 없이 바로 볼 수 있다



UCLASS(Blueprintable)

class UCCCWidget : public UUserWidget 


    virtual void SynchronizeProperties() override;


};





void UCCCWidget::SynchronizeProperties()

{

    Super::SynchronizeProperties();

//원하는 동작 작성..

}


반응형
반응형




World Location 은 일반적으로 알고 있는 월드 공간에서의 좌표 위치를 말한다


어떤 오브젝트의 자식 일지라도 자식을 SetWorldLocation 으로 위치를 지정하면 자식 오브젝트는 월드 좌표로 값이 세팅 되어 위치하게 된다는데에서는


큰 어려움은 없는데, Relative 의 경우에는 다른 말로 Local 좌표라고도 얘기를 하는데 이 것은 한 오브젝트에 대해서 해당 하는 내용이 아닌


자식 오브젝트(or Compoenent )를 가지고 있는 경우 자식의 위치를 부모 기준으로 얼마나 이동 할지에 대한 위치를 설정할때 쓰는 함수or 변수이다



하지만 특이점은(특이점이라 할 것도 없지만) 자식 오브젝트가 root 자체인 경우 즉 자식을 가지고 있지 않은 경우에서의 Relative Location 은 부모의 Location 즉 World Location 과 동일한 값을 가지게 된다!!







 3DMP engines



반응형
반응형

A 메쉬애니를 B메쉬에 동일한 애니메이션을 적용 시키고자 할 때 SetMasterPoseComponent를 쓰면 된다

동일한 동작이 됨으로 어떤 연출이나 효과에 좀 쓰일 수 있는 컴포넌트


USkinnedMeshComponent::SetMasterPoseComponent








UFUNCTION (BlueprintCallable , Category="Components|SkinnedMesh" )
void SetMasterPoseComponent
(
    USkinnedMeshComponent * NewMasterBoneComponent
)




참고 Ref :

https://docs.unrealengine.com/latest/INT/API/Runtime/Engine/Components/USkinnedMeshComponent/SetMasterPoseComponent/index.html

반응형
반응형



Render 3D objects in UMG Widget/HUD


https://engineunreal.wordpress.com/2015/04/21/render-3d-objects-in-umg-widget-hud/

As you may be aware of, it is not possible to directly render 3D objects/blueprints/meshes in a UMG widget (as of UE 4.7.4 at the time of writing).

I shall try to clearly explain how I achieved it. Here is what we are trying to get as a result: [gif coming soon]

The basic principle is to capture your 3D object to a 2D ‘image’ that you will be able to use in your UMG widget.

Basic explanation is good, but having more details is even better! So here are the steps:

  1. Create a scene capture blueprint
  2. Capture to a 2D texture
  3. Create a material from that texture
  4. Use that material in your widget

ProcessI you feel more like reverse engineering without reading what I have to say, I also made the code available on GitHub :p Download from GitHub


Prerequisites / Project setup

What you need to be able to follow this is a UE4 project with a UMG widget that displays somewhere in your game (basically in your HUD for instance).

If you don’t have such a UE project, you can follow this simple tutorial and come back here right after having completed it.

But if your very own project seems to fit to that description, you can skip directly to the scene capture creation.

Now that we are on common grounds, we are good to go!

1 – Create a scene capture blueprint

Begin by creating a… yep, a Blueprint, how surprising! Choose ‘Actor’ as its parent class. I named it ‘CaptureBlueprint’. New Actor Blueprint

Open it. We will start by creating a closed ‘room’. For that, add 6 StaticMesh components ‘Floor_400x400’ (that mesh is provided by default in the engine). Make sure that the root component of the BP is the actual floor of the ‘room’. “Why the heck would I need to build a box?!”, that’s probably what you’re thinking right now. I know that this comes ‘out of the blue’, but trust me, it will make sense! Here is what it looks like without the roof: room_outside

Now that we have our ‘studio’ (I think that’s a cool descriptive name actually, I’m going to call it ‘studio’ until the end), we need to change its walls color. We are willing to create a ‘bluescreen’, yes, exactly like the ones they use when shooting movies!

For that purpose, we will create a Material that we will be able to apply on those walls. I named it ‘StudioMaterial’. Edit it. Add a Constant4Vector component from the Palette and change its color to a color your 3D model won’t contain (again, this is a bluescreen). I chose a bright cyan color RGBA(0, 1, 1, 0). Studio Material color

Set this color as the Emissive Color of the Material. Finally, set the Shading Model of the Material to Unlit. This is really important, as with that option, our studio walls won’t be affected by the 3D object shadows and the lights, and will therefore appear with just one united color (the one we’ve just chosen, actually). Studio Material Unlit

Now back to our studio, set the walls material to the one we just created. You can now add the 3D Object/Mesh you want to render in the UMG widget to the studio! I did not have the time to find a funny model to render, so I just chose a default Mesh (SM_MatPreviewMesh_02). Make sure it is in the studio room (at least for the part you want to see). You can of course make the studio bigger if needed. Studio BlueprintThen add a Camera to the Blueprint. Try to put it in front of the Object to render, so that the camera can actually film it. Studio Camera

Finally, add a SceneCaptureComponent2D to the Camera. That is the component we are going to use to render what the camera films to a 2D Texture. Studio Capture component

As a final step for our studio, we add some light to the Blueprint. I insert the Light component in front of my object and I let the light options to their default value. You can of course add more than one, tweek their options, and place them wherever you like. If you don’t add light(s), then your capture will look very dark (but it could be the effect you want, I don’t know!). Add light to the studio

You can now relax, we are done with the tricky part of this. Compared to what we have already achieved here, what’s left will seem as easy as my first girlfr… NO, I cancel this sentence.


2 – Capture to a 2D texture

Now we need to tell our SceneCaptureComponent to what it should save what it captures. For that purpose, we first have to create a new TextureRenderTarget2D in our project. I named it ‘TextureRenderTarget’. Render Target creation

Edit it and set the ‘Size X’ and ‘Size Y’ to one that fits your needs. Note that the default is 256×256, and that those sizes will impact the quality of the rendering in UMG. Here I chose the maximum size, which is 2048×2048. Render Target size settings

Now back to our ‘CaptureBlueprint’, just set this brand new element as the Texture Target of the Scene Capture Component, then save. Set BP Render Target

That’s it, what the camera captures will be saved to your 2D texture!


3 – Create a material from the texture

Here we are going to ‘transform’ our captured 2D texture by removing its blue background (or the color you chose for your studio walls) and ‘convert’ it to a material that we will eventually be able to use in UMG.

First, create a new Material. I named it ‘CapturedMaterial’. Save and edit it. Set its Blend Mode to ‘Translucent’, because we will need some transparency (the Unreal Engine wiki is really insightful about the blend modes if you want to know more about them). Then set its Shading Mode to ‘Unlit’, to be sure that it won’t be altered by any dynamic light once in our HUD. HUD Material basic settings

Once this is done, be sure to check ‘Used with UI’ in the ‘Usage’ panel of the settings, as if you don’t you simply won’t be able to select this Material in a UMG widget. HUD Material UI setting

Now we’re good to go! Add a Texture Sample to the Material, and set your ‘TextureRenderTarget’ as its Texture in the settings panel. HUD Material texture sample add

Link it to the Material ‘Emissive Color’ pin. HUD Material emissive

Now comes the part where we are going to make our studio background color transparent, so that only our model will be visible in our HUD.

Add a Constant3Vector component from the Palette and change its color to the color you used as the walls color – remember that I used the color RGBA(0, 1, 1). HUD Material wall color

Then add the necessary elements to make your material look like this (the ‘0’ and the ‘1’ are simple Constant elements): HUD Material wall color transparency

Don’t forget to set the B constant of the If component. Adjust it if you later notice that the borders of your object are blue-ish when rendered (the higher its value is, the more blue will be transparent, but it could be that some unexpected parts of your object disappear if the value is too high). UMG Material B value

This is simply the part handling the transparency of the background color. I think what it does is straightforward enough.

Save. That’s it! Our Material is done!


4 – Use the material in a UMG widget

Now that we have a Material we can use in UMG, let’s… yeah, let’s use it!

Edit the UMG widget in which you want the 3D object to appear, and add an Image component where you want the object to appear. I will simply add it to the basic Canvas Panel, as you can see. UMG add image

Size it the way you desire. I am simply gonna go with 256×256. UMG image size

Then, in the Appearance panel, under Brush, set our ‘CapturedMaterial’ as the Image. UMG set Material as Image

Compile and save.

Last step, we need to add our CaptureBlueprint to our map, because it will not capture anything if it is not physically present in the world. Place it so that the player will not be aware of its existence (basically outside or under the map). Place capture BP in mapNotice that when you select a Blueprint that has a camera in it, a small window opens and shows what the camera sees.

Save, hit play, and enjoy: Your object is actually rendered on the HUD! Notice that the borders of my object are a bit blue-ish because of the reflections of the studio walls. If that happens to you too, you can fix it by adding lights to the studio in the CaptureBlueprint, and/or by augmenting your object material roughness.

Final result

Finally…That’s it, we have rendered a 3D Object in UMG! For now it does nothing in particular exept just standing there, but hey, it is a Blueprint after all, you can all the behaviors and functionnalities you can imagine to it. I don’t know, why not a 3D health gauge, with some particle effects like steam when it goes in the red for instance? Or whatever you need!

The whole project is available on GitHub if you need it. Feel free to clone/fork/download it!

Download from GitHub


Conclusion

I must admit that this looks more like a workaround than a real nice and perfect solution, and I realize that it needs a lot of some tweeking to look decent. But it will do the trick until Epic Games makes this a native feature of its great UMG… I hope…. And if I say please?!…😦

Don’t hesitate if any part of this seems unclear, or if you have any question/wittycomment/suggestion, or whatever.

See ya!


반응형
반응형

Vulkan 이 언리얼4에 들어가게됩니다, 언리얼 4.14 preview 에 포함 되는데.. 이런 언리얼 엔진을 깔아야 함...


아놔 빌드 시간,,, ㅡ.ㅡ;;;


벌칸은 오픈지엘 차기작 버전으로 폰에는 겔럭시 7 부터 가능해용~


Vulkan

https://wiki.unrealengine.com/Vulkan

How to use Vulkan in Unreal Engine 4


Rate this Article:
5.00
 (one vote)

Approved for Versions:(master)

Overview

On February 16th 2016 the final Vulkan specifications along with the Vulkan SDK were released. Vulkan is a new graphics API and Unreal Engine 4 supports it! In this small tutorial I will show you how to use Vulkan in UE4. So let's get started!

Setup

Setting up Vulkan for UE4 is easy, but you have to make sure to do everything in the correct order.

1. Download the newest graphics driver for your GPU, make sure you get the version with Vulkan support. Both AMD and Nvidia have released such drivers. Download it, install it and restart your PC.

2. Go to the official website and download the Vulkan SDK for your platform: http://lunarg.com/vulkan-sdk/ Then just install it, not that much to say about it.

3. Go to the Unreal Engine 4 github site: https://github.com/EpicGames/UnrealEngine

For being able to access it, you need to have your Unreal Engine Account linked to your github Account. Select the "master" branch and click on "download zip" on the right. Wait for the download to finish, extract the zip file, then first run the "Setup.bat" and once that finished, run the "GenerateProjectFiles.bat" and then double click the generated "UE4.sln" file to open up the Visual Studio project.

Right click the UE4 solution and select "Build". Then you have to wait a while for Unreal Engine to build. It's important that you build the engine *after* you installed the SDK. So if you have a recent master build, you can't use it if you only installed the Vulkan SDK after you built the engine.

4. Once the engine build finished, there are multiple options how to get Vulkan running. You can launch the whole Engine in "Vulkan Mode" with going into the Engine/Binaries/Win64/ directory, then right click the "UE4Editor.exe" and select "Create Shortcut". Then edit the shortcut so that it's pointing to

"C:\YOUR_INSTALL_DIRECTORY\Engine\Binaries\Win64\UE4Editor.exe" -vulkan

You can now launch the engine from that shortcut and it's running Vulkan!

Another way to see it running is just using the engine build without the -vulkan parameter, but using the new "Vulkan Preview" mode you find below the "Mobile Preview" you probably know about.

VulkanPreview.jpg

This will launch your game as a standalone application running Vulkan. On first launch, a lot of Shaders will have to compile and that might take a while, but once that's finished, you see your project running on the new Vulkan API!

But keep in mind that Vulkan is only using the mobile rendering path of UE4 at the moment, so you won't be able to use some of the "High End" features UE4 offers. Still, it's awesome to see a new API like Vulkan to run on your PC :)


I hope you find some useful information in this, is there are any questions left I would suggest to ask in the forums :) Cheers!

~John Alcatraz


반응형
반응형

1. 먼저 해야 되는게 우선 마티네를 클릭한다!!! (이게 중요)

2.  1번 직 후 바로, 레벨 블루프린트에서 오른쪽 버튼을 눌러서 마티네

 컨트롤 이벤트를 추가한다

3. 이후에 이벤트 트렉이 이벤트를 추가하면 자동으로 레벨블루프린트에 넣어 놓았던 이벤트에 추가적으로 이벤트가 들어 가 있는 것을 확인 할 수 



https://docs.unrealengine.com/latest/KOR/Engine/Matinee/UserGuide/BlueprintComponents/index.html


시간에 따라 이벤트 발동시키기

마티네에서, 블루프린트 액터에 대해 이벤트 트랙을 만들어 특정 이벤트를 발동시킬 시간을 정할 수 있습니다. 그런 다음 해당 이벤트를 블루프린트에 노출시키고 특정 시간에 발동시키고자 하는 함수에 걸어줍니다.

마티네 이벤트를 사용하여 블루프린트에서 특정 시간에 동작을 발동시키려면:

  1. 마티네에서, 블루프린트에 연관된 그룹에 이벤트 트랙을 추가합니다.

    Matinee_EventTrack.png

  2. 이벤트 트랙의 특정 시간에 키프레임을 추가합니다. 키프레임을 추가할 때마다, 새 이벤트에 이름을 지어달라는 창이 뜹니다.

    Matinee_AddEvent.png

    Matinee_Events.png

  3. 레벨 블루프린트에서, 마티네 액터를 선택한 채로, 그래프에 우클릭합니다. 가능한 옵션 중에 마티네 액터에 대해 마티네 콘트롤러(MatineeController)를 추가하는 옵션이 있습니다. 선택해서 마티네 콘트롤러 노드를 생성해 주면, 거기에 마티네에서 키프레임을 생성한 이벤트가 나열됩니다.

    Matinee_AddController.png

    Matinee_ControllerWithEvents.png

    이제 마티네 콘트롤러의 이벤트 실행 핀을 마티네 시퀀스 재생 도중 발동시키려는 함수 노드에 걸어주면 됩니다.


반응형
반응형

이것저것 하다 간만에 다시 이벤트를 만드는데 순간 어떻게 했지라는 정적이...

간단한걸 까먹는다 .. ㅋ


How do i call a custom event funtion?


https://answers.unrealengine.com/questions/154297/how-do-i-call-a-custom-event-funtion.html



I'm following this tutorial:

https://www.youtube.com/watch?list=PLCWzG3zfTUPOMKrOw3MS6rrx4ACxbF6Kg&v=DH8HHqiMbWA&feature=player_detailpage#t=595

At about the ten minute mark I am told to create a custom event, which I can do; however, immediately after I am told to call the custom event function and connect it to the first sequence pin. When I try to call the function, the function does not exist even though I have the option checked off to call the event in the editor.

How can I accomplish what is being done in the video?

I am using the 4.6.1 version of the engine.

Thanks

Product Version: Not Selected
Tags:
more ▼

eXi gravatar image eXi ♦ Jan 05 '15 at 6:25 AM

Öhm, this should work the same way, but i'm not sure if Epic changed something in the 4.6.1 update. There are a few things to check:

Are you sure you spelled it correctly?

Would you mind trying to press "Compile" in the upper left corner first?

Does this also happen in a complete new project?

Can you show me your Blueprint (:?

Can you make sure that you have "Context sensitive" marked at the upper right corner of the contest menu that opens when you rightclick?

Can you try calling the event by only rightclicking and searching it instead of dragging of the pin.

orrimer gravatar image orrimer Jan 05 '15 at 3:20 PM

https://www.dropbox.com/s/usido8i2gxdcyuk/Screenshot%202015-01-05%2001.16.12.png?dl=0

Attached screenshot shows a custom event I made and what happens when i try to search for the function call. It was compiled before searching. I started off with a blank c++ template and then created a new empty level. Please let me know if there is any other information you require.

eXi gravatar image eXi ♦ Jan 05 '15 at 6:26 PM

I'm not at my pc right now, but would you mind disabling "Call in Editor" at the Event options at the lower left of the BP and try it again?

rjvm gravatar image rjvm Jan 05 '15 at 10:25 PM

in level BP right clic and put this ===> alt text

alt text

custon event.png (60.3 kB)
call event.jpg (298.4 kB)



반응형
반응형

하드디스크에 정보를 저장하기


Remarks

This class acts as a base class for a save game object that can be used to save state about the game. When you create your own save game subclass, you would add member variables for the information that you want to save. Then when you want to save a game, create an instance of this object using CreateSaveGameObject, fill in the data, and use SaveGameToSlot, providing a slot name. To load the game you then just use LoadGameFromSlot, and read the data from the resulting object.



https://docs.unrealengine.com/latest/KOR/Gameplay/SaveGame/index.html

게임 저장하기

  • SHARE:

언리얼 엔진

게임 저장 및 로드 구성을 위한 가장 간단한 방법은 SaveGame 오브젝트를 사용하는 것입니다.

BlankSaveGame.png

SaveGame 오브젝트를 여러가지 부속으로 된 박스로 생각해 보세요. 각 부분마다 변수를 만들어 일정량의 정보를 저장하도록 설정할 수 있습니다. 예를 들어 플레이어의 점수는 물론 이름도 저장하는 변수를 만들 수 있습니다. Character, PlayerController, GameMode 와 같은 다른 클래스에서 SaveGame 오브젝트로 정보를 전달할 수 있습니다. 그러기 위해서는 먼저 SaveGame 오브젝트의 인스턴스를 생성하거나 복사해야 합니다.

SaveGameVariables.png

그런 다음 예를 들어 PlayerController 에서 플레이어의 점수와 이름에 대한 값을 받은 다음 SaveGame 오브젝트 내 일치하는 변수에 저장하면 됩니다.

StoreVariables.png

SaveGame 오브젝트는 이제 이 변수 값을 하드 디스크에 저장할 때까지 유지합니다.

StoredVariables.png

마지막으로 SaveGameToSlot 을 사용해서 SaveGame 오브젝트를 하드 디스크 상의 파일에 저장하면 됩니다. 다른 프로그램에서 새 게임 또는 문서를 저장하는 것과 똑같은 방식으로 이루어지는데, SaveGameToSlot 에 파일명을 지어주기 때문입니다. 기본적으로 세이브 게임은 Saved\SaveGames 폴더에 .sav 파일로 저장됩니다. SaveGameToSlot 에 사용자 ID 도 주어야 나중에 로드할 정보를 찾아보는 데 도움이 됩니다.

SaveGame 오브젝트에서 정보를 로드하는 것 역시 단순한 프로세스인데, 정보 저장의 거의 반대입니다. LoadGameFromSlot 함수를 사용하여 입력에서 파일명과 사용자 ID 를 받습니다. LoadGameFromSlot 으로 하드 디스크에서의 정보를 로드하면 SaveGame 오브젝트의 새로운 사본이 생성됩니다.

StoredVariables.png

이 오브젝트를 사용하면 게임내 다른 오브젝트와 액터에 있는 정보를 복사할 수 있습니다. 이 예제에서는 플레이어가 저장된 게임을 열어 플레이를 재시작할 때와 마찬가지로 플레이어의 점수와 이름을 PlayerController 속으로 로드시킵니다.

LoadingVariables.png





블루프린트로 게임 저장하기

https://docs.unrealengine.com/latest/KOR/Gameplay/SaveGame/Blueprints/index.html

  • SHARE:
언리얼 엔진

SaveGame 오브젝트 생성

SaveGame 오브젝트를 새로 생성하기 위해서는, 블루프린트 클래스를 새로 생성 합니다. 부모 클래스 선택 대화창이 뜨면, Custom Class드롭다운을 펼친 다음 SaveGame 을 선택합니다. 검색창에서 SaveGame 에 바로 점프할 수 있습니다. 새 블루프린트 이름은 MySaveGame 이라 합니다.

savegame.png

새로 만든 SaveGame 오브젝트 블루프린트에서, 저장하고자 하는 정보를 담을 변수를 생성합니다.

이 예제에서는, SaveSlotName 과 UserIndex 에 대한 기본값 저장에 사용될 변수도 선언되어 있어, 이 SaveGame 오브젝트에 저장하는 각 클래스에서는 그 변수를 따로 설정할 필요가 없습니다. 이 단계는 옵션으로, 기본값이 변경되지 않은 경우 하나의 세이브 슬롯을 덮어쓰게 됩니다.

SaveGameVariables.png

블루프린트 컴파일 이후 변수에 대한 기본값을 설정할 수 있습니다.

변수 저장하기

전체 저장 구성 스냅샷입니다. 이미지를 클릭하면 원래 크기로 볼 수 있습니다.

먼저 Create Save Game Object 노드를 사용하여 SaveGame 오브젝트의 인스턴스를 생성 또는 복사합니다. Save Game Class 드롭다운 이름을 새로운 SaveGame 오브젝트 블루프린트 이름으로 설정했는지 확인합니다. 이 경우 MySaveGame 입니다. Create Save Game Object 노드가 범용 SaveGame 오브젝트 사본을 만들기 때문에, Return Value 핀을 드래그한 다음 Cast to MySaveGame 를 놓아야 합니다. 나중에 SaveGame 오브젝트를 쉽게 재사용하려면 변수로 승격 을 통해 변수에 대한 형변환 결과를 저장하세요.

SaveGameBP_1.png

이제 커스텀 SaveGame 오브젝트인 MySaveGmae 사본을 Save Game Instance 변수에 저장했으니, 이제 거기에 정보를 전송할 수 있습니다. 여기서 Player Name 은 PlayerOne 으로 설정되어 있습니다. 정보를 저장하고자 하는 변수가 더 있는 경우, 이 단계를 반복해 주면 됩니다.

SaveGameBP_2.png

이제 Save Game To Slot 노드를 사용하여 SaveGame 오브젝트의 정보를 하드 디스크에 저장하면 됩니다. Save Game To Slot 노드는 파일명과 사용자 ID 를 받는데, 여기서는 앞서 만들어둔 기본값이 됩니다.

SaveGameBP_3.png

변수 로드하기

전체 저장 셋업에 대한 스냅샷입니다. 이미지를 클릭하면 확대해 볼 수 있습니다.

첫 단계는 옵션으로, SaveGame 오브젝트 안에 기본 세이브 슬롯과 사용자 ID 를 저장하는 것을 기반으로 합니다. 여기서는 빈 SaveGame 오브젝트를 먼저 생성하여, 거기서 기본 SaveSlotName 과 UserIndex 를 읽을 수 있도록 합니다. 마찬가지로 이 부분은 모든 게임 구현에 적용되는 것은 아닙니다.

LoadGameBP_1.png

Load Game From Slot 노드를 사용하여 SaveGame 오브젝트 블루프린트의 인스턴스를 생성할 수 있습니다. 정보 저장을 위해 SaveGame 오브젝트를 생성했을 때와 마찬가지로, 특정 SaveGame 오브젝트 블루프린트로 형변환시켜 줘야 그 결과를 변수에 저장하여 나중에 쉽게 접근할 수 있습니다.

LoadGameBP_2.png

하드 디스크에서 새로운 SaveGame 오브젝트를 로드한 이후에는 변수값을 읽어 필요한 액터 또는 클래스에 할당하거나 여기서처럼 직접 사용할 수도 있습니다.

LoadGameBP_3.png

반응형
반응형


이 둘의 차이점은 실행하다 성공이냐 아니면 실행하다 실패냐에 따라 트리를 빠져나올지 결정한다


selAndSeq.png


https://docs.unrealengine.com/latest/KOR/Engine/AI/BehaviorTrees/QuickStart/10/index.html

  1. 비헤이비어 트리 애셋이 이미 열려있지 않다면, 콘텐츠 브라우저 에서 더블클릭 하여 엽니다.

  2. 비헤이비어 트리 모드에서, 그래프 영역에 우클릭 한 다음 Composites -> Selector 노드를 두 개 추가합니다.

    selector.png

  3. 비헤이비어 트리 모드에서, 그래프 영역에 우클릭 한 다음 Composites -> Sequence 노드를 추가합니다.

    sequence.png

이 둘은 비헤이비어 트리에서 사용할 수 있는 두 가지 주요 의사결정 노드입니다. Selector 노드는 자손을 왼쪽에서 오른쪽 순으로 실행하다, 그 중 하나가 성공 하면 트리를 빠져나옵니다. 반면 Sequence 노드는 자손을 왼쪽에서 오른쪽 순으로 실행하다, 그 중 하나가 실패 하면 빠져나옵니다.



반응형
반응형

주의 점이라고 하긴 했지만 하면 안된다 그런게 아니고 네이밍만 보고선 어? 라는 부분이 생기게 될 수 있는데

[Size to Fit 에 체크를 해놨을 경우]

이 함수는 Add 처럼 Element 를 하나씩 뒤에서 추가하는 것이 아니고

해당 추가할 위치의 인덱스를 지정해주면 0번지 부터 해당 인덱스 번지까지 순차적으로 쭉 생성 한다는 것이 주의할 점이다


빈 TArray 에서 인덱스를 3으로 주면

0~3까지 4개의 공간이 생기게 된다





Set Array Elem



  • SHARE:

Target is Kismet Array Library

Set Array Elem
Target Array
Index
0
Item
Size to Fit

Inputs

In
Exec
Target Array
Array of Wildcards

The array to perform the operation on *

Index
Integer

The index to assign the item to *

Item
Wildcard (by ref)

The item to assign to the index of the array *

Size to Fit
Boolean

If true, the array will expand if Index is greater than the current size of the array

Outputs

Out
Exec


반응형
반응형
int 를 FString 으로 변환하기

int32 YourInt = 9000;
FString IntAsString = FString::FromInt(YourInt);



https://forums.unrealengine.com/showthread.php?67066-how-to-convert-quot-int32-quot-to-quot-string-quot-in-ue4-c




I have a wiki on exactly this subject!

I cover

FString to uint8 / int32

FString to float

float to FString

int32 to FString

FString to std::string

std:string to FString


~~~

Wiki Link

Rama's Wiki on String Conversions
https://wiki.unrealengine.com/String...oat_to_FString

~~~

C++ Code For You

This is the code you want:

Code:
int32 YourInt = 9000;
FString IntAsString = FString::FromInt(YourInt);

Enjoy!

Rama





https://wiki.unrealengine.com/String_Conversions:_FString_to_FName,_FString_to_Int32,_Float_to_FString


Overview

  1. FString to FName
  2. std::string to FString
  3. FString and FCString Overview
  4. FString to Integer
  5. FString to Float
  6. Float/Integer to FString
  7. UE4 C++ Source Header References

All the header files I refer to in this tutorial are found in

your UE4 install directory  / Engine / Source

you will probably want to do a search for them from this point :)

Converting FString to FNames

Say we have

FString TheString = "UE4_C++_IS_Awesome";

To convert this to an FName you do:

FName ConvertedFString = FName(*TheString);

std::string to FString

#include <string>
 
//....
 
some function
{
  std::string TestString = "Happy"; 
  FString HappyString(TestString.c_str());
}

FString to std::string

#include <string>
 
//....
FString UE4Str = "Flowers";
std::string MyStdString(TCHAR_TO_UTF8(*UE4Str));

FCString Overview

Converting FString to Numbers

The * operator on FStrings returns their TCHAR* data which is what FCString functions use.

If you cant find the function you want in FStrings (UnrealString.h) then you should check out the FCString functions (CString.h)

I show how to convert from FString to FCString below:

Say we have

FString TheString = "123.021";

FString to Integer

int32 MyShinyNewInt = FCString::Atoi(*TheString);

FString to Float

float MyShinyNewFloat = FCString::Atof(*TheString);


Note that Atoi and Atof are static functions, so you use the syntax FCString::TheFunction to call it :)


Float/Integer to FString

FString NewString = FString::FromInt(YourInt);
 
FString VeryCleanString = FString::SanitizeFloat(YourFloat);

Static functions in the UnrealString.h :)

UE4 Source Header References

CString.h
UnrealString.h
NameTypes.h

See CString.h for more details and other functions like

atoi64 (string to int64)
Atod	(string to double precision float)


For a great deal of helpful functions you will also want to look at

UnrealString.h for direct manipulation of FStrings!


For more info on FNames check out

 NameTypes.h

Enjoy!


반응형
반응형

FString names = FString::Printf(TEXT("UserName [%s]  UserNickName [%s]"), *LocalAccountName, *LocalAccountNickName);


UE_LOG(gamelog, Log, TEXT("%s"), *names);


GEngine->AddOnScreenDebugMessage(-1, 50000.f, FColor::Red, *names);

반응형
반응형

typedef TWeakPtr<Combine_Base> wpCombineBase;




TSharedPtr<Combine_EditorLogin> spCombineEditorLogin = 

StaticCastSharedPtr<Combine_EditorLogin>(retTop);

//스태틱 캐스팅과 콘스트 캐스팅은 지원하는데 Dynamic cast 는 없다



TSharedPtr<Combine_EditorGameSvrAuth> spCombineEditorGameSvrAuth = 


StaticCastSharedPtr<Combine_EditorGameSvrAuth>(retTop);




//TweakPtr 이 존재하는데 C++ 에서는 Lock() 함수지만 Unreal 에서는 Pin()

//이라는 이름으로 shared_ptr 로 convert 하는 함수를 지원한다


auto pred = [](wpCombineBase elem1)->bool {

return elem1.Pin()->GetTypeID() == "EditorLogin";

};


반응형
반응형

I hope I understood your question correctly, but it sounds like you're wondering how to create the .generated.hheader files.

The .generated.h header files are generated automatically for you by Unreal Header Tool (UHT). They will be generated whenever you declare a USTRUCT() or UCLASS() type in your header files. The name of the generated header will be the name of your header file, plus ".generated" appended. For example, if your header is called MyHeader.h and declares one or more UCLASS or USTRUCT types, the file MyHeader.generated.h will be generated for you.

The contents of the .generated.h file depend on the details of your type declarations. They generally contain glue code for run-time reflection, serialization, default constructors and initialization code.



https://answers.unrealengine.com/questions/298930/how-to-create-only-header-file-while-exist-inside.html

반응형
반응형

액터의 생명 주기

https://docs.unrealengine.com/latest/KOR/Programming/UnrealArchitecture/Actors/ActorLifecycle/index.html

  • SHARE:

언리얼 엔진

이 문서는 액터의 생명 주기에 대한 하이 레벨 개요서로, 액터가 레벨에 어떻게 인스턴스가 생성 (Spawn) 되고 소멸 (Destroy) 되는지에 대해서입니다.

아래 흐름도는 액터 인스턴스가 생성되는 세 가지 주요 경로에 대해 보여줍니다. 액터 생성이 어떻게 되었든지 관계없이, 소멸까지 모두 같은 경로를 따릅니다.

생명 주기 분해도


디스크에서 로드

이 경로는 이미 레벨에 있는 액터에 대해서, LoadMap 이 발생했을 때나 (스트리밍 또는 서브 레벨에서) AddToWorld 가 호출되었을 때 발생합니다.

  1. 패키지/레벨에 있는 액터가 디스크에서 로드됩니다.

  2. PostLoad 로드 이후 - 디스크에서의 로드 완료 후 serialize 된 액터에 의해 호출됩니다. 커스텀 버전이나 픽스 작업은 이 곳에 와야 합니다. PostLoad 는 PostActorCreated 와 상호 배제됩니다.

  3. InitializeActorsForPlay 플레이용 액터 초기화

  4. RouteActorInitialize 액터 초기화 경로변경 - 초기화되지 않은 액터에 대해 호출됩니다 (심리스 트래블 전환 처리)

    1. PreInitializeComponents 컴포넌트 초기화 이전 - 액터의 컴포넌트에 InitializeComponent 를 호출하기 전 호출합니다.

    2. InitializeComponent 컴포넌트 초기화 - 액터에 정의된 각 컴포넌트 생성용 헬퍼 함수입니다.

    3. PostInitializeComponents 컴포넌트 초기화 이후 - 액터의 컴포넌트 초기화 완료 후 호출됩니다.

  5. BeginPlay 플레이 시작 - 레벨이 시작되면 호출됩니다.

에디터에서 플레이

에디터에서 플레이 경로는 디스크에서 로드와 거의 똑같지만, 액터를 디스크에서 로드하기 보다는 에디터에서 복사해 옵니다.

  1. 에디터에 있는 액터를 새 월드로 복제합니다.

  2. PostDuplicate (복제 이후)를 호출합니다.

  3. InitializeActorsForPlay (플레이용 액터 초기화)

  4. 초기화되지 않은 액터는 RouteActorInitialize (액터 초기화 전달), (심리스 트래블 이전 처리)

    1. PreInitializeComponents (컴포넌트 초기화 이전) - 액터의 컴포넌트에서 InitializeComponent (컴포넌트 초기화)가 호출되기 이전에 호출됩니다.

    2. InitializeComponent 컴포넌트 초기화 - 액터에 정의된 컴포넌트 각각에 대한 생성을 돕는 함수입니다.

    3. PostInitializeComponents 컴포넌트 초기화 이후 - 액터의 컴포넌트 초기화가 완료된 이후 호출됩니다.

  5. BeginPlay 플레이 시작 - 레벨이 시작되면 호출됩니다.

스폰

액터를 스폰(인스턴싱)할 때 따르게 되는 경로입니다.

  1. SpawnActor (액터 스폰)이 호출됩니다.

  2. PostSpawnInitialize (스폰 초기화 이후)가 호출됩니다.

  3. PostActorCreated 액터 생성 이후 - 스폰된 액터의 생성 이후에 호출됩니다. 생성자같은 것이 여기에 와야 합니다.PostActorCreated (액터 생성 이후)는 PostLoad (로드 이후)와 상호 배제적입니다.

  4. ExecuteConstruction (생성 실행):

    • OnConstruction 생성시 - 액터의 생성 지점으로, 블루프린트 액터가 컴포넌트를 만들고 블루프린트 변수를 초기화시키는 곳입니다.

  5. PostActorConstruction (액터 생성 이후):

    1. PreInitializeComponents 컴포넌트 초기화 이전 - 액터의 컴포넌트에서 InitializeComponent (컴포넌트 초기화)가 호출되기 전에 호출됩니다.

    2. InitializeComponent (컴포넌트 초기화) - 액터에 정의된 컴포넌트 각각의 생성을 돕는 함수입니다.

    3. PostInitializeComponents 컴포넌트 초기화 이후 - 액터의 컴포넌트 초기화가 완료된 이후 호출됩니다.

  6. OnActorSpawned (액터가 스폰되었을 때)가 UWorld 에 방송됩니다.

  7. BeginPlay (플레이 시작)이 호출됩니다.

디퍼드 스폰

"Expose on Spawn" (스폰시 노출) 설정된 프로퍼티가 있으면 액터는 디퍼드(유예시켜 나중에 한 번에 몰아서) 스폰이 가능합니다.

  1. SpawnActorDeferred 액터 디퍼드 스폰 - 순차적 액터 스폰을 뜻하는 것으로, 블루프린트 컨스트럭션 스크립트 이전 추가적인 구성이 가능합니다.

  2. SpawnActor (액터 스폰) 안의 모든 것이 일어나지만, PostActorCreated (액터 생성 이후) 뒤에는 다음과 같은 일이 일어납니다:

    1. 유효하지만 완료되지는 않은 액터 인스턴스로 다양한 "초기화 함수" 구성 / 호출을 합니다.

    2. FinishSpawningActor 액터 스폰 마무리 - 액터를 마무리시키기 위해 호출되며, SpawnActor (액터 스폰) 줄의 ExecuteConstruction (생성 실행)을 집어듭니다.

수명의 막바지에 달해서

액터 소멸(destroy)은 여러가지 방식으로 가능하나, 존재의 종말은 항상 같습니다.

게임플레이 도중

이는 완벽히 옵션인데, 많은 액터가 플레이 도중에는 실제로 죽지 않을 것이기 때문입니다.

Destroy 소멸 - 액터를 제거해야겠다 싶지만 게임플레이가 계속 진행중일 때 게임에서 수동으로 호출됩니다. 액터는 킬 대기 상태로 마킹되며, 레벨의 액터 배열에서 제거됩니다.

EndPlay 플레이 종료 - 액터의 수명이 막바지에 다다랐음을 보증하기 위해 여러 곳에서 호출됩니다. 플레이 도중에는 Destroy (소멸)이나, Level Transition (레벨 전환)이나, 액터가 들어있는 스트리밍 레벨이 언로드되면 이 함수가 발동됩니다. EndPlay 가 호출되는 경우는 다음과 같습니다:

  • Destroy 명시적 호출

  • 에디터에서 플레이 종료

  • Level Transition (심리스 트래블 또는 맵 로드)

  • 액터가 들어있는 스트리밍 레벨 언로드

  • 액터의 수명 만료

  • 어플리케이션 종료 (모든 액터 소멸)

어떻게 발생했는지와는 상관없이, 액터는 RF_PendingKill 마킹되어 다음 가비지 콜렉션 주기 동안 deallocate (할당 해제)됩니다. 또한 pending kill (킬 대기상태)를 수동 검사하기 보다는, 보다 깔끔한 FWeakObjectPtr 사용을 추천합니다.

OnDestroy 소멸시 - Destory (소멸)에 대한 구식(legacy) 반응입니다. 여기 있는 것들은 Level Transition (레벨 전환)이나 기타 게임 정리용 함수에 호출되는 EndPlay (플레이 종료)에 옮기는 것이 좋을 것입니다.

가비지 콜렉션

오브젝트가 소멸 마킹된 이후에는, 가비지 콜렉션이 일어날 때 메모리에서 실제로 제거되어 사용중이던 리소스가 해제됩니다.

오브젝트의 소멸 도중 호출되는 함수는 다음과 같습니다:

  1. BeginDestroy 소멸 시작 - 여기서 오브젝트의 메모리를 해제하고 기타 (그래픽 스레드 프록시 오브젝트 등의) 멀티스레드 리소스 처리를 할 수 있습니다. 소멸 예정 관련 대부분의 게임플레이 함수성은 더욱 일찍 EndPlay 에서 처리되었을 것입니다.

  2. IsReadyForFinishDestroy 소멸 마무리 준비 여부 - 가비지 콜렉션 프로세스는 이 함수를 호출하여 오브젝트 할당을 영구히 해제할 준비가 되었는지 여부를 결정합니다. false 를 반환하면, 이 함수는 다음 가비지 콜렉션 패스까지 실제 오브젝트 소멸 작업을 유예시킵니다.

  3. FinishDestroy 소멸 마무리 - 오브젝트가 곧 소멸되므로, 내부 데이터 구조체를 해제시킬 마지막 기회입니다. 메모리 해제 이전 마지막 호출입니다.

고급 가비지 콜렉션

언리얼 엔진 4 의 가비지 콜렉션 프로세스에서는 모두 같이 소멸되는 오브젝트 클러스터를 만듭니다. 클러스터를 만들면 오브젝트를 개별적으로 삭제할 때에 비할 때 가비지 콜렉션 관련 전체적인 메모리 교란(churn) 정도나 총 시간이 감소됩니다. 오브젝트가 로드되면서 서브오브젝트가 생성될 수 있습니다. 오브젝트와 그 서브오브젝트를 가비지 콜렉터의 단일 클러스터로 합쳐 넣는 경우, 엔진은 전체 오브젝트가 해제 준비될 때까지 클러스터에 사용되는 리소스의 해제를 지연시켰다가, 모든 리소스를 한 번에 해제시킬 수 있습니다.

가비지 콜렉션은 대부분의 프로젝트의 경우 환경설정 또는 변경할 필요가 전혀 없으나, 가비지 콜렉터의 클러스터 작동방식을 바꿔서 효율을 향상시킬 수 있는 경우가 있을 수 있는데, 그 방법은 다음과 같습니다:

  1. Clustering 클러스터링 - 이 옵션은 끕니다. 프로젝트 세팅 에서 Garbage Collection (가비지 콜렉션) 섹션 아래 Create Garbage Collector UObject Clusters (가비지 콜렉터 오브젝트 클러스터 생성) 옵션을 false 로 설정하면 됩니다. 대부분의 프로젝트의 경우 이 옵션을 끄면 가비지 콜렉션 효율이 떨어지므로, 퍼포먼스 테스트를 통해 득이 되는 것이 확실한 경우에만 끄는 것이 좋습니다.

  2. Cluster Merging 클러스터 병합 - 클러스터링이 true 로 설정된 경우, (프로젝트 세팅 에서 Garbage Collection (가비지 콜렉션) 섹션 아래) Merge GC Clusters (GC 클러스터 병합) 옵션을 true 로 설정하면 클러스터 병합 기능을 켤 수 있습니다. 이 옵션은 기본적으로 꺼져있으며, 모든 프로젝트에 적합하지도 않습니다. 오브젝트의 클러스터를 만드는 프로세스 도중, 오브젝트를 검사하여 그 안에 다른 오브젝트로의 레퍼런스를 찾을 수 있습니다. 클러스터 병합이 없으면 (기본 동작) 그 레페런스가 기록은 되나, 로드되는 오브젝트와 그 서브오브젝트는 원래 클러스터에 남아있게 됩니다. 클러스터 병합이 있으면, 로드되는 오브젝트의 클러스터와 레퍼런스 대상 오브젝트가 합쳐집니다. 예를 들어 파티클 시스템 애셋이 머티리얼 애셋을 레퍼런스하나 클러스터 병합 옵션은 꺼진 경우, 머티리얼과 파티클 시스템은 가비지 콜렉션용 별도의 클러스터에 남아있습니다. 클러스터 병합 옵션이 켜진 경우, 파티클 시스템이 머티리얼을 레퍼런스하고 있기 때문에 파티클 애셋 클러스터가 머티리얼 클러스터와 병합됩니다. 이러한 방식은 오픈 월드 게임처럼 콘텐츠 스트리밍이 일어나는 경우엔 바람직하지 않을 수 있는데, 다수의 클러스터가 병합되면서 보다 거대하고 다양한 오브젝트 그룹을 형성하기 때문입니다. 클러스터의 오브젝트들은 개별적으로 소멸되지 않고, 그 그룹의 모든 오브젝트가 소멸 설정될 때까지 기다리게 됩니다. 그렇게 되면 그 오브젝트 중 소수만 사용되어도 거대한 오브젝트 클러스터가 메모리에 남아있게 되는 경우가 생길 수 있습니다. 하지만 클러스터 병합 기능을 켜고, 코드에서 다른 오브젝트에 공유되지 않는 레퍼런스된 오브젝트가 다수 있는 애셋과 같은 특별한 경우를 수동으로 추가해 주면, 서브오브젝트들을 한꺼번에 청소하고, 가비지 콜렉터가 게임 도중 유지하면서 검사해야 하는 개별 항목 및 서브오브젝트 수가 줄어들기에 퍼포먼스가 향상될 수 있습니다. AdvancedGC.png


반응형
반응형

String Conversions: FString to FName, FString to Int32, Float to FString


All the header files I refer to in this tutorial are found in

your UE4 install directory  / Engine / Source

you will probably want to do a search for them from this point :)

Converting FString to FNames

Say we have

FString TheString = "UE4_C++_IS_Awesome";

To convert this to an FName you do:

FName ConvertedFString = FName(*TheString);

std::string to FString

#include <string>
 
//....
 
some function
{
  std::string TestString = "Happy"; 
  FString HappyString(TestString.c_str());
}

FString to std::string

#include <string>
 
//....
FString UE4Str = "Flowers";
std::string MyStdString(TCHAR_TO_UTF8(*UE4Str));

FCString Overview

Converting FString to Numbers

The * operator on FStrings returns their TCHAR* data which is what FCString functions use.

If you cant find the function you want in FStrings (UnrealString.h) then you should check out the FCString functions (CString.h)

I show how to convert from FString to FCString below:

Say we have

FString TheString = "123.021";

FString to Integer

int32 MyShinyNewInt = FCString::Atoi(*TheString);

FString to Float

float MyShinyNewFloat = FCString::Atof(*TheString);


Note that Atoi and Atof are static functions, so you use the syntax FCString::TheFunction to call it :)


Float/Integer to FString

FString NewString = FString::FromInt(YourInt);
 
FString VeryCleanString = FString::SanitizeFloat(YourFloat);

Static functions in the UnrealString.h :)

UE4 Source Header References

CString.h
UnrealString.h
NameTypes.h

See CString.h for more details and other functions like

atoi64 (string to int64)
Atod	(string to double precision float)


For a great deal of helpful functions you will also want to look at

UnrealString.h for direct manipulation of FStrings!


For more info on FNames check out
 NameTypes.h

Enjoy!

Rama (talk)




https://wiki.unrealengine.com/String_Conversions:_FString_to_FName,_FString_to_Int32,_Float_to_FString

반응형
반응형


먼저 주의할 점은 언리얼 구조체를 만들때 구조체 이름 앞에 F를 붙여야 한다는 것에 주의!!

https://wiki.unrealengine.com/Structs,_USTRUCTS(),_They're_Awesome

Overview

Original Author: Rama (talk)

In C++, structs differ from classes only in that properties and methods defined prior to any accessibility keyword (public:protected:,private:) default to public: while in classes these default to private:. Structs are more or less artifacts of the transition from C to C++. In C, object oriented programming did not exist yet, thus structs were only used to organize data and pass that data to functions, for example, but lacked the support for methods. In C++, with the introduction of classes, this purpose became more or less deprecated. Personally I thus find it a good practice Epic is enforcing here.

Structs enable you to create custom variable types to organize your data, by relating other C++ or UE4 C++ data types to each other. The power of structs is extreme organization as well as the ability to have functions for internal data type operations. '

In UE4, structs should be used for simple data type combining and data management purposes. For complex interactions with the game world, you should make a UObject or AActor subclass instead.

Core Syntax

NOTE: Depending on your version of UE4, you'll need to replace GENERATED_BODY() with GENERATED_USTRUCT_BODY(). At least as of version 4.11, using GENERATED_USTRUCT_BODY() will result in a UHT error stating GENERATED_BODY() is expected.

//If you want this to appear in BP, make sure to use this instead
//USTRUCT(BlueprintType)
USTRUCT()
struct FJoyStruct
{
	GENERATED_BODY()
 
	//Always make USTRUCT variables into UPROPERTY()
	//    any non-UPROPERTY() struct vars are not replicated
 
	// So to simplify your life for later debugging, always use UPROPERTY()
	UPROPERTY()
	int32 SampleInt32;
 
	UPROPERTY()
	AActor* TargetActor;
 
	//Set
	void SetInt(const int32 NewValue)
	{
		SampleInt32 = NewValue;
	}
 
	//Get
	AActor* GetActor()
	{
		return TargetActor;
	}
 
	//Check
	bool ActorIsValid() const
	{
		if(!TargetActor) return false;
		return TargetActor->IsValidLowLevel();
	}
 
	//Constructor
	FJoyStruct()
	{
		//Always initialize your USTRUCT variables!
		//   exception is if you know the variable type has its own default constructor
		SampleInt32 	= 5;
		TargetActor = NULL;
	}
};


Additional Note Author: DesertEagle_PWN (talk)
Additional Note: The idea of USTRUCTS() is to declare engine data types that are in global scope and can be accessed by other classes/structs/blueprints. Because of this, it is invalid UE4 syntax to declare a struct inside of a class or other struct if using the USTRUCT() macro. Regular structs can still be utilized inside your classes and other structs; however these cannot be replicated natively and will not be available for UE4 reflective debugging or other engine systems such as Blueprints.

Examples

Example 1

You want to relate a float brightness value with a world space location FVector, both of which are interpolated using an Alpha value.

  • And you want to do this for 100 different game locations simultaneously.
  • And you want to do this process repeatedly over time!
  • You need to store the incremental interpolation values between game events.
  • AActors/UObjects are not involved (You could just subclass AActor/UObject and store the data per instance)


USTRUCT()
struct FMyInterpStruct
{
	GENERATED_BODY()
 
	UPROPERTY()
	float Brightness;
 
	UPROPERTY()
	float BrightnessGoal; //interping to
 
	UPROPERTY()
	FVector Location;
 
	UPROPERTY()
	FVector LocationGoal;
 
	UPROPERTY()
	float Alpha;
 
	void InterpInternal()
	{
		Location = FMath::Lerp<FVector>(Location,LocationGoal,Alpha);
		Brightness = FMath::Lerp<float>(Brightness,BrightnessGoal,Alpha);
	}
 
	//Brightness out is returned, FVector is returned by reference
	float Interp(const float& NewAlpha, FVector& Out)
	{
		//value received from rest of your game engine
		Alpha = NewAlpha;
 
		//Internal data structure management
		InterpInternal();
 
		//Return Values
		Out = Location;
		return Brightness;
	}
	FMyInterpStruct()
	{
		Brightness = 2; 
		BrightnessGoal = 100;
 
		Alpha = 0; 
 
		Location = FVector::ZeroVector;
		LocationGoal = FVector(0,0,200000);
	}
};

Example 2

You want to track information about particle system components that you have spawned into the world through

 UGameplayStatics::SpawnEmitterAtLocation() // returns a UParticleSystemComponent

and you want to track the lifetime of the particle and apply parameter changes from C++. You could write your own class, but if your needs are simple or you do not have project-permissions to make a subclass of UParticleSystemComponent, you can just make a USTRUCT to relate the various data types!

USTRUCT()
struct FParticleStruct
{
	GENERATED_BODY()
 
	UPROPERTY()
	UParticleSystemComponent* PSCPtr;
 
	UPROPERTY()
	float LifeTime;
 
	void SetColor()
	{
		//
	}
	FLinearColor GetCurrentColor() const
	{
		//
	}
 
	//For GC
	void Destroy()
	{
		PSCPtr = nullptr;
	}
 
	//Constructor
	FParticleStruct()
	{
		PSCPtr = NULL;
		LifeTime = -1;
	}
};

Particle Data Tracker

Now you can have an array of these USTRUCTS for each particle that you spawn!

//Particle Data Tracking Array
TArray<FParticleStruct> PSCArray;

Garbage Collection

Because all of your USTRUCT variables are UPROPERTY(), you must be careful to null them out when you are ready to destroy the particle system component.

Structs With Struct Member Variables

The struct that wants to use another struct must be defined below the struct it wants to include.

USTRUCT()
struct FFlowerStruct
{
	GENERATED_BODY()
 
	UPROPERTY()
	int32 NumPetals;
 
	UPROPERTY()
	FLinearColor Color;
 
	UPROPERTY()
	FVector Scale3D;
 
	void SetFlowerColor(const FLinearColor& NewColor)
	{
		Color = NewColor;
	}
 
	FFlowerStruct()
	{
		NumPetals 	= 5;
		Scale3D 		= FVector(1,1,1);
		Color 			= FLinearColor(1,0,0,1);
	}
};
 
USTRUCT()
struct FIslandStruct
{
	GENERATED_BODY()
 
	UPROPERTY()
	int32 Type;
 
	UPROPERTY()
	TArray<FVector> StarLocations;
 
	UPROPERTY()
	float RainAlpha;
 
	//Dynamic Array of Flower Custom USTRUCT()
	UPROPERTY()
	TArray<FFlowerStruct> FlowersOnThisIsland;
 
	void SetRainAlpha(const float& NewAlpha) 
	{
		RainAlpha = NewAlpha;
	}
 
	int32 GetStarCount() const
	{
		return StarLocations.Num();
	}
	FIslandStruct()
	{
		Type = 0;
		Percent = 1;
	}
};

Struct Assignment

My personal favorite thing about structs is that unlike UObject or AActor classes, which must be utilized via pointers (AActor*) you can directly copy the entire contents of a USTRUCT to another USTRUCT of the same type with a single line of assignment!

FFlowerStruct ExistingFlower;
 
// ... create ExistingFlower here
 
FFlowerStruct NewFlower;
NewFlower = ExistingFlower;

Caveat: Deep Copy

A misconception of the original author is probably that Epic created code in the GENERATED_BODY() macro that would deep-copy a struct upon assigning it to another. In reality, struct assignment has always been a shallow copy in native C. Thus if you were to assign one struct to another like so:

USTRUCT()
struct FMyStruct {
    int32* MyIntArray;
};
 
FMyStruct MyFirstStruct, MySecondStruct;
 
// Create the integer array on the first struct
MyFirstStruct.MyIntArray = new int32[10];
for( int i = 0; i < 10; ++i ) {
  MyFirstStruct.MyIntArray[i] = i;
}
 
GEngine->AddOnScreenMessage(-1, 10.f, FColor::Blue, FString::FromInt(MyFirstStruct.MyIntArray[4]));
 
// Assign the first struct to the second struct, i.e. create a shallow copy
MySecondStruct.MyIntArray[4] = 6;
 
GEngine->AddOnScreenMessage(-1, 10.f, FColor::Blue, FString::Printf(TEXT("%d %d"), MyFirstStruct.MyIntArray[4], MySecondStruct.MyIntArray[4]));

On screen the output will be

 4
 6 6

instead of the expected

 4
 4 6

This is because the data stored in MyStruct::MyIntArray is not actually stored inside of MyStruct. The new keyword creates the data somewhere in RAM and we simply store a pointer there. The address the pointer stores is copied over to MySecondStruct, but it still points to the same data. In fact, it would be counterproductive to remove this functionality since there are cases where you want exactly that. Additionally the Unreal Property System does not support non-UObject pointers, which is why MyIntArray is not marked with UPROPERTY().

However, copying arrays of integers (e.g. int32[10] instead of int32*) means the data is stored directly inside the struct and as such "deep copied". However, if you store a pointer to a UObject, this object is NOT deep copied! Once again only the pointer is copied and the original UObject left unchanged. Which is good because otherwise you might manipulate the wrong instance thinking you only had one to begin with leaving the original UObject unaffected, thus resembling a very nerve-wrecking and very difficult to track down bug!


이 부분이 핀 분할/ 재결합 부분으로

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Flower Struct") 이 한줄이 중요함

Automatic Make/Break in BP

Marking the USTRUCT as BlueprintType and adding EditAnywhere, BlueprintReadWrite, Category = "Your Category" to USTRUCT properties causes UE4 to automatically create Make and Break Blueprint functions, allowing to construct or extract data from the custom USTRUCT.

Special thanks to Community member Iniside for pointing this out. :)

USTRUCT(BlueprintType)
struct FFlowerStruct
{
	GENERATED_BODY()
 
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Flower Struct")
	int32 NumPetals;
 
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Flower Struct")
	FLinearColor Color;
 
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Flower Struct")
	FVector Scale3D;
};

CustomUStructMakeBreak.jpg

Replication




 Remember that only UPROPERTY() variables of USTRUCTS() are considered for replication!



So if your USTRUCT is not replicating properly, the first thing you should check is that every member is at least UPROPERTY()! The struct does not have be a BlueprintType, it just needs UPROPERTY() above all properties that you want replicated.

Related Links

UStruct data member memory management

Thank You Epic for USTRUCTS()

I love USTRUCTS(), thank you Epic!

반응형
반응형

언리얼4 블루프린트에서 short 그리고 uint64 같은 바이트를 지원하지 않는데 


short 이야 int 로 친다 하더래도, 8바이트 짜리는?? -> 이건 Fstring 으로 변환해 사용한다




Unreal Engine 4 - Converting uint64_t to FString


http://blog.vkarlsson.com/

In our current Game Jam we wanted BIG numbers for our score, so to make sure that the code can handle BIG numbers I wanted to implement the score as a unsigned long long int.

Unreal Engine 4 doesn’t support uint64_t to be converted into FString by default so I had to find a solution.

The solution was a combination of C++ string-stream strings and of course FString.

Below is the conversion code:

FString AGameHUD::GetScore()
{
  std::ostringstream ss;
  std::string s;
  s = (ss << Score).str();
  FString f(s.c_str());
  return f;
}


반응형
반응형

c++ 코드에서 함소 호출 시  인자와 같이 넘길 수 있는 방법은


함수명뒤에 인자를 같이 붙여주면 된다 아래처럼 단위 함수로 만들면 유용


https://answers.unrealengine.com/questions/116529/call-blueprint-functions-from-c.html?sort=oldest



Another bit of useful code....

  1. char funcCallBuf[1024];
  2. void UTDLSurvivorFastCache::CallActorFunc(AActor * c, FString funcName)
  3. {
  4. FOutputDeviceNull ar;
  5. c->CallFunctionByNameWithArguments(*funcName, ar, NULL, true);
  6. }
  7. void UTDLSurvivorFastCache::CallActorFuncIntParam(AActor * c, FString funcName, int32 f)
  8. {
  9. _snprintf(funcCallBuf, sizeof(funcCallBuf), "%s %d", *funcName, f);
  10. FOutputDeviceNull ar;
  11. c->CallFunctionByNameWithArguments(ANSI_TO_TCHAR(funcCallBuf), ar, NULL, true);
  12. }
  13. void UTDLSurvivorFastCache::CallActorFuncFloatParam(AActor * c, FString funcName, float f)
  14. {
  15. _snprintf(funcCallBuf, sizeof(funcCallBuf), "%s %f", *funcName, f);
  16. FOutputDeviceNull ar;
  17. c->CallFunctionByNameWithArguments(ANSI_TO_TCHAR(funcCallBuf), ar, NULL, true);
  18. }
  19. void UTDLSurvivorFastCache::CallActorFuncFloatIntParam(AActor * c, FString funcName, float f, int32 n)
  20. {
  21. _snprintf(funcCallBuf, sizeof(funcCallBuf), "%s %f %d", *funcName, f, n);
  22. FOutputDeviceNull ar;
  23. c->CallFunctionByNameWithArguments(ANSI_TO_TCHAR(funcCallBuf), ar, NULL, true);
  24. }

xlar8or gravatar image xlar8or Dec 22 '15 at 10:33 PM Newest

Is there a way to do this for a AActor parameter?



C++에서 블루프린트 함수 호출하기 .1


http://3dmpengines.tistory.com/1615

반응형
반응형


Ok, got this working so here is an example....

I want to call a blueprint function from C++.

So first I make a blueprint function called CallFunctionTest. (In our game, and we call a player a "Survivor".) It just prints "Survivor Call Function Test" in pink on the console.

Then I have a static blueprint set of functions like this...

The header file is

  1. #include "Kismet/BlueprintFunctionLibrary.h"
  2. #include "TDLSurvivorFastCache.generated.h"
  3. /**
  4. *
  5. */
  6. UCLASS()
  7. class TDL_API UTDLSurvivorFastCache : public UBlueprintFunctionLibrary
  8. {
  9. GENERATED_UCLASS_BODY()
  10. public:
  11. UFUNCTION(BlueprintCallable, Category = TDLSurvivorCache)
  12. static void TestCPPCallToBP(AActor * c);
  13. };

and the cpp file is...

  1. #include "tdl.h"
  2. #include "ConsoleManager.h"
  3. #include "TDLSurvivorFastCache.h"
  4. UTDLSurvivorFastCache::UTDLSurvivorFastCache(const class FObjectInitializer & PCIP)
  5. : Super(PCIP)
  6. {
  7. UE_LOG(TDLLog, Log, TEXT("UTDLSurvivorFastCache"));
  8. }
  9. void UTDLSurvivorFastCache::TestCPPCallToBP(AActor * c)
  10. {
  11. FOutputDeviceNull ar;
  12. c->CallFunctionByNameWithArguments(TEXT("CallFunctionTest"), ar, NULL, true);
  13. }

Then we call the test function from our SurvivorBP blueprint and it calls the function on the SurvivorBP.

Here are the blueprints

alt text

alt text


https://answers.unrealengine.com/questions/116529/call-blueprint-functions-from-c.html?sort=oldest


반응형
반응형

Blueprints, Empower Your Entire Team With BlueprintImplementableEvent

Overview

Original Author: Rama (talk)

Dear Community,

Here is perhaps the most powerful thing you can do as a c++ programmer for blueprint programmers!

So you've created your awesome new amazing C++ system,

but how do you tell the blueprint world when critical events occur in your C++ system?

You need to not only be able to have blueprint programmers call functions that use your C++ system,

you need to be able to spontaneously provide info to blueprint graph system, based on Run-Time events.

This is where BlueprintImplementableEvents come into play!

Providing Blueprints With Data And Critical Timings

Using the BlueprintImplementableEvent you can not only tell blueprints when a critical game event has occurred that your awesome C++ system is tracking / creating,

you can also send variable data to blueprints!

Example code below!

PlayerController.h

.h

/** Player's Health is Currently Above 50! Returns 
player's exact current health for convenience. This 
function runs every tick that the player's health 
is high enough! Play healthy sounds here. */
UFUNCTION(BlueprintImplementableEvent, meta=(FriendlyName = "Player Health ~ Player Is Healthy Tick"))
void PlayerIsHealthyTick(float CurrentHealth);

.cpp

void AYourPlayerController::PlayerTick(float DeltaTime)
{
	Super::PlayerTick(DeltaTime);
 
	//========================
	// 	BP Interface
	if(Health >= 50) 
	{
		this->PlayerIsHealthyTick(Health);
	}
	//========================
}

CPPBPEvent.jpg

This

 this->PlayerIsHealthyTick(Health);

I personally use this-> to tell myself I am not actually calling a C++ function, but am sending info to BP.

You could exclude the use of this->

Tick Function

Note that the sample code is sending an event to blueprints every tick!

You can call BlueprintImplementableEvent's any way you want,

but I used this example to show a constant interfacing from c++ to blueprint graphs.

Sending Data to Blueprints From C++

Notice how the player's current health is being sent to blueprints as a function parameter!

You can pass any data you want from C++ to blueprints this way!

Calling a BlueprintImplementableEvent in Blueprints

Make sure to include BlueprintCallable if you want to also call your event in Blueprints!

UFUNCTION(Category = "Player Health", BlueprintImplementableEvent, BlueprintCallable)
void PlayerIsHealthyTick(float CurrentHealth);

4.8 Standard, Non Virtual

As of 4.8 BlueprintImplementableEvents should not be made virtual!

From the 4.8 Engine upgrade notes:

 Removed "virtual" keyword from several engine-level BlueprintImplementableEvents 
 to conform to the new "BlueprintImplementableEvents should not be virtual" standard.

Debugging BlueprintImplementableEvent

Void Return Value

If you are having trouble getting a BlueprintImplementableEvent to show up in the blueprint graph, try making sure that your return type is void.

If you do have a return type, your BP implementable event will show up in the left panel and you can right click to implement it.

Do Not Pass by Non-Const Reference

Also, I dont recommend trying to pass data to blueprints using non-const reference.

either use const reference or no reference at all.

/** Player's Health is Currently Above 50! Returns player's exact current health for convenience. This function runs every tick that the player's health is high enough! Play healthy sounds here. */
UFUNCTION(BlueprintImplementableEvent, meta=(FriendlyName = "Player Health ~ Player Is Healthy Tick"))
void PlayerIsHealthyTick(float CurrentHealth);
/** Player's Health is Currently Above 50! Returns player's exact current health for convenience. This function runs every tick that the player's health is high enough! Play healthy sounds here. */
UFUNCTION(BlueprintImplementableEvent, meta=(FriendlyName = "Player Health ~ Player Is Healthy Tick"))
void PlayerIsHealthyTick(const float& CurrentHealth);

C++ to BP Interface

I am using the term interface loosely here, to describe how it is that you as the C++ programmer of an awesome new game mechanic can give Blueprint users all the info they need about what your C++ system is doing!

You can do all the core calculations in C++, and just send blueprint graphs the results!

Blueprints For More Than Prototyping

Using BlueprintImplementableEvent's I can now show you that blueprints are amazing for far more than just prototyping game logic that should then be re-written in C++.

Using BlueprintImplementableEvent's, you can actually build a complex low-level c++ system,

and then provide the blueprint graphs with all the critical access points and information needed,

so that blueprints can fully extend and utilize the core C++ system!

Use Blueprints & BlueprintImplementableEvent to Empower Your Entire Team

In this way, you as a C++ programmer can empower your entire team to access, utilize, and extend a core C++ system in blueprints!

This is my favorite thing about the synergy of C++ with Blueprints!

You can write the core system in C++, and then give all of its power and new creativity to the blueprint programmers to take in all sorts of new directions!

Enjoy!


반응형
반응형

Delegate UE4


https://docs.unrealengine.com/latest/KOR/Programming/UnrealArchitecture/Delegates/index.html


델리게이트로 C++ 오브젝트 상의 멤버 함수 호출을 일반적이고 유형적으로 안전한 방식으로 할 수 있습니다. 델리게이트를 사용하여 임의 오브젝트의 멤버 함수에 동적으로 바인딩시킬 수 있으며, 그런 다음 그 오브젝트에서 함수를 호출할 수 있습니다. 호출하는 곳에서 오브젝트의 유형을 몰라도 말이지요.

델리게이트 오브젝트는 복사해도 완벽히 안전합니다. 델리게이트는 값으로 전달 가능하나 보통 추천할 만 하지는 않는데, heap 에 메모리를 할당해야 하기 때문입니다. 가급적이면 델리게이트는 항상 참조 전달해야 합니다.

델리게이트는 싱글-캐스트(형 변환)와 멀티-캐스트 모두 지원되며, 디스크에 안전하게 Serialize 시킬 수 있는 "다이내믹" 델리게이트도 물론입니다.

델리게이트 선언하기

델리게이트의 선언은 제공되어 있는 선언 매크로 중 하나를 사용하여 이루어집니다. 사용되는 매크로는 델리게이트에 바인딩되는 함수의 시그너처에 따라 결정됩니다. 시스템에서는 델리게이트 유형을 선언해 낼 수 있는 범용 함수 시그너처의 다양한 조합을 미리 정의, 이를 통해 반환값과 파라미터에 대한 유형 이름을 필요한 대로 채워넣습니다. 현재 다음 항목들의 어떠한 조합에 대해서도 델리게이트 시그너처가 지원됩니다:

  • 값을 반환하는 함수

  • "페이로드"(payload, 유상) 변수 4 개 까지

  • 함수 파라미터 8 개 까지

  • 'const' 로 선언된 함수

이 표에서 델리게이트 선언에 사용할 매크로를 찾을 수 있습니다.

함수 시그너처선언 매크로
void Function()DECLARE_DELEGATE( DelegateName )
void Function( <Param1> )DECLARE_DELEGATE_OneParam( DelegateName, Param1Type )
void Function( <Param1>, <Param2> )DECLARE_DELEGATE_TwoParams( DelegateName, Param1Type, Param2Type )
void Function( <Param1>, <Param2>, ... )DECLARE_DELEGATE_<Num>Params( DelegateName, Param1Type, Param2Type, ... )
<RetVal> Function()DECLARE_DELEGATE_RetVal( RetValType, DelegateName )
<RetVal> Function( <Param1> )DECLARE_DELEGATE_RetVal_OneParam( RetValType, DelegateName, Param1Type )
<RetVal> Function( <Param1>, <Param2> )DECLARE_DELEGATE_RetVal_TwoParams( RetValType, DelegateName, Param1Type, Param2Type )
<RetVal> Function( <Param1>, <Param2>, ... )DECLARE_DELEGATE_RetVal_<Num>Params( RetValType, DelegateName, Param1Type, Param2Type, ... )

멀티-캐스트, 다이내믹, 래핑된(wrapped) 델리게이트에 대한 변종 매크로도 제공됩니다:

  • DECLARE_MULTICAST_DELEGATE...

  • DECLARE_DYNAMIC_DELEGATE...

  • DECLARE_DYNAMIC_MULTICAST_DELEGATE...

  • DECLARE_DYNAMIC_DELEGATE...

  • DECLARE_DYNAMIC_MULTICAST_DELEGATE...

델리게이트 시그너처 선언은 글로벌 영역에, 네임스페이스 안이나 심지어 (함수 본문은 제외한) 클래스 선언부 안에까지도 존재 가능합니다.

이러한 델리게이트 유형 선언에 있어서의 자세한 정보는 다이내믹 델리게이트 , 멀티캐스트 델리게이트 페이지를 참고해 주시기 바랍니다.

델리게이트 바인딩하기

델리게이트 시스템은 특정 유형의 오브젝트를 이해하고 있으며, 이러한 오브젝트를 사용할 때는 추가적으로 사용할 수 있는 기능이 있습니다. UObject 나 공유 포인터 클래스 멤버에 델리게이트를 바인딩하는 경우, 델리게이트 시스템은 그 오브젝트에 대한 약한 레퍼런스를 유지할 수 있어, 델리게이트 치하에서 오브젝트가 소멸된 경우 IsBound() 나 ExecuteIfBound() 함수를 호출하여 처리해 줄 수 있습니다. 참고로 여러가지 지원되는 오브젝트 유형에 대해서는 특수한 바인딩 문법이 사용됩니다.

함수설명
Bind()기존 델리게이트 오브젝트에 바인딩합니다.
BindStatic()raw C++ 포인터 글로벌 함수 델리게이트를 바인딩합니다.
BindRaw()날(raw) C++ 포인터 델리게이트에 바인딩합니다. 날 포인터는 어떠한 종류의 레퍼런스도 사용하지 않아, 만약 오브젝트가 델리게이트 치하에서 삭제된 경우 호출하기가 안전하지 않을 수도 있습니다. Execute() 호출시에는 조심하세요!
BindSP()공유 포인터-기반 멤버 함수 델리게이트에 바인딩합니다. 공유 포인터 델리게이트는 오브젝트로의 약한 레퍼런스를 유지합니다. ExecuteIfBound() 로 호출할 수 있습니다.
BindUObject()UObject 기반 멤버 함수 델리게이트를 바인딩합니다. UObject 델리게이트는 오브젝트로의 약한 레퍼런스를 유지합니다.ExecuteIfBound() 로 호출할 수 있습니다.
UnBind()이 델리게이트 바인딩을 해제합니다.

이 함수들의 변종, 인수, 구현을 확인하시려면 (..\UE4\Engine\Source\Runtime\Core\Public\Templates\ 에 있는)DelegateSignatureImpl.inl 파일을 확인해 주시기 바랍니다.

페이로드 데이터

델리게이트에 바인딩할 때, 페이로드 데이터를 같이 전해줄 수 있습니다. 페이로드 데이터란 바인딩된 함수를 불러낼(invoke) 때 직접 전해지는 임의의 변수를 말합니다. 바인딩 시간에 델리게이트 자체적으로 파라미터를 보관할 수 있게 되니 매우 유용합니다. ("다이내믹"을 제외한) 모든 델리게이트 유형은 페이로드 변수를 자동으로 지원합니다. 이 예제는 커스텀 변수 둘, 즉 bool 과 int32 를 델리게이트에 전달합니다. 그런 다음 델리게이트를 불러낼 때 이 파라미터가 바인딩된 함수에 전달됩니다. 여분의 변수 인수는 반드시 델리게이트 유형 파라미터 인수 이후에 받아야 합니다.

MyDelegate.BindRaw( &MyFunction, true, 20 );

델리게이트 실행하기

델리게이트에 바인딩된 함수는 델리게이트의 Execute() 함수를 호출하여 실행됩니다. 델리게이트를 실행하기 전 "바인딩" 되었는지 반드시 확인해야 합니다. 이는 코드 안전성을 도모하기 위함인데, 초기화되지 않은 상태로 접근이 가능한 반환값과 출력 파라미터가 델리게이트에 있을 수 있기 때문입니다. 바인딩되지 않은 델리게이트를 실행시키면 일부 인스턴스에서 메모리에 낙서를 해버릴 수가 있습니다. 델리게이트가 실행해도 안전한 지는 IsBound() 를 호출하여 검사해 볼 수 있습니다. 또한 반환값이 없는 델리게이트에 대해서는ExecuteIfBound() 를 호출할 수 있으나, 출력 파라미터는 초기화되지 않을 수 있다는 점 주의하시기 바랍니다.

실행 함수설명
Execute()
ExecuteIfBound()
IsBound()

멀티-캐스트 델리게이트 관련 자세한 내용은 멀티캐스트 델리게이트 페이지를 확인하시기 바랍니다.

사용 예제

아무데서나 호출했으면 하는 메소드를 가진 클래스가 있다고 쳐 봅시다:

class FLogWriter
{
    void WriteToLog( FString );
};

WriteToLog 함수를 호출하려면, 해당 함수의 시그너처에 맞는 델리게이트 유형을 생성해야 합니다. 그러기 위해서는 먼저 아래 매크로 중 하나를 사용하여 델리게이트를 선언해야 합니다. 여기 예제에서는 단순한 델리게이트 유형입니다:

DECLARE_DELEGATE_OneParam( FStringDelegate, FString );

이는 'FStringDelegate' 라는 델리게이트 유형을 생성하며, 'FString' 유형 파라미터를 하나 받습니다.

클래스에서 이 'FStringDelegate' 를 어떻게 사용하는가, 예제는 이렇습니다:

class FMyClass
{
    FStringDelegate WriteToLogDelegate;
};

이렇게 하여 위 클래스의 임의 클래스 안에 있는 메소드로의 포인터를 담을 수 있습니다. 위 클래스가 이 델리게이트에 대해 아는 것이라고는, 함수 시그너처 뿐입니다.

이제 델리게이트 할당을 위해, 단순히 델리게이트 클래스의 인스턴스를 생성하고, 그 메소드를 소유하는 클래스와 함께 템플릿 파라미터로 전해줍니다. 자기 오브젝트의 인스턴스와 그 메소드의 실제 함수 주소 역시도 전해줘야 합니다. 그래서 여기서는 우리 'FLogWriter' 클래스의 인스턴스를 생성한 다음, 그 오브젝트 인스턴스의 'WriteToLog' 메소드에 대한 델리게이트를 생성하겠습니다.

FSharedRef< FLogWriter > LogWriter( new FLogWriter() );

WriteToLogDelegate.BindSP( LogWriter, &FLogWriter::WriteToLog );

이렇게 하여 클래스의 메소드에 델리게이트를 동적으로 바인딩하였습니다! 차암 쉽죠?

BindSP 의 SP 부분은 shared pointer, 공유 포인터를 뜻하는데, 공유 포인터에 소유된 오브젝트에 바인딩하고 있기 때문입니다. BindRaw(), BindUObject() 처럼 다양한 오브젝트 유형 버전도 있습니다.

이제 'FLogWriter' 클래스에 대해 아무것도 모를지라도 FMyClass 를 통해 'WriteToLog' 메소드를 호출할 수 있습니다! 자신의 델리게이트를 호출하려면, 그냥 'Execute()' 메소드를 사용하면 됩니다:

WriteToLogDelegate.Execute( TEXT( "델리게이트 쥑이네!" ) );

델리게이트에 함수를 바인딩하기 전 Execute() 를 호출하면 assert 가 발동됩니다. 그런 경우를 피하기 위해 대부분 이렇게 하는 것이 좋습니다:

WriteToLogDelegate.ExecuteIfBound( TEXT( "함수가 바인딩되었을 때만 실행!" ) );




반응형
반응형

Remarks

GameInstance: high-level manager object for an instance of the running game. Spawned at game creation and not destroyed until game instance is shut down. Running as a standalone game, there will be one of these. Running in PIE (play-in-editor) will generate one of these per PIE instance.



가비지 컬렉터에의해 제거 되지 않도록 플래그 값을 세팅해줘야한다



반응형
반응형

UGameInstance

  • SHARE:

Remarks

GameInstance: high-level manager object for an instance of the running game. Spawned at game creation 

and not destroyed until game instance is shut down. Running as a standalone game, 

there will be one of these. Running in PIE (play-in-editor) will generate one of these per PIE instance.


https://docs.unrealengine.com/latest/INT/API/Runtime/Engine/Engine/UGameInstance/index.html





Thread: Game Instance VS Singleton

  1. #1
    0
    Infiltrator
    Join Date
    Jul 2014
    Posts
    14

    Game Instance VS Singleton

    The recently released UE 4.4 introduced the new UGameInstance class. From what I understand you can have a single global instance of UGameInstance per game and it stays even between level transitions. But I wonder: what are the main differences between a UGameInstance and a Singleton object (which was already available in earlier versions of UE4)? Do they have any advantages over one another or can do anything the other type can't? When should I use which type?
    Quick reply to this messageReply   Reply With QuoteReply With Quote   Multi-Quote This Message     
  2. #2
    0
    Unreal Engine Developer
    Join Date
    Mar 2014
    Posts
    294
    Frankly, GameSingleton was a bit of a hack put in by one of our game teams to deal with the fact that something like GameINstance didn't exist. I'd definitely recommend not using it going forward.

    In a standalone game the GameInstance and a Singleton (that is allocated at startup and cleaned up at shutdown) will have very similar lifespans, however, in the editor, GameInstance will exist just while a Play in Editor (PIE) session is running and there will be one for each PIE session. Game Singleton will exist for the entire duration of the editor and need to be cleaned up or managed each time you start or end a PIE session and if you are using the multiplayer PIE feature (where you can have multiple networked PIE windows within the editor) there is only one Singleton that is shared between them.


https://forums.unrealengine.com/showthread.php?29765-Game-Instance-VS-Singleton

반응형
반응형
  1. #1
    0
    Samaritan
    Join Date
    Jul 2014
    Posts
    130

    Question BeginPlay VS Constructor?

    I have been trying to spawn a certain object when the game starts and have been using constructor to do so, but nothing is happening. DebugMessages I surrounded it with are neither firing. Is there some crucial difference between BeginPlay and contructor?
    Quick reply to this messageReply   Reply With QuoteReply With Quote   Multi-Quote This Message     
  2. #2
    0
    Champion
    Join Date
    Mar 2014
    Posts
    627
    This is due to that when the constructor is called the Actor or world is potentaly not loaded.
    You can use BeginPlay if the actor is placed in the world, or PostInitelize methods to do this.






https://forums.unrealengine.com/showthread.php?27461-BeginPlay-VS-Constructor

반응형

+ Recent posts