Level : WORDPRESS BOOK LINKEDIN PATENT Send Mail 동냥하기 hajunho.com

반응형

`UObject`는 언리얼 엔진의 핵심 클래스 중 하나로, 대부분의 언리얼 엔진 오브젝트 클래스의 기본 클래스 역할을 합니다. 이 클래스는 언리얼 엔진의 반영성 시스템, 가비지 컬렉션, 직렬화, 복제, 그리고 블루프린트 시스템 등 다양한 엔진 기능을 지원하기 위한 기본 틀을 제공합니다.

### 주요 특징

1. **반영성 시스템 (Reflection System)**:
   - `UObject`는 클래스 및 멤버에 대한 메타데이터를 제공하여 런타임 및 디자인 타임 반영성을 지원합니다. 이를 통해 블루프린트, 에디터에서 변수와 함수를 노출하고 사용할 수 있습니다.

2. **가비지 컬렉션 (Garbage Collection)**:
   - `UObject` 클래스는 자동 메모리 관리를 위해 가비지 컬렉션 시스템과 통합됩니다. 이를 통해 메모리 누수를 방지하고, 수명이 끝난 객체를 자동으로 정리할 수 있습니다.

3. **직렬화 (Serialization)**:
   - `UObject` 기반 클래스는 엔진의 직렬화 시스템을 통해 객체의 상태를 저장하고 복원할 수 있습니다. 이를 통해 게임 저장/로드 기능을 쉽게 구현할 수 있습니다.

4. **복제 (Replication)**:
   - `UObject`는 네트워크 환경에서 객체를 동기화하기 위한 복제 시스템을 지원합니다. 이를 통해 서버와 클라이언트 간 객체 상태를 유지할 수 있습니다.

### 사용하는 방법

다음은 `UObject`를 상속받아 새로운 클래스를 정의하는 기본적인 방법입니다:

```cpp
#pragma once

#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "MyUObject.generated.h"

UCLASS(Blueprintable)
class MYGAME_API UMyUObject : public UObject
{
    GENERATED_BODY()

public:
    UMyUObject();

    UFUNCTION(BlueprintCallable, Category="My Functions")
    void MyFunction();

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="My Variables")
    int32 MyVariable;
};
```

### 주요 매크로와 함수

#### 매크로

- `UCLASS()`: 클래스를 언리얼 엔진의 반영성 시스템에 등록합니다.
- `GENERATED_BODY()`: 클래스에 필요한 기본 구현 코드를 자동으로 추가합니다.
- `UFUNCTION()`: 함수를 반영성 시스템에 등록합니다.
- `UPROPERTY()`: 멤버 변수를 반영성 시스템에 등록합니다.

#### 주요 멤버 함수

- **생성자와 소멸자**:
  - 대부분의 `UObject` 파생 클래스에는 기본 생성자가 있습니다. 이 생성자는 객체가 생성될 때 초기화 작업을 수행합니다.
  
- **AddToRoot()**:
  - 객체를 "루트"로 추가하여 가비지 컬렉터에 의해 수거되지 않도록 합니다.
  
- **RemoveFromRoot()**:
  - 객체를 "루트"에서 제거하여 가비지 컬렉터가 수거할 수 있도록 합니다.
  
- **MarkPendingKill()**:
  - 객체를 "킬 펜딩" 상태로 표시하여 다음 가비지 컬렉션 주기에서 제거되도록 합니다.

- **IsPendingKill()**:
  - 객체가 "킬 펜딩" 상태인지 확인합니다.

### UObject와 메모리 관리

언리얼 엔진에서 메모리 관리와 관련된 중요한 내용 중 하나는 `UObject`의 생성 및 소멸입니다. `UObject` 객체는 `NewObject` 함수를 통해 생성되어야 하며, 이는 메모리 관리와 반영성 시스템 통합을 위해 필요합니다:

```cpp
UMyUObject* NewObj = NewObject<UMyUObject>();
```

### 가비지 컬렉션
- 엔진은 `UObject` 파생 객체의 수명을 자동으로 관리합니다. `UPROPERTY` 매크로를 사용하여 객체 참조를 정의하면, 엔진의 가비지 컬렉션 시스템이 해당 참조를 추적하고 적절히 메모리를 관리합니다.

### 결론
`UObject`는 언리얼 엔진에서 객체를 안전하고 효율적으로 관리하기 위한 기본 클래스입니다. 이를 잘 활용하면, 메모리 관리, 반영성 시스템, 블루프린트 통합 등의 다양한 엔진 기능을 보다 효율적으로 사용할 수 있습니다. `UObject`를 통해 엔진의 기본 제공 기능을 최대한 활용하여 게임 로직을 구현하고 관리하는 것이 중요합니다.


