Vector3.Lerp()
는 두 벡터 사이를 선형 보간(Linear Interpolation)하여 주어진 시간 비율에 따라 중간 위치를 계산하는 함수입니다. 이 함수를 사용하면 두 위치 사이를 부드럽게 이동하는 효과를 만들 수 있습니다.
Vector3.Lerp(Vector3 a, Vector3 b, float t);
0
에서 1
사이의 값을 가집니다.t
가 0
이면 반환 값은 a
와 동일합니다.t
가 1
이면 반환 값은 b
와 동일합니다.t
가 0.5
면 a
와 b
의 중간 지점이 반환됩니다.t
값이 0에서 1로 증가할수록 a
에서 b
로 점진적으로 이동하게 됩니다.
Random.insideUnitCircle
은 Unity에서 제공하는 Random
클래스의 함수로, 반지름이 1인 단위 원 안의 무작위 점을 반환합니다. 이 함수는 2D에서 원형 영역 내의 임의의 위치를 얻을 때 유용합니다. 반환되는 값은 Vector2 타입이며, 단위 원의 중심을 (0, 0)
으로 기준으로 합니다.
normalized
는 벡터(Vector)의 크기(길이)를 1로 맞추면서 같은 방향을 유지하는 단위 벡터를 의미합니다. Unity의 Vector3
와 Vector2
구조체에 포함된 프로퍼티로, 벡터의 방향을 유지하면서 길이만 1로 변경합니다.
Vector3 originalVector = new Vector3(3, 4, 0);
Vector3 normalizedVector = originalVector.normalized;
C#에서는 readonly
필드나 const
필드 또는 람다 표현식을 사용해 간단히 값을 정의할 수 있습니다. 이러한 방식으로 필요한 값을 코드의 어디에서든 바로 사용할 수 있게 합니다.
readonly
필드 사용다음과 같이 readonly
필드로 무작위 단위를 정의할 수 있습니다.
private readonly Vector2 RandomDirection = Random.insideUnitCircle.normalized;
이 경우 RandomDirection
은 생성자에서만 설정할 수 있으므로, 필요에 따라 한 번만 초기화되는 값이라면 적합한 방식입니다. 그러나 매번 새로운 값을 필요로 한다면 이 방식은 적합하지 않습니다.
람다 표현식을 사용해 간단히 구현할 수도 있습니다. RandomDirection
을 메서드로 정의하는 대신, 아래와 같이 람다로 정의하면 함수처럼 호출하면서도 더 간결하게 사용할 수 있습니다.
private Vector2 RandomDirection => Random.insideUnitCircle.normalized;
이렇게 하면 RandomDirection
을 호출할 때마다 새로운 무작위 방향을 반환합니다.
static
필드로 정의 (공통적으로 사용할 경우)프로젝트에서 여러 곳에서 공통적으로 사용하는 무작위 방향이 필요하다면, static
필드로 정의할 수도 있습니다.
public static Vector2 RandomDirection => Random.insideUnitCircle.normalized;
Renderer
: 모든 렌더러의 기본 클래스이며, 3D와 2D 렌더러를 포함하여 공통 속성에 접근할 수 있습니다.SpriteRenderer
: 2D 전용 렌더러로, 스프라이트를 화면에 표시하고 2D 스프라이트 전용 기능에 접근할 수 있습니다.따라서, 2D 스프라이트를 다룰 때는 SpriteRenderer
, 공통적인 렌더링 속성에 접근할 때는 Renderer
를 사용하는 것이 좋습니다.
animation 만들 때 show sample rate 하고 sample rate 조절
스프라이트 끌어당겨도 안 들어가면 시간 선에 정확히 드래그앤드랍
파리 랜덤 움직임 구현? : spline interpolation
https://www.youtube.com/watch?v=7j_BNf9s0jM
spline interpolation
[SerializeField] private Transform pointA;
[SerializeField] private Transform pointB;
[SerializeField] private Transform pointAB;
private float interpolateAmount;
private void Update()
{
interpolateAmount = (interpolateAmount + Time.deltaTime) % 1f;
pointAB.position = Vector3.Lerp(pointA.position, pointB.position, interpolateAmount);
}
선형 보간
private void Update()
{
interpolateAmount = (interpolateAmount + Time.deltaTime) % 1f;
pointAB.position = Vector3.Lerp(pointA.position, pointB.position, interpolateAmount);
pointBC.position = Vector3.Lerp(pointB.position, pointC.position, interpolateAmount);
pointCD.position = Vector3.Lerp(pointC.position, pointD.position, interpolateAmount);
pointAB_BC.position = Vector3.Lerp(pointAB.position, pointBC.position, interpolateAmount);
pointBC_CD.position = Vector3.Lerp(pointBC.position, pointCD.position, interpolateAmount);
pointABCD.position = Vector3.Lerp(pointAB_BC.position, pointBC_CD.position, interpolateAmount);
}
앵커와 핸들
private float interpolateAmount;
private void Update()
{
interpolateAmount = (interpolateAmount + Time.deltaTime) % 1f;
/*
pointAB.position = Vector3.Lerp(pointA.position, pointB.position, interpolateAmount);
pointBC.position = Vector3.Lerp(pointB.position, pointC.position, interpolateAmount);
pointCD.position = Vector3.Lerp(pointC.position, pointD.position, interpolateAmount);
pointAB_BC.position = Vector3.Lerp(pointAB.position, pointBC.position, interpolateAmount);
pointBC_CD.position = Vector3.Lerp(pointBC.position, pointCD.position, interpolateAmount);
pointABCD.position = Vector3.Lerp(pointAB_BC.position, pointBC_CD.position, interpolateAmount);
*/
pointABCD.position = CubicLerp(pointA.position, pointB.position, pointC.position, pointD.position, interpolateAmount);
}
private Vector3 QuadraticLerp(Vector3 a, Vector3 b, Vector3 c, float t)
{
Vector3 ab = Vector3.Lerp(a, b, t);
Vector3 bc = Vector3.Lerp(b, c, t);
return Vector3.Lerp(ab, bc, interpolateAmount);
}
private Vector3 CubicLerp(Vector3 a, Vector3 b, Vector3 c, Vector3 d, float t)
{
Vector3 ab_bc = QuadraticLerp(a, b, c, t);
Vector3 bc_cd = QuadraticLerp(b, c, d, t);
return Vector3.Lerp(ab_bc, bc_cd, interpolateAmount);
}
리팩토링
찾아보니까 UnityEngines.Splines 있는데 using 써보니까 안됨.
패키지 깔아야 되는듯. 근데 여기까지 다 따라해놓고 딸깍은 좀.
렌더러나 콜라이더 바운드 가져올 수 있구나
gameObject.position이 아니라 gameObject.transform.position이구나 (물론 gameObject는 생략하고 바로 transform.postion도 가능)
public class RandomFly : MonoBehaviour
{
private Vector2 RandomDirection => Random.insideUnitCircle.normalized;
private Vector2[] Course;
private float interpolateAmount;
[SerializeField] private GameObject SpawnArea;
void Awake()
{
// 스폰 위치 정해놓고 그 안에서만 랜덤하게 스폰
Bounds SpawnBounds = SpawnArea.GetComponent<Renderer>().bounds;
float randomX = Random.Range(SpawnBounds.min.x, SpawnBounds.max.x);
float randomY = Random.Range(SpawnBounds.min.y, SpawnBounds.max.y);
transform.position = new Vector2(randomX, randomY);
Course = RandomNewCourse(transform.position, 10f);
}
void Update()
{
interpolateAmount += Time.deltaTime;
Debug.Log("interpolateAmount = " + interpolateAmount);
if (interpolateAmount > 1f)
{
interpolateAmount = 0;
Course = RandomNewCourse(transform.position, 10f);
}
transform.position = QuadraticLerp(Course[0], Course[1], Course[2], interpolateAmount);
}
// 2중 보간
private Vector2 QuadraticLerp(Vector2 a, Vector2 b, Vector2 c, float t)
{
Vector2 ab = Vector2.Lerp(a, b, t);
Vector2 bc = Vector2.Lerp(b, c, t);
return Vector2.Lerp(ab, bc, t);
}
// 시작점에서 가까운 점 C를 고르고, 멀 수도 있는 점 B를 고른다.
private Vector2[] RandomNewCourse(Vector2 start, float maxDistance)
{
float d_close = Random.Range(0, maxDistance);
float d_far = Random.Range(0, maxDistance * 2);
Vector2[] NewCourse = new Vector2[3];
NewCourse[0] = start;
NewCourse[1] = start + RandomDirection * d_far;
NewCourse[2] = start + RandomDirection * d_close;
return NewCourse;
}
}
일단 이제 날아다니긴 함. 이상하게 날아다니는게 문제지.
문제를 해결하는 연습을 더 하고,
문제를 해결하는 능력을 내세울 것.
다른 것은 부차적이다.
면접관은 바쁘기 때문에 첫 30초 이후에 읽을지 말지를 결정한다.
첫번째 장
: 일단 블로그 링크는 넘김. 이건 나중에 흥미가 생겼을 때 유의미한 정보가 됨.
첫번째 장에서 유의미한 키워드는 운영체제, 스케줄링, 시스템 콜, 가상 메모리 정도.
이렇게 많은 지면을 할애해서 남는게 정보 4개밖에 없음.
두번째 장
: 유니티 써봤구나, 웹으로 뭔가 게임 만들어봤구나.
이력서 보는 사람이 컴공 아니면 red black tree도 모를 수도.
web server 구현했다는 것도 오해의 소지가 있음. 근데 뭔가 c를 이용해서 해봤나보네.
핀토스가 뭔지 면접관은 모름. 운영체제를 책으로 배웠다고 오해할수도.
세번째 장
: (원래는 여기까지도 안 가지만) 여기엔 유의미한 정보가 좀 있네. 이런 것들 할 줄 알구나.
종합
새로 쓰면
종합적으로 : 내가 어떤 '기술자'인지에 대한 설명을 보여줘야 하고, 실력을 길러야 한다.
CS랑 포폴 준비(기술 스택 공부)는 내가 부족하다 싶은 부분에 비중 더 두면 되는 것.
요새 면접 대비용 CS 책들 잘 나와있는거 있으니까 그거 보면
코치님의 피드백
1분 자기소개
안녕하세요! (회사이름) (직무)에 지원한 OOO입니다.
저는 학부 때 OO을 전공했고, OO에서 OO으로 1년 반 가까이 근무했습니다.
( 회사에 지원한 이유 ).
저는 빠르게 성장하는 개발자입니다. ( 근거 ).
저는 성실하게 성장하는 개발자입니다. 현재 5개월 가까이 하루도 빠짐없이 TIL을 작성하고 있습니다.
저는 기초를 중요시하는 개발자입니다. 개발자로의 이직을 결정하고 나서 크래프톤 정글이라는 부트캠프에서 컴퓨터 공학을 배우며 기초를 먼저 쌓았습니다.
( 회사에 입사한다면 어떤 부분에서 기여하고 싶은지 말하기 )
본인에게 가장 큰 영향을 준 프로젝트는 무엇인가요?
10년 후에 어떤 개발자가 되고 싶나요?
왜 프로그래밍을 시작했나요?
최근 읽은 기술 책은 무엇인가요?
본인의 강점은 무엇인가요?
프로젝트 일정을 계산할 때 팁이 있나요? 혹은 산정을 잘못한 경험을 얘기해주세요
모르는 기술의 경우 어떻게 학습합니까?
원격 협업을 어떻게 생각하시나요?
만약 불가능한 이슈를 수행해야 한다면 어떻게 하겠는가?
논쟁이 벌어지면 어떻게 해야 하나요?
팀원간 의견 불일치가 생긴 경험과 해결한 경험이 있나요?
리더에게 필요한 것은 무엇인가요?
바빠 보이는 상대방에게 꼭 도움을 청해야 한다면 어떻게 하나요?
기술 스택은 어떻게 정하나요?
프로젝트를 함에 있어서 "빠른 호흡"에 대해 어떻게 생각하나요?
마지막으로 회사에 궁금한 것이 있나요?
추상 자료형 : 뭐를 하라는 것만 정의돼있음. 어떻게 하는지는 자유. 스택이나 큐를 뭘로 만들던 상관이 없다. 그냥 FIFO랑 LIFO만 지키면 됨. 리스트도 add, remove, get만 되면 됨. 배열로 만들었는지 연결 리스트로 만들었는지 궁금하지 않음.
자료 구조 : 실제 구현
이게 이렇게 오래 걸릴 문제가 아닌 것 같은데 하
N=int(input())
for i in range(N):
for j in range(N):
temp_i, temp_j = i, j
flag = False
if temp_i % 3 == 1 and temp_j % 3 == 1:
flag = True
while temp_i >= 3 and temp_j >= 3:
temp_i //= 3
temp_j //= 3
if temp_i % 3 == 1 and temp_j % 3 == 1:
flag = True
if flag:
print(" ",end="")
else:
print("*", end="")
print("")
if문 while에서 밖으로 뺐더니 일정 크기 이상은 찍어주질 못함
안으로 넣었더니 정상 작동
맞았다고 생각해서 제출했더니
시간 초과
내일 다시 하자...
쉬운거라고 생각해서 풀고 가려고 한 거였는데
예상보다 늦어진데다 맞았습니다도 못 띄움