유니티에서 Amazon S3에 업로드할 때 PostObject를 사용하면 파일 업로드에 실패하는 문제

 

 

AWS에서는 유니티에서 AWS 기능들을 사용할 수 있게 해주는 SDK를 제공한다. (AWS에서 제공되는 유니티용 AWS SDK) 해당 SDK에는 AWS의 기능을 유니티에서 사용하는 방법에 대한 샘플 코드 역시 포함되어 있는데, 그 중에서 Amazon S3의 기능을 알려주는 샘플 코드에 문제가 있다.

 

해당 샘플 코드에서는 S3에 등록된 버킷의 목록을 가져오는 법, 버킷에 업로드된 오브젝트의 목록을 가져오는 법, 버킷에 있는 오브젝트를 내려받는 법, 버킷에 새로운 오브젝트를 업로드하는 법, 버킷에 있는 오브젝트를 삭제하는 법에 대한 코드들이 포함되어 있다. 예제를 실행시켜보면 대부분 잘 작동하지만, 버킷에 새로운 오브젝트를 업로드하는 코드만 유독 정상적으로 작동하지 않는다.

 

다음은 문제의 작동하지 않는 코드이다.

 

/// <summary>
/// Post Object to S3 Bucket.
/// </summary>
public void PostObject()
{
    ResultText.text = "Retrieving the file";

    string fileName = SampleFileName;
            
    var stream = new FileStream(Application.dataPath + "/" + fileName, FileMode.Open, FileAccess.Read, FileShare.Read);

    ResultText.text += "\nCreating request object";
    var request = new PostObjectRequest()
    {
        Bucket = S3BucketName,
        Key = fileName,
        InputStream = stream,
        CannedACL = S3CannedACL.Private
    };

    ResultText.text += "\nMaking HTTP post call";

    Client.PostObjectAsync(request, (responseObj) =>
    {
        if (responseObj.Exception == null)
        {
            ResultText.text += string.Format("\nobject {0} posted to bucket {1}", responseObj.Request.Key, responseObj.Request.Bucket);
        }
        else
        {
            ResultText.text += "\nException while posting the result object";
            ResultText.text += string.Format("\n receieved error {0}", responseObj.Response.HttpStatusCode.ToString());
        }
    });
}

 

해당 코드를 실행하면 파일이 Amazon S3에 업로드되어야 하지만 정확한 실패 원인이 나오지 않고 업로드에 실패한다. 아마존 측에서 제공한 API에 문제가 있을 것으로 추정된다. 유니티에서 Amazon S3에 파일을 업로드하기 위해서는 코드를 다음과 같이 변경하여야 한다.

 

 

/// <summary>
/// Put Object to S3 Bucket.
/// </summary>
public void PutObject()
{
    AWSConfigs.HttpClient = AWSConfigs.HttpClientOption.UnityWebRequest;

    ResultText.text = "Retrieving the file";

    string fileName = GetFileHelper();

    var stream = new FileStream(Application.persistentDataPath + Path.DirectorySeparatorChar + fileName, FileMode.Open, FileAccess.Read, FileShare.Read);

    ResultText.text += "\nCreating request object";
    var request = new PutObjectRequest()
    {
        BucketName = S3BucketName,
        Key = fileName,
        InputStream = stream,
        CannedACL = S3CannedACL.Private
    };

    ResultText.text += "\nMaking HTTP post call";
    Client.PutObjectAsync(request, (responseObj) =>
    {
        if (responseObj.Exception == null)
        {
            ResultText.text += string.Format("\nobject {0} puted to bucket {1}", responseObj.Request.Key, responseObj.Request.BucketName);
        }
        else
        {
            ResultText.text += "\nException while puting the result object";
            ResultText.text += string.Format("\n receieved error {0}", responseObj.Response.HttpStatusCode.ToString());
        }
    });
}

 

위의 코드와 같이 PostObject 대신에 PutObject를 사용해야 Amazon S3에 파일 업로드가 정상적으로 되는 것을 확인할 수 있다.

 


 

참고

 

(AWS) 유니티에서 S3에 업로드하기

사흘 간 헤매던 원인을 해결해서 매우 기분이 좋다. 결론적으로 말하면 AWS에서 제공하는 Unity SDK...

blog.naver.com

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

안드로이드 버전의 빌드에서 디바이스의 로컬 저장소에 파일을 저장하는 법

 

유니티에서 게임을 만들 때, 네트워크로 받아온 파일을 로컬에 저장해야 하는 일이 많다. 특히 게임의 패치 시스템(Patch System)을 만들어야 하는 경우라면 100% 필요한 일이다. 윈도우 버전의 빌드에서는 적당히 원하는 경로에 파일을 저장할 수 있지만, 안드로이드 버전의 빌드에서는 경로마다 읽기/쓰기의 권한이 다르고 제한이 있다.

 

안드로이드의 데이터 경로와 읽기/쓰기 권한은 다음과 같다.

 

[안드로이드 External]
Application.persistentDataPath : /mnt/sdcard/Android/data/com.YourProductName.YourCompanyName/files [파일 읽기/쓰기 가능]
Application.dataPath : /data/app/번들이름-번호.apk
Application.streamingAssetsPath : jar:file:///data/app/번들이름.apk!/assets [파일이 아닌 WWW로 읽기 가능]

