1인개발, 모든 기능 블루프린트로 구현했으며,
스팀에 출시 했습니다.
스팀.
https://store.steampowered.com/app/1000370/SurReal_Subway/?beta=0
1인개발, 모든 기능 블루프린트로 구현했으며,
스팀에 출시 했습니다.
스팀.
https://store.steampowered.com/app/1000370/SurReal_Subway/?beta=0
시한부 저주에 걸린 할아버지가 제한된 기간 안에 덕질하는 아이돌 콘서트에 가야하는것이 목적인 게임입니다.
엄청나게 느린 이동속도로 아이템과 각종 이벤트를 겪으며 버스를 타야하는 게임입니다.
구현기능.
cn컨트롤러 에셋을 활용한 이동.
할아버지(플레이어) 모델링과 애니메이션 제작.
자동차 신호등과 빨간불 파란불에따른 교통시스템.
무단횡단하는것을 보면 좆아오는 경찰관기능 구현과 모델링과 애니메이션 제작.
지팡이를 살 수있는 상점페이지
싱클톤패턴과 스크립터블 오브젝트를 활용한 게임세이브기능과
내레이션 + 대화기능,
수중물리 구현 (0) | 2019.04.04 |
---|---|
프로토 타입 (0) | 2019.04.04 |
전 게시물에서 fbx까지 만들었다.
이제 콘텐츠 브라우저 창에 언리얼 엔진으로 드래그 해서 임포트를하면
임포트 옵션이 뜨는데 나중에 마네킹과 함께 리타겟팅 해서 애니메이션을 동기화 할거니 모프타겟만 체크해주고
모두임포트를 누른다.
내가 원한결과는 당연히 이건데
이렇게 나올것이다.
당연히 fbx는 그저 메쉬에 텍스쳐만 매칭되어있을뿐 아무런 쉐이더 적용이 안되어있기 때문.
따라서 이 초기화되어버린 머테리얼들을 작업해줘야한다.
이 머티리얼들을 더블클릭해서.
노말맵 이미시브컬러 맵 디퓨즈 컬러는 자동적으로 설정되어있어 수고를 덜었다.
저 머리카락 텍스쳐에 색깔을 곱하면된다.
뭔말이냐면
VRM임포트 만드신 갓발자님께서 툰쉐이더를 이쁘게 구현해주셨으니
그걸보고 참고해서 따라하거나 추가하고 싶은부분은 내가 표현하면되는것이다
빨간색부분을 중점으로 보면
cutout 렌더링모드는 흑백 0~1(255)값에 따라 모서리를 주는 타입의 렌더링모드다.
불투명 쉐이더니 당연히 opaque로 되어있고.
이미션은 저 하얀부분은 빛에 영향받는것을 제외한다는 말이다. 즉 저 머리칼에 하얀부분만 써주겠다 하는 맵이다.
다음으로 옷을 해보자
블렌드모드를 마스크로해주고 옷 텍스쳐의 알파값 핀을 오파시티 마스크로 끌어다 주면
저 검은색부분은 제외되고 렌더링 한다.
나머지 속눈썹 부분도 이런식으로 매터리얼 전부 편집해주면 된다.
속눈썹 색깔도 머리 해주듯이 해주면 된다.
이작업을 다하면 대충 맨 첫그림과 비슷하게 나온다.
unlit이라 하면 unlighting을 줄인말인데
카툰렌더링이 언릿을 기본으로 깔고있으며
빛이 들어오는 부분의 내적연산을 단계적으로 조절해서 그림자를 표현한다.
라이팅 제외를 하니까 그럴싸 하게 나오지만 게임에 라이팅을 안쓸리가 없으니
저것을 셀쉐이더를 입혀주도록하고
vrm쉐이더 코드를 뜯어서 최대한 비슷하게 만들어보도록 하겠다.
다음 포스팅에는 언리얼엔진에서 과도하게 뽀샤시하게 나오는 포스트 프로세싱을 꺼주고
톤맵퍼에 대해 알아보자.
vroid를 좀더 이쁘게 해보자.#6 (0) | 2019.04.19 |
---|---|
셀셰이딩(툰쉐이딩)하기 #5 (1) | 2019.04.18 |
Vroid를 언리얼에서 이쁘게 쉐이딩하기 #4 (0) | 2019.04.09 |
vroid를 언리얼에서 써보자 #3 (0) | 2019.04.08 |
유니티에만 vroid 모델쓸수있다고? ㄴㄴ 언리얼도 가능 #1 (0) | 2019.04.05 |
https://www.udemy.com/share/100YVuA0sbd1tXRng=/
이거보고 공부했읍니다.
가격도 매우 저렴합니다 언리얼 블로그에서 링크통해가면 더 할인도 되요(영어주의)
리플리케이트로 움직이는 액터의
헤더파일
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Engine/StaticMeshActor.h"
#include "MovingPlatform.generated.h"
/**
*
*/
UCLASS()
class TEST_API AMovingPlatform : public AStaticMeshActor
{
GENERATED_BODY()
public:
AMovingPlatform();
virtual void Tick(float DeltaTime) override;
virtual void BeginPlay() override;
UPROPERTY(EditAnywhere)//블프나 에디터상에서 모두 편집가능
float Speed = 20;
UPROPERTY(EditAnywhere, Meta = (MakeEditWidget = true))//에디터상 위젯에 나타냄
FVector TargetLocation;
void AddActiveTrigger(); //이동
void RemoveActiveTrigger(); //해제
private:
FVector GlobalTargetLocation;
FVector GlobalStartLocation;
UPROPERTY(EditAnywhere)
int ActiveTriggers = 0; //트리거 발동조건
};
구현부
// Fill out your copyright notice in the Description page of Project Settings.
#include "MovingPlatform.h"
//움직이는 스태틱메쉬
AMovingPlatform::AMovingPlatform() {
//틱 이벤트 사용
PrimaryActorTick.bCanEverTick = true;
//이물체가 이동성을 가지는지 설정 Enum형
SetMobility(EComponentMobility::Movable);
}
void AMovingPlatform::BeginPlay()
{
Super::BeginPlay();
if (HasAuthority()) {
//서버와 클라이언트를 동기화
SetReplicates(true);
SetReplicateMovement(true);
}
GlobalStartLocation = GetActorLocation();
GlobalTargetLocation = GetTransform().TransformPosition(TargetLocation);
}
void AMovingPlatform::Tick(float DeltaTime) {
//부모로부터 가상함수를 재정의 하고있는지 확인
Super::Tick(DeltaTime);
if(ActiveTriggers >0 ) //트리거 발동되었을때.
//참이면 서버, 거짓이면 단일 클라이언트일때를 분기
if (HasAuthority()){
//현재액터의 위치 변수저장하기
FVector location = GetActorLocation();
//틱마다 x축으로 델타시간*스피드 만큼 이동
float JourneyLength = (GlobalTargetLocation - GlobalStartLocation).Size(); //목표지점과 첫지점의 거리
float JourneyTravelled = (location - GlobalStartLocation).Size(); //현재내지점과 목표지점의 거리
if (JourneyTravelled >= JourneyLength) //목표지점 첫지점을 바꿈
{
FVector Swap = GlobalStartLocation;
GlobalStartLocation = GlobalTargetLocation;
GlobalTargetLocation = Swap;
}
//방향벡터구하기
FVector Direction = (GlobalTargetLocation - GlobalStartLocation).GetSafeNormal();
//이동
location += Speed * DeltaTime * Direction;
SetActorLocation(location);
}
}
void AMovingPlatform::AddActiveTrigger()
{
ActiveTriggers++;
}
void AMovingPlatform::RemoveActiveTrigger()
{
if (ActiveTriggers > 0) {
ActiveTriggers--;
}
}
버튼이눌렸을때 액터가 움직이도록 하는 액터의 헤더파일
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "PlatformTrigger.generated.h"
UCLASS()
class TEST_API APlatformTrigger : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
APlatformTrigger();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
private:
UPROPERTY(VisibleAnywhere)
class UBoxComponent* TriggerVolume;
UFUNCTION() // 겹쳤을때 함수
void OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
UFUNCTION() // 나왔을대 함수
void OnOverlapEnd(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);
UPROPERTY(EditAnywhere) //트리거가 발동되었을때 움직이는 플랫폼의 배열
TArray<class AMovingPlatform*> PlatformsToTrigger;
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "PlatformTrigger.h"
#include "Components/BoxComponent.h"
#include "MovingPlatform.h"
// Sets default values
APlatformTrigger::APlatformTrigger()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
TriggerVolume = CreateDefaultSubobject<UBoxComponent>(FName("TriggerVolume"));
if(!ensure(TriggerVolume != nullptr)) return;
RootComponent = TriggerVolume;
TriggerVolume->OnComponentBeginOverlap.AddDynamic(this, &APlatformTrigger::OnOverlapBegin);
TriggerVolume->OnComponentEndOverlap.AddDynamic(this, &APlatformTrigger::OnOverlapEnd);
}
// Called when the game starts or when spawned
void APlatformTrigger::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void APlatformTrigger::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void APlatformTrigger::OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
UE_LOG(LogTemp, Warning, TEXT("Activated"));
for (AMovingPlatform* Platform : PlatformsToTrigger) //배열에있는 트리거들 모두순회
{//이동트리거발동
Platform->AddActiveTrigger();
}
}
void APlatformTrigger::OnOverlapEnd(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
UE_LOG(LogTemp, Warning, TEXT("Deactivated"));
for (AMovingPlatform* Platform : PlatformsToTrigger)
{//이동트리거제거
Platform->RemoveActiveTrigger();
}
}
네트워크 모듈추가시 핫리로드+인텔리센스가 개발자를 엿먹이는방법 (0) | 2019.05.20 |
---|---|
서버에서 나오기, 게임종료하기. (0) | 2019.04.15 |
IP를 입력받아서 로컬에 접속하기. (0) | 2019.04.15 |
UMG 셋팅하고 적용하기 (0) | 2019.04.11 |
서버 트래블링 (0) | 2019.04.10 |
내가 3D맥스를 공부한 이유를 무쓸모로 만들어버린
Vroid를 유니티로 만들었다고 유니티에서만 써야한다는건 좀 뭔가 불합리해보여서
VR장비만으로 Vtuber 만드는김에 언리얼엔진에서도 써보고싶었다.
나온지 오래되지않은거라 영어,일본어,중국어로 구글링해봤는데 안나와서 직접 삽질하기로 결정!
vroid로 모델링을 만들어서 익스포트하면
vrm확장자로 나온다.
이걸 fbx로 만들고싶다! 해서
시도한 첫번째방법.
이걸 gbl파일로 이름바꾸기하고 윈도우3D에서 fbx파일로 다른이름으로 저장!
텍스쳐 다날라가서 흰색 지점토만 나온다 ^오^
그래서 혼자 별짓다해서 드디어 방법을 찾아냄.
준비물.
VRoid
https://studio.vroid.com/download.html
VRoid
VRoid Studioは、人型アバター(キャラクター)の3Dモデルを作成できるWindows・Mac用アプリケーションで、どなたでも無償で利用可能になります。
studio.vroid.com
미소녀를 엄청나게 빠르게 모델링가능한 갓갓툴이다..
그러나 하이폴리곤 모델링이니 여러모델을 동시에 쓰기는 좀 힘들다.
전문 모델러가 리토폴로지하던가 머리카락 본도 손보고 등등 해야할게 좀 있을것이다.
그래도 버텍스가 많은만큼 이쁘게 나오고 쉐이더 공부하기 엄청조흠 굿굿.
https://github.com/dwango/UniVRM/releases
dwango/UniVRM
Unity package that can import and export VRM format - dwango/UniVRM
github.com
vrm을 유니티로 임포트 시켜주는 플러그인을 다운받는다.
그리고 에셋스토어에서 fbx익스포터를 다운받는다.
유니티 익숙한사람은 이쯤되면 감 올것이다.
자 이렇게 준비물 갖고오면
유니티에 이렇게 보인다.
VRM탭에서
import를 찾아 vrm파일을 임포트하면
요로케 프리팹으로 만들어준다.
유니티용답게 이쁘게 나오고 프레넬효과로 뽀샤시한 쉐이더가 적용되어있다.
스킨드메쉐 렌더러로 모퍼도 잘 임포트 되었다.
이제 지옥이 시작될것이니라
이 오브젝트를 하이어라키에서 오른클릭해서 fbx 익스포트를 한다.
스킨드메쉬 옵션 꺼져있는데 저거 체크해야한다.
나머지 옵션들 그대로 익스포트 ㄱ
그러면 스탠다드 쉐이더가 적용된 FBX의 몬슁긴 모델링이 나온다.
내가 맥스 배우고 저꼴나서 쉐이더 공부하기 시작했다.
이제 유니티 경로에있는 이 모델을 잘보이는 바탕화면이든 아무데나 복사해서 옮긴다!
vroid를 좀더 이쁘게 해보자.#6 (0) | 2019.04.19 |
---|---|
셀셰이딩(툰쉐이딩)하기 #5 (1) | 2019.04.18 |
Vroid를 언리얼에서 이쁘게 쉐이딩하기 #4 (0) | 2019.04.09 |
vroid를 언리얼에서 써보자 #3 (0) | 2019.04.08 |
vroid를 언리얼에서도 써보자 #2 (0) | 2019.04.07 |
이득우 교수님께서 IGC에서 발표해주신 언리얼 에디터 확장하기를 메인으로 공부 시작.
언리얼 위키
https://wiki.unrealengine.com/Creating_an_Editor_Module#Module_Folder_Structure
일본어 블로그
http://historia.co.jp/archives/370/
내가 이걸 정리하는 이유는 처음봤을때 자료를보며 누락된 내용이나 배경지식의 부족 때문에
삽질을 오지게해서다.
자 여기서 흔히 언리얼에서 코딩하는건 런타임모듈인데.
저기 에디터 모듈이라는거 따로 만들어줘야한다.
난 이거 언리얼에서 자동으로 만들어주는줄 알고 코드만 따라 쳐봤다가ㅋㅋ
왜 에러나지 하면서 하루종일 MSDN 쳐다보고있었다. ㅡㅡ
첫번째로 할일은 uproject파일을 메모장으로열면
프로젝트의 정보가 json파일 형태로 나타난다.
요걸
이렇게 모듈이름을 정해주도 타입을 에디터로 해서 추가해준다.
대표
사진 설명을 입력하세요.
저 폴더를 만들고
extensionEditor.target.cs 소스를
using UnrealBuildTool;
using System.Collections.Generic;
public class extensionEditorTarget : TargetRules
{
public extensionEditorTarget(TargetInfo Target) : base(Target)
{
Type = TargetType.Editor;
ExtraModuleNames.AddRange( new string[] { "extension", "extensionEditor" } );
}
}
코드처럼 에디터 모듈을 코딩해준다.
일단 모듈을 만드려면 이렇게
소스폴더 안에 모듈폴더를 만들고
그 안에 폴더이름과 같은 파일들을 만들어줘야 하는데 내용물도 비슷해야 하므로
아예 새로만들면 같은 코딩을 두번해야하는 귀찮음이 있으니
프로젝트 만들면 있는 소스들을 복붙한다음 파일 이름이랑 안에 코드들만 바꿔주면 편하게만들 수 있다.
EditorStudy.build.cs 파일을 보고 의미를 찾아봤다.
이외에 API목록은 여기 찾아보면 있음 http://api.unrealengine.com/INT/API/
이제 헤더파일을 뜯어보자.
#pragma once
#include "CoreMinimal.h"
//
class FExtensionModule : public IModuleInterface
{
public:
// IModuleInterface 인터페이스 상속을 받으며 이 모듈이 로드,언로드 될때 호출할 가상함수 선언
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
//이 두개는 cpp에서 무조건 구현해야함 안하면 에러뱉음
private:
//FUIcommandlist 클래스는 에디터상의 멀티박스와 매핑해주는 클래스.
TSharedPtr<class FUICommandList> CommandList;
};
열심히 구글링했는데 아직은 먼말인지 정확히 이해는 안되나 그런 인터페이스라고 대충 알아먹어두자.
그리고 모듈의 구현부
#include "extensionEditor.h"
#include "Modules/ModuleManager.h"
//멀티박스 추가에 필요한 헤더
#include "Framework/MultiBox/MultiBoxExtender.h"
#include "Framework/MultiBox/MultiBoxBuilder.h"
#include "LevelEditor.h"
// IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, extension, "extension" );
//Primary게임모듈은 한프로젝트에 하나만 있어야한다는 규칙이다.
//지금 만드는건 에디터용 보조모듈이니 임플리먼트 모듈로 만든다.
IMPLEMENT_MODULE(FextensionEditor, "ExtensionEditor");
#define LOCTEXT_NAMESPACE "Menu"
void FextensionEditor::StartupModule(){
}
void FextensionEditor::ShutdownModule() {
}
#undef LOCTEXT_NAMESPACE
이렇게 만들고 솔루션을 다시 빌드한 후 .
언리얼 에디터를 켜서러 새 c++ 클래스를 만들면.
그리고 모듈제작을 했으니 에디터 모듈이 제작가능해진다!
내가 이 모듈을 사용할때 어떤 명령을 내리고 어떤 동작을 실행할건지 또 정해줘야한다.
https://api.unrealengine.com/INT/API/Runtime/Slate/Framework/Commands/TCommands/index.html
TCommands
A base class for a set of commands.
api.unrealengine.com
FUICommandInfo::FUICommandInfo
Creates and initializes a new instance.
api.unrealengine.com
위 링크는 언리얼 에디터 내에 UI정보를 담고있는 커맨드에 대한 설명
다음글에서
인터페이스 상속받아서 구현해야하는
StartupModule 과
ShutdownModule를
이제 내가 원하는 대로 코딩해보자
1. 프린세스 커넥트
일본 cygames 답게 게임 진짜 공들여서 잘만들었다.
과금모델도 돈 잘벌리게 잘 설계해놨다.
게임성보다 호화 성우진 풀보이스 더빙과 애니메이션 퀄리티때문에 하게되는게임.
2. 밀리시타
캐릭터 렌더링도 이쁘게 잘나오고 최적화도 완전 잘되있다.
무엇보다 카메라 워킹이 정말 대박이라 연출에 배울게 많다!
라이트하게 즐길수 있어서 좋다.
정작 게임은안하고 오토돌리고 춤추는거 구경하고있다 ㅋㅋㅋㅋ
유나이트 재팬 2018때 최적화 노하우발표가있어서 봤는데 크리티컬한 부분은 공개를 안해줘서 아쉬움.
3. 붕괴3
모바일인데비해 액션과 이펙트 퀄리티가 정말 장난아닌데도 렉도 그다지 안걸리는 외계인기술 게임.
유나이트 2018때 발표보고 쉐이더 최적화 뽕맞아서 텍스쳐 하나도 못뽑는주제에 TA가 되고싶다고 생각하게 된 게임.
복귀한후 1년넘게 꾸준히 즐기는중.
근데도 아직 만렙을 못찍었다..
컨텐츠 업데이트량이 장난 아니라서 해야할 컨텐츠가 정말 많아서 좋다.
4. 라스트오리진
오토만 돌렸는데 레벨은 거의 흑우가 되어있다 ㅋㅋ
똉컨이좀 나왔으면ㅜㅜ
20명남짓한 중소기업에서 만들어서 그런지 최적화, 버그 엄청많다.
근데 매력적인 캐릭터가 몇몇있어서 그거 모으려고 오토돌리는게임.
출시후 한달째인데 버그가 많고 캐릭터만 생기고 컨텐츠 업데이트가 없다.
과금모델만큼은 정말 혜자라고해도 무방하지만 덜만들어서 내놓았다고할까..
유저들이 QA하는 얼리억세스 게임 ㅠㅠ
버그때메 겜이 안되서 거의 접은상태
프리코네 vtuber 홍보전략 (0) | 2019.04.08 |
---|
넓은 바다나 호수를 누비는 레이싱게임을
pc vr 플랫폼으로 만들어보고싶어서 여기까지만 만들어봤다.
물아래가아니라 위에서 움직일때 물살 가르는듯한 느낌을 이펙트 적용하는데에서 애먹었다.
그리고 부력이라고 해야하나 아래로 갈수록 뜨는힘이 강해져야하고
제동시에 걸리는 물의 저항과 가속도 구현하는데 제일 시간 오래걸렸다.
물위에서 높게 떠올랐을때 카메라가 아래를 보게해서 플레이어가 맵을 구경할 수 있게 하는게 포인트.
달려요 할아버지 (0) | 2019.04.08 |
---|---|
프로토 타입 (0) | 2019.04.04 |