midas+son의 크리에이티브(creative) 이야기

우리들은 배열을 비우고자 한다.


byte[] recvData = new byte[10];


위와 같이 배열을 구성하고

뒤에 사이즈를 넣어주게 된다.

"이 배열은 이만큼만 쓸 것입니다"라는 의미이다.


거기에 0부터 9까지 byte를 넣었다고 생각해보자.

(int[]로 해도 됨)


그리고 01234 숫자를 없애고 싶다면 어떻게 할 것인가?


Array.Clear(recvData, 0, 5);    //(배열, 시작 인덱스, 시작 인덱스 부터 지울 길이)

위와 같은 C#의 Array 클래스에 있는 Clear 함수를 사용 할 수 있을 것이다.


하지만 recvData 를 내부를 보면

0000056789 의 byte 가 들어있다.


그게 아니라 앞에 지운것은 다 없애고

56789 만 남게 하고 싶다면 어떻게 해야 하겠는가?


Array.Clear(recvData, 0, 5);


int count = 0;

for (int i = 0; i < recvData.Length; ++i)

{

    if (recvData[i] == '\0')

    {

        ++count;

    }

    else break;

}

byte[] recvData2 = new byte[recvData.Length - count];

Array.Copy(recvData, count, recvData2, 0, recvData2.Length);    // (원본배열, 옮길 인덱스 시작 위치, 복사본 배열, 복사될 시작위치, 복사될 길이)


편리한 함수가 따로 있지 않은 것 같다.

(내가 못찾은 것일 수도 있다.)


위와 같이 '\0'이 들어간 부분을 카운트 하여 앞에서부터 길이를 재고

Array.Copy 로 다른 배열로 옮기는 것이다.

그러면 뒤에서 부터 잘라 올 수 있다.


그럼 반대로 뒤에를 날리고 앞에꺼만 보존 하여

배열 사이즈를 맞춘다면 어떻게 할까?


Array.Resize(ref recvData, recvData.Length - eraseLength);    // (원본 배열 ref 꼭 붙여야 함(참조의 의미), 재조정할 사이즈)


위와 같은 Resize함수를 사용해주면 

사이즈를 재조정해주면서 

뒤를 없앨 수 있다.


위의 함수 들을 복합적으로 사용하면

중간 중간에 비어있는 값들도 뺄 수 있게 되니

잘 처리해보도록 하자

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

연산자 오버로딩(==, !=)  (0) 2017.05.12
C#에서의 상수 사용 - c++의 #define 같은 활용 방안  (0) 2016.06.16
C# 람다 식  (0) 2016.06.08
C# Windows Forms - 오목  (0) 2016.05.31
소켓 통신, 웹 통신(간략 설명, 메모)  (0) 2016.05.28

요즘 TcpListner로 동기식 소켓 네트워킹을 배워서

유니티 게임에 접목 시키기 위해 테스트 중이다.


유니티 프로젝트를 

서버용으로 하나

클라이언트용 하나

각각 만들어 사용하는데


서버랑 클라이언트랑 각각 실행 시키다가

재 실행을 하거나

아니면 하나가 오류 동작을 하면

문제가 없는 프로젝트도 "응답없음"으로

아무 동작 할 수가 없다.


작업관리자에서 

유니티 2개를 끄거나 

아니면 하나만 끄거나(남은 하나도 결국 동작이 이상해진다)

해야 하는데

테스트 시간이 너무 오래 걸린다.


지금 몇시간 째 후회 중이다.


유니티에서 지원하는 

네트워크 컴포넌트를 사용한건 아니라고 하지만

이건 참 너무 한거 같다.



https://msdn.microsoft.com/ko-kr/library/dd293608.aspx

//c++11에서 추가된 람다 식 MSDN 참조


C#에서도 썼던 기법인데....

뭔가 설명이 더 엄청 어렵다.


C++11 전에는 없었다.


C++11 부터 생겼는데

C++14 에서 뭔가 더 추가 되었다.


아직 c++ 에서 정식으로 사용하기엔 

사용법에 대한 설명이 난해한것 같다.


//TODO - 더 알아보고 내용을 추가하자

C# 람다 식

공부/C#2016. 6. 8. 13:10
//람다식에 관한 MSDN 의 정식 설명

=> 

위의 기호로 사용 되는 익명함수 기법.

"람다 식" 이라고 불린다. 

c++ 11버전 부터도 추가된 기법이다.