[안드로이드 Internal]
Application.persistentDataPath : /Android/data/com.YourProductName.YourCompanyName/files [파일 읽기/ 쓰기 가능]
Application.dataPath : /data/app/번들이름-번호.apk
Application.streamingAssetsPath : jar:file:///data/app/번들이름.apk!/assets [파일이 아닌 WWW로 읽기 가능]

 

위에 적힌 것처럼 네트워크에서 받아온 파일을 로컬에 저장하기 위해서는 읽기/쓰기가 모두 가능한 Application.persistentDataPath의 경로를 사용해야 한다.

 

위의 경로에 원하는 폴더를 만들고자 할 때는 다음의 코드를 참조하면 된다.

 

if (!Directory.Exists(Application.persistentDataPath + "/생성할 폴더 이름"))
{
    Directory.CreateDirectory(Application.persistentDataPath + "/생성할 폴더 이름");
}

 

위의 경로에 원하는 파일을 쓰고자 할 때는 다음의 코드를 참조하면 된다.

 

FileStream fs = new FileStream(Application.persistentDataPath + "/" + "TestFileName.txt", FileMode.Create, FileAccess.Write);
byte[] data = new byte[writeDataSize];
fs.Write(data, 0, (int)writeDataSize);
fs.Close();

 

이 섹션에서 소개한 내용은 제일 처음에 설명했듯이 주로 게임 패치 시스템에 많이 사용되는데, 유니티에서는 게임 패치에 에셋 번들을 많이 사용하는 편이다. 빌드된 에셋 번들은 manifest 파일을 제외하면 공통적으로 나오는 AssetBundles 파일을 비롯해서 주로 확장자 없이 지정한 번들 이름만 적힌 파일이 나오는데, 이렇게 확장자가 없는 에셋 번들 파일을 그대로 사용할 때는, 각 에셋 번들의 이름과 같은 폴더를 생성하려고 하면 폴더 생성에 실패하게 된다. 그렇기 때문에, 에셋 번들의 이름과 같은 이름의 폴더의 생성은 피하거나 에셋 번들 파일의 끝에 ".unity3d"같은 확장자를 붙여주는 것이 좋다.

 


참고 사이트

 

# Uniyt3D 게임엔진 예약된 폴더이름 및 데이터 경로 정리.

[윈도우 에디터]Application.persistentDataPath : 사용자디렉토리/AppData/LocalLow/회사이름/프로덕트이름 파일 읽기 쓰기 가능Application.dataPath : 프로젝트디렉토리/AssetsApplication.streamingAssetsPath : 프로젝트디

egloos.zum.com

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

.NET용 AWS SDK에서 지원되는 플랫폼

 

.NET용 AWS SDK는 개발자가 대상으로 하는 여러 플랫폼에 대해서 고유한 어셈블리 그룹을 제공한다. 그러나 모든 SDK 기능이 이러한 각 플랫폼에서 동일하지는 않다. 이 주제에서는 각 플랫폼에 지원되는 것들의 차이점을 설명합니다.

 

.NET 프레임워크 4.5

이 버전의 .NET 용 AWS SDK는 .NET Framework 4.5 용으로 컴파일되고 .NET 4.0 런타임에서 실행된다. AWS 서비스 클라이언트는 동기식 및 비동기식 호출 패턴을 지원하고 C# 5.0에 도입 된 async 및 await 키워드를 사용한다.

 

.NET 프레임워크 3.5

이 버전의 .NET 용 AWS SDK는 .NET Framework 3.5에 대해 컴파일되며 .NET 2.0 또는 .NET 4.0 런타임을 실행한다. AWS 서비스 클라이언트는 동기 및 비동기 호출 패턴을 지원하고 이전 Begin 및 End 패턴을 사용합니다.

참고

.NET 용 AWS SDK는 CLR 버전 2.0에 맞게 작성된 응용 프로그램에서 사용할 경우 FIPS (Federal Information Processing Standard)와 호환되지 않는다. 해당 환경에서 FIPS 호환 구현을 대체하는 방법에 대한 자세한 내용은 Microsoft 블로그의 CryptoConfig 및 Security.Cryptography.dll의 CLR 보안 팀의 HMACSHA256 클래스 (HMACSHA256Cng)를 참조하면 된다.

 

.NET 코어

.NET 용 AWS SDK는 .NET Core 용으로 작성된 응용 프로그램을 지원한다. AWS 서비스 클라이언트는 .NET 코어에서 비동기 호출 패턴만 지원한다.
이는 .NET Core 환경에서 비동기 호출만 지원하는 Amazon S3의 TransferUtility와 같은 서비스 클라이언트의 최상위에 구축 된 많은 수준의 추상화에도 영향을 미친다. 자세한 내용은 .NET Core에서 사용되는 .NET용 AWS SDK 구성[번역링크]을 참조하면 된다.

 

포터블 클래스 라이브러리(Portable Class Library)

.NET 용 AWS SDK에는 포터블 클래스 라이브러리 구현이 포함되어 있다. Portable Class Library 구현은 UWP(Universal Windows Platform) 및 iOS 및 Android의 Xamarin을 비롯한 여러 플랫폼을 대상으로 할 수 있다. 자세한 내용은 .NET 용 AWS Mobile SDK 및 Xamarin을 참조하면 된다. AWS 서비스 클라이언트는 비동기 호출 패턴만 지원한다.

 

