2025-03-11 언리얼에서 동기화

별빛에소원을·2025년 3월 11일

TeamSparta-Unreal1기-TIL

목록 보기
55/90
post-thumbnail

알고리즘

챌린지(03-10일자)

브루트포스

무식한 탐색기법이다.
완전탐색을 무식하게 하는 방법을 말한다.
1. 주어진 문제를 선형으로 구조화한다.
2. 구조화된 문제 공간을 해를 구할때 까지 탐색한다.
3. 구성된 해를 정리한다.


비트마스킹

비트마스킹은 집합의 경우의수를 표현하기 위한 기법이다.
비트로 표현하게 되는데 배열의 요소를 비트로 표현하면 요소가 3개일 경우 2^3이니까 총 8개가 나온다.
이를 비트로 표현해서 집합을 가지게 된다.

예시

int main()
{
	const int Size = 3;
	const int Case = 8;
	int Value[Size] = { 1,2,3 };

	int Bitmask[Case][Size] = {};

	//	Outer는 총 횟수를 정의
	for (int i = 0; i < (1 << Size); ++i)
	{
		//	inner는 필터적용을 정의
		for (int j = 0; j < Size; ++j)
		{
			// i의 비트수는 필터이고 j는 0,1,2를 필터에 포함되는지를 검사할 것
			if ((1 << j) & i)
			{
				Bitmask[i][j] = Value[j];
			}
		}
	}
}

요소가 3개이므로 2^3하면 총 8개다 2진수로 표현하면
0~7까지 표현하는 것. 총 나올 수 있는 집합이 8개인 것이다.
Outer는 총 집합의 수를 나타내고
inner는 집합의 요소를 결정한다.
집합을 정의하는 문장은 Value의 요소가 판별식(1<<j)를 통해 판별 될 수 있도록한다.


격자이동

n,m 격자의 크기가 주어졌을 때 n-1,m-1로 갈 수 있는 모든 경우의수를 구하라

//	아래와 오른쪽으로만 갈 수 있는 방법중 n-1, m-1로 가는 모든 경우의수를 구하라.
int soulution(int n, int m)
{
    int count = 0;
    // 총 이동 횟수: (n-1) + (m-1)
    int MoveCount = n + m - 2;
    for (int i = 0; i < (1 << MoveCount); i++)
    { 
        int x = 0, y = 0;
        for (int j = 0; j < MoveCount; j++)
        {
            if (i & (1 << j)) 
            {
                ++x;
            }
            else 
            {
                ++y;
            }
            if (x >= n || y >= m) 
                break;
        }
        if (x == n - 1 && y == m - 1) 
            count++;
    }

    return count;
}

목표점이 n-1, m-1이니까 이동회수는 무조건 n+m-2가 나온다.
3*3격자를 줄 경우 4가되고 모든 경우의 수는 2^4 = 16이 된다.
오른쪽으로 가거나, 아래로만 가능 경우가 존재하니까 이 경우의 수는 비트마스크로 표현할 수 있다.

x,y는 이동방향을 표시한 것이고 inner포문을 통해 비트마스크의 경우의수를 체크를 한다. 이 중 x,y가 n-1,m-1인 것만 카운트를 증가시키면 원하는 결과가 나오게 된다.

제일 간단한건 재귀로 돌리는 것

int solution(int x,int y,int n, int m)
{
	//범위를 벗어났다면 return 0;
	if(x >= n || y >= m)
    	return 0;
        	
    if ( x == n-1 && y == m-1)
    	return 1;
        
    return solution(x+1,y,n,m) + solution(x,y+1,n,m);
}
int main()
{
	solution(0,0,3,3);
	return NULL;
}

언리얼 소스 빌드

github에서 언리얼 소스를 빌드하려면 github의 토큰을 발급받아서 진행해야한다.
github->setting->developer setting->token(classic)


github epicgames에 링크를 복사할때 토큰의 주소를 넣고 @를 붙여서 clone하면 빌드가 가능해진다.

