답변:
게임의 범위에 따라 다릅니다. 큰 게임에서는 자산 관리자가 필수적이며 작은 게임에서는 그렇지 않습니다.
큰 제목의 경우 다음과 같은 문제를 관리해야합니다.
작은 제목의 경우 이러한 문제는 문제가되지 않으며 XNA와 같은 프레임 워크에는 자산 관리자가 있습니다.
자산 관리자가 필요하다고 생각하면 실제로 모든 크기에 맞는 솔루션은 없지만 키를 파일 이름의 해시 *로 사용하는 해시 맵을 찾았습니다 (낮은 구분 기호는 모두 '고정'). 내가 한 프로젝트에서 잘 작동합니다.
일반적으로 앱에서 파일 이름을 하드 코딩하지 않는 것이 좋습니다. 일반적으로 XML과 같은 다른 데이터 형식으로 파일 이름을 'ID'로 나타내는 것이 좋습니다.
(토픽을 고려하지 않기 때문에 "자산 관리자를 사용하지 마십시오"-논의를 피하려고합니다.)
키 / 값 맵은 매우 유용한 접근 방식입니다.
서로 다른 리소스 유형에 대한 팩토리를 등록 할 수있는 하나의 ResourceManager 구현이 있습니다.
"getResource"메소드는 템플리트를 사용하여 원하는 자원 유형에 대한 올바른 팩토리를 찾고 특정 ResourceHandle을 리턴합니다 (템플릿을 사용하여 SpecificResourceHandle을 리턴 함).
리소스는 ResourceManager (ResourceHandle 내부)에 의해 계산되고 더 이상 필요하지 않을 때 해제됩니다.
우리가 작성한 첫 번째 애드온은 "reload (XYZ)"방법으로 코드를 변경하거나 게임을 다시로드하지 않고도 실행중인 엔진 외부에서 리소스를 변경할 수 있습니다. (예술가가 콘솔에서 작업 할 때 필수적입니다.)
대부분의 경우 ResourceManager 인스턴스에만 있지만 가끔 레벨이나 맵에 대해서만 새 인스턴스를 만듭니다. 이런 식으로 levelResourceManager에서 "종료"를 호출하고 누출이 없는지 확인할 수 있습니다.
// very abbreviated!
// this code would never survive our coding guidelines ;)
ResourceManager* pRm = new ResourceManager;
pRm->initialize( );
pRm->registerFactory( new TextureFactory );
// [...]
TextureHandle tex = pRm->getResource<Texture>( "test.otx" ); // in real code we use some macro magic here to use CRCs for filenames
tex->storeToHardware( 0 ); // channel 0
pRm->releaseResource( pRm );
// [...]
pRm->shutdown(); // will log any leaked resource
전담 관리자 수업은 결코 올바른 엔지니어링 도구가 아닙니다. 애셋이 한 번만 필요한 경우 (배경 또는 맵과 같이) 한 번만 요청하고 애셋이 끝나면 정상적으로 죽게해야합니다. 특정 종류의 객체를 캐시 해야하는 경우 먼저 캐시를 확인하고 무언가를로드하고 캐시에 넣은 다음 반환하는 팩토리를 사용해야합니다. 공장은 정적 변수에 액세스하는 정적 함수 일 수 있습니다 자체 유형이 아닙니다.
Steve Yegge (많은 사람들 중에서도)는 싱글 톤 패턴을 통해 쓸모없는 관리자 클래스가 어떻게 끝났는지에 대한 좋은 이야기를 썼습니다. http://sites.google.com/site/steveyegge2/singleton-considered-stupid
저는 항상 훌륭한 자산 관리자가 여러 가지 운영 모드를 가져야한다고 생각했습니다. 이러한 모드는 공통 인터페이스를 준수하는 별도의 소스 모듈 일 가능성이 높습니다. 두 가지 기본 작동 모드는 다음과 같습니다.
공유 데이터베이스의 모든 의견을 파악하고 프로덕션 데이터 세트를 생성 할 수있는 도구가 필요합니다.
몇 년 동안 개발자로서, 나는 소수의 회사에서만 일한 적이 있기 때문에 이런 것을 본 적이 없습니다.
최신 정보
네, 일부 부정적인 투표입니다. 이 디자인을 확장하겠습니다.
첫째, 팩토리 클래스가 필요하지 않습니다.
TextureHandle tex = pRm->getResource<Texture>( "test.otx" );
유형을 알고 있으므로 다음과 같이하십시오.
TextureHandle tex = new TextureHandle ("test.otx");
그러나 위에서 말하려는 것은 어쨌든 명시 적 파일 이름을 사용하지 않을 것이고, 텍스처가 사용되는 모델에 의해로드 될 텍스처가 지정되므로 실제로 사람이 읽을 수있는 이름이 필요하지 않다는 것입니다. 32 비트 정수 값일 수 있으며 CPU가 처리하기가 훨씬 쉽습니다. 따라서 TextureHandle의 생성자에는 다음이 있습니다.
if (texture already loaded)
update texture reference count
else
asset_stream = new AssetStream (resource_id)
asset_stream->ReadBytes
create texture
set texture ref count to 1
AssetStream은 resource_id 매개 변수를 사용하여 데이터의 위치를 찾습니다. 이를 수행하는 방법은 실행중인 환경에 따라 다릅니다.
개발 중 : 스트림은 데이터베이스에서 ID를 조회하여 (예를 들어 SQL 사용) 파일 이름을 얻은 다음 파일을 엽니 다. 파일이 로컬로 캐시되거나 로컬 파일이 존재하지 않거나 서버에있는 경우 서버에서 파일을 가져올 수 있습니다 오래된.
릴리스에서 : 스트림은 키 / 값 테이블에서 ID를 조회하여 큰 팩 파일 (Doom의 WAD 파일)로 오프셋 / 크기를 가져옵니다.
내가 자산을 위해하고 싶은 것은 일괄 관리자 를 설정하는 것 입니다. Doom 엔진에서 영감을 얻은 덩어리는 자산을 포함하고 덩어리 이름, 길이, 유형 (비트 맵, 사운드, 쉐이더 등) 및 콘텐츠 유형 (파일, 다른 덩어리, 내부)을 선언 하는 덩어리 파일에 저장되는 데이터 조각입니다 . 덩어리 파일 자체). 시작할 때 이러한 덩어리는 이진 트리에 입력되지만 아직로드되지는 않습니다. 각 맵 (또한 덩어리 임)에는 맵이 작동해야하는 덩어리의 이름 인 종속성 목록이 있습니다. 이러한 덩어리는 이미로드되지 않은 경우 맵이로드 될 때로드됩니다. 또한, 동시에 인접한지도가 아니라 어떤 이유로 엔진이 공전 할 때지도의 인접한지도 덩어리가로드됩니다. 이를 통해 맵을 매끄럽게 만들 수 있으며 로딩 화면이 없습니다.
내 방법은 오픈 월드 맵에 완벽하지만 레벨 기반 게임은이 방법으로 얻는 매끄러움의 이점을 얻지 못합니다. 이것이 도움이되기를 바랍니다!