유니티 지원

.NET 용 AWS SDK는 Unity용 어셈블리 생성을 지원한다. 더 많은 정보는 Unity README에서 찾을 수 있다.

 

추가 정보

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

게임 오브젝트에 Collider 컴포넌트를 추가하지 않고 한번만 충돌체를 찾아내는 Physics의 Cast 계열 함수들의 사용법

 

유니티 엔진에서 충돌체(Collider)를 찾아내는 방법은 여러 가지가 있다. 일반적으로는 게임 오브젝트에 캡슐(Capsule), 박스(Box), 구(Sphere) 형태의 콜라이터 컴포넌트를 달아서 OnTrigger나 OnCollision 계열의 이벤트를 사용해서 충돌체를 찾아내게 된다. 하지만 위 방법의 경우에는 콜라이더 컴포넌트를 지속적으로 유지해야하고 OnTrigger나 OnCollision 계열의 이벤트는 매 프레임 실행되기 때문에 필요한 순간에 한번만 충돌체를 찾아내려는 경우에는 성능상 부적절할 수 있다.

 

이렇게 필요한 순간에 단 한번 충돌체를 찾아내는 함수는 Physics라는 클래스가 static으로 가지고 있고 여기에 해당하는 함수들은 Cast라는 이름이 붙어있다. 이 Cast 함수에는 크게 4가지의 충돌체를 찾아내는 모양이 있는데 Ray, Box, Sphere, Capsule이 그것이다.

 

Ray

가장 일반적으로 사용되는 형식으로 특정 지점에서 시작하여 특정한 방향으로 향하는 직선 형태의 Cast이다. 이 직선에 닿은 Collider를 찾아낸다. 이 Ray Cast는 주로 사용자가 클릭한 지점이나 오브젝트를 3D 공간 상에서 찾아내기 위해서 주로 사용된다.

 

Box

설정한 중심점을 시작으로 하여 지정한 가로, 세로, 높이에 해당하는 직육면체 형태의 Cast이다. 이 직육면체의 면에 닿거나 직육면체의 안에 있는 Collider를 찾아낸다.

 

Sphere

설정한 중심점을 기준으로 지정한 반지름 내의 구 형태의 Cast이다. 이 구의 표면에 닿거나 구 안에 있는 Collider를 찾아낸다.

 

Capsule

설정한 두 점을 있는 선을 중심으로 지정한 반지름만큼의 캡슐 형태의 Cast이다. 이 캡슐의 표면에 닿거나 캡슐 안에 있는 Collider를 찾아낸다.

 

앞서서 살펴본 내용이 충돌체를 찾아내는 모양에 따른 분류였다면 지금 이야기하는 것은 찾아낼 충돌체의 개수에 따른 분류이다. 이 분류에는 Cast, CastAll, CastNonAlloc이 있다.

 

Cast

Cast는 찾아낸 충돌체 하나만을 반환한다. Ray Cast를 예로 들자면 제일 처음 선에 충돌한 물체만을 반환하는 형식이다. 그 결과는 RayCastHit이라는 구조체로 반환된다.

 

CastAll

CastAll은 찾아낸 충돌체 전부를 반환한다. 찾아낸 결과는 찾아낸 오브젝트의 개수와 딱맞는 RayCastHit 배열로 반환된다.

 

CastNonAlloc

CastNonAlloc은 약간 독특한 방식인데 반환이 return을 통해서 이루어지는 것이 아니라, 매개변수를 통해서 이루어진다. 사용자가 RayCastHit의 배열을 만들어서 함수의 매개변수에 넣어주면, 함수가 그 배열에 찾아낸 오브젝트를 채워서 돌려주는 방식이다. 그렇기 때문에 찾아낸 오브젝트의 수가 배열의 수보다 적을 수도 많을 수도 있기 때문에 항상 주의해서 사용해야 한다.

 

각 형태와 방식에 따른 Cast의 사용법은 다음과 같다.

 

 

 

Cast 사용법

// Raycast

Vector3 startVect = Vector3.zero;
Vector3 direction = Vector3.forward;
float distance = 10f;

Ray ray = new Ray(startVect, direction);
RayCastHit hit = Physics.Raycast(ray, distance);

 

 

// RaycastAll

Vector3 startVect = Vector3.zero;
Vector3 direction = Vector3.forward;
float distance = 10f;

Ray ray = new Ray(startVect, direction);
RaycastHit[] hits = Physics.RaycastAll(ray, distance);

foreach(var hit in hits)
{
    Debug.Log(hit.collider.name);
}

 

 

// RaycastNonAlloc

Vector3 startVect = Vector3.zero;
Vector3 direction = Vector3.forward;
float distance = 10f;
Ray ray = new Ray(startVect, direction);
RaycastHit[] hits = new RaycastHit[10];     // 여기서 할당한 배열 수 이상은 가지고 오지 못한다.
int hitCount = Physics.RaycastNonAlloc(ray, hits, distance);

// foreach를 사용할 경우, 찾아낸 숫자가 배열 길이보다 작으면 에러가 발생한다.
for (int i = 0; i < hitCount; i++)
{
    Debug.Log(hits[i].collider.name);
}

 

 

// BoxCast

Vector3 boxCenter = Vector3.zero;
Vector3 boxHalfSize = new Vector3(1f, 1f, 1f);  // 캐스트할 박스 크기의 절반 크기. 이렇게 하면 가로 2 세로 2 높이 2의 크기의 공간을 캐스트한다.
Vector3 direction = Vector3.up;

 