Setup.bat을 이용해 필요한 파일들을 받아놓고,
GenerateProjectFiles.bat을 이용해 visualstudio파일을 생성하면 된다.

visualstudio에서 빌드가 안된다면 필요한 구성요소를 충분히 보유하고 있지 않은것이다.


확인사항

  • .NET Multiplatform
  • .Net 데스크톱
  • c++ 사용한 데스크톱
  • c++ 사용한 게임개발
  • MSVC v143 - VS 2022 C++ x64/x86 빌드 도구
  • 윈도우 SDK

Replication

언리얼에서 리플리케이션은 네트워크 프레임워크를 상속받아 구현한 구조체다.

중요한 개념은 RepNotify, ActorReplication, RPCs다

RepNotify

  • 사용용도 : 서버에서 클라이언트로 이벤트호출
  • 실행방법 : 자동
  • 실행주체 : 클라이언트
    사용방법
UPROPERTY(ReplicatedUsing=OnRep_HealthChanged)
int32 PlayerHealth = 100;
UFUNCTION()
void OnRep_HealthChanged();

ActorReplication

  • 사용용도 : 변수값을 동기화 시켜준다. (서버->클라이언트)
  • 실행방법 : 자동
  • 실행주체 : 서버에서 값 변경 후 클라이언트에 반영
    사용방법
UPROPERTY(Replicated)
int32 PlayerHealth = 100;

RPCs

  • 사용용도 : 서버와 클라이언트 양자간 양방향 함수 호출
  • 실행방법 : 수동
  • 실행주체 : 서버, 클라이언트
    사용방법
UFUNCTION(Server, Reliable)
void ServerFireWeapon();
UFUNCTION(NetMulticast, Unreliable)
void MulticastPlayExplosionEffect();

Reliable - TCP 통신(Actor의 핵심로직)
Unreliable - UDP 통신(이펙트,Sound)

대부분의 경우는 Reliable해놓고 Unreliable로 최적화


RunOnServer
클라이언트가 서버에게
NetMulticast
서버가 전체 클라이언트에게
RunOnClient
서버가 클라이언트에게


ListenServer와 DedicatedServer

DedicatedServer

특정서버의 로직만 추려서 빌드된 버젼이다.
별도로 빌드해야하며, 클라이언트의 기능은 포함하지 않는다.
보안의 장점이 있고, 독립서버를 갖춘 환경일 때 사용한다.

Listen Server(워크래프트?)

클라이언트 하나가 서버의 기능을 겸칙한다.
별도의 빌드는 필요없고, 클라이언트의 기능을 포함할 수 있다.
해킹에 취약하지만 근거리통신이 가능하다.

DedicatedServer는 현업에서는 자주 사용하지 않는다.
MMO_RPG의 경우 dedicated_server를 잘 아는 사람도 없고,
DB가 없기 때문에 선호되지 않는다.


객체간 통신

다른 객체와 통신을 위해 이벤트를 생성하고 이를 호출 할 수 있다.
A가 B,C의 메시지를 전달하려면 B와 C를 형변환한뒤 각각의 이벤트를 호출해야 한다.

이를 피하려면 A객체에 이벤트 패처를 등록하고, 다른 객체에서 A의 이벤트를 구독하는 원리로 작동시키면 된다.

로컬에서만 사용할 이벤트의 경우에는 디스패처를 사용하는게 좋다.
서버에서는 디스패처를 사용할 수 없기 때문이다.
댕글링 포인터를 방지하기 위해서라도 해당 방법이 유효하다.

객체 A가 B를 가지고서 호출하는 방식은 B가없으면 위험하다.
B가 A의 이벤트를 구독하는 형태가 안전하다.


생성한 이벤트의 Replicate속성
Multicas : 서버가 모든 클라이언트에게
RunonServer : 서버에 있는 이벤트 객체
RunOnOwningClient : 로칼 이벤트 객체


서버로직 호출

언리얼 에서는 플레이어 컨트롤러를 중심으로 요소들이 이루어져있다.

이를 네트워크로 가져가면 다음과 같다.

profile
취미로 게임하는사람

0개의 댓글