안녕하세요. 인텔리원스튜디오(IntelliOneStudio)입니다.
이번 시간에는 Unity에서 iOS 네이티브 코드를 활용하여 텍스트와 이미지를 공유하는 방법을 알아보겠습니다. 특히 ImageSharing.mm 파일을 중심으로, Unity C# 코드에서 iOS 네이티브 함수를 호출하여 **공유 시트(UIActivityViewController)**를 띄우고, 공유 완료 상태를 Unity로 다시 전달하는 과정을 소개해 드릴게요.
이 스크립트를 통해 게임 내에서 스크린샷, 메시지, 게임 초대 링크 등을 iOS 플랫폼 상에서 손쉽게 공유할 수 있습니다. 단계별로 필요한 코드와 설명을 함께 제공하니, 프로젝트에서 바로 적용해 보세요.
2024.11.14 - [분류 전체보기] - [외워라!창고] 챗GPT를 활용해서 개발한 두 번째 게임을 여러분께 소개합니다!
[외워라!창고] 챗GPT를 활용해서 개발한 두 번째 게임을 여러분께 소개합니다!
안녕하세요, 인텔리원스튜디오(IntelliOneStudio)에서 흥미진진한 소식을 가지고 왔어요! 저희가 챗GPT를 활용해서 개발한 두 번째 게임을 여러분께 소개합니다! 이 게임은 챗GPT의 놀라운 AI 기능을
intellinomadlife.tistory.com
창고에 물건을 보관하면 더이상 보여주지 않고, 오로지 당신의 기억력으로 찾아야해요.
날이 갈수록 늘어나는 상품들과 주문에도 정확하고 빠르게 물건을 찾아 배송해야해요.
과연 당신은 며칠까지 버틸수 있을까요?
당신의 기억력을 시험해봐요. 지금 다운로드하세요.
[아이폰 앱스토어 다운로드]
https://apps.apple.com/kr/app/%EC%99%B8%EC%9B%8C%EB%9D%BC%EC%B0%BD%EA%B3%A0/id6737766088
외워라창고
환영합니다. 우리 창고는 매일 새롭게 들어오는 상품을 각기 다른 각기 다른 상자에 보관해요. 주문이 들어오면 그 상품들을 찾아 포장하고, 정확한 주소로 배송하는 것이 여러분의 임무입니
apps.apple.com
[구글 플레이 다운로드]
https://play.google.com/store/apps/details?id=com.intellione.warehousedelivery
외워라 창고 - Google Play 앱
창고의 기억왕: 물건 찾기의 달인이 되어라.
play.google.com
저희가 챗GPT를 활용해서 개발한 첫 번째 게임을 여러분께 소개합니다! 이 게임은 챗GPT의 놀라운 AI 기능을 활용해 개발했어요. 즐거움이 가득한 이번 게임은, 챗GPT를 활용해서 누구든지 게임을 재미있게 만들 수 있다는 것을 보여줄 거에요.
* APP Store 에서 다운로드
https://apps.apple.com/kr/app/%EB%86%8D%EB%B6%80%EC%9D%98-%EA%BF%88/id6479183930
농부의 꿈
오래된 전설이 숨겨져 있는 [농부의 꿈]목장 한구석에서 ‘비밀의 문'과 '마법 책'이 발견되었어요. [변신하는 동물들] 병아리가 합쳐져 닭이 되고, 닭이 합쳐져 고슴도치로 변신하며, 점점 더
apps.apple.com
*Google Play 에서 다운로드
https://play.google.com/store/apps/details?id=com.intellione.farmersfirstdream&pcampaignid=web_share
농부의 꿈 - Google Play 앱
평화로운 목장에서 신나는 동물 합치기 무료게임 (바람, 뚫어뻥, 밧줄, 무중력 등 매직 아이템 활용해 병아리를 젖소로 키워보세요.)
play.google.com
아래와 같이 ChatGPT에게 질문했어요.
※ ChatGPT 답변 내용 중 제가 별도로 표시한 굵은 글씨를 기준으로 읽으시면 좀 더 이해가 쉽게 될 거예요.
[질문]
안녕, ChatGPT. Unity에서 iOS 네이티브 코드를 통해 텍스트나 이미지를 다른 앱과 공유하고 싶어. ImageSharing.mm 파일을 작성했는데, 어떻게 동작하는지 자세히 설명해 줄 수 있어?
[답변]
안녕하세요! ImageSharing.mm 파일을 통해 Unity와 iOS 네이티브 코드 간에 상호작용하여 텍스트와 이미지를 공유하는 방법을 단계별로 설명해 드릴게요.
1. 함수 개요
void _shareText(const char *message, const char *unityObjectName);
void _shareTextWithImage(const char *message, const char *filePath, const char *unityObjectName);
void showAlertWithMessage(NSString *message);
설명:
- _shareText: Unity에서 호출할 때 텍스트만 공유하는 함수입니다.
- _shareTextWithImage: Unity에서 호출할 때 텍스트와 이미지(파일) 경로를 함께 전달하여 공유하는 함수입니다.
- showAlertWithMessage: 에러 발생 시 사용자에게 Alert을 표시하는 함수입니다.
이 함수들은 Unity C# 코드에서 DllImport 또는 [System.Runtime.InteropServices]를 통해 직접 호출할 수 있습니다.
2. 텍스트만 공유하기
void _shareText(const char *message, const char *unityObjectName) {
// filePath에 빈 문자열을 전달하여 텍스트만 공유하는 로직으로 일원화
_shareTextWithImage(message, "", unityObjectName);
}
설명:
- _shareText 함수는 텍스트만 공유할 때 호출합니다.
- 내부적으로 _shareTextWithImage 함수로 빈 파일 경로("")를 전달하여 로직을 일원화합니다.
3. 텍스트와 이미지 공유하기
void _shareTextWithImage(const char *message, const char *filePath, const char *unityObjectName) {
NSString *text = [NSString stringWithUTF8String:message];
NSString *path = [NSString stringWithUTF8String:filePath];
NSString *unityObject = [NSString stringWithUTF8String:unityObjectName];
NSMutableArray *itemsToShare = [NSMutableArray array];
// 텍스트 추가
if (text != nil && text.length > 0) {
[itemsToShare addObject:text];
}
// 이미지 추가
if (path != nil && path.length > 0) {
UIImage *image = [UIImage imageWithContentsOfFile:path];
if (image != nil) {
[itemsToShare addObject:image];
} else {
NSLog(@"Error: Could not load image from path: %@", path);
showAlertWithMessage(@"이미지를 로드하는 데 실패했습니다. 파일 경로를 확인해주세요.");
return;
}
}
// 공유 시트 표시
UIActivityViewController *activityViewController =
[[UIActivityViewController alloc] initWithActivityItems:itemsToShare applicationActivities:nil];
// iPad 호환성 처리
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
activityViewController.popoverPresentationController.sourceView = [UIApplication sharedApplication].keyWindow.rootViewController.view;
activityViewController.popoverPresentationController.sourceRect = CGRectMake(
CGRectGetMidX([UIApplication sharedApplication].keyWindow.rootViewController.view.bounds),
CGRectGetMidY([UIApplication sharedApplication].keyWindow.rootViewController.view.bounds),
0, 0);
activityViewController.popoverPresentationController.permittedArrowDirections = 0; // 화살표 숨김
}
// 공유 완료 여부 콜백 처리
activityViewController.completionWithItemsHandler = ^(UIActivityType activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
if (completed) {
NSLog(@"사용자가 공유를 완료했습니다.");
UnitySendMessage([unityObject UTF8String], "OnShareCompleted", "success");
} else {
NSLog(@"사용자가 공유를 취소했습니다.");
UnitySendMessage([unityObject UTF8String], "OnShareCompleted", "canceled");
}
if (activityError) {
NSLog(@"공유 중 에러 발생: %@", activityError.localizedDescription);
}
};
// 현재 화면에 공유 시트 표시
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:activityViewController animated:YES completion:nil];
}
설명:
- Unity에서 전달한 message와 filePath, unityObjectName을 NSString으로 변환합니다.
- 텍스트와 이미지를 itemsToShare 배열에 추가하고, UIActivityViewController를 생성합니다.
- iPad에서의 팝오버 위치를 설정하여 UI 호환성을 확보합니다.
- 공유 시 완료, 취소, 에러 상태를 Unity로 다시 전달하기 위해 UnitySendMessage를 사용합니다.
- 공유 시트가 표시되면 사용자는 원하는 앱으로 텍스트나 이미지를 공유할 수 있습니다.
4. 에러 발생 시 Alert 표시
void showAlertWithMessage(NSString *message) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Error"
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:nil];
[alert addAction:okAction];
// 현재 뷰 컨트롤러에서 alert를 표시
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alert animated:YES completion:nil];
}
설명:
- 이미지 로딩 실패 또는 다른 에러 발생 시 사용자가 알 수 있도록 Alert을 표시합니다.
- iOS 네이티브 UI를 통해 사용자에게 피드백을 제공합니다.
전체 코드 예제
// ImageSharing.mm
#import <UIKit/UIKit.h>
// 함수 선언
void _shareText(const char *message, const char *unityObjectName);
void _shareTextWithImage(const char *message, const char *filePath, const char *unityObjectName);
void showAlertWithMessage(NSString *message);
// Unity에서 호출할 함수 (텍스트만 공유)
void _shareText(const char *message, const char *unityObjectName) {
_shareTextWithImage(message, "", unityObjectName);
}
// Unity에서 호출할 함수 (텍스트와 파일을 함께 공유)
void _shareTextWithImage(const char *message, const char *filePath, const char *unityObjectName) {
NSString *text = [NSString stringWithUTF8String:message];
NSString *path = [NSString stringWithUTF8String:filePath];
NSString *unityObject = [NSString stringWithUTF8String:unityObjectName];
NSMutableArray *itemsToShare = [NSMutableArray array];
if (text != nil && text.length > 0) {
[itemsToShare addObject:text];
}
if (path != nil && path.length > 0) {
UIImage *image = [UIImage imageWithContentsOfFile:path];
if (image != nil) {
[itemsToShare addObject:image];
} else {
NSLog(@"Error: Could not load image from path: %@", path);
showAlertWithMessage(@"이미지를 로드하는 데 실패했습니다. 파일 경로를 확인해주세요.");
return;
}
}
UIActivityViewController *activityViewController =
[[UIActivityViewController alloc] initWithActivityItems:itemsToShare applicationActivities:nil];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
activityViewController.popoverPresentationController.sourceView = [UIApplication sharedApplication].keyWindow.rootViewController.view;
activityViewController.popoverPresentationController.sourceRect = CGRectMake(
CGRectGetMidX([UIApplication sharedApplication].keyWindow.rootViewController.view.bounds),
CGRectGetMidY([UIApplication sharedApplication].keyWindow.rootViewController.view.bounds),
0, 0);
activityViewController.popoverPresentationController.permittedArrowDirections = 0;
}
activityViewController.completionWithItemsHandler = ^(UIActivityType activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
if (completed) {
NSLog(@"사용자가 공유를 완료했습니다.");
UnitySendMessage([unityObject UTF8String], "OnShareCompleted", "success");
} else {
NSLog(@"사용자가 공유를 취소했습니다.");
UnitySendMessage([unityObject UTF8String], "OnShareCompleted", "canceled");
}
if (activityError) {
NSLog(@"공유 중 에러 발생: %@", activityError.localizedDescription);
}
};
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:activityViewController animated:YES completion:nil];
}
// 에러 발생 시 사용자에게 알림
void showAlertWithMessage(NSString *message) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Error"
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:nil];
[alert addAction:okAction];
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alert animated:YES completion:nil];
}
적용 방법
- Native Plugin 구성
- 이 Objective-C 코드를 iOS Native Plugin 형태로 Xcode 프로젝트에 추가합니다.
- Unity iOS 빌드 시 ImageSharing.mm가 포함되도록 설정하세요.
- Unity C# 코드에서 호출
- DllImport("__Internal")] 또는 extern "C"로 선언하여 _shareText와 _shareTextWithImage 함수를 호출합니다.
- 아래 예제 참고하세요.
- 유니티 오브젝트 이름 설정
- unityObjectName 파라미터를 통해 Unity 오브젝트를 지정하고, 공유 완료 시 OnShareCompleted 메시지를 받습니다.
- Unity C# 코드에서 OnShareCompleted를 구현하여 공유 결과를 처리할 수 있습니다.
- 빌드 및 테스트
- iOS 실제 기기에서 테스트하여 공유 시트가 정상적으로 표시되는지 확인합니다.
- 텍스트만 공유, 텍스트와 이미지 공유, 이미지 로딩 실패 시 Alert 표시 등을 테스트하세요.
[DllImport("__Internal")]
private static extern void _shareText(string message, string unityObjectName);
[DllImport("__Internal")]
private static extern void _shareTextWithImage(string message, string filePath, string unityObjectName);
오늘은 ImageSharing.mm를 활용하여 Unity와 iOS 네이티브 코드를 연동하고, 텍스트와 이미지 공유 기능을 구현하는 방법을 알아봤습니다.
이 시스템을 통해 게임 내 스크린샷 공유, 게임 초대, 프로모션 코드 공유 등을 손쉽게 처리할 수 있습니다.
지금까지 인텔리원스튜디오(IntelliOneStudio)였습니다!
감사합니다.
'디지털노마드' 카테고리의 다른 글
챗GPT 게임개발75: iOS 앱 이름 현지화, InfoPlist.strings 파일 생성 및 언어 추가 방법 (0) | 2024.12.27 |
---|---|
챗GPT 게임개발74: Unity에서 DOTween을 활용한 보상 젬 이동 연출하기 (3) | 2024.12.11 |
챗GPT 게임개발72: Unity에서 타이머와 애니메이션 제어하기 (4) | 2024.12.04 |
챗GPT 게임개발71: Unity에서 Game Center 및 Google Play Games 리더보드 구현하기 (1) | 2024.12.03 |
챗GPT 게임개발70: Unity에서 다국어 지원과 언어별 폰트 적용하기 (4) | 2024.12.02 |