bool isCollide = Physics.BoxCast(boxCenter, boxHalfSize, direction);    // 일반적으로 BoxCast는 충돌 여부만 반환한다.

 

RaycastHit hit;

Physics.BoxCast(boxCenter, boxHalfSize, direction, out hit);    // 충돌 결과에 대한 내용을 가져오려면 RaycastHit 구조체를 out 매개변수로 넣어주어야 한다.

Debug.Log(hit.collider.name);

 

 

// BoxCastAll

Vector3 boxCenter = Vector3.zero;
Vector3 boxHalfSize = new Vector3(1f, 1f, 1f);  // 캐스트할 박스 크기의 절반 크기. 이렇게 하면 가로 2 세로 2 높이 2의 크기의 공간을 캐스트한다.
Vector3 direction = Vector3.up;
RaycastHit[] hits = Physics.BoxCastAll(boxCenter, boxHalfSize, direction);    // BoxCastAll은 찾아낸 충돌체를 배열로 반환한다.

foreach (var hit in hits)
{
    Debug.Log(hit.collider.gameObject.name);
}

 

 

// BoxCastNonAlloc

Vector3 boxCenter = Vector3.zero;
Vector3 boxHalfSize = new Vector3(1f, 1f, 1f);  // 캐스트할 박스 크기의 절반 크기. 이렇게 하면 가로 2 세로 2 높이 2의 크기의 공간을 캐스트한다.
Vector3 direction = Vector3.up;
RaycastHit[] hits = new RaycastHit[10];
int hitCount = Physics.BoxCastNonAlloc(boxCenter, boxHalfSize, direction, hits);

for (int i = 0; i < hitCount; i++)
{
    Debug.Log(hits[i].collider.name);
}

 

 

// SphereCast

Vector3 origin = Vector3.zero;
Vector3 direction = Vector3.up;
Ray ray = new Ray(origin, direction);
float radius = 5f;
bool isCollide = Physics.SphereCast(ray, radius);

RaycastHit hit;
Physics.SphereCast(ray, radius, out hit);

Debug.Log(hit.collider.name);

 

 

// SphereCastAll

Vector3 origin = Vector3.zero;
Vector3 direction = Vector3.up;
Ray ray = new Ray(origin, direction);
float radius = 5f;
RaycastHit[] hits = Physics.SphereCastAll(ray, radius);

foreach (var hit in hits)
{
    Debug.Log(hit.collider.gameObject.name);
}

 

 

// SphereCastNonAlloc

Vector3 origin = Vector3.zero;
Vector3 direction = Vector3.up;
Ray ray = new Ray(origin, direction);
float radius = 5f;
RaycastHit[] hits = new RaycastHit[10];
int hitCount = Physics.SphereCastNonAlloc(ray, radius, hits);

for (int i = 0; i < hitCount; i++)
{
    Debug.Log(hits[i].collider.name);
}

 

 

// CapsuleCast

Vector3 v1 = new Vector3(0f, 0f, 0f);    // 캡슐 시작 부분의 구에 대한 중심점
Vector2 v2 = new Vector3(0f, 3f, 0f);    // 캡슐 끝 부분의 구에 대한 중심점
Vector3 direction = Vector3.up;
float radius = 5f;
bool isCollide = Physics.CapsuleCast(v1, v2, radius, direction);

RaycastHit hit;
Physics.CapsuleCast(v1, v2, radius, direction, out hit);

Debug.Log(hit.collider.name);

 

 

// CapsuleCastAll

Vector3 v1 = new Vector3(0f, 0f, 0f);
Vector2 v2 = new Vector3(0f, 3f, 0f);
Vector3 direction = Vector3.up;
float radius = 5f;
RaycastHit[] hits = Physics.CapsuleCastAll(v1, v2, radius, direction);

foreach (var hit in hits)
{
    Debug.Log(hit.collider.gameObject.name);
}

 

 

// CapsuleCastNonAlloc

Vector3 v1 = new Vector3(0f, 0f, 0f);
Vector2 v2 = new Vector3(0f, 3f, 0f);
Vector3 direction = Vector3.up;
float radius = 5f;
RaycastHit[] hits = new RaycastHit[10];
int hitCount = Physics.CapsuleCastNonAlloc(v1, v2, radius, direction, hits);

for (int i = 0; i < hitCount; i++)
{
    Debug.Log(hits[i].collider.name);
}

 

추가적인 이야기로는 캡슐 캐스트를 사용할 때, v1과 v2의 정의에 대해서 헷갈리는 경우가 발생할 수 있는데 그것은 캡슡의 상단과 하단에 가상의 구가 존재한다고 생각했을 때, 그 구의 중심 위치라고 생각하면 된다.

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

잘못된 애니메이션 리소스로 인해서 발생하는 버그

 

