반응형

 

안녕하세요.

앱등록할 떄, 다음과 같은 오류에 대해 수정하는 법에 대해 공유 드립니다.

"이 버전을 출시하기 전에 다음 오류를 확인하세요."

오류 메세지를 보면 다음과 같이 나옵니다.

이 출시 버전은 Google Play 64비트 요구 사항을 준수하지 않습니다.

다음 APK 또는 APP Bundle은 64비트 기기에서 사용할 수 있으나 현재 다음 32비트 네이티브 코드만 있습니다. 

앱에 64비트 및 32비트 네이티브 코드를 포함하세요. Android App Bundle 게시 형식을 사용하여 각 기기 아키텍쳐가 필요한 네이티브 코드만 수신하도록 자동으로 확인하세요. 그래야 앱 전체 크기를 줄일 수 있습니다.

이런 에러가 발생합니다.

다음과 같이 해결합니다.

64버전을 지원하려면 ARM64를 체크해야합니다.

일단, Scripting Backend에 Mono를 IL2CPP로 변경하고, ARM64를 체크합니다.

그리고 다시 빌드합니다.

만약 unable to locate android ndk 문제 오류가 난다면 다음 글을 확인하세요.

https://scvtwo.tistory.com/70?category=877671

 

[Unity] unable to locate android ndk 문제

안녕하세요. 유니티 빌드 중에 "unable to locate android ndk" 메세지박스가 출력되는 경우 해결 방법에 대해 알아보도록 하겠습니다. 일단 검색해봤을 때, Android SDK & NDK Tools을 설치했습니다. 근데 여전..

scvtwo.tistory.com

 

반응형
반응형

이미 버전 코드가 1인 APK가 있으므로 다른 버전 코드를 사용해야 합니다.

다음과 같이 버전이 같은 APK를 넣으면 업로드 실패가 뜹니다.

이렇게 해결합니다.

버전을 변경하고, 다시 빌드를 합니다.

반응형
반응형

 

안녕하세요.

유니티 빌드 중에 "unable to locate android ndk" 메세지박스가 출력되는 경우 

해결 방법에 대해 알아보도록 하겠습니다.

일단 검색해봤을 때, 

Android SDK & NDK Tools을 설치했습니다.

근데 여전히 같은 현상이 발생했습니다.

그래도 또 검색하다보니, Edit-Preferences에서 NDK를 다운로드 받습니다.

링크는 다음과 같습니다.

ndk를 저장한 후 C:\에 넣습니다.

https://dl.google.com/android/repository/android-ndk-r16b-windows-x86_64.zip

불러오는 중입니다...

그리고 경로를 변경합니다.

그리고 다시 빌드를 합니다.

반응형
반응형

안녕하세요.

구글 플레이 게임 서비스(GPGS) 연동 후 구글 플레이에 등록하는 과정에 대해 알아보도록 하겠습니다.

다음 과정을 거쳐서 GPGS 연동 후 앱등록 해보도록 하겠습니다.

1. Google Play Games plugin for Unity 

 

https://developers.google.com/games/services/integration

 

Game Engine Integrations  |  Play Games Services  |  Google Developers

Several plugins and extensions offer support for Google Play games services. If you are developing your game with a third-party game engine, you may be interested in using one of these plugins or extensions to integrate Google Play games services features.

developers.google.com

여기에 접속하여, Google Play Games plugin for Unity 를 눌러 GitHub에 접속합니다.

https://github.com/playgameservices/play-games-plugin-for-unity

 

playgameservices/play-games-plugin-for-unity

Google Play Games plugin for Unity. Contribute to playgameservices/play-games-plugin-for-unity development by creating an account on GitHub.

github.com

 

current-build로 들어갑니다.

GooglePlayGamesPlugin-0.10.06.unitypackage를 다운로드받습니다.

그리고 사용할 프로젝트에 import 합니다.

GooglePlayGamesPlugin-0.10.06.unitypackage 파일을 끌어서 해당 프로젝트에 넣으면 됩니다.

 

2. Build Settings

그 후 File-Build Settings에 Build Settings창을 엽니다.

Android로 변경합니다.

Switch Platform을 한 후 Player Settings...버튼을 누릅니다.

그리고 다음과 같이 Company Name을 지정하고. Keystore Manager...버튼을 누릅니다.

 

Create New - Anywhere 한 후 KeyStore를 저장합니다.

 

 

패스워드를 입력하고, Alias는 아무거나 입력합니다.

그리고 AddKey 버튼을 누릅니다.

이제 다시 빌드 셋팅으로 돌아가서 빌드 버튼을 눌러 apk를 만듭니다.

만약 씬이 추가가 안되어있다면 "Add Opn Scenes"를 누릅니다.

 

3. 앱등록

Google Play Console에 접속하여 로그인 합니다.

https://developer.android.com/distribute/console?hl=ko

 

Google Play  |  Android Developers

