이번에는 Unity 프로젝트에 Unity Ads를 연동해보겠습니다. (매우 간단 주의)



우선 Unity에서 [Window -> Services] 하면 인스펙터 뷰 옆에 아래와 같은 화면이 나타나는데


Ads 항목이 OFF(디폴트)로 되어있는 것을 볼 수 있습니다.





Ads 항목을 클릭하면 아래와 같이 나오는데


토글 버튼을 눌러 비활성화되어있는 Ads를 활성화 시킵니다.





13세 미만 아이들에게 지도감독이 필요한 앱인지 여부를 설정하고 Continue 합니다.





활성화가 완료되면 아래와 같이 나옵니다.


원하는 Platform을 체크합니다.


Enable test mode를 체크하면 유니티에서 제공하는 짧은 테스트 광고영상만 송출됩니다.


(런칭 시 반드시 위 항목 체크를 해제할 것)





여기까지 완료했다면, 


using UnityEngine.Advertisements; 


를 할수있게 됩니다!


UnityAdsHelper라는 C# 스크립트를 하나 생성하고


아래의 코드를 복사해서 붙여 넣습니다.


그 다음, 빈 게임 오브젝트를 하나 생성하고 UnityAdsHelper.cs를 AddComponent 해줍니다.



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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
using UnityEngine;
using UnityEngine.Advertisements;
 
public class UnityAdsHelper : MonoBehaviour
{
    private const string android_game_id = "xxxxxxx";
    private const string ios_game_id = "xxxxxxx";
 
    private const string rewarded_video_id = "rewardedVideo";
 
    void Start()
    {
        Initialize();
    }
 
    private void Initialize()
    {
#if UNITY_ANDROID
        Advertisement.Initialize(android_game_id);
#elif UNITY_IOS
        Advertisement.Initialize(ios_game_id);
#endif
    }
 
    public void ShowRewardedAd()
    {
        if (Advertisement.IsReady(rewarded_video_id))
        {
            var options = new ShowOptions { resultCallback = HandleShowResult };
 
            Advertisement.Show(rewarded_video_id, options);
        }
    }
 
    private void HandleShowResult(ShowResult result)
    {
        switch (result)
        {
            case ShowResult.Finished:
                {
                    Debug.Log("The ad was successfully shown.");
 
             // to do ...
             // 광고 시청이 완료되었을 때 처리
 
                    break;
                }
            case ShowResult.Skipped:
                {
                    Debug.Log("The ad was skipped before reaching the end.");
 
             // to do ...
             // 광고가 스킵되었을 때 처리
 
                    break;
                }
            case ShowResult.Failed:
                {
                    Debug.LogError("The ad failed to be shown.");
 
             // to do ...
             // 광고 시청에 실패했을 때 처리
 
                    break;
                }
        }
    }
}
 
cs



위 코드는


ShowRewardedAd() 함수로 비디오 광고 송출 요청을 하고


HandleShowResult 콜백으로 요청 결과에 따라 Finished, Skipped, Failed 처리하는 구조로 되어있습니다.


* 여기서 androiod game id와 ios game id 그리고 rewarded video id가 필요한데


Services의 우측 상단에 있는 Go to Dashboard 를 누르면





아래와 같은 화면이 뜨는데


여기서 android 게임 ID와 ios 게임 ID를 확인할 수 있습니다.





UnityAdsHelper.cs의 android_game_id 변수와 ios_game_id 변수에 Game Id 숫자 7자리를 각각 넣어주시면 됩니다.


그 다음, 구글 플레이 스토어 또는 애플 앱 스토어 플랫폼을 클릭하여 Ad placements 정보를 확인합니다.





기본적으로 Video와 Rewarded Video 두 가지가 생성되어있는데


첫 번째에 있는 Video는 Skip이 가능한 광고이고


두 번째에 있는 Rewarded Video는 Skip이 불가능한 보상형 광고입니다. 


수익을 많이 내려면 당연히 Skip이 불가능한 보상형 광고를 써야겠죠?


위 스크린샷 처럼 Rewarded Video를 Enabled 하고 Default로 설정합니다. (우측에 EDIT 버튼으로 세부설정이 가능함)