게임 제작에서 일반적으로 버그라고 하면, 프로그래머의 전유물 되는 경우가 많다. 물론 대다수의 게임 버그는 프로그래머의 실수나 설계 미스로 인해서 발생하는 것이지만, 잘못된 리소스로 인해서 발생하는 경우도 꽤나 있다. 대표적인 리소스로 인한 버그를 예로 들자면 3D 모델을 3ds 맥스나 마야같은 3D 툴에서 작업할 때, 실수로 폴리곤을 뒤집어서 내보내는 것과 같은 것이 있다. 이렇게 폴리곤이 뒤집힌 모델은 게임 엔진에 올릴 경우, 해당 부위가 뻥 뚫려서 보이는 문제가 발생한다. 이렇게 눈에 바로 보이는 버그라면 다행이지만 눈에 보이지 않는 리소스로 인한 버그라면 찾아내기가 매우 어려울 것이다.

 

찾아내기 어려운 리소스 버그 중에 하나가 바로 잘못된 애니메이션 리소스로 인해서 발생하게 되는 버그이다. 단지 애니메이션이 이상하게 움직이는 버그라면 상관이 없지만, 애니메이션은 정상적으로 동작하지만 어느 순간부터인가 캐릭터의 로테이션이 돌아가있다던지 정상적인 위치를 조금씩 벗어나게 되는 문제가 발생한다면 어떨까? 프로그래머나 엔진 작업자는 우선 캐릭터의 로테이션이나 포지션에 관여하는 모든 코드를 검토해야할 것이다. 이상한 현상을 보일 수 있는 코드가 있는지 모든 부분을 확인해야 한다. 만약 규모가 있는 프로젝트라면 이 작업만으로도 엄청난 시간을 소모해야 하지만, 이 과정을 거친 이후에 코드에 문제가 없음을 확인했다면 어떨까? 만약 이러한 문제에 대한 경험이 없다면 큰 혼란에 빠질 것이다.

 

나는 최근에 이렇게 코드에 문제가 없음에도 불구하고 캐릭터가 회전하는 문제와 원래 위치를 조금씩 벗어나서 움직이는 버그를 모두 겪어본 적이 있다. 코드를 검토했음에도 불구하고 코드에는 문제가 없음을 확인했지만 여전히 캐릭터가 이상한 회전이나 이동을 하는 문제가 발생했는데, 그때가 되어서야 나는 코드가 아닌 리소스를 의심해보기로 했다. 우선은 어떤 상황에서 이런 문제가 발생하는지 명확하게 확인해야 했다. 여러 번 테스트해본 결과 캐릭터의 로테이션이 이상한 각도로 변하는 문제는 캐릭터가 사망하고 난 이후에, 오브젝트 풀링으로 재활용해서 가져왔을 때 발생했고, 캐릭터가 원래 위치를 벗어나는 문제는 캐릭터가 공격 모션을 취한 다음에 조금씩 이동하는 것을 확인할 수 있었다. 그렇게 해서 우선 문제가 발생하는 원인이 사망 애니메이션과 공격 애니메이션이라는 것을 알 수 있었고, 그 이후에는 유니티에서 캐릭터의 본들의 트랜스폼을 분석해서 특정한 본이 애니메이션 이후에 원래 상태로 돌아가지 않고 이상한 각도를 유지하거나 이상한 위치를 유지하는 것을 확인할 수 있었다. 이러한 문제를 애니메이터에게 알려주고 수정된 애니메이션 리소스를 받아서 적용한 이 후에는 이 버그는 해결되었다.

 

버그는 코드에만 있지 않다. 스크립트에 캐릭터의 회전이나 이동에 이산한 동작을 하는 코드가 없음에도 불구하고 이상한 회전을 보인다거나 원래 위치를 조금씩 벗어나서 이동하는 버그를 보게 된다면 애니메이션 리소스의 버그를 의심해보라.

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

Character Joint - 캐릭터에 물리효과를 받는 본 추가하기

 

지난 섹션들에서 래그돌을 만들고 사용하는 방법을 배우면서 Character Joint의 존재와 사용법에 대해서 알게 되었을 것이다. 그리고 이전 섹션까지는 애니메이션이 적용된 오브젝트와 Character Joint가 적용된 래그돌 오브젝트를 따로 사용한 것 역시 기억할 것이다. 테스트를 해보면 알겠지만 앞 섹션의 예시처럼 애니메이션이 적용된 모델링에는 일반적으로 Character Joint를 추가해도 물리 기능이 작동하지 않는 것을 알 수 있다.

 

하지만 디테일한 묘사를 원하는 개발자의 경우라면, 캐릭터의 허리 춤에 매달린 장비나 포니테일 같은 묶인 머리가 물리 효과를 받아서 자연스럽게 흔들리는 것을 원할 것이다. 이번 섹션에서 다룰 주제는 바로 그것에 대한 내용이다.

 

 

 

3D 모델 준비

 

 

 

 

흔들리는 '포니테일'을 구현하기 위해 간단한 말 모델을 만들어 봤다. 꼬리의 물리 효과에만 집중할 것이기 때문에 다른 부위는 크게 구현하지 않았다. 우선 모델 파일은 스키닝만 한 상태로 애니메이션을 포함하지 않고 익스포트했다.

 

 

그리고 말이 달릴 때 사용할 애니메이션을 간단하게 만들었다. 이 애니메이션을 만드는 과정에서 주의할 점은 Character Joint로 물리 효과를 사용할 본에는 절대로 애니메이션 키를 잡아서는 안된다. 만약 애니메이션을 만드는 과정에서 물리 효과를 적용하려고 하는 본에 키를 잡아버리면 그 본은 Character Joint를 적용해도 애니메이션 대로만 움직이고 원하는 움직임을 보이지 않게 된다. 이런 방식으로 애니메이터가 애니메이션 작업을 할 때, 애니메이션을 넣지 않은 본을 Jiggle bone이라고 부른다.

 