Google Play Console로 앱과 게임을 게시하고 Google Play에서 비즈니스를 성장시키세요. 앱의 품질을 개선하고, 사용자층과 소통하고, 수익을 창출하기 위한 여러 기능을 활용할 수 있습니다.

developer.android.com

GOOGLE PLAY에 ANDROID 앱을 출시 버튼을 누릅니다.

 

제목을 입력하고 만들기 버튼을 누릅니다.

그러면 다음과 같은 화면이 나오는데, 체크 항목을 모두 기입해야합니다.

 

3-1 스토어 등록정보

일단 별로 표시된 항목들은 모두 기입해야합니다.

 

콘텐츠 등급은 apk올린 후 합니다.

3-2 앱 버전

apk를 등록합니다.

 

저장을 누르면 검토 버튼이 활성화되는데, 검토버튼을 누릅니다..

3-3 콘텐츠 등급

저장하고 등급계산을 합니다.

 

3-4 가격 및 배포

 

그 후 임시저장 버튼을 누릅니다.

3-5 가격 및 배포

 

광고가 있다면 "예, 광고가 포함되어 있습니다"를 체크합니다.

저는 광고가 없어서 "아니요"를 했습니다.

앱버전탭으로 이동합니다.

그 후 프로덕션 출시 시작을 합니다.

반응형
반응형

안녕하세요.

스레드에서 동시에 같은 메서드에 접근하거나 같은 변수값을 변경할 때, 실행 결과가 잘못될 경우가 있습니다.

이럴때는 쓰레드가 동시에 같은 메서드에 접근을 못하게 하거나 같은 변수에 접근을 못하게 막아야합니다.

이렇게 순차적으로 접근시키고, 동시접근을 막아주는게 동기화라고 할 수 있습니다.

다음 코드는 동기화를 하지 않았을 때 문제가 발생합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
 
namespace ConsoleApplication1
{
    class Program
    {
        static int Count = 0;
 
        static void print()
        {
            for (int i = 0; i < 5; i++)
            {
                Count++;
                Console.WriteLine(Count);
                Thread.Sleep(1000);
            }    
        }
        static void Main(string[] args)
        {
            Thread thread1 = new Thread(new ThreadStart(print));
            Thread thread2 = new Thread(new ThreadStart(print));
            Thread thread3 = new Thread(new ThreadStart(print));
            Thread thread4 = new Thread(new ThreadStart(print));
 
            thread1.Start();
            thread2.Start();
            thread3.Start();
            thread4.Start();
 
            thread1.Join();
            thread2.Join();
            thread3.Join();
            thread4.Join();
 
        }
    }
}
cs

4개의 쓰레드를 생성해서 Count 변수에 1씩 5번 더해줘서 총 20을 더하게 됩니다.
근데 출력된 값을 보면 1~20으로 순차적으로 찍히는게 아니라, 다음과 같이 찍히는 경우도 존재합니다.

제대로 연산이 안될 경우가 있으면, 계속 버그가 만들어지게 되므로, 우리는 항상 규칙적으로 코드가 실행되야 합니다.

그래서 동기화를 사용해서 한 쓰레드가 메모리에 접근중이면 다른 쓰레드가 해당 메모리에 접근하지 못하도록 막습니다.

동기화에는 다음과 같은 클래스를 사용합니다.

1. Lock

상호 배제 잠금을 획득하여, 명령문 브록을 실행 후, 잠금을 해제합니다.
잠금을 보유하는 스레드에서 잠금을 다시 해제할 수 있으며, 
다른 스레드에서는 잠금을 획득이 차단되고, 잠금이 해제될때까지 대기하게 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
 
namespace ConsoleApplication1
{
    class Program
    {
        static int Count = 0;
 
        static System.Object lockThis = new System.Object();
 
        static void print()
        {
            lock (lockThis)
            {
                for (int i = 0; i < 5; i++)
                {
                    Count++;
 
                    Console.WriteLine(Count);
                }
            }
        }
        static void Main(string[] args)
        {
            Thread thread1 = new Thread(new ThreadStart(print));
            Thread thread2 = new Thread(new ThreadStart(print));
            Thread thread3 = new Thread(new ThreadStart(print));
            Thread thread4 = new Thread(new ThreadStart(print));
 
            thread1.Start();
            thread2.Start();
            thread3.Start();
            thread4.Start();
 
            thread1.Join();
            thread2.Join();
            thread3.Join();
            thread4.Join();
 
        }
    }
}
cs

2. Monitor

Lock과 같이 해당 블록을 잠금 후 실행하고, 잠금을 해제합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
 
namespace ConsoleApplication1
{
    class Program
    {
        static int Count = 0;
        static Object monitorLock = new System.Object();
 