`UObject`와 `NSObject`는 각각 언리얼 엔진과 iOS/macOS에서 사용되는 기본 객체 클래스입니다. 두 클래스는 각각의 환경에서 다양한 특징과 기능을 제공하며, 여러 면에서 유사하지만 세부적인 차이점도 존재합니다. 아래에서 두 클래스의 공통점과 차이점을 비교해 보겠습니다.

### 공통점

1. **기본 객체 클래스**:
   - 두 클래스 모두 각 프레임워크에서 가장 기본이 되는 객체 클래스입니다. 많은 다른 클래스가 이 클래스를 상속받아 구현됩니다.

2. **메모리 관리**:
   - `NSObject`는 Objective-C의 ARC (Automatic Reference Counting)를 통해 메모리를 관리합니다.
   - `UObject`는 언리얼 엔진의 가비지 컬렉션 시스템을 통해 메모리를 관리합니다.

3. **리플렉션(반영성)**:
   - `NSObject`는 런타임에 객체의 메타데이터를 조회하고, 메서드를 호출하거나 프로퍼티에 접근할 수 있는 기능을 제공합니다.
   - `UObject`도 런타임 반영성을 제공하며, 이 정보는 주로 블루프린트, 에디터 스크립팅, 네트워크 복제 등에서 사용됩니다.

### 차이점

#### 1. 플랫폼 및 사용 환경

- **NSObject**:
  - Apple의 Objective-C 및 Swift 언어에서 사용되며, iOS, macOS, watchOS, tvOS와 같은 Apple 플랫폼에서 기본 객체 클래스로 사용됩니다.
- **UObject**:
  - 언리얼 엔진에서 사용되며, C++을 기반으로 하는 기본 객체 클래스입니다. 주로 게임 개발과 관련된 플랫폼에서 사용됩니다.

#### 2. 메모리 관리

- **NSObject**:
  - ARC(Automatic Reference Counting) 시스템을 사용하여 메모리 관리가 이루어집니다. 참조 카운트 기반으로 객체의 생애주기를 관리합니다.
  - 개발자가 직접 `retain`, `release`, `autorelease` 등을 호출하지 않아도 됩니다.
  
- **UObject**:
  - 가비지 컬렉션(Garbage Collection) 시스템을 사용하여 메모리 관리가 이루어집니다. 객체의 참조 관계를 통해 자동으로 메모리를 해제합니다.
  - `AddToRoot`와 `RemoveFromRoot`를 사용하여 수명 주기를 제어할 수 있습니다.

#### 3. 반영성(리플렉션)

- **NSObject**:
  - Objective-C 런타임을 통해 메타데이터를 조회하고, 런타임에 메서드를 호출하거나 프로퍼티에 접근할 수 있습니다 (`performSelector:` 등을 통해).
  - KVO(Key-Value Observing), KVC(Key-Value Coding) 등의 다양한 반영성 관련 기능을 제공합니다.

- **UObject**:
  - 언리얼 엔진의 반영성 시스템을 통해 메타데이터를 조회하고, 런타임에 함수 호출, 프로퍼티 접근, 네트워크 복제 등이 가능합니다.
  - `UFUNCTION`과 `UPROPERTY` 매크로를 통해 반영성 시스템과 통합합니다.

#### 4. 블루프린트 및 코드 통합

- **NSObject**:
  - 주로 Objective-C 및 Swift 코드를 통해 사용되며, Interface Builder와의 통합을 통해 UI 요소와 결합할 수 있습니다.

- **UObject**:
  - 언리얼 엔진의 블루프린트 시스템과 밀접하게 통합되어 있습니다. 개발자들은 블루프린트를 사용하여 C++ 코드를 시각적으로 작성하고 수정할 수 있습니다.

#### 5. 가비지 컬렉션과 라이프사이클 관리

- **NSObject**:
  - ARC에 의해 참조 카운트가 0이 되면 자동으로 메모리가 해제됩니다. 개발자가 객체 수명 주기를 직접 제어할 수 있는 다양한 방법이 제공됩니다.

- **UObject**:
  - 언리얼 엔진의 가비지 컬렉션 시스템이 객체를 자동으로 추적하고 해제합니다. `MarkPendingKill()`을 호출하면 객체가 가비지 컬렉션 대상이 됩니다.
  
#### 6. 네트워크 복제