테스트할 때 사용할 이 귀여운 말의 모델과 애니메이션은 여기에서(

Horse.zip
다운로드

) 다운받을 수 있다.

 

 

 

 

유니티에 모델링과 애니메이션 넣기

 

3ds 맥스에서 필요한 모델과 애니메이션을 모두 익스포트했다면, 이제는 이것들을 유니티 엔진에 적용할 차례다.

 

 

우선은 모델과 애니메이션 파일을 유니티에 넣어준다.

 

 

모델과 애니메이션 파일을 가져왔다면 씬을 다음과 같이 구성해보자. 씬 한가운데에 말의 모델링을 넣고 추가된 말의 오브젝트에 애니메이션을 관리할 애니메이터를 넣어주는 것이다.

 

 

그리고 나서 플레이 버튼을 누르고 애니메이터의 isMove 파라메터를 활성화시키면 말이 달리듯이 위아래로 움직이는 것을 볼 수 있다. 하지만 말의 꼬리는 전혀 움직이지 않는 것을 확인할 수 있을 것이다.

 

 

 

꼬리에 Character Joint 적용하기

 

이제부터 꼬리에 물리 효과를 주기 위해 아까 전에 모델과 애니메이션을 만들 때, 애니메이션 키를 잡아주지 않았던 본들에 Character Joint와 Collider를 넣을 것이다.

 

 

유니티의 Hierarchy 뷰에서 말의 본들을 확인할 수 있다. 이 중에서 실제로 Character Joint가 들어갈 본은 3~5번 본이고 2번 본은 애니메이션 키가 적용된 본으로서 단지 Character Joint가 적용된 본들이 연결될 본이며, 2번 본에는 물리효과가 들어가지 않을 것이다.

 

물리 효과를 적용하기 위해서 다음의 순서를 따라해보자.

 

1. 2번 본에 Rigidbody를 추가한다.

 

 

2. 3~5번 본에 Character Joint를 추가해준다. Connected Body의 경우는 각 본마다 Rigidbody가 적용된 바로 한 단계 전의 본을 넣어주면 된다. 예를 들자면 3번 본의 경우에는 2번 본, 4번 본의 경우에는 3번 본을 넣어주는 식이다.

 

 

3. Character Joint가 추가된 본에 충돌 처리를 해줄 Collider를 넣어주고 적절한 크기로 만들어준다.

 

 

위의 과정을 모두 마치고 난후 플레이 버튼을 눌러보면 말의 꼬리가 자연스럽게 아래로 처지는 것을 볼 수 있다. 그리고 애니메이션을 실행시켰을때에도 물리효과를 받고 있는 것을 알 수 있는데, 아직 모자란 점이 눈에 보일 것이다.

 

 

분명 꼬리는 물리 효과를 받아서 흔들리고 있지만 애니메이션이 위아래로 움직이고 있지만 꼬리는 그 영향을 전혀 받고 있지 않음을 알 수 있다. 이 부분에 대해서는 관성을 처리해주는 별도의 스크립트를 추가로 작성해야 한다.

 

using UnityEngine;

public class JiggleBonePhysics : MonoBehaviour
{
    /// <summary>
    /// 부모 본의 트랜스폼
    /// </summary>
    Transform parentTransform;
    /// <summary>
    /// 이 스크립트가 포함된 본 오브젝트의 리지드 바디
    /// </summary>
    Rigidbody boneRigidbody;
    /// <summary>
    /// 이전 프레임까지의 부모 본의 위치
    /// </summary>
    Vector3 prevFrameParentPosition = Vector3.zero;
    /// <summary>
    /// 관성 가중치
    /// </summary>
    public float power = 0f;
    /// <summary>
    /// 변경된 위치의 크기의 제한. 제한 값이 너무 크면 이 본이 제대로 따라가지 못해서
    /// 각 관절들이 이상한 위치로 날아가는 문제가 발생할 수 있다.
    /// </summary>
    public float clampDist = 0.03f;

    void Start()
    {
        parentTransform = transform.parent;
        prevFrameParentPosition = parentTransform.position;

        boneRigidbody = GetComponent<Rigidbody>();
    }

    void FixedUpdate()
    {
        Vector3 delta = (prevFrameParentPosition - parentTransform.position);
        boneRigidbody.AddForce(Vector3.ClampMagnitude(delta, clampDist) * power);

        prevFrameParentPosition = parentTransform.position;
    }
}

 

위의 코드가 바로 관성을 처리해주는 코드이다. 이전 부모 본의 위치와 현재 부모 본의 위치로 계산해서 이전 위치에 남아있으려는 힘을 본의 Rigidbody에 전해주는 방식이다. 이 스크립트를 Character Joint 컴포넌트를 가진 모든 본에 추가해주면 된다.

 

 

그리고 나서 애니메이션을 동작시켜보면 말의 움직임에 따라 꼬리가 물리효과를 받는 것을 볼 수 있다. 여기에 추가적으로 간단하게 말을 움직이게 만들어 본다면 다음과 같은 장면을 얻을 수 있다.

 

 

