01/23 본캠프 #21

guno park·2024년 1월 23일
0

본캠프

목록 보기
21/77
post-thumbnail

---알고리즘---

신고 결과 받기

문제 링크

풀이

이번 문제는 딕셔너리를 사용해 풀었다. (딕셔너리 사용법)
입력받은 값들에 따라
1번 딕셔너리 = ID(string) - 신고당한 횟수(int)
2번 딕셔너리 = 신고한 사람(string) - 신고 대상자(string[])
로 분리해서 저장해주었고, 똑같은 신고 내용은 Distinct를 사용해 제거했다.
중복 제거

그 후 정리된 신고내용을 반복문을 통해 신고 당한 횟수에 더하고,
정지될 ID들을 선별해 신고한 사람을 키값으로 가지는 딕셔너리(id_List순서로 배치되어있음)에서 신고 대상자 중 정지된 인물을 포함하는 인덱스에 ++해준다.

using System;
using System.Collections.Generic;
using System.Linq;

public class Solution {
    public int[] solution(string[] id_list, string[] report, int k) {
           int[] answer = new int[id_list.Length];
        Dictionary<string,int> IDDic = new Dictionary<string,int>();
        Dictionary<string,List<string>> reportDic = new Dictionary<string,List<string>>();
        string[] newreport = report.Distinct().ToArray();
        
        foreach (string ID in id_list)
        {
            IDDic.Add(ID,0);
        }
        
        for (int i=0;i<newreport.Length;i++)
        {
            string[] reportlist = newreport[i].Split(' ');
            IDDic[reportlist[1]]++;
            if (reportDic.ContainsKey(reportlist[0]))
            {       
                if (reportlist[1] != reportlist[0])
                {
                    reportDic[reportlist[0]].Add(reportlist[1]);
                }                    
            }
            else
            {
                if (reportlist[1] != reportlist[0])
                {
                    reportDic.Add(reportlist[0],new List<string>());
                    reportDic[reportlist[0]].Add(reportlist[1]);                    
                }
            }
        }

        List<string> stopId = new List<string>();

        foreach (string keys  in IDDic.Keys)
        {
            if (IDDic[keys] >=k)
                stopId.Add(keys);
        }

         for (int i=0;i<id_list.Length;i++)
        {
             if (reportDic.ContainsKey(id_list[i]))
            {
                foreach (var id in stopId)
                {
                    if (reportDic[id_list[i]].Contains(id))
                        answer[i]++;
                }
            }
        }
        return answer;
    }
}

트러블 슈팅

특정 테스트들을 통과하지 못하는 문제 발생, 반례를 찾아 디버깅 해본 결과, 처음 작성했던 반복문이 제대로 돌아가지 않던 문제를 확인했다.

int num=0;
 for (var variable in id_list)
        {
            if (reportDic.ContainsKey(variable)
            {
                foreach (var id in stopId)
                {
                    if (reportDic[variable].Contains(id))
                        answer[i]++;
                }
                  num++;
            }
        }


for문을 사용해 변수 두개를 같이 증가시키고자 할 때 사용하던 방법인데,

이 num은 해당 키 값이 있든 없든 증가해야하는데, 좀 더 안쪽에 넣어놔서 증가하지 않게되었다.
반례 : ("abc", "abcd"], ["abcd abc"],1)(출처)

---개인과제 해설영상 정리---

내용 정리

ppu

ppu 설정할 때 스프라이트 크기 보고 결정하면 편함.
ppu를 바꾸고 스케일을 안건드리는게 좋음.

Input 관련

타임,델타타임 = 프레임단위 보정값
getaxis = 소숫점도 포함 ,getaxisraw -1.1
대각이동은 노멀라이즈 -벡터의 방향값을 얻어옴

mousePosition

스크린의 좌표값은 카메라가 가지고 있다.
태그에 메인카메라 붙어있는게 있다, camera.main 호출하면 그게 호출됨
ScreenToWorldPoint(newAim);
vector3 mouscepos = Input.mouseposition;
스크린에서의 좌표는 왼쪽아래가 작고 오른쪽위로 갈수록 크다
스크린 크기 받아오기
Screen.width / Screen.heigth

if (mousePos.x > Screen.width/2)
{
spriterenderer.flipX(false);
}
else if ( mousePos.x < Screen.width/2)
{
spriterenderer.flipX(true);
}

Input System

  • 인풋시스템 오토세이브하면 값을 변경할떄마다 로딩이 계속 걸리니까 그냥 저장을 자주하자
  • 인풋시스템에서 정규화벡터로 설정해줄수있다.
    인풋시스템은 꼭 꼭 컴포넌트 넣어줘야됨. 중요한 이유 내가 기억을 못하고있음
  • 비헤비어
    센드 메시지 - 해당 오브젝트에만
    브로드캐스트 메시지 - 자식오브젝트에도 보냄
    인보크 유니티 이벤트 - 키입력에 따라 이벤트를 직접 넣어줘야됨. (버튼에 이벤트 넣듯)

이벤트 연결하기