- **NSObject**:
  - 기본적으로 네트워크 복제를 지원하지 않으며, 네트워크 기능은 별도의 프레임워크 (예: `NSURLSession`, `MultipeerConnectivity`) 등을 사용하여 구현해야 합니다.

- **UObject**:
  - 네트워크 멀티플레이어 게임 개발을 염두에 두고 설계되었기 때문에, 변수 복제를 위한 `Replicated` 플래그 등을 통해 간단하게 네

 

`UPROPERTY`는 언리얼 엔진에서 UObject 기반 클래스의 멤버 변수를 정의할 때 사용되는 매크로로, 변수가 엔진의 반영성 시스템 (Reflection System)에 포함되어 다양한 엔진 기능 (예: 가비지 컬렉션, 직렬화, 복제, 편집기 노출 등)과 호환되도록 합니다. `UPROPERTY`는 변수 선언 앞에 위치하며, 속성 플래그를 통해 변수의 다양한 동작을 제어할 수 있습니다.

### 주요 기능

1. **반영성 (Reflection)**:
   - 엔진은 `UPROPERTY`를 통해 클래스의 구조를 런타임 및 디자인 타임에 인식할 수 있습니다. 이를 통해 블루프린트 시스템에서도 해당 변수를 사용할 수 있습니다.

2. **가비지 컬렉션 (GC)**:
   - UPROPERTY를 사용하면 가비지 컬렉터가 해당 변수를 추적하여 메모리 누수를 방지할 수 있습니다.

3. **직렬화 (Serialization)**:
   - 저장 및 로드 기능을 사용할 때 변수의 값을 자동으로 직렬화할 수 있습니다.

4. **복제 (Replication)**:
   - 네트워크 게임에서 변수의 값이 서버와 클라이언트 간에 동기화되어야 할 경우 복제 기능을 사용할 수 있습니다.

5. **편집기 노출**:
   - UPROPERTY 플래그를 통해 변수 값을 언리얼 에디터에서 편집할 수 있도록 노출할 수 있습니다.

### 속성 플래그

**가장 많이 사용되는 플래그들은 다음과 같습니다**:

- `VisibleAnywhere`, `VisibleInstanceOnly`, `VisibleDefaultsOnly`: 변수는 에디터에서 볼 수 있지만 수정할 수 없습니다.
- `EditAnywhere`, `EditInstanceOnly`, `EditDefaultsOnly`: 변수는 에디터에서 수정할 수 있습니다.
- `BlueprintReadOnly`: 변수는 블루프린트에서 읽을 수 있습니다 (작업 및 함수에서).
- `BlueprintReadWrite`: 변수는 블루프린트에서 읽고 쓸 수 있습니다.
- `Transient`: 변수는 저장되지 않으며, 런타임에만 사용됩니다.
- `Replicated`: 해당 변수를 네트워크에서 복제합니다.
- `Category`: 이 속성을 사용하여 변수의 카테고리를 지정할 수 있습니다 (에디터 UI 정리).

### 예제 코드

다음은 다양한 플래그를 사용하는 예제입니다:

```cpp
UCLASS()
class MYGAME_API AMyActor : public AActor
{
    GENERATED_BODY()

public:
    // 에디터에서 값을 수정할 수 있도록 허용
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="My Variables")
    int32 EditableVariable;

    // 블루프린트와 에디터에서 읽기만 가능
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="My Variables")
    float ReadOnlyVariable;

    // 네트워크 복제를 위한 변수
    UPROPERTY(Replicated, VisibleAnywhere, Category="My Variables")
    bool bReplicatedVariable;

    // 트랜지언트 플래그, 저장되지 않음
    UPROPERTY(Transient)
    FVector TransientVariable;

    // 델리게이트 선언
    UPROPERTY(BlueprintAssignable)
    FMyDelegate OnMyEvent;

    // UObject 참조, 가비지 컬렉션에 따라 관리됨
    UPROPERTY()
    UObject* ObjectReference;
};
```

### 참고 사항

1. **정적 변수와 UPROPERTY**:
   - `UObject` 기반 클래스의 멤버 변수에 대해 `UPROPERTY`를 사용할 수 있지만, 정적 정적 멤버 변수에는 사용할 수 없습니다. 이들은 반영성 시스템과 호환되지 않기 때문입니다.

2. **네트워크 복제**:
   - 복제되는 변수는 항상 UObject 클래스와 함께 사용되며, `GetLifetimeReplicatedProps` 함수를 오버라이드해서 변수를 등록해야 합니다.

3. **가비지 컬렉션**:
   - UPROPERTY를 사용하지 않는 객체 참조는 가비지 컬렉터가 인식하지 않기 때문에 메모리 관리에서 주의가 필요합니다.