(주의 // C++11 에서는 사용법이 다르다.)


정확한 것은 위의 url에 접근하여

한번씩 글을 읽어 보기 바란다.


간략하게 얘기 해보면

=> 왼쪽에 입력될 매개 변수가 지정되고

=> 오른쪽에서는 왼쪽의 매개변수를 사용하여 식을 적용하면 

결과로서 값이 다시 매개변수로 반환되는 유용한 식이다.


제약 사항이나 다양한 사용 방법을 다 설명하긴 너무 길어지니 

역시 위의 url을 클릭해서 읽어보자.

유니티에서 Scene을 여러개 생성한뒤

Scene 간의 이동이 가능 하다.


이전에는 


Application.LoadLevel(int index);    //빌드 셋팅할 때의 index번호 


Application.LoadLevel(string name);    //Scene 이름


을 사용 하였지만


현재 최신 버전에서는 위의 코드는 사용하지 않기를 권장한다.


새로 권장 하는 코드는


using UnityEngine.SceneManagement; 을 추가하여


아래 코드 중에서 사용 하는 것이다.


SceneManager.LoadScene(int index);    //빌드 셋팅할 때의 index번호 


SceneManager.LoadScene(string name);    //Scene 이름


SceneManager.LoadScene(int index, LoadSceneMode mode);


SceneManager.LoadScene(string name, LoadSceneMode mode);



LoadSceneMode 에는 

LoadSceneMode.Single 과 LoadSceneMode.Additive 가 있는데


LoadSceneMode.Single은 예전과 같이 

현재 Scene 의 Object들을 날리고

이동하는 Scene의 Object만을 새로 로드라는 것이고

LoadSceneMode.Additive은 현재 Scene을 그대로 남긴체

이동할 Scene을 로드하여 추가하는 것이다.


이전에는 현재 Scene의 객체중 남기고 싶은 것만 

스크립트에서 DontDestroyOnLoad(gameObject); 해주었는데

LoadSceneMode.Additive를 하면서 

DontDestroyOnLoad(gameObject);를 해버리면

DontDestroyOnLoad 한 객체들만 별도로 Scene의 구분이 되어 버린다.


Scene의 관리를 위해 적절히 잘 사용 하여야 할 것이다.

AudioSource 다중 사용이 무슨 말인가 하면

보통 AudioSource의 clip(음원 이라고 생각하자)을 

하나 등록 하여 사용하게 된다.


스크립트에서 도중에 해당 clip을 바꾸어 사용할 수 있다.

하지만 그러면 이전의 음원은 날라가거나 짤리게 된다.


배경음이 있고 몬스터가 있고

스킬이 있고 이펙트가 있다.


하나의 AudioSource를 사용하면

게임을 하기 싫어질 만큼 귀가 괴로워진다.


보통은 하나의 오브젝트에 하나의 AudioSource를 가지고 있다.

몬스터는 몬스터의 음악이 있고

배경음도 지역에 따라 clip을 바꾸어 틀어 주게 된다.


하지만 하나의 오브젝트에서

동시에 들려주어야 하는 것이 있다면 어떻게 할 것인가?


쉽게 예를 들어 설명하면

캐릭터가 있다. 

점프를 할 떄 점프 음을 튼다.

펀치를 날리면 타격음이 나와야 한다.

도중에 맞으면 잡음정도 하나 생겨야 한다.


이렇게 하나의 FBX로 만들어진 오브젝트의 경우

상태 값이 많아 사용될 AudioSource의 양도 많아 질텐데

하나의 AudioSource로는 감당이 안되며

동시에 처리가 힘들다.


그럼 어떻게 해야 되겠는가?


쉽게 AudioSource를 여러개 만드는 것이다.


어디에 만드느냐?


오브젝트에 Create Empty를 하여 자식으로 더미를 만든다.

FBX로 불러온 것이라면 본의 위치를 잡는다.

점프음은 다리 부분에 더미를 만들어 AudioSource를 넣는다.

펀치는 주먹에 더미를 만들고 AudioSource를 추가한다.

이렇게 자식으로 더미를 만들어 AudioSource를 각각 추가한다.

그리고 캐릭터 컨트롤 스크립트에서 

public으로 전역변수 AudioSource를 

각각 변수에 할당 하여 컨트롤 하거나

child를 찾아 컨트롤 할 수 있다. 

그러면 여러가지의 음원이 씹히지 않고

깔끔하게 따로따로 나올 수 있다.


AudioSource 를 설계 할 때에는

하나의 AudioSource에서 clip을 바꾸어 가며 컨트롤 할지

더미로 분할하여 다중으로 AudioSource를 생성해 컨트롤 할지 

고려해봐야 함을 기억하자.

'공부 > Unity' 카테고리의 다른 글

[잡담]유니티로 서버 달지 말자!!!  (0) 2016.06.11
Unity Scene Change(씬 바꾸기)  (0) 2016.06.04
GetComponent<T>() 사용에 대해  (0) 2016.06.02
다중 트리거(Trigger) 조작 문제  (0) 2016.06.01
splat map  (0) 2016.05.30

유니티로 게임을 개발하고

스크립트에서 GetComponent는 자주 사용되는 문법이다.


특정 오브젝트의 Component를 가져와 

컨트롤 할 수 있어 꽤 유용하다.


하지만 함수 자체가 많이 무겁다.

빈번하게 동작되는 함수(Update 등등의 이벤트함수)에서 사용하거나

루프를 돌면서 쓰거나하면 

게임의 성능이 저하된다.


그래서 생각을 잘하여 사용하여야 하는데

보통은 Awake나 Start 함수에서 한번 전역 변수에 할당해주고

변수로 사용을 많이 하게 된다.


하지만 그 외에도 고려해야 하는 방식이 있는데

GetComponent를 사용하는 스크립트가 포함된

오브젝트가 얼마나 자주 새로 생성되느냐 이다.


쉽게 예를 들어서 설명해 보자.

런 게임이 하나 있다.

캐릭터 오브젝트가 있고

코인 오브젝트가 있다.

캐릭터 오브젝트는 단일 오브젝트고

코인은 개별적으로 하나하나 생성된다.

코인을 먹었을 때 나오는 음원 AudioSource의 clip을 Play 하고자 한다.


먹는 순간 Play를 해야 하므로 미리 AudioSource를 할당 받아야 한다.


그렇다면 

코인을 먹었을 때 나오는 음원 AudioSource 를 어디에 둘 것인가?

라는 문제가 발생한다.


코인을 먹는 소리이기 때문에 코인 종속일 것 같다는 생각이 먼저 들수 있지만

코인 하나하나 생성될 때 마다 Awake나 Start에서 GetComponent를 한다면

코인이 100개 라면 100번 GetComponent된다는 것이다.

성능이 생각만 해도 뚝뚝 떨어진다.


캐릭터도 코인을 먹을 때를 체크 할 수 있고

단일 오브젝트이므로 

캐릭터의 자식으로 

AudioSource를 GetComponent하는 것이 바람직하다.

몇 백의 코인을 먹어도 

AudioSource를 가져오기 위한

GetComponent를 캐릭 한번만 사용하므로

게임 성능 저하가 거의 없다.


동적으로 생성되거나 

수가 많을 오브젝트의 경우는 

GetComponent의 사용을 최소화 하자.

'공부 > Unity' 카테고리의 다른 글

Unity Scene Change(씬 바꾸기)  (0) 2016.06.04
AudioSource 다중 사용  (0) 2016.06.03
다중 트리거(Trigger) 조작 문제  (0) 2016.06.01
splat map  (0) 2016.05.30
[잡담]유니티에서 구현하는 2D에 관련하여  (0) 2016.05.27

유니티의 하나의 오브젝트에서

Collider에 Is Trigger를 체크 하면

물리적 충돌이 비물리적 충돌을 체크 할 수 있게 된다.

 

스크립트 상에서 

void OnTriggerEnter(Collider other) 

void OnTriggerStay(Collider other)

void OnTriggerExit(Collider other)

등의 이벤트 함수를 적용 할수 있다.


여기에도 문제가 하나 있다.


하나의 오브젝트에서

Collider를 여러가지 가질 수 있고

Trigger도 여러개 가질 수 있지만

스크립트 상의 이벤트 함수는

공용으로 사용을 한다는 것이다.


하지만 게임을 만들다 보면

Trigger마다 각각 체크하여 

동작을 다르게 해야 할 때가 있다.


이럴 때에는 어떻게 해야 하는가?


해당 오브젝트의 자식으로 Empty 오브젝트를 만들고

그 자식 Empty 오브젝트에 Collider를 달아 trigger로 만든후

OnTrigger 함수만 따로 스크립트로 작성하여 적용하는 것이다.


즉 Trigger 가 2개 이상 필요 하다면

Empty오브젝트로 자식을 만들어

각각 나누어서 적용시키면 된다.

어렵게 고민하지 말고 위처럼 쉽게 생각하여 적용하자.

'공부 > Unity' 카테고리의 다른 글

AudioSource 다중 사용  (0) 2016.06.03
GetComponent<T>() 사용에 대해  (0) 2016.06.02
splat map  (0) 2016.05.30
[잡담]유니티에서 구현하는 2D에 관련하여  (0) 2016.05.27
Ctrl + Shift + f  (0) 2016.05.25

C#에서 WinForm 을 처음 다루어 보았다.

오목을 만들었다.

오목 게임 자체는 c++ Console로도 만들어봤으니 

과거를 추억해가며 금방 만들었다.

직관성 있게 디자인 한 것을 

바로바로 확인할 수 있으니 편했다.


[그림 1 - 결과 오목]



[그림 2 - 결과 타임 아웃]



C# 윈폼을 다룰 때 속성 창이나 이벤트 처리등은

예전 회사 다닐때 써봤던 국산 UI 툴 중

투비소프트 사의 마이플랫폼, 엑스플랫폼 을 사용 했을 때나

그 외 다른 툴 들 과도 사용 방법이 거의 비슷해서

과거가 새록새록 기억나며 재미있었다.

splat map

공부/Unity2016. 5. 30. 13:18

splat map 이란 것이 unity에서 나온 것은 아니다.(셰이더 기법...)

하지만 unity 강의를 들으면서 존재를 첨 알았기에 분류를 unity로 빼겠다.


splat map 이란 것은 아래와 같은 이미지를 먼저 떠올려야 한다.



빨강 노랑 파랑 초록 하양 등등 형형색색이 이미지인데

여러가지의 텍스쳐(texture)를 섞을 때 사용되는 셰이더 기법이다.


컴퓨터는 이미지를 RGB값으로 나누어 판단 할 수 있다.

거기에 alpha값(투명도)까지 추가하여 

RGBA(혹은 RGBW) 4가지의 값을 1바이트씩 (0~255)

총 4바이트로 해당 픽셀의 색상 값을 나타낸다.


하지만 splat map 자체가 이미지가 아니며

데이터라고 생각 해야 한다.


맵(혹은 그외 오브젝트)에 투영될 Texture가 하나가 아니라

2개 이상일 경우 합성을 하게 되는데

합성을 위한 데이터로서 splat map이 작성된다.


예를 들어 보자.

바위이미지 A와 풀 이미지B

2개의 이미지를 합성할 경우 

그 경계선부근은 바위 이미지 절반과

풀 이미지 절반의 색상을 구해서 삽입하게 된다.

그러면 A이미지의 RGB값에 0.5를 곱하고

B의 이미지 RGB값에 0.5를 곱해 더해주면 되고

영향도에 따라 비율을 각각 곱해주면 합성이 되는 것이다.


하지만 그 비율을 어떻게 데이터화 시키느냐가 문제가 된다.

각각 변수에 담기에는 맵의 크기에 따라 컨트롤이 힘들어 질수 있다.

그래서 생각해낸 것이 RGBA에 각각 하나씩 비율을 대입해보자였다.


즉 2가지 이미지를 사용한다면

원본 이미지가 아닌

별도의 이미지를 만들어

R값에 첫번째 이미지의 비율

G값에 두번째 이미지의 비율을 담는다는 것이다.

세번째와 네번째 이미지 소스가 있다면

각각 B, A 값에 비율을 담아 놓으면 되는 것이다.

그것이 바로 splat map이 된다.


splat map의 한 픽셀을 조사 하였는데

RGBA 값이 127, 63, 63, 0 이었다고 하면

첫번째 Texture의 값이 절반 정도, 

두번째 세번째 Texture는 1/4정도 값이 투영되고

네번째 이미지는 없거나 참조 되지 않는 것을 의미한다.


이리하여 Texture들을 합성 하기 위한 

데이터가 또다른 이미지로 나오게 되는 재밌는 기법이 나왔다.


그렇다면 4가지 Texture 보다 더 많은 가지수를 합성 하기 위해서 

어떻게 해야 하는가 궁금증이 있을 수 있다.

그건 별 수 없이 splat map이 하나 더 생성 되어야 한다.

그리고 splat map에 인덱싱을 해줘서

0번 splat map의 RGBA 값, 1번 splat map의 RGBA 값 체크가 

각각 되어야 한다.

그렇기에 물론 성능이 저하된다.

1~4개의 Texture 합성에는 splat map이 하나 필요하고

5~8개는 2개, 9~12는 3개의 splat map이 필요하며

성능은 splat map 수가 많을 수록 저하된다.


그래서 splat map에서 처리할 Texture는 

4개 이하를 권장한다.