반응형

안녕하세요.

지연실행과 관련되어, Invoke, InvokeRepeating, CancelInvoke에 대해 알아보도록 하겠습니다.

 

1. Invoke

Unity 스크립트 작업중에 함수가 일정시간만큼 지연된 후 실행이 되게 하고자 할때 Invoke함수를 사용할 수 있습니다.

Invoke함수를 모른다면 코루틴(coroutine)을 사용해서 시간 지연을 준 후 실행되게 할수있지만 단순히 시간을 지연한 후 함수를 실행 시킨다면 Invoke로 쉽게 구현할 수 있습니다.

형식
Invoke("함수명", 지연시간(초));

예제

1
2
3
4
5
6
7
8
9
10
void Start()
{
    Debug.Log("Start() Time : " + Time.time);
    Invoke("FuncInvoke"5.0f);
}
 
void FuncInvoke()
{
    Debug.Log("FuncInvoke() Time : " + Time.time);
}
 
cs

다음과 같이 출력이 됩니다.

이렇게 한다면 시작 후 5초 후 FuncInvoke함수가 호출됩니다.

 

2. InvokeRepeating

Invoke함수는 지연시간 후 한번만 실행이되는데 여러번 반복실행을 위해서는 InvokeRepeating함수를 사용해서 지정한 주기로 반복할 수 있습니다.

형식
InvokeRepeating(함수명, 지연시간, 반복주기);
지연시간만큼 지연된후 반복주기 만큼 계속 반복합니다.

예제

1
2
3
4
5
6
7
8
9
10
void Start()
{
    Debug.Log("Start() Time : " + Time.time);
    InvokeRepeating("FuncInvoke"5.0f, 1.0f);
}
 
void FuncInvoke()
{
    Debug.Log("FuncInvoke() Time : " + Time.time);
}
 
cs

다음과 같이 출력됩니다.

5초 후 FuncInvoke함수가 호출되고, 1초마다 FuncInvoke가 계속 반복됩니다.

멈추기위해서는 CancelInvoke함수를 이용합니다.

 

3. CancelInvoke

실행중인 Invoke함수를 중지합니다

형식
CancelInvoke(함수명);

예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int m_nCount = 0;
 
void Start()
{
    Debug.Log("Start()");
    InvokeRepeating("FuncInvoke"5.0f, 1.0f);
}
 
void FuncInvoke()
{
    m_nCount++;
    Debug.Log("FuncInvoke()");
 
    if( m_nCount >= 5 )
        CancelInvoke("FuncInvoke");
}
 
cs

다음과 같이 출력됩니다.

InvokeRepeating로 인해 FuncInvoke가 5번 반복되면 CancelInvoke함수로 더 이상 반복되지 않도록 합니다.

반응형
반응형

보통 함수는 하나의 프레임내에서 명령이 실행되게 하는데, 여러 프레임에 걸쳐서 코드를 실행시키기 위한 함수가 코루틴(Coroutine)입니다.
쓰레드와 비슷하다고 느낄 수 있지만 비동기가 아니기 때문에 쓰레드는 아닙니다.
대체로 Update함수를 이용해서 구현할 수 있지만, 코루틴을 사용해야하는 이유는 작업을 나눠서 수행할 수 있고, 불필요한 작업들이
Update문에서 계속 실행되는 것을 방지할 수 있습니다.


형식
함수를 정의한 후 StartCoroutine(코루틴함수)로 실행을 합니다.
코루틴 함수는 IEnumerator의 반환형을 가집니다.

예제

 

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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class Test : MonoBehaviour
{
    GameObject goSprite;
    SpriteRenderer spriteRenderer;
    float m_fAlpha = 0f;
    void Start()
    {
        goSprite = GameObject.Find("Sprite");
        spriteRenderer = goSprite.GetComponent<SpriteRenderer>();
        spriteRenderer.color = new Color(0000);
        StartCoroutine ("Fade");
    }
 
    void Update()
    {
        
    }
    IEnumerator Fade()
    {
        
        for(int i = 0; i < 10; i++)
        {
            m_fAlpha += 0.1f;
            spriteRenderer.color = new Color(000, m_fAlpha );
            yield return new WaitForSeconds(1f);
        }
        
    }
}
 

Sprite Object의 알파수치를 변경하는 예제입니다.
IEnumerator Fade() 함수를 생성해주고, StartCoroutine을 통해 시작하도록 했습니다.
yield return new WaitForSeconds(1f); 이 코드는 1초를 대기하라는 의미입니다.