        static void print()
        {
            Monitor.Enter(monitorLock);
            try
            {
                for (int i = 0; i < 5; i++)
                {
                    Count++;
                    Console.WriteLine(Count);
                    Thread.Sleep(1000);
                }
            }
            finally
            {
                Monitor.Exit(monitorLock);
            }
        }
        static void Main(string[] args)
        {
            Thread thread1 = new Thread(new ThreadStart(print));
            Thread thread2 = new Thread(new ThreadStart(print));
            Thread thread3 = new Thread(new ThreadStart(print));
            Thread thread4 = new Thread(new ThreadStart(print));
 
            thread1.Start();
            thread2.Start();
            thread3.Start();
            thread4.Start();
 
            thread1.Join();
            thread2.Join();
            thread3.Join();
            thread4.Join();
 
        }
    }
}
cs

Monitor 클래스 중에는 Wait()와 Pulse() 메서드가 있습니다.
쓰레드를 Wait() 메서드로 잠시 대기상태로 만들어 준 후 Pulse()로 활성화 시킬 수 있습니다.
보통 메모리 상에 데이터를 가질때까지 대기하고 데이터를 가지게 되면 활성화 시켜서 작업을 진행할 수 있도록 할 수 있습니다.
다음은 Count 필드 값을 순차적으로 증가 시킨 후 다른 스레드에서 감소합니다.

반응형

'개발공부 > C#' 카테고리의 다른 글

[C#] 스레드(Thread)  (0) 2019.11.04
[C#]컬렉션(Collections)  (0) 2019.10.31
C# 인터페이스(interface)  (0) 2019.10.30
[C#] 배열(Array)  (0) 2019.10.29
[C#] String.Format  (0) 2019.10.28
반응형

스레드는 프로세스 내에서 실행되는 흐름의 단위를 말합니다.
프로세스 내에는 여러 개의 스레드가 존재할 수 있습니다.

그리고 여러개의 스레드로 여러 작업 들을 실행할 수 있습니다.
예를 들면, 어떠한 연산을 동시에 실행되게 할 수 있습니다.

동시에 연산을 진행하게 되면 다른 연산 결과를 얻을 수 있으므로 제대로 된 설계를 하여 스레드를 사용해야 합니다. 스레드는 프로세스 내에서 실행되는 흐름의 단위를 말합니다.
프로세스 내에는 여러 개의 스레드가 존재할 수 있습니다.

그리고 여러개의 스레드로 여러 작업 들을 실행할 수 있습니다.
예를 들면, 어떠한 연산을 동시에 실행되게 할 수 있습니다.

동시에 연산을 진행하게 되면 다른 연산 결과를 얻을 수 있으므로 제대로 된 설계를 하여 스레드를 사용해야 합니다.

바로 예제 코드 작성을 하여, 설명드리겠습니다.

다음과 같이 코드를 작성하면 쓰레드가 만들 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void print()
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("out : {0}", i);
                Thread.Sleep(1000);
            }
        }
        static void Main(string[] args)
        {
            Thread thread = new Thread(new ThreadStart(print));
 
            thread.Start();
            
        }
    }
}
cs

using System.Threading를 사용하여 Thread클래스를 생성할 수 있습니다.

new Thread(new ThreadStart(print))로 스레드로 생성할 메서드를 델리게이트를 만들어서 스레드를 생성합니다.

thread.Start();로 시작합니다.

순차적으로 out : 0 ~ out : 5까지 출력되는것을 확인할 수 있습니다.

Main에서 print함수를 같이 실행 시켜봅니다.

1
2
3
4
5
6
7
8
static void Main(string[] args)
{
    Thread thread = new Thread(new ThreadStart(print));
 
    thread.Start();
 
    print();    // 이부분만 추가합니다.
}
cs

이렇게 한다면 새로 만든 print메서드를 사용하는  thread와 메인 스레드 두개가 동시에 진행되면서,
out : 0 ~ out : 5가 2개씩 찍히는 것을 확인할 수 있습니다.

쓰레드 실행 중에 종료를 하면 어떻게 할까요??

바로 Abort함수를 이용합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void print()
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("out : {0}", i);
                Thread.Sleep(1000);
            }
        }
        static void Main(string[] args)
        {
            Thread thread = new Thread(new ThreadStart(print));
 
            thread.Start();
 
            Thread.Sleep(3000);
            thread.Abort();
            thread.Join();    // 종료대기
        }
    }
}
cs

이렇게 코드를 작성하면 3초 후 종료가 되어서 print메서드의 출력을 모두 할 수 없습니다.

Abort()를 호출하면, ThreadAbortException를 throw 하여 종료가 됩니다.

근데 Abort()는 지금 같이 간단한 코드에서는 문제가 생기지 않지만, 

바로 종료가 된다는 보장도 없으며, Join함수로 인해 종료 대기가 된다는 보장도 없습니다.

웬만하면 Abort()를 이용해서 종료하지 않는 편이 좋습니다.

다음과 같이 작성하면 throw 할 때 상태를 확인할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void print()
        {
            try
            {
                for (int i = 0; i < 5; i++)
                {
                    Console.WriteLine("out : {0}", i);
                    Thread.Sleep(1000);
                }
            }
            catch (ThreadAbortException e )
            {
                Console.WriteLine(e);
            }
            finally
            {
                Console.WriteLine("About Complete");
            }
        }
        static void Main(string[] args)
        {
            Thread thread = new Thread(new ThreadStart(print));
 
            thread.Start();
 
            Thread.Sleep(3000);
            thread.Abort();
            thread.Join();    // 종료대기
        }
    }
}
cs
반응형