이 Jiggle Bone 기능을 만들 때에는 Rigidbody와 Character Joint의 프로퍼티 값들을 세밀하게 살피면서 잘 조절해주어야 자연스러운 움직임을 연출할 수 있다. 위의 과정을 응용하면 이런 말의 꼬리 이외에도 앞서 말한 캐릭터의 허리춤에 매달린 도구, 묶은 머리, 쇠사슬 등 캐릭터에 추가적으로 달린 여러 가지를 흔들리게 만들 수 있다. 물론 잘 설정하면 신체 부위도 가능하다. 가슴이라던가... 바스트라던가... 엉덩이라던가... 개발자라면 도전해볼만한 기능이다.

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

Ragdoll 사용하기 - 게임에서 자연스럽게 적용하기

 

이전 섹션까지는 캐릭터에 인체형 래그돌을 적용하고 확장된 커스텀 본에 Character Joint를 넣어서 최대한 자연스러운 래그돌을 만들어내는 작업을 진행해보았다. 그렇게 함으로써 게임에 적용하기 적당한 래그돌을 얻었다. 래그돌을 설명하는 제일 첫 번째 섹션의 아래 쪽에서 실제로 게임에서 래그돌을 사용하는 방법에 대해서 이야기했었는데, 이번 섹션에서는 그 부분에 대해서 자세하게 이야기해볼 것이다.

 

 

게임에서 래그돌을 사용하는 실제 방법은 실제 애니메이션이 적용되어 있는 캐릭터 오브젝트가 살아있는 동안에는 정상적으로 움직이다가, 캐릭터의 체력이 0이 된다던가 하는 방식으로 사망하게 되면 캐릭터 오브젝트를 래그돌 오브젝트로 교체하는 것이다. 다음은 애니메이션된 캐릭터 오브젝트와 래그돌 오브젝트를 교체해주는 코드이다.

 

using UnityEngine;

public class Character : MonoBehaviour
{
    public GameObject charObj;
    public GameObject ragdollObj;

    public Rigidbody spine;

    void Update ()
    {
        if (Input.GetKeyDown(KeyCode.Space))   // Space 키를 누르면 캐릭터가 사망한다고 가정하자.
        {
            ChangeRagdoll();
            spine.AddForce(new Vector3(0f, 0f, 5000f));
        }
    }

    public void ChangeRagdoll()
    {
        charObj.gameObject.SetActive(false);
        ragdollObj.gameObject.SetActive(true);
    }
}

 

 

코드를 작성하고 이미지처럼 적용을 한 다음, 플레이 버튼을 눌러서 테스트를 해보자.

 

 

플레이 되는 도중에 Space 키를 누르면 달리기를 하던 캐릭터가 래그돌로 바뀌면서 풀썩 쓰러지는 것을 볼 수 있을 것이다. 하지만 예시 이미지에서도 보이듯이 캐릭터가 래그돌로 바뀔 때, 갑자기 캐릭터의 포즈가 T자로 바뀌면서 변경되는 것을 볼 수 있다. 이것은 래그돌의 기본 자세가 T자 자세이기 때문에 발생하는 문제이다. 하지만 유니티에서 제공하는 기본적인 래그돌 적용 기능은 T자 자세로 하기를 권장하기 때문에 다른 자세로 만드는 것은 추천하지 않는다.

 

그렇다면 이 어색한 래그돌 전환 문제를 어떻게 해결해야 할지를 찾아야 한다.

 

 

 

우선 캐릭터의 본은 유니티의 Hierarchy 뷰에서 오브젝트로 볼 수 있는데 각 본은 위치와 각도 정보를 가지고 있는 Transform 컴포넌트를 가진다.

 

 

애니메이션을 가진 오브젝트와 래그돌이 적용된 오브젝트를 살펴보면 같은 모델링을 사용했기 때문에 같은 구조를 가지고 있는 것을 알 수 있다.

 

1. 캐릭터의 각 본들은 그 위치와 각도에 대한 정보를 담고 잇는 Transform 컴포넌트를 가진다.

2. 애니메이션 캐릭터 오브젝트와 래그돌 오브젝트의 구조는 1:1로 대응이 된다.

 

위의 2가지 정보를 이용하나면 하나의 아이디어를 얻을 수 있다. 그것은 바로 "애니메이션 캐릭터 오브젝트가 래그돌 오브젝트로 교체될 때 각 본들의 위치와 각도를 전해주면 애니메이션 캐릭터 오브젝트가 취한 마지막 포즈를 래그돌 오브젝트가 취한 채로 시작되지 않을까?" 하는 것이다.

 

이 아이디어를 코드로 만들어보자.

 

using UnityEngine;

public class Character : MonoBehaviour
{
    public GameObject charObj;
    public GameObject ragdollObj;

    public Rigidbody spine;

    void Update ()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            ChangeRagdoll();
            spine.AddForce(new Vector3(0f, 0f, 5000f));
        }
    }

    public void ChangeRagdoll()
    {
        CopyAnimCharacterTransformToRagdoll(charObj.transform, ragdollObj.transform);

        charObj.gameObject.SetActive(false);
        ragdollObj.gameObject.SetActive(true);
    }

    private void CopyAnimCharacterTransformToRagdoll(Transform origin, Transform rag)
    {
        for (int i = 0; i < origin.transform.childCount; i++)
        {
            if (origin.transform.childCount != 0)
            {
                CopyAnimCharacterTransformToRagdoll(origin.transform.GetChild(i), rag.transform.GetChild(i));
            }
            rag.transform.GetChild(i).localPosition = origin.transform.GetChild(i).localPosition;
            rag.transform.GetChild(i).localRotation = origin.transform.GetChild(i).localRotation;
        }
    }
}

 