이벤트 연결을 이해하기 쉽게 델리게이트로 설명.

  • 델리게이트 선언
    public void CallMoveEvent(Vector2 direction){
    OnMoveEvent?.Invoke(direction)
    }

  • 이벤트 작동 방식의 비유
    책임자 - 콜백을 받아 각 이벤트를 실행 시키는 스크립트
    대리자 - 매개변수를 콜백을 통해 전달하는 스크립트
    실행자 - 이벤트 실행 시 실제 동작을 수행하는 스크립트로 실행메서드 보유하고 있으며 책임자를 가져와 준비된 이벤트에 메서드를 등록해야 이벤트가 연결되었다고 할 수 있다.

event

public OnMoveDel OnMoveEvent;
public event OnMoveDel OnMoveEvent;
두개의 차이는?

event가 없으면 외부 스크립트에서 호출 가능함
_controller.OnMoveEvent.Invoke();
event 있으면 해당 스크립트 내에서만 실행 가능함.

Action과 Func(익명대리자) Delegate 차이

Action => public event Action OnMoveEvent; 반환이 없을 때
델리게이트의 반환값이 void 일 때 Action으로 축약할 수 있다.
Func => public event Func OnMoveEvent; 반환이 있을 때
델리게이트의 반환값이 있을 때 Func으로 축약할 수 있다.

tilemap 관련

  • 타일맵을 칠하기 전, 타일 팔레트를 구성하는데 나는 한칸씩 잘리도록 만들었는데, 그냥 픽셀에 맞춰 자르지 않고 넣어두어도 드래그해서 그 타일을 고를 수 있더라.
  • 타일맵 하위에 빈 오브젝트 만들고 텍스트 넣어서 맵에 표시할 수 있다.
    개인과제 할 때 UI로 표시했었는데 맵에 넣는 편이 더 깔끔할 듯 하다.

Button 관련

  • 버튼에 이벤트 넣어주려면 public void로 선언해야 한다.
  • InputField 안에 값이 있는지 없는지 체크하려면
    if (string.IsNullorEmpty(inputField.text)) -> 이렇게 작성하면 된다.

이름표 만들기

나는 카메라가 어차피 따라다녀서 playingUI에 이름 넣엇는데,
플레이어 오브젝트 하위에 Canvas 생성 후 월드스페이스로 하면 플레이어 따라서 움직이는 이름표가 생성 가능하다.

스프라이트

각기 크기가 다른 스프라이트를 사용하다보면, 스프라이트가 찌그러질 때가 있다.
그럴 때 사용하는 속성이다.
setNativeSize 하면 비율이 맞춰진다 .코드에서는 SpriteRenderer.SetNativeSize();

싱글턴

awake 할때
instance = this는 조건을 if (instance==null)일때만
아니라면 한개가 더 만들어졌다는 소리니까 Destroy(gameobject)해줘야됨.

특강 : 게임 개발자와 업계 직무에 대한 이해

  • 유니티 프로그래머로서 게임 개발자를 한다는 것은 클라이언트 프로그래머를 한다는 것

  • 오브젝트 배치나 맵 같은건 개발자가 할 수도 있고 아트팀이 할수도있지만, 개발자도 할줄 알아야된다. 결국 코드를 건드리는게 클라이언트 프로그래머라서

  • 기획자들도 쉽게 이용할 수 있게 툴을 만들어줌 - 에디터 프로그래밍

firebase
빌드 자동화(젠킨스) - 오전 10시에 빌드를 실행하겠다 라고 코드로 작성을 해놓으면 자동으로 빌드를 해주는 솔루션

갖추어야 할 것

협업(커뮤니케이션)
검색
Unity Documnet,Google,Stack over flow 내가 필요로 하는 기능이 유니티에서 만들거나 사용할 수 있는지
설계
디버깅

유니티 팁

---청소---

하는 이유

버전에 따라 달라지거나 깃허브에 올리다보면 프로젝트 세팅이랑 유저세팅이 달라질 수도 있어서 라이브러리가 깨지거나 한쪽에서 라이브러리 버전을 업데이트하면 다른 컴퓨터에서 못 따라오는 경우가 생긴다.

해결 방법

에셋이랑 깃파일만 남겨두고 전부 삭제한 후, 재실행 해서 패키지들을 다시 설치해줘야 한다.
설치가 끝나면 File - BuildSetting에서 씬도 다시 등록해주자.
소스에 유저 기록이 남을수도 있으니까 로그아웃도 한번 해주는게 좋음.
(Hub 로그아웃 한번 하라는 뜻)

유니티 개인과제 수정

오늘 개인과제 해설 영상을 보다가 갑자기 이름에 글자제한이 있다고 하길래 부랴부랴 만들었다.

public void setname()
  {
      string rename = InputField.text; //입력된 이름 가져오기
      if (rename.Length >= 2 && rename.Length <= 10) //길이 체크
      {
          _PlayerName = rename;
          SceneManager.LoadScene("MainScene");
      }
      else  //길이가 조건에 맞지 않을 시 동작
      {
          StopCoroutine("namefail");
          StartCoroutine("namefail");
      }
  }

  IEnumerator namefail() //조건에 맞지않는다는 문구를 2초동안 출력
  {
      NameFailed.SetActive(true);
      yield return new WaitForSeconds(2f);
      NameFailed.SetActive(false);
  }

내일 할 일

  1. 알고리즘 1개만
  2. 유니티 입문 팀 프로젝트 시작

0개의 댓글