yield 키워드의 종류는 다음과 같습니다.
yield return null
yield return new WaitForSeconds(float second)  - 주어진 시간(초)동안, co-routine의 수행을 중단합니다.
yield return new WaitForFixedUpdate() - 다음 고정 프레임 업데이트 함수(fixed frame rate update)가 호출될 때까지 기다립니다.
yield return new WaitForEndOfFrame() - 화면에 컨텐츠를 보여주는 프레임 바로 직전에, 모든 카메라와 GUI가 렌더링을 완료하는 프레임의 마지막을 기다립니다.
yield return StartCoRoutine(string) - 다른 코루틴이 끝날 때까지 기다립니다.
yield return new WWW() - 웹 통신 작업이 끝날 때까지 기다립니다.
yield return new AsyncOperation - 비동기 작업이 끝날때까지 기다립니다.

코루틴이 진행중에도 StopCoroutine(함수명)을 입력한다면 정지시킬 수 있습니다.

방금 사용한 StartCoroutine ("Fade"); 이렇게 스트링으로 함수명을 넣을 수도 있지만,
직접 함수를 StartCoroutine (Fade());로 코드를 작성할 수 있습니다.

그리고 함수에 매개변수를 넣어서 표현도 가능합니다.

StartCoroutine (Fade(0.1f));

IEnumerator Fade(float fAlphaPlus)

    for(int i = 0; i < 10; i++)
    {
        m_fAlpha += fAlphaPlus;
        spriteRenderer.color = new Color(0, 0, 0, m_fAlpha );
        yield return new WaitForSeconds(1f);
    }  
}

반응형
반응형

명시적으로 데이터 타입을 정의할 필요 없이 읽기 전용 속성 집합을 단일 개체로 편리하게 캡슐화가 가능합니다.
타입은 컴파일러에 의해 생성되고, 소스 코드 수준에서 값을 변경할 수 없습니다.
속성을 초기화하는데 사용되는 식은 null, 익명 함수 또는 포인터 형식일 수 없습니다.

형식
var 변수명 = new { 속성 = 값, 속성 = 값,....}

예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var a = new { num1 = 50, strMessage = "HI" };
            //a.num1 = 20; 읽기전용이므로 할당이 불가능합니다.
            Console.WriteLine("a.num1 = " + a.num1);
            Console.WriteLine("a.strMessage = " + a.strMessage);
        }
    }
}
 
 

a란 변수를 만들어 num1, strMessage라는 속성을 가진 값을 만들 수 있습니다.

읽기전용이므로 "a.num1 = 20;"와 같이 값을 할당할 수 없습니다.

또한 다음과 같이 배열형식으로 넣을 수 있습니다.

var a = new[] { new { num1 = 50, strMessage = "Kim"}, new { num1 = 100, strMessage = "Lee"} }

 

예제

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var a = new[] { new { num1 = 50, strMessage = "Kim"},
                            new { num1 = 100, strMessage = "Lee"},
                            new { num1 = 150, strMessage = "Choi"},
                            new { num1 = 2500, strMessage = "Jung"},
                            new { num1 = 3050, strMessage = "Park"}
                            };
            foreach (var aaaa in a)
            {
                Console.WriteLine("a.num1 = " + aaaa.num1);
                Console.WriteLine("a.strMessage = " + aaaa.strMessage);
            }
        }
    }
}
 
 

LINQ 쿼리 식을 사용해서 데이터 조회도 가능합니다.

 

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var a = new[] { new { num1 = 50, strMessage = "Kim"},
                            new { num1 = 100, strMessage = "Lee"},
                            new { num1 = 150, strMessage = "Choi"},
                            new { num1 = 2500, strMessage = "Jung"},
                            new { num1 = 3050, strMessage = "Park"}
                            };
            var list = a.Where(p => p.num1 > 1000).Select( p=> new { p.num1, p.strMessage } );
            foreach (var aaaa in list)
            {
                Console.WriteLine("a.num1 = " + aaaa.num1);
                Console.WriteLine("a.strMessage = " + aaaa.strMessage);
            }
        }
    }
}
 
반응형

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