그리고 Rewarded Video의 PLACEMENT ID를 복사하여


UnityAdsHelper.cs의 rewarded_video_id 변수에 넣어줍니다.



----------------------------------------------------------------------------------



자, 모든 준비가 끝났습니다!


Unity Editor에서 ShowRewardedAd()로 광고를 요청했을 때 아래와 같은 화면이 나온다면


정상적으로 연동된 것입니다.





이제 원하는 상황에 ShowRewardedAd() 함수를 호출하고 (주로 게임 오버될 때 혹은 특정 버프를 받을 때)


HandleShowResult 콜백에서 원하는 처리를 하여 마무리해줍니다. (캐릭터 부활 혹은 버프효과 적용 등)





Fab Lab Seoul과 서울 디자인재단 주최로 진행된 [2016 패션웨어러블 메이커톤]에 

개발자로 참가했었습니다.

옷에 달린 단추를 누르거나 소매에 달린 슬라이더를 조절하여 

스마트폰 뮤직플레이어를 컨트롤하는 웨어러블 디바이스를 개발하는 것이 저희 팀의 목표였고

옷과 스마트폰의 사이에 블루투스 통신할 수 있는 뮤직플레이어 App을 만드는 것이 제 역할이였습니다.



여기서 

▶MAKE A THON 이란? 

의상 제작이 가능한 패션 디자이너와 기획자, 개발자, 2D/3D 디자이너 등 다양한 분야의 메이커들이 팀을 이루어 사전행사와 무박2일의 본행사동안 “패션 웨어러블”을 주제로 Ideation부터 Prototyping 까지 진행하는 메이킹 마라톤입니다.



제가 만든 간단한 뮤직플레이어 App을 소개해드리겠습니다!



Unity3D로

 - 플레이리스트

 - 음악 재생/정지

 - 볼륨 조절

 - 재생 위치 조절


등의 기능이 구현된 간단한 뮤직플레이어를 만들었는데요.

그 중에, 현재 재생되고 있는 음악의 강약을 옷에 달린 LED에 그대로 표현해주기 위해 비쥬얼라이저를 구현했습니다.

화면 가운데에는 PointLight가 있고 하단에는 막대 그래프가 있는데

영상에서 보이는 것 처럼 재생 중인 음악의 세기에 따라 PointLight의 밝기가 반응하고 하단의 막대그래프도 요동치게끔 하였습니다.


이처럼 AudioListener.GetOutputData() 함수를 이용하면 사운드 비쥬얼라이저를 쉽게 구현할 수 있습니다.


https://docs.unity3d.com/ScriptReference/AudioListener.GetOutputData.html



아래는 코드의 일부입니다.



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
using UnityEngine;
using System.Collections.Generic;
 
public class Visualizer : MonoBehaviour
{
    public List<UISprite> target_sprites;
 
    public Light pointLight;
 
    public int detail;
    public float amplitude;
    public float intensityFactor;
 
    private float baseIntensity = 0.1f;
 
    void Update()
    {
        GetOutputData();
    }
 
    private void GetOutputData()
    {
        float[] data = new float[detail];
        float packagedData = 0.0f;
 
        AudioListener.GetOutputData(data, 0);
 
        for (int i = 0; i < data.Length; ++i)
        {
            packagedData += Mathf.Abs(data[i]);
        }
 
        float resultHeight = packagedData * amplitude;
        float resultIntensity = baseIntensity + packagedData * amplitude;
 
        for (int i = 0; i < target_sprites.Count; ++i)
        {
            target_sprites[i].height = (int)(resultHeight * ((i + 1* 0.4f));
        }
 
        pointLight.intensity = (baseIntensity + packagedData) / (detail / intensityFactor);
    }
 
}
cs


여기서 target_sprites 는 아래의 5개 막대를 담은 변수이고

AudioListner.GetOutputData()로 추출된 데이터(packagedData)를 통해 막대그래프의 height와 PointLight의 밝기를 조절하는 코드입니다.




아래는 메이커톤 당시 시연영상입니다~



영상 초중반 부는 팀원의 프로젝터 맵핑 연출이고 후반부 조금은 음악에 LED가 반응하는 모습을 짧게! 볼 수 있습니다.

시연 영상을 제대로 찍지 못해서 아쉬움이 많이 남네요 ㅠㅠ




1
2
3
4
5
6
7
8
9
10
11
12
13
14
    public static DateTime JavaToCSharpUTC(long javaLong)
    {
        DateTime Jan1st1970 = new DateTime(197011000, DateTimeKind.Utc);
        DateTime result = Jan1st1970.AddMilliseconds(javaLong).ToUniversalTime();
 
        return result;
    }
 
