[C#] Struct? Class?

이미지
 Struct와 Class의 큰 차이점은 상속에 대한 처리라고 생각합니다 이러한 예시의 두 Struct, Class 만들었을 시  Struct는 Class와 달리 new 키워드 없이 바로 변수로 불러와 사용이 가능합니다. Struct를 사용 하는 여러 다른 값들을 생성할 수 있지만  Class는 new 키워드가 없다면 처음 값에 값이 덮혀져버려  결국 똑같은 값 밖에 만들어 낼 수 없습니다.  위의 예시처럼 Struct는 몇 개의 변수를 선언을 해줘도 다른 값이 나오지만 Class는 같은 값이 복사가 됩니다. Class는 다른 값을 나타내려면 새로운 변수에 다시 new 키워드를 통해 다시 할당을 해줘야 한다. 이로 인한 메모리의 할당 방식에도 많이 차이가 난다. Class는 힙(없어지지 않는 메모리 동작 속도 다운)에 메모리 할당을  Struct는 스텍(사용 후 종료되는 메모리 많이 쓰면 스텍오버플로우 발생) 메모리 할당

[C#] 접근 제한자란?

이미지
 접근제한자란? 접근 제한자는 외부로부터 타입(클래스, 구조체, 인터페이스, 델리게이트 등) 혹은 그 타입 멤버들(메서드, 속성, 이벤트, 필드 등)로의 접근을 제한할 때 사용하는 것  접근제한자 종류는?  접근 제한자 언제 쓰나? 1. Class의 필드는 기본적으로 private로 설정하여 외부로부터 접근을 제한하는 것이 일반적이다 2. Method는 외부에서 회출해야 하는 것만 public으로 사용 하고 전부 private로 설정한다 3. Method 외에도 어셈블리 내부에서만 사용 가능한 internal, 파생클래스에서 엑세스할 수 잇는 protected를 사용할 수 있다.

[C#] 'ref' 와 'out'의 차이

이미지
ref 함수는 밖에 있는 인자를 메서드로 넘겨주는 형식 입니다. out은 메서드 안에 있는 인자를 밖에 있는 변수에 넘겨주는 형식입니다. ref는 메서드 안에서 변수를 변경할때 좋고  out은 메서드 안에서 전달하는 변수를 초기화 할 때 많이 사용한다고 합니다. 

[Unity] 숙련주차 트러블 슈팅

이미지
  트러블 스테이지 난이도를 조절 할 때 스테이지 난이도별 몬스터의 체력이 증가하는 코드를 짰다. 하지만 SceneRouter를 통해 restart를 하게 되면 모든 변수 값이 초기화 되어 스테이지(Level) 변수가 계속 ‘1’로 고정 되는 트러블을 겪었다. 고민한 해결 방안 및 해결 시도 GameManager를 DontDestroyOnLoad(this.gameObject); 통해 꺼지지 않게 해준 후 변수를 설정해 주었다. 하지만 설계miss로 인해 이미 GameManager에는 많은 변수 값이 들어갔고 초기화가 필수였다. 2. 저장되어야만 하는 변수 값만 들고 갈 수 있는 새로운 cs파일 생성 DataManger.cs라는 파일을 생성, 변수 저장 후 파괴되지 않게 해주었다 (만든김에 bestScore 도 해준건 덤) 해결 후 아쉬움 이번 트러블을 만나면서 다시 느끼는 것이 처음 설계가 정말 중요하다는 것을 다시 느꼈다. 처음부터 이러한 기능을 만들 것이라는 생각을 했더라면 굳이 DataManger라는 파일을 만들지 않고 좀 더 깔끔한 코드로 GameManger를 이용해 만들 수 있었을 것 같다. 게임 시연영상

[유니티] 숙련주차 트러블

  트러블 처음에 시작했을때 랜덤 맵 생성과 랜덤한 위치에 몬스터를 생성할 때 맵과 동시에 몬스터가 스폰이 동시에 진행하는데 있어 몬스터의 타겟팅 문제와 문의 setActive의 문제가 생겼다. 고민한 해결 방안 맵 생성을 하는 트리거를 만들어 동시에 진행하고 게임을 잠시 멈춘 뒤 카메라와 플레이어가  다음맵에 이동하는 형식을 하려 했다. 코드가 많이 꼬여버려 트리거가 발동 되어도 조금씩 어긋나고 에러가 뜨는 현생이 계속 되었다. 해결 시도 너무나 복잡한 이슈로 인해 트리거를 다 나눠보도록 했다. 카메라 앵글은 플레이어가 화면 밖으로 나가는 순간 맵 크기만큼 position을 바꿔주었다. 방 생성은 화면이 넘어가기 직전에 트리거를 발동시켜 만들어주었다. 몬스터와 구조물은 방을 넘어가고 문에서 조금 떨어진 곳에 트리거를 주었다. 그 순간 몬스터의 유무를 판단하여 문을 닫아 주었다. 즉 방 생성 → 카메라 이동 → 몬스터,구조물 생성 → 문 닫힘 최종 결정 해결 방안 및 이유 처음에는 상하좌우 랜덤한 방향으로 뻗어 나가는 맵을 만드려 했으나… 중복으로 맵이 같은 곳에 생성되는 이슈로 포기 하고 가능한 랜덤맵을 사용 할 수 있도록 안의 구조물과 몬스터 배치를 랜덤으로 바꾸게 되었다. 그리고 한번에 실행이 되는 것보다 하나하나 트리거를 나눠주니 에러도 어디서 왜 뜨는지 확실하게 알았다.

[Unity] Fade in 쉽게 사용해보기

이미지
 Fade in의 가장 쉬운 방법으로는 당연히 Asset 사용일테지만  그 외의 방법을 한번 알아보려고 하였다. Canvas Group을 사용하면 쉽게 사용이 가능하다. Fade in 이란  Alpha가 0에서 서서히 1로 되는 효과를 말하기에 우리는 그것을 바꿔만 주면 되는 것이다 코드에서 CanvasGroup 컨포넌트를 불러온 후 시간이 지남에 따루 alpha 값을 증가시켜주면 끝 오프닝에 많이 사용할 수 있을만한 Fade in기능이 완성되었다.

[Unity] Rigidbody가 있는 두 물체 충돌 무시

이미지
플레이어와 충돌 이벤트가 있는 서로 다른 2개의 Object는 충돌을 무시해야한다. 충돌을 무시하기 위해 Physics.IgnoreCollision 을 쓰려 했지만 잘 되지 않아 조사 끝에 찾아낸 답은  Layer였다. 지정된 레이어끼리의 값은 충돌 및 모든 것이 무시가 됐다. 원하는 물체에 Layer를 달아준 후 Edit > Project Settings >Phusics 2D 물리법칙을 무시하고 싶은 레이어 사이의 체크를 풀어주게 된다면 물체들은 전부 통과하게 된다.

[Unity] 애니매이션 없이 최대한 애니매이션 만들어보기`

이미지
 무료에셋으로 물방울이 떨어져서 퍼지는 모션을 구현하기가 너무 힘들어 어떻게 하면 좋을까 하는 도중에 이러한 동영상을 보게 된다. 안된다면 만들어 보자라는 생각에 무료 에셋을 찾는것을 멈추고 파티클에 집중하도록 하였다. 지금 현재 진행형이며 조금 힘들겠지만 내일이면 완성할 수 있을거같다.

[VS2022] 비주얼 스튜디오 비정상 종료 될시

 내 컴퓨터는 그리 좋지 못하다. 역시나 프로젝트를 진행하다 결국 블루스크린 이슈가 텨졌다. 다시 진행을 하려하는데 vs2022가 열리지 않아 매우 당황 급한대로 프로그램 수정 및 재설치도 해보았지만 똑같은 현상이 반복 되었다. 그래서 다른 사람들도 만약 이런 상황이 터지거나 나에게 또 이런현상이 터지게 된다면 도움이 되고자 글을 써보겠다. 아래와 같은 폴더를 완전히 삭제하여 주십시오. C:\ Users\<<Your Alias>> \AppData\Local\Microsoft\Team Foundation C:\ Users\<<Your Alias>> \AppData\Local\Microsoft\VisualStudio C:\ Users\<<Your Alias>> \AppData\Local\Microsoft\VSCommon 이 폴더들을 다 삭제 후 재시작 하면 다행이 정상 실행이 되는 것을 확인하였다. 해당내용은 이곳을 참고하였다. If you have problems with TFS or Visual Studio flush the user cache … or not?

[Git] Git Wiki를 만들어보자

이미지
 어쩌다보니 이번 프로젝트 발표자로 당첨이 되어버렸다... 그래서 notion을 보고 하는 것 보다는 git을 이용한 발표자료를 만들고자 git wiki를 사용해보기로 하였다. 일단 우리의 깃 허브에는 위키가 없었기에 Setting ->Features 항목에서 Wikis 체크박스를 선택 두둥.... 언어가 Markdown... Markdown 언어를 알아보도록 합시다. https://gist.github.com/ihoneymon/652be052a0727ad59601 이런 것들을 통해  내일 발표할 자료 완성 Markdown 언어 지식에 따라 엄청난 퀄리티 변화가 일어나는 것을 알게 되었고 다음에 또 wiki를 통한 자료를 남겨두거나 발표자료 준비를 해보도록 하겠다.

[C#] RPG 레벨링 작업

이미지
콘솔 RPG에 레벨링 작업을 하고 있는 도중 레벨링 계산식이 RPG에는 따로 있다고 하여 조사하려 알아보았다. 계산식은 레벨까지 필요 경험치 = ((레벨 - 1) * 50/49)^2.5 * 계수 가 되시겠다. 이걸 역계산하면 현재레벨 = (총경험치 / 계수 )^0.4 * 49/50 + 1 이 된다. 이것을 사용하여  를 구할 수 있게 되었다. 다음에 게임을 만들때 정말 유용한 코드가 될 수 있을거 같다.

[Git] 협업을 위한 브랜치 관리

이미지
 콘솔 RPG를 만들기 전 팀원간 역할을 정하였다. git에 conflict을 피하기 위해 그리고 잘못된 push로 인해 프로젝트가 날아갈 수 있기 때문에 Branch 관리에 신경을 많이 썼다. 각자 맡은 Branch에서 작업 후 Dev에서 합쳐보는  형식으로 최대한 conflict를 줄여보았다 수정 할 Branch 앞글자 + feature + 이니셜 ex)B_feature_JYP 이런식으로 다른 사람의 브랜치에 관하여 수정을 했을 경우 누가 수정을 했는지 알 수 있도록 이름을 뒤에 붙여 Branch를 생성하였다. 조금 시행착오를 겪어 예쁘지는 않지만 브랜치 관리가 되고 있다라는 것을 알 수 있다.

[Data] 데이터 형식 정리

이미지
 오늘 처음으로 팀 프로젝트에 들어가기 앞서 각자 맡을 부분과 데이터명과 형식을 정하였다. 그 때 사용 한 툴이  https://dbdiagram.io/ db다이어그램이다. 테이블을 만들어 데이터와 형식에 맞게 넣었다, 이렇게 표와 관계성까지 보여주는 툴이라 정말 유용한 것 같다.

[C#] 다른 파일에 있는 클래스 불러오기

이미지
 프로젝트를 마치면서 내가 쓴 코드를 보니까 정리가 하나도 안되어 작성한 나도 보기 힘들어 전부는 아니지만 한번 정리를 해보기로 했다. 별기능이 없었는데.... 한 파일 978줄.... 가독성이 너무 떨어져 파일을 쪼개보기로 하였다.     Program.cs에 있는 코드를 Item.cs / Dungeon.cs / Player.cs 로 나누어 주었다. Program.cs에 선언한 List 이름 앞에 각 파일 안에 들어가 있는 클래스 이름을 붙여주었다. 결과물은 바뀐 것이 없으나 그래도 파일들 정리를 '조금'이라도 해보았다. 처음부터 파일을 나누고 했더라면 좀 더 알아보기 쉽고 찾기도 쉬웠을 것이다. 이번 작업으로 처음 설계가 중요하다라는 것을 다시 깨닫았다. 정말 조금만 나눴는데 200줄이 줄었다 시간이 좀 더 있었으면 기능 별 파일을 만들어서 나누었을 것 같은데 아쉽다.

[Git] Visual Studio 2022 에서 git command 사용해보기

이미지
 개인 프로젝트가 어느정도 마무리가 되어 이제 git에 업로드 및 업데이트를 하려고 하였지만 vscode와 달리 command 콘솔창의 사용법이 달라 조금 헤메였다. 환경창에 git이라는 항목이 있다 처음에 Git 리포지토리를 만들기를 들어간 후 내 git 계정과 연결을 해준다. 그 후 gitdp 레파지토리를 초기화를 하게 되면 깃에 아주 잘 올라가는 것을 확인 하였다. 두번째로 그러면 업데이트(push)는 어떻게 하는 걸까? 나는 깃 명령 프로토콜을 실행하여 진행하려 하였으나 "git은 내부 또는 외부 명령 실행할 수 있는 프로그램 또는 배치 파일이 아닙니다" 라는 문구가 나를 가로막았다. 내 컴퓨터에 git이 설치가 되지 않아있었다는 사실을 깨닫고 다운 받았다. https://git-scm.com/download/win 작동을 확인 후 dev 브랜치를 만들어 똑같이 add -> commit -> push를 해주었다.   업데이트를 확인하였다. 이번 경험을 통하여 git desktop이 아닌 visual studio에서 직접 git에 업로드 및 업데이트를 하는 방법을 터득하였다. 다음 팀원들과의 협업에서 많은 도움이 될 것이다.

[C#] 콘솔 데이터 저장 및 불러오기

이미지
  콘솔에 있는 데이터를 저장하는 방법을 찾다 JSON 파일에 저장 후 불러오는 방법을 생각해 냈다. 저장에 Newtonsoft.Json 프레임워크를 사용하였다. 다음 방법은 도구 -> Nuget 패키지 관리자 -> 솔루션용 Nuget 패키지 관리로 들어가 다운 받으면 된다. 다운 후  사용을 해주고 세이브 / 로드 함수를 만들어 주었다. 살펴보자면 JsonConvert.SerializeObject(object) : list -> Json 파일 형식 변경 JsonConvert.DeserializeObject<List<list>>(json); : Json -> 리스트 파일 형식 변경 File.WriteAllText(@"경로", json); : Data를 .json 파일에 저장 File.ReadAllText(@"경로") : json 파일에서 Data 불러오기 저장/불러오기 경로가 서로 다르거나 없는 경로라면 작동을 하지 않기 때문에 조심해야한다. 그리고 List 하나의 항목만 저장은 가능하나 불러올때는 이유는 잘 모르겠지만  불러올 수 없었다. 그래서 새로운 리스트를 만들어 add를 해주어 Array로 감싸주었다. 데이터를 쌓은 후 저장을 해고 종료 후 다시 실행 데이터가 없는 것을 확인 후 로드 데이터가 고스란히 들어오는 것을 확인 하였다. 이게 저장 불러오기를 할 때 많이 사용하는 방법인지는 알고 있지 못하나  프레임워크를 이용해 간단하게 구현을 해보았다

[C#] Array 활용법

이미지
 js와 달리 C#의 array는 뭔가 좀 더 복잡한 것 같다. Array.push()만 쓰면 추가 되는 js 와 달리 C#에서는 새요소를 추가하려면 조금 복잡하게 넣어야 하는 것 같다. 1. Array.CopyTo() 새로운 요소를 수용하기 위해 더 큰 Array를 할당하는 방법이다. 2. Enumerable.Concat 두 입력 시퀀스의 요소를 연결하는 메서드이다 3. 목록으로 변환 리스트로 변환후 다시 어레이로 변환 시키는 방법이 있을것 같다.

[Unity] 자주 사용하는 문법

이미지
  Transform 트랜스폼의 포지션, 회전 및 스케일 값은  트랜스폼 부모를 기준으로 측정됩니다.  트랜스폼에 부모가 없는 경우 프로퍼티는 월드 공간에서 측정된다. ex)  newCard.transform.position = new Vector3(x, y, 0); - GameObject 새 게임 오브젝트를 생성합니다. ex) GameObject player = new GameObject("Player"); - SetActive GameObject를 활성화 / 비활성화합니다. ex) gameObject.SetActive(false); - Instantiate 오브젝트의 인스턴스 ID를 반환하며, 선택한 오브젝트를 복제해서 생성합니다. ex)   GameObject newCard = Instantiate(card); - Find 게임 오브젝트를 찾는 함수이며, 게임 오브젝트를 찾을 수 없다면, null이 반환됩니다. ex)  newCard.transform.Find("front") - GetComponent 다른 구성 요소에 액세스 하는 기본 방법입니다.  이 함수를 사용하여 내장 구성 요소 또는 스크립트에 모두 액세스 할 수 있습니다. ex)   GameObject player = new GameObject("Player"); - FindWithTag 태그 된 하나의 활성 GameObject를 반환합니다.  게임 오브젝트를 찾지 못했으면 null을 반환합니다. ex)  GameObject player = GameObject.FindWithTag("Player"); - Destroy 게임 오브젝트, 컴포넌트나 애셋을 삭제합니다. ex)  Destroy(gameObject);

C# 자료형

이미지
 지금까지 사용했던 언어 중에 가장 힘든 부분이 형 변환인 것 같아 한번 정리를 해보기로 하였다 많은 자료형들이 있지만  중요한 형은 크게  string, int, float, bool  이다 string - 문자(한글,영어 etc) int - 정수 float - 실수(소수점 7자리까지) bool - true / false 여기서 가장 헷갈리는 것은 형변환이다. 숫자와 숫자 끼리의 형변환은 (int) <-> (float) 앞에 ( ) 안에 명시하고 싶은 자료형을 적으면 된다. ex) 다른 자료형에서 문자형의 변경은 . ToString()을 붙이면 변환할 수 있다 이곳이 가장 헷갈리는 부분인데 문자형에서 다른 자료형으로 변형 시킬 때 나는 Parse() 함수를 사용 하려고 한다. 원하는 자료형의 이름 후 parse만 사용하면 되는 간단한 변환 방법이다.