### 최적의 사용 예제

UPROPERTY를 적절히 사용하면 코드 품질과 유지보수성을 높일 수 있습니다. 게임 로직, 네트워크 동기화, 데이터 직렬화 등 다양한 기능에서 효율적이고 안전하게 활용할 수 있습니다.

 

맞습니다. 언리얼 엔진에서는 `UPROPERTY`로 정적인 변수를 선언하는 것을 지원하지 않습니다. 정적 멤버는 반영성이 필요 없으므로, 객체에 대한 메타데이터를 생성하지 않기 때문에 언리얼 엔진의 UPROPERTY 시스템과 호환되지 않습니다.

따라서 `FOnNewFrameAvailable` 델리게이트를 정적 멤버로 선언할 수 없으며, 이를 해결하기 위해 싱글톤 패턴을 사용하거나 다른 클래스에 이 델리게이트를 저장하는 방법을 고려해야 합니다.

다음은 정적 멤버를 사용하지 않도록 코드를 수정한 예제입니다:

### 헤더 파일 (`WebcamStreaming.h`)

```cpp
#pragma once

#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"
#include "Engine/Texture2D.h"
#include "HAL/RunnableThread.h"
#include "UObject/WeakObjectPtr.h"
#include "WebcamStreaming.generated.h"

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnNewFrameAvailable, UTexture2D*, Frame);

UCLASS()
class UE53_RESTAPI_API UWebcamStreaming : public UObject
{
    GENERATED_BODY()
    
public:
    UWebcamStreaming();
    virtual ~UWebcamStreaming();

    UFUNCTION(BlueprintCallable, Category = "Webcam")
    bool StartStreaming(int32 WebcamIndex, float FrameRate);
    
    UFUNCTION(BlueprintCallable, Category = "Webcam")
    void StopStreaming();
    
    UFUNCTION(BlueprintCallable, Category = "Webcam")
    bool IsStreaming() const;

    UPROPERTY(BlueprintAssignable, Category = "Webcam")
    FOnNewFrameAvailable OnNewFrameAvailable;

private:
    void StreamingThread();

    TUniquePtr<FRunnableThread> Thread;
    FThreadSafeBool bStreaming;
    FCriticalSection StreamingLock;
    TWeakObjectPtr<UTexture2D> CurrentFrame;
    int32 CurrentWebcamIndex;
    float TargetFrameRate;
};

```

### 소스 파일 (`WebcamStreaming.cpp`)

```cpp
#include "WebcamStreaming.h"

UWebcamStreaming::UWebcamStreaming()
    : Thread(nullptr),
      bStreaming(false),
      CurrentWebcamIndex(0),
      TargetFrameRate(30.0f)
{
}

UWebcamStreaming::~UWebcamStreaming()
{
    StopStreaming();
}

bool UWebcamStreaming::StartStreaming(int32 WebcamIndex, float FrameRate)
{
    if (bStreaming)
    {
        UE_LOG(LogTemp, Warning, TEXT("Webcam streaming is already active"));
        return false;
    }

    CurrentWebcamIndex = WebcamIndex;
    TargetFrameRate = FrameRate;
    bStreaming = true;

    Thread = TUniquePtr<FRunnableThread>(FRunnableThread::Create([this]() { StreamingThread(); }, TEXT("WebcamStreamingThread")));
    return Thread.IsValid();
}

void UWebcamStreaming::StopStreaming()
{
    bStreaming = false;
    if (Thread)
    {
        Thread->WaitForCompletion();
        Thread.Reset();
    }
}

bool UWebcamStreaming::IsStreaming() const
{
    return bStreaming;
}

void UWebcamStreaming::StreamingThread()
{
    while (bStreaming)
    {
        UTexture2D* NewFrame = UWebcamManager::TakeWebcamSnapshot(CurrentWebcamIndex);
        
        if (NewFrame)
        {
            FScopeLock Lock(&StreamingLock);
            if (CurrentFrame.IsValid())
            {
                CurrentFrame->RemoveFromRoot();
            }
            CurrentFrame = NewFrame;
            CurrentFrame->AddToRoot();

            AsyncTask(ENamedThreads::GameThread, [this]()
            {
                if (CurrentFrame.IsValid())
                {
                    OnNewFrameAvailable.Broadcast(CurrentFrame.Get());
                }
            });
        }

        FPlatformProcess::Sleep(1.0f / TargetFrameRate);
    }

    FScopeLock Lock(&StreamingLock);
    if (CurrentFrame.IsValid())
    {
        CurrentFrame->RemoveFromRoot();
        CurrentFrame.Reset();
    }
}
```