[C#] String.Format  (0) 2019.10.28
[C#] #region  (0) 2019.10.27
[C#] Action, Func  (0) 2019.10.22
[C#] 람다식(Lambda expressions)  (0) 2019.10.21
[C#] 무명 메서드(anonymous method)  (0) 2019.10.20
반응형

 

안녕하세요. 개발남입니다. 

 

알기 쉬운 C#  Action, Func입니다.

 

델리게이트를 생성하기 위해 필요한 델리게이트 형태에 맞춰서 미리 선언해줘야하는데,
만약 무명 메소드로 잠깐 사용하거나 델리게이트 형태가 많은 경우 모두 선언해줘야하는 불편함이있습니다.
C#에서는 이런 불편함을 없애기위해 Func와 Action delegate가 미리 선언되어있습니다.

Action - 매개 변수를 0~16개 가질 수 있는 값을 반환하지 않는 메서드를 캡슐화
Func - 매개 변수를 0~16개를 가질 수 있는 값을 반환하는 메서드를 캡슐화


형태
Action
public delegate void Action<입력 매개변수> (매개변수);

Func
public delegate 반환형 Func<입력 매개변수,반환형> (매개변수);

 

예제
Action

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
 
    class Program
    {
        static void Main(string[] args)
        {
            Action output1 = () => Console.WriteLine("AAAA");
            output1();
 
            Action<int> output2 = (v) => Console.WriteLine(v);
            output2(2);
        }
    }
}
 
 

Func

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    delegate void DelegateParameterTwo(int n1, int n2);
 
    class Program
    {
        static void Main(string[] args)
        {
            Func<int> value = () => 2+8;
            Console.WriteLine(value());
            Func<intintint> plus = (n1, n2) => n1 + n2;    
            Console.WriteLine(plus(27));
            Func<intintfloat> minus = (n1, n2) => n1 * n2 * 0.5f; 
            Console.WriteLine(minus(67));
        }
    }
}
 
 

 

반응형

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

[C#] #region  (0) 2019.10.27
[C#] 익명 타입(Anonymous Types)  (0) 2019.10.23
[C#] 람다식(Lambda expressions)  (0) 2019.10.21
[C#] 무명 메서드(anonymous method)  (0) 2019.10.20
[C#] 제네릭  (0) 2019.10.19
반응형

 

 

무명 메서드와 비슷하게 이름 없이 함수를 표현할 수 있습니다.

형식
(입력 파라메터) => { 실행문 } 

실행문이 한개일때는 중괄호 없이 표현합니다.

(입력 파라메터) => 실행문

입력 파라메터에는 0개부터 여러 개까지 다양하게 만들 수 있습니다.

보통 Delegate를 이용해서 사용합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    delegate void AAAA();
 
    class Program
    {
        static void Main(string[] args)
        {
            AAAA output = () => Console.WriteLine("AAAA");
            output();
        }
    }
}
 

파라메터에 여러 개를 넣을 수 있습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    delegate void AAAA1();
    delegate void AAAA2(int nNum);
 
    class Program
    {
        static void Main(string[] args)
        {
            AAAA1 output1 = () => Console.WriteLine("AAAA");
            output1();
 
            AAAA2 output2 = (v) => Console.WriteLine(v);
            output2(2);
        }
    }
}
 
 

 

람다식에 여러 실행문을 넣을 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    delegate void DelegateParameterTwo(int n1, int n2);
    
    class Program
    {
        static void Main(string[] args)
        {
            DelegateParameterTwo plus = (n1, n2) => { int n3 = n1 + n2; Console.WriteLine(n3); };
            plus(27);
 
            DelegateParameterTwo minus = (n1, n2) => { int n3 = n1 - n2; Console.WriteLine(n3); };
            minus(127);
        }
    }
}
 
 

 

반응형

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

[C#] 익명 타입(Anonymous Types)  (0) 2019.10.23
[C#] Action, Func  (0) 2019.10.22
[C#] 무명 메서드(anonymous method)  (0) 2019.10.20
[C#] 제네릭  (0) 2019.10.19
[C#] 인덱서(Indexer)  (0) 2019.10.18
반응형

델리게이트(delegate)에 미리 정의하지 않아도 되는 메서드명이 없는 메서드로 정의하지 않고 중괄호안에 명령문만 넣어서 간편하게 구현할수 있습니다.
인라인 메서드와 비슷한 형식을 보입니다.

형식
delegate( 매개변수 ) { 실행문 }

예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    class Program
    {
        delegate void printNum(int nNum);
        static void Main(string[] args)
        {
 
            printNum print = delegate ( int nNum )
            {
                Console.WriteLine(nNum);
            };
 
            print(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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    delegate void PrintNum(int nNum);
 
    class AAA
    {
        public event PrintNum print;
        public void totalOutPut()
        {
            print(5);
        }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            AAA aaa = new AAA();
 
            aaa.print += delegate(int nNum)
            {
                Console.WriteLine(nNum);
            };
 
            aaa.print += delegate(int nNum)
            {
                Console.WriteLine(nNum * nNum);
            };
 
            aaa.totalOutPut();
        }
    }
}
 
s
반응형

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

[C#] Action, Func  (0) 2019.10.22
[C#] 람다식(Lambda expressions)  (0) 2019.10.21
[C#] 제네릭  (0) 2019.10.19
[C#] 인덱서(Indexer)  (0) 2019.10.18
[C#] 이벤트(event) & 델리게이트(delegate)  (0) 2019.10.17
반응형

C# 제네릭 (C# Generics)
클래스 또는 메서드(함수)를 선언하고 인스턴스화 할때까지 하나이상의 형식을 따르는 클래스나 메서드(함수)를 디자인할 수 있도록 형식 매개 변수 개념을 도입할 수 있습니다. 

 

보통 사칙연산등에서 변수타입에서 관련 없이 함수의 매개변수에 값을 넣어 다용도로 사용할 수 있게 만들기 위해 사용합니다.
C++에 템플릿하고 비슷한 역할을 수행합니다.

 

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    class AAAA<T>
    {
        public void print(T value)
        {
            Console.WriteLine(value);
        }
        
    }
    class Program
    {
        static void Main(string[] args)
        {
            AAAA<int> aaaaInt = new AAAA<int>();
            aaaaInt.print(1);
            AAAA<string> aaaaString = new AAAA<string>();
            aaaaString.print("AAAAA");
        }
    }
}
 
 

위 예제는 클래스 함수에 템플릿을 사용한 예를 보여줍니다.
int형과 string형에 관련없이 해당 값을 출력할 수 있도록 구현되었습니다.

반응형

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

[C#] 람다식(Lambda expressions)  (0) 2019.10.21
[C#] 무명 메서드(anonymous method)  (0) 2019.10.20
[C#] 인덱서(Indexer)  (0) 2019.10.18
[C#] 이벤트(event) & 델리게이트(delegate)  (0) 2019.10.17
[C#] delegate  (0) 2019.10.16
반응형

C# 인덱서(Indexer)
C# 인덱서(Indexer)는 클래스나 구조체의 데이터를 배열처럼 인덱스로 접근이 가능하도록 구현을 할 수 있게 합니다.

정의 
this[]를 사용하여 속성처럼 get과 set으로 정의합니다.

 

예제

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;
 
namespace ConsoleApplication1
{
    class AAAA
    {
        private int[] num = new int[10];
        public int this[int nIndex]
        {
            get
            {
                if (nIndex < 0 || nIndex > 10)
                {
                    throw new IndexOutOfRangeException();
                }
                else
                {
                    return num[nIndex];
                }
            }
            set
            {
                if (nIndex < 0 || nIndex > 10)
                {
                    throw new IndexOutOfRangeException();
                }
                else
                {
                    num[nIndex] = value;
                }
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            AAAA aaaa = new AAAA();
            aaaa[0= 2;
            Console.WriteLine(aaaa[0]);
        }
    }
}
 
 

위와 같이 클래스에 배열변수를 인덱서를 이용해서 접근해서 get / set이 가능하도록 만들 수 있습니다.


C# 6(Visual Studio 2015)부터는 이 구문 대신


public int this[int nIndex] => num[nIndex];

이렇게 표현할 수 있습니다.

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
public int this[int nIndex]
{
    get
    {
        if (nIndex < 0 || nIndex > 10)
        {
            throw new IndexOutOfRangeException();
        }
        else
        {
            return num[nIndex];
        }
    }
    set
    {
        if (nIndex < 0 || nIndex > 10)
        {
            throw new IndexOutOfRangeException();
        }
        else
        {
            num[nIndex] = value;
        }
    }
}
 
s

 

C# 7.0(Visual Studio 2017)부터 get 및 set 접근자 모두 본문 멤버로 구현할 수 있습니다.

1
2
3
4
5
public T this[int nIndex]
{
    get => num[nIndex]; 
    set => num[nIndex] = value; 
}
 
반응형

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

[C#] 무명 메서드(anonymous method)  (0) 2019.10.20
[C#] 제네릭  (0) 2019.10.19
[C#] 이벤트(event) & 델리게이트(delegate)  (0) 2019.10.17
[C#] delegate  (0) 2019.10.16
[C#] Event  (0) 2019.10.15
반응형

델리게이트(delegate)의 문제
- 추가 연산(+=)을 하려고 했는데, 할당 연산(=)을 하는 경우 이전에 추가했던 함수 리스트들이 사라지는 문제
- 외부에서 접근제한이 없다면 함수와 같이 호출이 가능하게 된다.

위와 같은 문제를 해결하기 위해 event를 사용합니다.
이벤트(event)는 외부에서 추가나 차감 연산만 가능합니다.
이벤트(event)는 외부에서 직접 호출이 아닌 함수를 통한 호출을 해야합니다.

 

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    delegate void Print(string strContent);
    class AAA
    {
        public event Print print;
 
        public void DelegatePrintAAA1(string strContent)
        {
            Console.WriteLine("AAA1" + strContent);
        }
        public void DelegatePrintAAA2(string strContent)
        {
            Console.WriteLine("AAA2" + strContent);
        }
        public void DelegatePrintAAA3(string strContent)
        {
            Console.WriteLine("AAA3" + strContent);
        }
 
        public void totalOutput()
        {
            if (this.print != null)
            {
                print("11111");
            }
        }
    }
    class Program
    {
        static void DelegatePrint(string strContent)
        {
            Console.WriteLine("normal" + strContent);
        }
 
        static void Main(string[] args)
        {
            AAA aaa = new AAA();
            aaa.print += aaa.DelegatePrintAAA1;
            aaa.print += aaa.DelegatePrintAAA2;
            //aaa.print = aaa.DelegatePrintAAA3; error 발생
            //aaa.print("111111"); error 발생
            aaa.totalOutput();
 
            aaa.print -= aaa.DelegatePrintAAA1;
            aaa.totalOutput();
        }
    }
}
 
 
 

이 예제에서 확인해봤을때 할당 연산이나 직접호출은 불가능합니다.

반응형

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

[C#] 제네릭  (0) 2019.10.19
[C#] 인덱서(Indexer)  (0) 2019.10.18
[C#] delegate  (0) 2019.10.16
[C#] Event  (0) 2019.10.15
[C#] yield  (0) 2019.10.14
반응형

특정 매개 변수와 반환 형식을 가진 함수에 대한 참조를 나타내는 형식을 말합니다.
delegate는 함수에 변수나 클래스를 인수로 전달하는 것과 같이 함수를 인수로 전달하는데 사용됩니다.
접근 가능한 클래스 또는 delegate형식과 일치하는 구조를 가진 모든 메서드는 대리자로 할당할 수 있습니다.
함수는 정적 함수거나 인스턴스 함수일 수 있습니다.

속성
- C++ 함수 포인터와 유사하지만 C++ 함수 포인터와 달리 어느 클래스 함수에서도 쉽게 할당 가능합니다.
- delegate는 함수 매개 변수로 전달이 가능합니다.
- delegate를 통해 콜백 함수를 정의할 수 있습니다.
- 여러 delegate를 연결 할 수 있습니다.

형식
public delegate 반환타입 함수명(매개 변수);
ex) public delegate void print(string strContent)


예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
 
    class Program
    {
        public delegate void Print(string strContent);
        static void DelegatePrint(string strContent)
        {
            Console.WriteLine(strContent);
        }
        
        static void Main(string[] args)
        {
            Print print = DelegatePrint;
 
            print("output1");
        }
    }
}
 
 



이렇게 간단하게 연결해서 사용할 수 있다.

1. 콜백함수
또한 매개변수로 전달하여 함수내에서 delegate를 호출할 수도 있습니다.
이렇게되면 동일한 함수안에 함수를 손쉽게 넣을 수 있게 됩니다.

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
 
    class Program
    {
        public delegate void Print(string strContent);
        static void DelegatePrint(string strContent)
        {
            Console.WriteLine(strContent);
        }
 
        static void Callback(Print callbackprint)
        {
            callbackprint("output2");
        }
        
        static void Main(string[] args)
        {
            Print print = DelegatePrint;
            // delegate를 매개변수로 넣습니다.
            Callback(print);
        }
    }
}
 
 



2. 멀티캐스트
대리자는 호출 시 둘 이상의 메서드를 호출할 수 있습니다.
더 추가하려는 경우 더하기 또는 더하기 대입 연산자('+' 또는 '+=')를 사용할 수 있으며,
추가된 메서드를 제거하기위해서는 빼기 또는 빼기 대입연산자('-' 또는 '-=')를 사용할 수 있습니다.

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    class AAA
    {
        public void DelegatePrintAAA1(string strContent)
        {
            Console.WriteLine("AAA1" + strContent);
        }
        public void DelegatePrintAAA2(string strContent)
        {
            Console.WriteLine("AAA2" + strContent);
        }
    }
    class Program
    {
        public delegate void Print(string strContent);
        static void DelegatePrint(string strContent)
        {
            Console.WriteLine("normal" + strContent);
        }
        
        static void Main(string[] args)
        {
            AAA aaa = new AAA();
            Print print = new Print(DelegatePrint);
            print += aaa.DelegatePrintAAA1;
            print += aaa.DelegatePrintAAA2;
            print("++");
 
            print -= aaa.DelegatePrintAAA1;
            print -= aaa.DelegatePrintAAA2;
            print("--");
        }
    }
}
 
 

3. 범용성
제너릭 <T>를 이용해서 어떤 변수형에 상관없이 구현할 수 있다.

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    delegate T calcDelegate<T>(T num1, T num2);
    
    class Program
    {
        static int addint(int num1, int num2)
        {
            return num1 + num2;
        }
 
        static float addfloat(float num1, float num2)
        {
            return num1 + num2;
        }
 
        public static void Calc<T>(T num1, T num2, calcDelegate<T> calc)
        {
            Console.WriteLine(calc(num1, num2));
        }
 
        static void Main(string[] args)
        {
            calcDelegate<int> addint1 = new calcDelegate<int>(addint);
            calcDelegate<float> addfloat2 = new calcDelegate<float>(addfloat);
 
            Calc(89, addint1);
            Calc(9.7f, 10.8f, addfloat2);
        }
    }
}
 
s
반응형

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

[C#] 인덱서(Indexer)  (0) 2019.10.18
[C#] 이벤트(event) & 델리게이트(delegate)  (0) 2019.10.17
[C#] Event  (0) 2019.10.15
[C#] yield  (0) 2019.10.14
[C#] 반복문  (0) 2019.10.13
반응형

이벤트는 어떠한 문제가 발생했다는 사실을 개체가 시스템의 모든 관련 구성 요소에 전달하는 방법입니다.
보통 클래스내에 발생하는 이벤트를 외부에 전달할 수 있습니다.
+= 연산자를 사용하여 이벤트를 추가할 수 있다.
-= 연산자를 사용하여 이벤트를 제거할 수 있다.

 

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    class Output
    {
        public event EventHandler print;
        public void totalOutput()
        {
            if (this.print != null)
            {
                print(this, EventArgs.Empty);
            }
        }
    }
 
 
    class Program
    {
        static void Output1(object sender, EventArgs args)
        {
            Console.WriteLine("Output1");
        }
        static void Output2(object sender, EventArgs args)
        {
            Console.WriteLine("Output2");
        }
 
        static void Main(string[] args)
        {
            Output output = new Output();
            output.print += new EventHandler(Output1);
            output.print += new EventHandler(Output2);
            output.totalOutput();
        }
    }
}
 
 

지금은 간단하게 함수를 이벤트에 추가하게되면 이벤트를 호출 시 추가한 함수들이 같이 순차적으로 호출되게 됩니다.

 

그리고 추가와 삭제를 클래스 객체의 get이나 set처럼 add와 remove를 사용하여 추가 삭제가 가능합니다.

 

다음과 같이 사용할 수 있습니다.

 

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
{
    class Output
    {
        private EventHandler _print;
        public event EventHandler print
        {
            add
            {
                _print += value;
            }
            remove
            {
                _print -= value;
            }
        }
        public void totalOutput()
        {
            if (this._print != null)
            {
                _print(this, EventArgs.Empty);
            }
        }
    }
 
 
    class Program
    {
        static void Output1(object sender, EventArgs args)
        {
            Console.WriteLine("Output1");
        }
        static void Output2(object sender, EventArgs args)
        {
            Console.WriteLine("Output2");
        }
 
        static void Main(string[] args)
        {
            Output output = new Output();
            output.print += new EventHandler(Output1);
            output.print += new EventHandler(Output2);
            output.totalOutput();
        }
    }
}
 

이렇게 add와 remove를 사용할 수 있습니다.

private EventHandler _print;

public event EventHandler print

{

       add

       {

                _print += value;

       }

       remove

       {

              _print -= value;

       }

}

 

반응형

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

[C#] 이벤트(event) & 델리게이트(delegate)  (0) 2019.10.17
[C#] delegate  (0) 2019.10.16
[C#] yield  (0) 2019.10.14
[C#] 반복문  (0) 2019.10.13
[C#] 조건문  (0) 2019.10.12
반응형

yield는 반복기 함수(iterator method)에서 컬렉션 데이터를 하나씩 리턴하게 할 때 사용하게 됩니다.


yield에는 두 가지 형태의 yield문을 가지고 있습니다.
yield return <수식(expression)>;
yield break;

yield return을 사용하면 호출할 때마다 순차적으로 따로 반환할 수 있습니다.
yield break을 사용하면 바로 반복기를 종료할 수 있게 됩니다.


반복기 함수는 다음과 같은 형식을 가져야합니다.
- 반환 형식은 IEnumerable, IEnumerable, IEnumerator, 또는 IEnumerator여야 합니다.
- 선언에 ref 또는 out 매개 변수가 허용되지 않습니다.


기본 형식

IEnumerable<변수형> elements = MyIteratorMethod();   
foreach (변수형 element in elements)   
{   
    실행문
}   

예제
static void Main(string[] args)
{
foreach (int nNum in funsion())
    Console.WriteLine(nNum);
}

public static IEnumerable funsion()
{
yield return 1;
yield return 2;
yield return 3;
yield return 4;
}
이렇게 구현하면 순차적으로 값을 리턴합니다.
출력 값
1
2
3
4



static void Main(string[] args)
{
foreach (int nNum in multiplication(2))
    Console.WriteLine(nNum);
}

public static IEnumerable multiplication(int nNum)
{
for ( int i = 1; i <= 9; i++ )
yield return nNum * i;
}
반복기 함수에서 for문을 이용해서 리턴할 수 있습니다.
출력 값
2
4
6
8
10
12
14
16
18


static void Main(string[] args)
{
foreach (int nNum in multiplication(2))
Console.WriteLine(nNum);
}

public static IEnumerable multiplication(int nNum)
{
for (int i = 1; i <= 9; i++)
{
if (i == 5) yield break;
yield return nNum * i;
}
}

중간에 yield break를 만나면 종료됩니다.
출력 값
2
4
6
8

반응형

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

[C#] delegate  (0) 2019.10.16
[C#] Event  (0) 2019.10.15
[C#] 반복문  (0) 2019.10.13
[C#] 조건문  (0) 2019.10.12
[C#] 연산자  (0) 2019.10.10
반응형

오늘은 반복문에 대해 알아보도록 하겠습니다.

 

반복문은 같은 코드를 계속 반복해야 할 때 사용합니다.

 

예를 들면

int nNum = 0;

Console.WriteLine(nNum++); 

Console.WriteLine(nNum++); 

Console.WriteLine(nNum); 

이런 코드가 있다면

반복문인 for문으로 손쉽게

for(int nNum = 0; nNum <= 2; nNum++ ) 
{ 
    Console.WriteLine(nNum); 
}

만들어서 코드를 알아보기 쉽고 단순하게 만들 수 있습니다.

그리고 만약에 코드가 3개가 아니라 10000개 20000개를 반복할 경우에도 손쉽게 변경할 수 있어서 코드를 유지 보수할 때에도 유용할 수 있습니다.

 

1. do - while문 

일단 블록 안에 실행문을 실행 후 while의 조건식을 확인한 후 조건식 값이 true값을 가지면 다시 블록 안의 실행문을 실행합니다.

루프 실행 후 조건을 확인하기 때문에 한번 이상 실행이 되며, 실행 전에 조건을 확인하는 while과 비교가 됩니다.

중간에 break문을 만나면 어느 문에서 든 블록 문을 빠져나갑니다.

 

do

{

     실행문

} while(조건식);

 

예제

int nNum = 0;
do
{
    Console.WriteLine(nNum);
    nNum++;
} while (nNum < 2);

출력 값

0

1

 

2. while문

while에 지정된 조건식을 확인하여 조건식 값이 true값을 가지면 블록 문의 실행문을 반복해서 실행합니다.

중간에 break문을 만나면 어느 문에서 든 블록 문을 빠져나갑니다.

 

while(조건식)

{

    실행문

}

 

예제

int nNum = 0;
while (nNum < 2)
{
    Console.WriteLine(nNum);
    nNum++;

출력 값

0

1

 

3. for문

for문에 지정된 조건식을 확인하여 조건식 값이 true값을 가지면 블록 문을 반복해서 실행합니다.

중간에 break문을 만나게 되면 블록문을 빠져나갑니다.

 

for( 초기값; 조건식; 증감식)

{

    실행문

}

 

예제

for(int i = 0; i < 2; i++ )
{
    Console.WriteLine(i);
}

출력 값

0

1

 

4. foreach문

배열과 컬렉션을 순회하여 변수에 값을 대입하고, 소스 컬렉션이 비워있으면 종료가 됩니다.

중간에 break문을 만나게 되면 블록 문을 빠져나갑니다.

 

foreach(변수 in 배열, 컬렉션)

{

     실행문

}

 

예제

int[] arrNum = new int[] { 0, 1, 2 };

foreach (int nNum in arrNum)
{
    Console.WriteLine(nNum);
}

 

출력 값

0

1

2

반응형

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

[C#] Event  (0) 2019.10.15
[C#] yield  (0) 2019.10.14
[C#] 조건문  (0) 2019.10.12
[C#] 연산자  (0) 2019.10.10
[C#] 데이터 타입  (0) 2019.10.09
반응형

안녕하세요.

 

오늘은 조건문에 대해서 알아보도록 하겠습니다.

 

1. if문

조건문이 true인지 false인지를 확인하여, true이면 다음 구문(블럭문)을 실행합니다.

 

if(조건문)

{

       실행문

}

 

예제

int nNum = 2;
if (nNum == 2)
{
    Console.WriteLine("Num : 2");
}

출력값

Num : 2

 

2. if - else문

조건문이 true인지 false인지를 확인하여, true이면 if 블록 문을 실행하고, 아니면 else 블럭문을 실행합니다.

 

if(조건문)

{

       실행문

}

else

{

       실행문

}

 

예제

int nNum = 5; 
if (nNum == 2) 
{ 
    Console.WriteLine("Num : 2"); 
}

else

{

    Console.WriteLine("Num : " + nNum);    

}

출력 값

Num : 5

 

3. if - else if - else문

if 조건문이 true인지 false인지 확인하여 true이면 if 블록 문을 실행하고, 아니면 else if 조건식을 확인해여 true인지 false인이 확인하여 else if 블럭문을 실행하고, 아니면 else 블럭문을 실행합니다.

 

if(조건문)

{

       실행문

}

else if(조건문)

{

       실행문

}

else

{

       실행문

}

 

예제

int nNum = 5; 
if (nNum == 2) 
{ 
    Console.WriteLine("Num : 2"); 
}

else if (nNum == 5) 
{ 
    Console.WriteLine("Num : 5"); 
}

else

{

    Console.WriteLine("Num : " + nNum);    

}

 

출력 값

Num : 5

 

4. switch-case문

switch문에 조건값에 따라서 case문의 실행문을 실행합니다. 그리고 중간에 break문을 만나게 되면 switch문을 빠져나오게 됩니다. case문에 조건값과 같은 값이 없다면 default문의 실행문을 실행하게 됩니다.  

 

switch(조건값)

{

      case 조건값 1:

             실행문

             break;

      case 조건값 2:

              실행문

             break;

              :

              :

      default:

             실행문

             break;

}

 

예제

int nNum = 2;
switch(nNum)
{
    case 1:
        Console.WriteLine("Num : 1");
        break;
   case 2:
        Console.WriteLine("Num : 2");
         break;
    default:
        Console.WriteLine("default");
        break;
}

출력 값

Num : 2

 

주의점은 break;를 안 넣게 되면 다음 구문이 진행이 됩니다.

예를 들면

int nNum = 2; 
switch(nNum) 
{ 
    case 1: 
        Console.WriteLine("Num : 1"); 
        //break;  제거
   case 2: 
        Console.WriteLine("Num : 2"); 
         break; 
    default: 
        Console.WriteLine("default"); 
        break; 
}

 

출력이 

Num : 1

Num : 2가 출력이 됩니다.

반응형

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

[C#] yield  (0) 2019.10.14
[C#] 반복문  (0) 2019.10.13
[C#] 연산자  (0) 2019.10.10
[C#] 데이터 타입  (0) 2019.10.09
[C#] 직렬화(Serialization)  (2) 2019.07.16
반응형

오늘은 점프를 구현해보려고 합니다.

 

바로 실습하겠습니다.

 

일단 바닥을 생성합니다.

 

Hierarchy에서 오른쪽 클릭해서 3D Object - Plane 합니다.

다음은 점프할 객체를 생성합니다.

Cylinder를 이용하겠습니다.

3D Object - Cylinder

처음에는 약간 위로  떠있는 상태입니다.

그렇기 때문에 Cylinder의 초기 위치를 지정합니다.

다음은 Rigidbody를 추가합니다.

객체에 힘을 가해서 점프와 같이 보이게 하려고 합니다.

힘을 가다 보면 객체가 쓰러지는 현상이 발생할 수 있습니다.

이것을 방지하기 위해서 Rigidbody속성을 설정합니다.

constaints(제약) 설정을 보시면 Freeze Rotation에 x, z를 체크합니다.

x, z축으로 회전을 막는다는 의미입니다.

스크립트 추가

Cylinder에 스크립트를 추가합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class Player : MonoBehaviour
{
    public float m_fForce = 5.0f;
    void Start()
    {
 
        
    }
 
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            GetComponent<Rigidbody>().AddForce(Vector3.up * m_fForce, ForceMode.Impulse);
        }
    }
}
 
cs

 

Rigidbody의 AddForce를 이용해서 객체에 힘을 가합니다.

객체의 위쪽 방향으로 5만큼의 힘을 가합니다.

 

ForceMode.Impulse는 질량의 영향을 받으면서 힘을 가하는 옵션입니다.

 

옵션은 다음과 같습니다.

Force rigidbody에 지속적인 힘 추가, 질량 사용.
Acceleration rigidbody에 지속적인 가속 추가, 질량 무시.
Impulse rigidbody에 순간적으로 충격 추가, 질량 사용.
VelocityChange rigidbody에 순간속도 변경, 질량 무시.

 

스페이스키를 입력하면 객체가 점프하는 것을 볼 수 있습니다.

 

근데 스페이스키를 계속 입력하면 계속 점프를 하는 것이 확인됩니다.

점프 중에는 스페이스 입력을 받지 않게 하기 위해서는 다음과 같이 구현할 수 있습니다.

Plane 오브젝트에 태그를 변경해야 합니다.

 

일단 태그를 추가하겠습니다.

"Plane"라고 태그를 만듭니다.

Tag를 Plane로 변경합니다.

 

그리고 스크립트를 수정합니다.

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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class Player : MonoBehaviour
{
    public float m_fForce = 5.0f;
    bool m_bJumping = false;
 
    void Start()
    {    
 
    }
 
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            if(!m_bJumping)
            {
                GetComponent<Rigidbody>().AddForce(Vector3.up * m_fForce, ForceMode.Impulse);
                m_bJumping = true;
            }
        }
    }
 
    void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.CompareTag("Plane"))
        {
            m_bJumping = false;
        }
    }
}
 
cs

 

스페이스 키를 누를 때 점프 중이 아닐 때만 점프가 가능하도록 하고, AddForce함수가 호출되었을 때, 점프 중으로 m_bJumping 값을 true로 변경합니다.

 

OnCollisionEnter함수를 사용해 오브젝트가 바닥과 충돌했을 때를 나타냅니다.

OnCollisionEnter는 충돌했을 때 발생하는 함수입니다.

충돌한 오브젝트의 태그가 "Plane"일 때 m_bJumping 값을 false로 만들어서 점프가 가능하도록 합니다.

 

이렇게 구현하면 여러 번 점프가 불가능하도록 구현할 수 있습니다.

 

반응형

+ Recent posts