위의 코드는 SetActive로 오브젝트들을 교체하기 직전에 원본의 자식 오브젝트들의 Transform을 래그돌의 자식 오브젝트들의 Transform에 복사해주는 작업을 진행한다.

 

 

 

완성된 코드를 적용하고 테스트를 해보면 Space 키를 누르면 달리는 동작과 자연스럽게 이어지면서 쓰러지는 것을 볼 수 있다.

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

Ragdoll 사용하기 - 커스텀 본에 Ragdoll 적용하기

 

이전 섹션들에서는 기본적인 인체 형태(Humanoid)의 본 구조에 대해 래그돌을 적용하고 거기에 사용되는 Character Joint 컴포넌트의 상세한 옵션에 대해서 알아보았다. 이번 섹션에서는 지난 섹션에서 본 Character Joint를 이용해서 일반적인 인체 구조의 외의 다른 형태의 본에 대해서 래그돌을 적용하는 법에 대해서 알아보게 될 것이다.

 

새로운 응용법을 배우게 될 것이지만 준비물은 전과 같다. 유니티 짱 캐릭터 하나면 충분하다.

 

 

유니티 짱 캐릭터의 모델링은 기본적인 인체 구조를 약간 벗어나 머리카락 부분에도 본이 심어져 있다. 이번 예제에서는 이 머리카락의 본 부분에 Character joint를 적용해서 래그돌이 되었을때 머리카락 역시 움직임을 보이도록 만들것이다.

 

 

뒷 머리카락의 본은 Head에 연결된 HairTail에서 시작된다.

 

 

이 두개의 본을 선택하고 Character Joint와 Sphere Collider를 생성한다. Rigidbody 컴포넌트의 경우는 Character Joint를 생성하면 자동으로 생성된다. Sphere Collider는 머리카락의 충돌을 처리하기 위해 생성한다.

 

 

다음은 Character Joint의 Connected Body 프로퍼티에 Head의 Rigidbody를 넣어준다. 그러면 머리카락의 조인트는 머리에 연결된다.

 

 

그 다음엔 추가한 Collider의 크기를 조절해야 한다.

 

 

만약 그렇지 않으면 이런 장면을 보게 될 것이다.

 

 

Collider의 설정을 적절히 수정해서 아래와 같은 모습이 되도록 하자.

 

 

그리고 머리카락의 무게가 너무 무거우면 이상한 움직임을 보일 수 있으므로 적절하게 수정해주어야 한다.

 

 

위와 같은 과정을 머리카락 끝까지 반복하여 이미지처럼 만들면 된다.

 

 

설정을 끝낸 후에 머리카락의 본에 Character Joint를 심은 모델과 심지 않은 모델을 비교해보면 그 차이를 확실하게 느낄 수 있다. 머리카락에도 래그돌이 적용된 캐릭터의 머리카락은 자연스럽게 바닥에 떨어져 모양이 잡히는 반면에 적용되지 않는 캐릭터의 머리카락은 뻣뻣하게 되어 있는 것을 볼 수 있다.

 

이렇듯이 인간형이 아니거나 인간형에서 확장된 모델의 경우에도 적절하게 Character Joint를 심고 형태에 맞는 Collider를 넣어주는 것 만으로 래그돌을 적용할 수 있다.

 

 

[유니티 어필리에이트 프로그램]

아래의 링크를 통해 에셋을 구매하시거나 유니티를 구독하시면 수익의 일부가 베르에게 수수료로 지급되어 채널의 운영에 도움이 됩니다.

 

에셋스토어

여러분의 작업에 필요한 베스트 에셋을 찾아보세요. 유니티 에셋스토어가 2D, 3D 모델, SDK, 템플릿, 툴 등 여러분의 콘텐츠 제작에 날개를 달아줄 다양한 에셋을 제공합니다.

assetstore.unity.com

 

Easy 2D, 3D, VR, & AR software for cross-platform development of games and mobile apps. - Unity Store

Have a 2D, 3D, VR, or AR project that needs cross-platform functionality? We can help. Take a look at the easy-to-use Unity Plus real-time dev platform!

store.unity.com

 

Create 2D & 3D Experiences With Unity's Game Engine | Unity Pro - Unity Store

Unity Pro software is a real-time 3D platform for teams who want to design cross-platform, 2D, 3D, VR, AR & mobile experiences with a full suite of advanced tools.

store.unity.com

[투네이션]

 

-

 

toon.at

[Patreon]

 

WER's GAME DEVELOP CHANNEL님이 Game making class videos 창작 중 | Patreon

WER's GAME DEVELOP CHANNEL의 후원자가 되어보세요. 아티스트와 크리에이터를 위한 세계 최대의 멤버십 플랫폼에서 멤버십 전용 콘텐츠와 체험을 즐길 수 있습니다.

www.patreon.com

[디스코드 채널]

 

Join the 베르의 게임 개발 채널 Discord Server!

Check out the 베르의 게임 개발 채널 community on Discord - hang out with 399 other members and enjoy free voice and text chat.

discord.com

 

반응형

+ Recent posts