위 코드에서는 `OnNewFrameAvailable` 델리게이트를 정적 멤버가 아닌 인스턴스 멤버로 선언하였으며, 따라서 각 객체마다 고유하게 사용할 수 있습니다. 이렇게 하면 언리얼 엔진의 반영성 시스템과의 호환성을 유지할 수 있습니다.

 

 



C++17 자체에서 객체지향 프로그래밍과 관련하여 여러 기능을 제공합니다. 예를 들어, 아래와 같은 도구들을 사용할 수 있습니다:

1. **std::shared_ptr, std::unique_ptr**: 메모리 관리를 위한 스마트 포인터
   ```cpp
   #include <memory>

   class MyClass {
   public:
       int value;
   };

   int main() {
       std::unique_ptr<MyClass> ptr = std::make_unique<MyClass>();
       ptr->value = 42;
   }
   ```

2. **std::any**: 동적 타입을 저장할 수 있는 컨테이너
   ```cpp
   #include <any>
   #include <iostream>

   int main() {
       std::any myVariable = 5;
       std::cout << std::any_cast<int>(myVariable) << std::endl;

       myVariable = std::string("Hello");
       std::cout << std::any_cast<std::string>(myVariable) << std::endl;
   }
   ```

3. **std::variant**: 여러 타입 중 하나를 가질 수 있는 타입 안전한 유니언
   ```cpp
   #include <variant>
   #include <iostream>

   int main() {
       std::variant<int, std::string> myVariant;
       myVariant = 10;
       std::cout << std::get<int>(myVariant) << std::endl;

       myVariant = "Hello";
       std::cout << std::get<std::string>(myVariant) << std::endl;
   }
   ```

이 기능들은 표준 C++에서 편하게 사용할 수 있으며, Unreal Engine과는 별도의 객체지향 프로그래밍 방법론을 제공합니다. 

그러나 만약 Unreal Engine을 사용하고 있는 사용자라면, UObject를 대체할 방법은 거의 없으며, 그것을 사용하는 것이 최선의 선택이라 할 수 있습니다. UObject는 Unreal Engine의 리플렉션 시스템, 가비지 컬렉션, 그리고 많은 엔진 레벨 기능과 깊이 연동되어 있습니다. 따라서 Unreal Engine에서 작업하고 있다면 UObject를 사용하는 것이 좋습니다.

 


iOS용 openCV 라이브러리 나왔으면 좋겠다. 파일 설치

  • python opencv/platforms/ios/build_framework.py ios
  • python opencv/platforms/ios/build_framework.py ios --contrib opencv_contrib
  • python opencv/platforms/ios/build_framework.py ios --contrib opencv_contrib --iphoneos_archs arm64 --iphonesimulator_archs x86_64



- (IBAction)onClickSegmentedControl:(id)sender {

    self.mNmTppg=@"";

    if(self.mDokkaebi.selectedSegmentIndex ==0) {

        mCanYouSeeThisSword = @"H";

    } else if(self.mDokkaebi.selectedSegmentIndex ==1) {

        mCanYouSeeThisSword = @"P";

    }

    [self initializeData];

}




 HPQualityControl2 *v = [[HPQualityControl2 alloc] initWithNibName:@"HPQualityControl2" bundle:[NSBundle mainBundle]];

        if(self.mDokkaebi.selectedSegmentIndex ==0) {

            v.previousSegment = false;

        } else if(self.mDokkaebi.selectedSegmentIndex ==1) {

            v.previousSegment = true;

        }

            if(self.mDokkaebi.selectedSegmentIndex ==0) {

                v.mNm_tppg = _mCdTppg; } else {

                                v.mNm_tppg = _mNmTppg;

                }



  if(self.mDokkaebi.selectedSegmentIndex ==0) {

            [mLblHosh setText:[NSString stringWithFormat:@"→%@ %@호(%@)→%@%ld건", dongNm, nohs, tppgCd, mvin, (long)cntB]];

            [GlobalVar saveToUserDefaults:tppgCd forKey:@"HP_CD_TPPG"];

            } else if(self.mDokkaebi.selectedSegmentIndex ==1) {




반응형

'AudreyHepburnDEV > 수학모델' 카테고리의 다른 글

Population Model(인구 모델)  (0) 2024.11.12
Prey-Predator 모델  (0) 2020.06.17
Multiple Clock  (0) 2019.03.13
MTBF  (0) 2019.03.13
Clock Domain Crossing (CDC)  (0) 2019.03.13
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기