'개발공부 > C#' 카테고리의 다른 글

[C#] 스레드 동기화(Lock, Monitor)  (0) 2019.11.05
[C#]컬렉션(Collections)  (0) 2019.10.31
C# 인터페이스(interface)  (0) 2019.10.30
[C#] 배열(Array)  (0) 2019.10.29
[C#] String.Format  (0) 2019.10.28
반응형

안녕하세요.

코딩하다 보면 플랫폼별로 실행되는 코드를 분류해야 하는 경우가 있습니다.

예를 들면, 안드로이드 폰에서는 뒤로 가기가 있지만, 아이폰에서는 뒤로 가기가 없습니다.

그러므로 안드로이드 폰에서만 실행되는 코드를 작성해야합니다.

그럴 경우에 다음과 같이 작성할 수 있습니다.

if (Application.platform == RuntimePlatform.Android)
            실행코드;

현재 플랫폼을 확인해서 그에 맞는 코드를 작성합니다.

Application.platform은 플랫폼별로 다음과 같은 값을 가지고 있습니다.

RuntimePlatform변수 설명
OSXEditor Mac OS X 유니티 에디터 플레이어
OSXPlayer Mac OS X 플레이어
WindowsPlayer Windows 플레이어
OSXWebPlayer Mac OS X 플레이어
OSXDashboardPlayer Mac OS X Dashboard widget
WindowsWebPlayer Windows 플레이어
WindowsEditor Windows 유니티 에디터
IPhonePlayer iPhone 플레이어
XBOX360 XBOX360 플레이어
PS3 Play Station 3 플레이어
Android 안드로이드 장치 플레이어
LinuxPlayer 리눅스 플레이어
WebGLPlayer WebGL 플레이어
WSAPlayerX86 CPU 아키텍쳐가 x86 윈도우스토어 앱플레이어
WSAPlayerX64 CPU 아키텍쳐가 x64 윈도우스토어 앱플레이어
WSAPlayerARM CPU 아키텍쳐가 ARM 윈도우스토어 앱플레이어
TizenPlayer 리눅스상에서 동작하는 플레이어를 나타냅니다.
PSP2 PS Vita 플레이어
PS4 Playstation 4 플레이어
XboxOne Xbox One 플레이어
SamsungTVPlayer Samsung Smart TV 플레이어
WiiU Windows플레이어
tvOS iPhone 플레이어
   

 

안드로이드 폰에서 뒤로가기를 눌렀을 때는 다음과 같이 코드를 작성합니다.

1
2
3
4
5
6
7
void Update()
{
    if (Application.platform == RuntimePlatform.Android && Input.GetKeyDown(KeyCode.Escape))
    {
        Application.Quit();
    }
}
 
cs
반응형
반응형

안녕하세요.

오늘은 유니티로 개발중에 발생한 Screen.width가 폰 스펙과 다르게 나오는 문제에 대해 다루겠습니다.

제가 하려고 했던건 폰 width값을 버튼의 width값에 넣으려고 했는데, 유니티상이나 애뮬레이터 상에도 문제가 없었는데, 갤럭시 S8 기종에서는 다른 width값을 가지고 있었습니다.

분명히 S8기종 해상도는 2960 x 1440 으로 알고 있습니다.

가로모드로 해놓았기 때문에 2960이 width값으로 들어있어야하는데, 2220이 들어있었습니다.

또한 Screen.height값도 1440이 아니라 1080으로 들어가 있었습니다.

검색을 해봐도 해결이 되지 않았습니다.

그러던중 혹시 몰라서 폰 디스플레이 설정을 확인했습니다.

설정 - 디스플레이 - 화면해상도를 확인했습니다.

 

그런데 이와 같이 2220 x 1080으로 설정되어있어서 Screen.width와 Screen.height에서 각각 2220 / 1080으로 값이 들어가 있었습니다.

결론적으로 이런 방법으로는 해상도를 맞출 수 없을거같아서, 다른 방법을 다시 찾아야 할 것 같습니다.

반응형
반응형

해외 서비스를 하기 위해서는 Collation를 변경해야 스트링이 깨지는 현상을 방지할 수 있습니다.


데이터 베이스의 Collation 변경 쿼리는 다음과 같습니다.
1. 다른 사용자가 DB를 사용하고 있는데, 변경되면 안 되기 때문에 SINGLE USER로 변경합니다.
-- SINGLE USER MODE 변경 
ALTER DATABASE
DBNAME_DBF
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE

2. collate 변경합니다.
--  Thai_CI_AS로 변경
ALTER DATABASE
DBNAME_DBF
COLLATE
Thai_CI_AS

3. 다시 MULTI USER MODE로 원복합니다
-- MULTI USER MODE
ALTER DATABASE
DBNAME_DBF
SET MULTI_USER 


테이블의 컬럼(char, nvarchar, text형 데이터) COLLATE도 변경해야 데이터가 제대로 입력될 수 있습니다.
테이블 컬럼 변경 쿼리는 다음과 같습니다.
ALTER TABLE
DBTable_TBL
ALTER COLUMN
CharacterName varchar(50)
COLLATE
Thai_CI_AS

그리고 만약 위에 CharacterName가 인덱싱이 되어있다면, 인덱싱을 제거하고 collate작업을 한 후 다시 생성해줘야 합니다.


그리고 주의할 점은 만약에 내가 AAAA_DBF라는 데이터 베이스에서 BBBB_DBF라는 데이터베이스 CCCC_TBL테이블의 데이터를 조회했을 때,
AAAA_DBF데이터베이스 COLLATE과 BBBB_DBF 데이터베이스 COLLATE가 다르다면, CCCC_TBL테이블의 스트링이 깨져서 출력될 수 있습니다.
(BBBB_DBF와 CCCC_TBL테이블의 컬럼은 같은 Collation)
USE [AAAA_DBF]
SELECT * FROM BBBB_DBF.dbo.CCCC_TBL WHERE m_szName = 'พูริคอง';

USE [BBBB_DBF]
SELECT * FROM BBBB_DBF.dbo.CCCC_TBL WHERE m_szName = 'พูริคอง';

이 두가지 조회 쿼리의 결과가 달라질 수 있습니다.
저는 AAAA_DBF가 Korean_Wansung_CI_AS이고,  BBBB_DBF가 Thai_CI_AS일 때, 조회된 m_szName이 ????로 깨져 나왔습니다.
AAAA_DBF를 Thai_CI_AS로 변경해서 해결했습니다.

반응형
반응형
 

데이터들은 한 그룹으로 모아서 관리할때 배열을 만들거나 컬렉션을 만들어서 관리를 하게됩니다.

하지만 배열은 초기에 데이터크기를 정해서 사용해야하기때문에 유동성있게 데이터를 추가/삭제가 편리하게 구성되어있는 컬렉션을 사용할 수 있습니다.

컬렉션은 System.Collections.Generic 네임스페이스의 using하여 사용할수있습니다.

컬렉션 종류
Dictionary<TKey,TValue>키에 따라 구성된 키/값 쌍의 컬렉션을 나타냅니다.
List<T>인덱스로 액세스할 수 있는 개체 목록을 나타냅니다. 목록의 검색, 정렬 및 수정에 사용할 수 있는 메서드를 제공합니다.
Queue<T>FIFO(선입선출) 방식의 개체 컬렉션을 나타냅니다.
SortedList<TKey,TValue>연관된 IComparer<T> 구현을 기반으로 키에 따라 정렬된 키/값 쌍의 컬렉션을 나타냅니다.
Stack<T>LIFO(후입선출) 방식의 개체 컬렉션을 나타냅니다.
ArrayList필요에 따라 크기가 동적으로 증가하는 개체 배열을 나타냅니다.
Hashtable키의 해시 코드에 따라 구성된 키/값 쌍의 컬렉션을 나타냅니다.
QueueFIFO(선입선출) 방식의 개체 컬렉션을 나타냅니다.
StackLIFO(후입선출) 방식의 개체 컬렉션을 나타냅니다.
반응형

'개발공부 > C#' 카테고리의 다른 글

[C#] 스레드 동기화(Lock, Monitor)  (0) 2019.11.05
[C#] 스레드(Thread)  (0) 2019.11.04
C# 인터페이스(interface)  (0) 2019.10.30
[C#] 배열(Array)  (0) 2019.10.29
[C#] String.Format  (0) 2019.10.28
반응형
인터페이스는 클래스와 비슷하지만, 메서드, 이벤트, 인덱서, 속성을 클래스에서 가질 수 있는 기능들을 정의하지만, 구현은 하지않습니다.
 
구현을 인터페이스를 갖는 클래스에서 반드시 해야합니다.
이렇게 쓰는 이유는 인터페이스 하나만으로 내가 구현부를 알지못해도 사용이 가능하도록 하고, 
이런 기능들이 클래스에서 꼭 사용되야한다고 명시한다고 볼 수도 있습니다.
 
추상 base 클래스와 매우 유사하지만, 클래스는 다중상속을 지원하지 않지만 인터페이스는 다중상속을 지원합니다
또한 구조체는 다른 구조체나 클래스를 상속할 수 없지만 인터페이스는 지원합니다.
 
형식
public interfase 인터페이스명
{
int 메서드이름();
}
 
구현
인터페이스를 갖는 클래스의 경우 인터페이스에서 정의한 메서드등을 반드시 구현해야합니다.
public interface IAAAA
{
void print();
}
 
public class BBBB : IAAAA
{
public void print()
{
Console.WriteLine("print()");
}
}
 

 

인터페이스는 클래스와 비슷하지만, 메서드, 이벤트, 인덱서, 속성을 클래스에서 가질 수 있는 기능들을 정의하지만, 구현은 하지 않습니다.

구현을 인터페이스를 갖는 클래스에서 반드시 해야합니다.
이렇게 쓰는 이유는 인터페이스 하나만으로 내가 구현부를 알지 못해도 사용이 가능하도록 하고, 
이런 기능들이 클래스에서 꼭 사용되야한다고 명시한다고 볼 수도 있습니다.

추상 base 클래스와 매우 유사하지만, 클래스는 다중상속을 지원하지 않지만 인터페이스는 다중 상속을 지원합니다
또한 구조체는 다른 구조체나 클래스를 상속할 수 없지만 인터페이스는 지원합니다.

형식
public interfase 인터페이스명
{
int 메서드이름();
}

구현
인터페이스를 갖는 클래스의 경우 인터페이스에서 정의한 메서드 등을 반드시 구현해야 합니다.
public interface IAAAA
{
void print();
}

public class BBBB : IAAAA
{
public void print()
{
Console.WriteLine("print()");
}
}


인터페이스로 정의를 하면 인터페이스 맴버만 접근이 가능합니다.

public interface IAAAA
{
void print();
}

public class BBBB : IAAAA
{
public void print()
{
Console.WriteLine("print()");
}

public void print2()
{
Console.WriteLine("print()2");
}
}

static void Main(string[] args)
{
IAAAA B1 = new BBBB();
B1.print();
//B1.print2();
}

B1.print2();가 접근이 불가능합니다.

접근이 가능하려면 
IAAAA B1 = new BBBB(); 이 부분을 BBBB B1 = new BBBB(); 이렇게 수정하면 됩니다.

반응형

'개발공부 > C#' 카테고리의 다른 글

[C#] 스레드(Thread)  (0) 2019.11.04
[C#]컬렉션(Collections)  (0) 2019.10.31
[C#] 배열(Array)  (0) 2019.10.29
[C#] String.Format  (0) 2019.10.28
[C#] #region  (0) 2019.10.27
반응형

배열
형식이 동일한 변수를 여러개 저장이 가능하도록 모아놓은 데이터 집합입니다.

형식
type[] arrayName;

속성
- 1차원, 혹은 다차원 또는 가변으로 만들 수 있습니다.
- 차원 수와 각 차원 길이는 배열 인스턴스를 만들 때 설정되는데, 인스턴스 수명동안 변경이 불가능합니다.
- 숫자(int형) 배열 요소의 기본값은 0으로 설정되고, 참조 요소는 null로 설정됩니다.
- 가변 배열은 요소들이 참조형식이며, null로 초기화됩니다.
- 배열은 0으로 인덱싱되고, 요소들은 0~n-1로 인덱싱됩니다.
- 배열 형식은 Array 추상 기본 형식에서 파생된 참조 형식입니다. 이 형식은 IEnumerable 및 IEnumerable을 구현하므로 foreach반복을 사용할 수 있습니다.


1차원 배열

다음과 같이 선언할 수 있습니다.
int[] arrayName = new int[10]

배열 선언 시 배열 초기값을 설정은 다음과 같이 할 수 있습니다.
int[] arrayName = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

다음과 같이 초기화 하지 않고 배열을 선언하고 배열을 할당할 때 값을 설정할 수도 있습니다.
int[] arrayName;
arrayName = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

특정 배열요소에 접근할때에는 인덱스로 접근합니다.
예를들어, 위에 arrayName에 5값을 접근하려면 arrayName[4]로 접근할 수 있습니다.


다차원 배열

2차원 배열은 다음과 같이 선언할 수 있습니다.
int[,] arrayName = new int[5, 2];

3차원 배열은 다음과 같이 선언할 수 있습니다.
int[, ,] = arrayName = new int [5, 2, 4];

초기화는 다음과 같이 할 수 있습니다.
int[,] array2 = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 }, { 9, 10 } }; 

int[,] array2a = new int[5,2] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 }, { 9, 10 } };

int[,] array2b =  { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 }, { 9, 10 } };

특정 배열요소로의 접근은 다음과 같이 할 수 있습니다.
array2[2, 1] = 9;
array2a[2, 1] = 9;
arraarray2b[2, 1] = 9;

가변 배열

가변 배열의 요소들은 차원과 크기가 다를 수 있습니다.

다음과 같이 선언해서 설정합니다.

int[][] arrayName = new int [2][];
arrayName[0] = new int[4];
arrayName[1] = new int[2];

초기값을 넣어서 값을 채울 수 있습니다.
int[][] arrayName = new int [2][];
arrayName[0] = new int[] { 1, 2, 3, 4 };
arrayName[1] = new int[] { 5, 6 };

다음과 같이 선언시에 초기화할 수도 있습니다.
int[][] arrayName = new int [][]
{
    new int[] { 1, 2, 3, 4 },
    new int[] { 5, 6 }
};

new int[][]를 다음과 같이 생략할 수 있습니다.
int[][] arrayName = 
{
    new int[] { 1, 2, 3, 4 },
    new int[] { 5, 6 }
};

배열 요소에 접근하려면 다음과 같이 하면됩니다.
arrayName[0][1] = 5;

서로 다른 크기의 세가지 2차원 배열을 만들 수 도있습니다.
int[][,] arrayName = new int[3][,]
{
    new int[,] { {1, 2}, {3, 4} },
    new int[,] { {5, 6}, {7, 8}, {9, 10} },
    new int[,] { {11, 12}, {13, 14}, {15, 16}, {17, 18} }
};
Console.WriteLine(arrayName[2][1, 0]);
출력:13

Length를 이용해서 가변 배열에 포함된 배열수를 알 수 있습니다.
Console.WriteLine(arrayName.Length);
이렇게 한다면 3이 출력됩니다.

Length를 이용해서 가변값을 다음과 같이 출력할 수 있습니다.

int[][] arrayName = new int[][]
{
    new int[] { 1, 2, 3, 4 },
    new int[] { 5, 6 }
};

for (int i = 0; i < arrayName.Length; i++)
{
    for ( int j = 0; j < arrayName[i].Length; j++ )
        Console.Write("{0} ", arrayName[i][j]);
        System.Console.WriteLine();
}


foreach 사용
foreach문을 사용하여 배열의 데이터를 가져올 수 있습니다.

다음과 같이 사용할 수 있습니다.
int[] arrayName = new int[]{1,2,3,4,5};

foreach (int i in arrayName)
    Console.Write("{0} ", i);

배열을 인수로 전달

배열을 함수 인수로 전달할 수 있습니다.
int[] arrayName = new int[]{1,2,3,4,5};
printArray(arrayName);

static void printArray(int[] arr)
{
    foreach(int i in arr)
    Console.Write("{0} ", i);
}

반응형

'개발공부 > C#' 카테고리의 다른 글

[C#]컬렉션(Collections)  (0) 2019.10.31
C# 인터페이스(interface)  (0) 2019.10.30
[C#] String.Format  (0) 2019.10.28
[C#] #region  (0) 2019.10.27
[C#] 익명 타입(Anonymous Types)  (0) 2019.10.23
반응형

문자열을 나타낼 때 String에 데이터를 넣고 사용할 수 있습니다.
다양한 형태로 사용하려면 String의 Format함수를 이용합니다.

다음과 같이 사용할 수 있습니다.
String str;
str = String.Format("{0}", 1);
Console.WriteLine(str);
출력 : 1

두 개의 항목을 스트링에 넣으려면 {1}을 추가하면 됩니다.
String str;
str = String.Format("{0}, {1}", 1, 7);
Console.WriteLine(str);
출력 : 1, 7

서식으로도 넣을 수 있습니다.
String str;
str = String.Format("{0:D5}", 7);
Console.WriteLine(str);
출력:00007
D5같이 해당 항목에 서식으로 넣을 수 있게됩니다.
다음과 같은 서식이 있습니다.
"C" 또는 "c" - 통화형식 언어가 우리나라로 지정되어있을 경우 '\'가 앞에 붙어서 표기됩니다.
"D" 또는 "d" - 정수형식 1234을 D로 했을 경우 1234, D5로 했을 경우 01234로 표기됩니다.
"E" 또는 "e" - 지수형식 12345.6789691226 E로 했을 경우 1.234568E+004, e로 했을 경우 1.234568e+004로 표기됩니다. 또한 E2는 1.23E+004로 표기됩니다.
"F" 또는 "f" - 고정소수점형식 1234.567를 F로 했을 경우 1234.56, 1234.56을 F4로 했을 경우 1234.5600로 표기됩니다.
"G" 또는 "g" - 모든 숫자 형식 12345.6789를 G로 지정하면 12345.6789로 표기되지만, G2하면 1.2E+04로 표기가 됩니다.
"N" 또는 "n" - 자릿수를 지정합니다. 1234.567을 N으로 지정하면 1,234.567로 표기되고, N4로 지정하면 1,234.5670으로 표기됩니다.
"P" 또는 "p" - 100으로 곱하고 백분율 기호와 함께 표시합니다. 1을 P로 지정하면 100%로 표기됩니다.
"R" 또는 "r" - 해당 숫자로 라운드트립할 수 있는 문자. BigInteger형식에만 권장됩니다. 
"X" 또는 "x" -  16진수 형식. 10을 X로 지정하면 A로 표기됩니다.

간격을 제어할 수 있습니다.
String str;
str = String.Format("{0,10} {1,5}", 10, 2);
Console.WriteLine(str);

반응형

'개발공부 > C#' 카테고리의 다른 글

C# 인터페이스(interface)  (0) 2019.10.30
[C#] 배열(Array)  (0) 2019.10.29
[C#] #region  (0) 2019.10.27
[C#] 익명 타입(Anonymous Types)  (0) 2019.10.23
[C#] Action, Func  (0) 2019.10.22
반응형
안녕하세요

오늘은 스크립트를 보기좋게 단락별로 구분할 수 있는 "#region"에 대해서 알아보도록 하겠습니다.

코드가 몇천줄만 넘어도 코드가 한눈에 들어오기가 어렵게되는데 이럴때 유용하게 사용할수 있습니다.

코드가 어떤코드인지 제목을 넣을수 있고 현재 작업중인 코드에 집중하기 위해 영역을 축소하거나 숨길수 있습니다.

형식
#region 제목
내용
#endregion

예제
#region class AAA
public class AAA
{
     int nNum;
}
#endregion

이렇게 간단하게 사용할 수 있습니다.
반응형

'개발공부 > C#' 카테고리의 다른 글

[C#] 배열(Array)  (0) 2019.10.29
[C#] String.Format  (0) 2019.10.28
[C#] 익명 타입(Anonymous Types)  (0) 2019.10.23
[C#] Action, Func  (0) 2019.10.22
[C#] 람다식(Lambda expressions)  (0) 2019.10.21
반응형

이 글과 관련된 글입니다.

[Unity] 해상도에 따른 UI 위치 변경

 

안녕하세요.

 

개발을 하다 보면 핸드폰마다 해상도가 달라서 곤란한 경우가 자주 있습니다.

 

지금 출시된 모든 휴대폰을 다 확인이 불가능하기 때문에 간단하게 해상도를 설정하는 방법에 대해 알아보도록 하겠습니다.

 

일단 현재 나와있는 폰들의 해상도를 알아보도록 하겠습니다.

 

구글에서 "휴대폰 해상도"라고 검색을 하면 휴대폰 해상도에 대한 정보들이 나와있는 것을 볼 수 있습니다.

 

그중에서 다음 사이트에 보면 잘 정리가 되어있습니다.

 

https://zetawiki.com/wiki/%EC%8A%A4%EB%A7%88%ED%8A%B8%ED%8F%B0_%ED%95%B4%EC%83%81%EB%8F%84,_%ED%99%94%EB%A9%B4%EB%B9%84%EC%9C%A8

 

스마트폰 해상도, 화면비율 - 제타위키

9:16 ★★★ 1440 × 2560(갤6, 갤7, 갤노4, 갤노5, G3, G4, G5, 픽셀XL)1080 × 1920(갤4, 갤5, 갤노3, 옵G프로, G2, 넥5, 아이폰6, 픽셀)

zetawiki.com

스마트폰은 16:9가 많이 있는 것을 확인해 볼 수 있어서 앱 개발 시 16:9를 기준으로 개발하는 것이 좋을 것 같습니다.

 

그러나 기타 해상도가 다른 휴대폰들은 화면에 UI가 이상한 곳으로 이동되는 현상이 발생할 수 있습니다.

 

유니티 에디터 상에서 해상 해상도를 설정하는 방법은 게임 탭에서 해당 해상도를 추가하는 방법입니다.

 

 

추가해서 해당 해상도로 설정을 하면 문제와 생긴 기기와 같은 화면을 볼 수 있습니다.

 

그리고, 기기 해상도를 완벽히 다 호환하기는 어렵지만 Canvas Object에서 "Canvas Scaler" Componect를 수정하면 됩니다.

 

 

잠시 설정에 대한 설명을 하면,

 

UI Scale Mode - 캔버스에 UI 요소들이 스케일링되는 방법을 결정하게 됩니다.

   Constant Pixel Size - 화면 크기에 관계없이 동일한 픽셀 크기를 유지합니다.

   Scale With Screen Size - 화면이 커질수록 UI 요소도 커집니다.

   Constant Physical Size - 화면 크기와 해상도에 관계없이 UI 요소가 동일한 물리적인 크기로 유지됩니다.

 

여기서 "Scale With Screen Size"를 설정해서 해상도에 맞춰서 기준 해상도를 Referance Resolution을 정한 후

"Match Widh Or Heght"로 해상도에 따라 스케일을 변경할 수 있습니다.

만약 위에 같이 X 2560, Y 1440으로 설정을 했다면 Match를 0.5로 했을 경우 그에 따라 전제 스케일이 변하게 되고,

만약 X가 변경되지 않게 하려면 Match를 0, Y이 변경이 되지 않게 하려면 Match를 1로 하면 된다.

 

세부 설정은 유니티 매뉴얼을 참조하시면 됩니다.

https://docs.unity3d.com/kr/current/Manual/script-CanvasScaler.html

 

캔버스 스케일러 - Unity 매뉴얼

캔버스 스케일러(Canvas Scaler) 컴포넌트는 캔버스 내 UI 요소의 전체적인 스케일과 픽셀 밀도를 제어하는 데 사용됩니다. 스케일은 글꼴 크기와 이미지 경계 등 캔버스 아래의 모든 요소에 영향을 미칩니다.

docs.unity3d.com

 

반응형

+ Recent posts