    public static long CSharpToJavaUTC(long ticks)
    {
        DateTime Jan1st1970 = new DateTime(197011000, DateTimeKind.Utc);
 
        return ticks - Jan1st1970.Ticks;
    }
cs



'02.Development > C#' 카테고리의 다른 글

[C#] 숫자 문자열에 컴마(,) 찍기  (0) 2016.02.12
[C#] List, Array 셔플  (0) 2016.02.04

● 옵저버 패턴 (Observer Pattern)

 - 한 객체(Subject)의 상태가 바뀌면 그 객체에 의존하는 모든 객체들(Observers)에 알린 후(Notify) 자동으로 내용이 갱신(Update)되는 방식

 - 일대다(one-to-many) 의존성을 정의함

 - MVC 패턴의 View에 해당하는 부분에서 많이 나타날 수 있음 

 - 한 객체의 상태에 대한 참조를 여러 곳에서 하고 있을 때 주로 사용 될 수 있음

 - 때문에, 한 객체의 상태에 대한 일관성이 보장됨



 UML Diagram - Observer Pattern



아주 간단한 예를 들면, (아래의 스크린 샷은 페인트히어로즈의 히어로 선택창스킬 정보창입니다.)

페인트히어로즈에서 현재 선택된 히어로(Subject)가 무엇인지에 따라


이를 의존하고 있던 스킬 정보창의 UI 요소들(Observers - 스킬 이름, 스킬 설명, 스킬 레벨, 스킬 아이콘 등...)이

자동으로 현재 선택된 히어로에 대한 내용으로 갱신되어 유저에게 보여지는 것도 Observer Pattern이 사용될 수 있습니다.




- Source Code

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Subject.cs
using System.Collections.Generic;
 
public class Subject 
{
    private List<Observer> observerList = new List<Observer>();
 
    public void Attach (Observer o)
    {
        observerList.Add(o);
    }
 
    public void Notify ()
    {
        foreach (Observer o in observerList)
        {
            o.Update();
        }
    }
}
 
 
// SbjHero.cs
public class SbjHero : Subject
{
    private string _heroName;
    private string _heroSkillName;
 
    public string heroName
    {
        get { return _heroName; }
        set { _heroName = value; }
    }
 
    public string heroSkillName
    {
        get { return _heroSkillName; }
        set { _heroSkillName = value; }
    }
}
 
 
// Observer.cs
public abstract class Observer
{
    public abstract void Update ();
}
 
 
// ObsHeroName.cs
using UnityEngine;
 
public class ObsHeroName : Observer 
{
    private SbjHero sbjHero;
 
    public ObsHeroName (SbjHero sbj)
    {
        sbjHero = sbj;
    }
 
    public override void Update ()
    {
        Debug.Log("current hero name : " + sbjHero.heroName);
    }
}
 
 
// ObsHeroSkill.cs
using UnityEngine;
 
public class ObsHeroSkill : Observer 
{
    private SbjHero sbjHero;
 
    public ObsHeroSkill (SbjHero sbj)
    {
        sbjHero = sbj;
    }
 
    public override void Update ()
    {
        Debug.Log("current hero skill name : " + sbjHero.heroSkillName);
    }
}
 
 
// Game.cs
using UnityEngine;
using System.Collections;
 
public class Game : MonoBehaviour 
{
    void Start ()
    {
        SbjHero h = new SbjHero();
 
        h.Attach(new ObsHeroName(h));
        h.Attach(new ObsHeroSkill(h));
 
        // change subject state and notify observers
        h.heroName = "Lucian";
        h.heroSkillName = "Charging Shot";
        h.Notify();
 
        // result
        // current hero name : Lucian
        // current hero skill name : Charging Shot
    }
}
cs


Generic Singleton 패턴 (유니티) 소스코드 입니다.

 - 유니티 app이 종료될 때, 무작위 순서로 오브젝트들이 destroy 됩니다. 
   대체적으로 싱글턴 객체는 app이 종료될 때에만 destroy 되게끔 코딩하는데, 
   OnApplicationQuit에서 싱글턴 객체가 이미 destroy 된 이후에 다른 스크립트에서의 싱글턴 객체 참조를 막기 위해 appIsQuitting 변수를 추가했고
   get부분의 안정성을 위해 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
51
52
53
54
55
56
57
58
59
60
61
62
63
// Singleton<T>.cs
using UnityEngine;
using System.Collections;
 
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T _singleton;
 
    private static object _lock = new object();
 
    private static bool appIsQuitting = false;
 
    public static T singleton
    {
        get
        {
            if (appIsQuitting)
            {
                Debug.LogError("[Singleton<" + typeof(T).ToString() + ">] : " +
                                "already destroyed on application quit");
 
                return null;
            }
 
            lock (_lock)
            {
                if (_singleton == null)
                {
                    _singleton = FindObjectOfType<T>();
 
                    if (FindObjectsOfType(typeof(T)).Length > 1)
                    {
                        Debug.LogError("[Singleton<" + typeof(T).ToString() + ">] : " +
                                        "singleton instance is duplicated");
 
                        return _singleton;
                    }
 
                    if (_singleton == null)
                    {
                        GameObject go = new GameObject();
                        _singleton = go.AddComponent<T>();
                        _singleton.name = typeof(T).ToString();
 
                        DontDestroyOnLoad(_singleton);
                    }
                }
 
                return _singleton;
            }
        }
    }
 
    public virtual void OnApplicationQuit ()
    {
        appIsQuitting = true;
 
        _singleton = null;
    }
 
}
 
 
cs

Singleton 클래스를 'T myClass = new T();' 와 같이 생성자 호출을 통해 생성하는 것을 막으려면
아래처럼 생성자에 protected 지시자를 붙여 주세요.

1
2
3
4
5
6
7
8
// Example - GameManager.cs
public class GameManager : Singleton<GameManager> 
{
    protected GameManager ()
    {
        // guarentee this object will be always a singleton only - can not use the constructor
    }
}
cs

사용 예시

1
2
3
4
5
6
7
8
9
10
11
// Example - Main.cs
using UnityEngine;
using System.Collections;
 
public class Main : MonoBehaviour 
{
    void Awake ()
    {
        Debug.Log(GameManager.singleton.GetType().ToString());
    }
}
cs



'02.Development > Design Pattern' 카테고리의 다른 글

[DesignPattern] Observer Pattern (C#)  (0) 2016.03.15
디바이스의 시스템 언어 정보를 가져오는 간단한 방법!

Application.systemLanguage



다국어 지원(Localization) 할 때 유용하게 사용하세요!


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
51
52
53
54
55
56
57
58
59
60
61
62
    public enum SystemLanguage
    {
        Afrikaans = 0,
        Arabic = 1,
        Basque = 2,
        Belarusian = 3,
        Bulgarian = 4,
        Catalan = 5,
        Chinese = 6,
        Czech = 7,
        Danish = 8,
        Dutch = 9,
        English = 10,
        Estonian = 11,
        Faroese = 12,
        Finnish = 13,
        French = 14,
        German = 15,
        Greek = 16,
        Hebrew = 17,
        Hungarian = 18,
        Hugarian = 18,
        Icelandic = 19,
        Indonesian = 20,
        Italian = 21,
        Japanese = 22,
        Korean = 23,
        Latvian = 24,
        Lithuanian = 25,
        Norwegian = 26,
        Polish = 27,
        Portuguese = 28,
        Romanian = 29,
        Russian = 30,
        SerboCroatian = 31,
        Slovak = 32,
        Slovenian = 33,
        Spanish = 34,
        Swedish = 35,
        Thai = 36,
        Turkish = 37,
        Ukrainian = 38,
        Vietnamese = 39,
        Unknown = 40,
    }
    
 
    // 예시
 
    SystemLanguage sl = Application.systemLanguage;
    
    switch (sl)
    {
        // to do ...
    }
    
    // 또는
        
    switch (sl.ToString())
    {
        // to do ...
    }
cs


돈 표기처럼, 
숫자 문자열에 컴마를 찍어서 출력하는 방법은 정말 간단합니다. 

ToString("n0") 


하세요!


1
2
3
4
5
6
7
8
9
10
public static string InsertComma (int n)
{
    return n.ToString("n0");
}
 
int n = 1234567;
 
Console.WriteLine(string.Format("{0}", InsertComma(n)));
 
// 출력결과 : 1,234,567
cs



'02.Development > C#' 카테고리의 다른 글

[C#] Convert C# to Java, Java to C# - UTC  (0) 2016.07.07
[C#] List, Array 셔플  (0) 2016.02.04


ObjectPoolSample.unitypackage


모바일 프로젝트의 필수요소인 오브젝트 풀,

구글링하여 찾은 C# 소스를 기반으로 유니티에서 재사용 가능하도록 제작해보았습니다.

이를 활용한, 총에서 불렛을 발사하는 예제도 함께 첨부했습니다.


( ObjectPool<T>.cs, PoolableObject.cs, ObjectPoolManager.cs, Gun.cs, Bullet.cs )



풀링할 객체는 모두 PoolableObject 클래스를 상속받아서 사용하시면 됩니다.


ObjectPool<T>.cs의

 - objStack : 비활성화 된 object들을 담고있는 Stack (풀)

 - objList : 활성화 된 object들을 담고있는 List (참조용)


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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
// ObjectPool<T>.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
 
public class ObjectPool<T> where T : PoolableObject
{
    private int allocateCount;
 
    public delegate T Initializer ();
    private Initializer initializer;
 
    private Stack<T> objStack;
    public List<T> objList;
 
    public ObjectPool ()
    {
        // default constructor
    }
 
 
    public ObjectPool (int ac, Initializer fn)
    {
        this.allocateCount = ac;
        this.initializer = fn;
        this.objStack = new Stack<T>();
        this.objList = new List<T>();
    }
 
    public void Allocate ()
    {
        for (int index = 0; index < this.allocateCount; ++index)
        {
            this.objStack.Push(this.initializer());
        }
    }
 
    public T PopObject ()
    {
        if (this.objStack.Count <= 0)
        {
            Allocate();
        }
 
        T obj = this.objStack.Pop();
        this.objList.Add(obj);
 
        obj.gameObject.SetActive(true);
 
        return obj;
    }
 
    public void PushObject (T obj)
    {
        obj.gameObject.SetActive(false);
 
        this.objList.Remove(obj);
        this.objStack.Push(obj);
    }
 
    public void Dispose ()
    {
        if (this.objStack == null || this.objList == null)
            return;
 
        this.objList.ForEach(obj => this.objStack.Push(obj));
 
        while (this.objStack.Count > 0)
        {
            GameObject.Destroy(this.objStack.Pop());
        }
 
        this.objList.Clear();
        this.objStack.Clear();
    }
    
 
 
// PoolableObject.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
 
public class PoolableObject : MonoBehaviour 
{
    protected ObjectPool<PoolableObject> pPool;
 
    public virtual void Create (ObjectPool<PoolableObject> pool)
    {
        pPool = pool;
 
        gameObject.SetActive(false);
    }
    
    public virtual void Dispose ()
    {
        pPool.PushObject(this);
    }
 
    public virtual void _OnEnableContents ()
    {
        // to do ...
    }
    
    public virtual void _OnDisableContents ()
    {
        // to do ...
    }
 
 
 
// ObjectPoolManager.cs
using UnityEngine;
using System.Collections;
 
public class ObjectPoolManager : MonoBehaviour 
{
    private static ObjectPoolManager singleton;
    public static ObjectPoolManager GetInstance () { return singleton; }
 
    public ObjectPool<PoolableObject> bulletPool = new ObjectPool<PoolableObject>();
    
    public Bullet bulletPrefab;
 
    void Awake ()
    {
        if (singleton != null && singleton != this)
        {
            Destroy(gameObject);
        }
        else 
        {
            singleton = this;
        }
    }
 
    void Start ()
    {
        bulletPool = new ObjectPool<PoolableObject>(5, () => 
        {
            Bullet bullet = Instantiate(bulletPrefab);
            bullet.Create(bulletPool);
            return bullet;
        });
        
        bulletPool.Allocate();
    }
 
    void OnDestroy ()
    {
        bulletPool.Dispose();
        singleton = null;
    }
 
 
 
// Gun.cs
using UnityEngine;
using System.Collections;
 
public class Gun : MonoBehaviour 
{
    [HideInInspector] public Transform tm;
    private Vector3 bulletSpawnPoint;
 
    void Awake ()
    {
        tm = gameObject.GetComponent<Transform>();
        bulletSpawnPoint = transform.FindChild("bulletSpawnPoint").transform.position;
    }
 
    void Update ()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Bullet bullet = ObjectPoolManager.GetInstance().bulletPool.PopObject() as Bullet;
            bullet.Fire(bulletSpawnPoint);
        }
    }
 
 
 
// Bullet.cs
using UnityEngine;
using System.Collections;
 
public class Bullet : PoolableObject
{
    [HideInInspector] public Transform tm;
    [HideInInspector] public Rigidbody2D rb2D;
 
    private float force;
 
    public override void Create (ObjectPool<PoolableObject> pool)
    {
        base.Create (pool);
    }
 
    public override void Dispose ()
    {
        base.Dispose ();
    }
 
    public override void _OnEnableContents ()
    {
        base._OnEnableContents ();
 
        rb2D.Sleep();
    }
 
    public override void _OnDisableContents ()
    {
        base._OnDisableContents ();
    }
 
    void Awake ()
    {
        tm = gameObject.GetComponent<Transform>();
        rb2D = gameObject.GetComponent<Rigidbody2D>();
 
        force = 800.0f;
    }
 
    void OnEnable ()
    {
        _OnEnableContents();
    }
 
    void OnDisable ()
    {
        _OnDisableContents();
    }
 
    void Update ()
    {
        if (tm.position.x > 10.0f)
        {
            Dispose();
        }
    }
 
    public void Fire (Vector3 spawnPoint)
    {
        tm.position = spawnPoint;
 
        rb2D.AddForce(Vector3.right * force);
    }
 
cs



1
2
3
4
5
6
7
8
9
    using UnityEngine;
 
    // return : -180 ~ 180 degree (for unity)
    public static float GetAngle (Vector3 vStart, Vector3 vEnd)
    {
        Vector3 v = vEnd - vStart;
 
        return Mathf.Atan2(v.y, v.x) * Mathf.Rad2Deg;
    }
cs



정렬되지 않은 전체 자료 중에서 해당 위치에 맞는 자료를 선택하여 위치를 교환하는 정렬 방식

같은 값의 인덱스끼리도 교환 연산이 발생하기때문에 안전성을 만족하지 않고 전체적인 알고리즘 효율성을 볼 때 느림

 

 - 시간복잡도 (Big-O notation)  


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
51
52
using System.Collections.Generic;
 
    public enum SortType
    {
        Asc,
        Desc
    }
 
    public static void SelectionSort(int[] array, SortType st)
    {
        int length = array.Length;
 
        int key;
        int tmp;
 
        if (st == SortType.Asc)
        {
            // Asc
            for (int i = 0; i < length - 1++i)
            {
                key = i;
 
                for (int j = i + 1; j < length; ++j)
                {
                    if (array[key] > array[j])
                    {
                        tmp = array[j];
                        array[j] = array[key];
                        array[key] = tmp;
                    }
                }
            }
        }
        else
        {
            // Desc
            for (int i = 0; i < length - 1++i)
            {
                key = i;
 
                for (int j = i + 1; j < length; ++j)
                {
                    if (array[key] < array[j])
                    {
                        tmp = array[j];
                        array[j] = array[key];
                        array[key] = tmp;
                    }
                }
            }
        }
    }
cs

+ Recent posts