정리필요

 

인스턴스

 

 

 

static 스태틱

-유니티에서 알게 모르게 쓰고있던 Static들

   ->클래스 인스턴스를 생성하지 않고 바로 사용한것이 Static이라 했다.

      GameObjec.Find("Player");

      우리가 자주 썼던 이 함수 또한 원래라면 인스턴스 생성하고 써야 했지만, Find함수는 Static으로 만들어졌기 때문에 그냥 바로       클래스에서 접근이 가능하다.

 

 

 

싱글톤

 

gpt는 도구로 사용하기

ex)방법을 알려줘(방법 서칭용)

->canvasr가뭐지?color가 뭐지?같은 기능을 묻는건 ok

->유니티 리지드바디의 Interpolate와 Collision Detection에 대해 설명해줄래?

 

인스펙터의 rigidbody 기능 알아보기- 어떤 상황에서 어떻게 쓰이는지 학습하기ex)Mass, Linear Damping

숙제

1.간단한 UI 추가해서 블럭이 쌓일때마다 1점씩 추가

2. [선택사항]
시간이 지날수록 또는 떨어트린 블럭의 개수가 많아질수록 난이도 증가
특수 블럭 같은거 : 골든 블럭 ( 점수 2배 ) , 짱큰 블럭  ( 더 큰 크기), 개빠른 블럭 (좌우 움직이는게 엄청 빠른 블럭)

 

 

 

 

 


오프셋

기준 위치는 오브젝트의 원래 위치이다.

 

Offset은 기준 위치에서 얼마나 떨어졌는지를 나타내는 변화량이다.
기준 위치 자체는 포함하지 않는다.

Sin 값(Mathf.Sin)은 -1 ~ 1 사이를 오가는 파형 값이며, 그 자체로는 Offset이 아니다.

Sin 값에 거리(range)를 곱하면 실제 Offset이 만들어진다.

최종 위치는 항상 기준 위치 + Offset으로 계산된다.

즉,

기준 위치 → startX
Offset → x
결과 위치 → startX + x

 

기준 위치까지 포함된 값은 Offset이 아니라 “결과 위치”이다.

이 개념은 위치 이동뿐 아니라회전, 스케일, 카메라 흔들림 등모든 진동 표현의 기본 구조이다

 


Unity Rigidbody의 Collision Detection(충돌 감지)

충돌 감지 방식은 물리 엔진이 얼마나 정밀하게 충돌을 계산할지 결정합니다.

네가지 옵션 Discreate, Continuous, Continous Dynamic, Continuous Speculative이 있음.

 

빠르게 움직이는 발사체(총알, 미사일), 고속이동캐릭터. 얇은 벽이나 바닥이 있는 게임에서 터널링을 방지하려면 Continous Dynamic 이상을 사용해야 합니다. 느리게 움직이거나 큰 객체는 Discreate로 충분합니다

 

Discreate: 기본 설정, 각 물리 프레임마다 한 번만 충돌을 체크합니다. 빠르지만 빠르게 움직이는 객체가 얇은 벽을 통과하는 "터널링" 현상이 발생할 수 있습니다.

 

Continuous: 정적 메시 콜라이더(static mesh collider)에 대해 연속적인 충돌 감지를 수행합니다. 움직이는 객체가 정적인 벽을 뚫고 지나가는 것을 방지합니다.

 

Continuous Dynamic: 다른 동적 객체와 정적 객체 모두에 대해 연속 충돌 감지를 수행합니다.

가장 정밀하지만 성능 비용이 높습니다.

 

Continuous Speculative: 연속 충돌 감지를 사용하되 추측 기반으로 작동해서 Continuous Dynamic 보다 성능이 좋습니다. 

 

참고자료

https://garagefarm.net/ko-blog/collision-detection-in-2d-and-3d-concepts-and-techniques

https://blog.naver.com/PostView.nhn?blogId=jerrypoiu&logNo=221172549241

 

 

 


raycast

Debug.DrawRay(dropBlock.transform.position, dropBlock.transform.up * -checkDistance, Color.red);
if(Physics.Raycast(dropBlock.transform.position, dropBlock.transform.up * -1f, out RaycastHit hit, checkDistance))
{
    Debug.Log("닿음");

    if(hit.collider.CompareTag("Plane"))
    {
        Debug.Log("게임오버");
    }

    if(hit.collider.CompareTag("Block"))
    {
        Debug.Log("블럭에 닿음");
        dropBlock.GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezeAll;
        dropBlock.GetComponent<Rigidbody>().isKinematic = true;
    }
}

 

 

hit 6 개를 많이 쓴다(정리하기)

hit.normal

hit.collider ( 예시: hit.collider.CompareTag("Block")처럼~  ) 

 


OnCollisionEnter

private void OnCollisionEnter(Collision collision){}

"물체가 처음으로 다른 물체와 부딪히는 순간 자동으로 실행되는 함수"다

 

* Collision collision: 부딪힌 상대 정보가 들어 있음. 누구랑 부딪혔는지 알려주는상자. 예를 들면 바닥인가? 블럭인가? 어떤 GameObject인가?이런

 

*On: ~했을때 ,  Ondestory나 OnCollisionEnter처럼

*둘 다 collider가 있어야함(둘다 Is Trigger 꺼져있어야함)+ 둘 중 하나 이상 rigidbody가 있어야함(Rigidbody가 없으면 안불린다.).

 

private void OnCollisionEnter(Collision collision){}이런식으로 쓰며, 

OnCollisionEnter함수안에 if문으로 collision.transform.CompareTag("Plane") 이렇게 쓸 수 있음.

* 쓰다가 문득 생각이 난건데, transform.CompareTag도 가능하지만 당연히 GameObject.CompareTag도 가능함

 

 

 

 


isDrop 기본값을 false로 시작하는이유

public bool isDrop = false;

 void Update()
 {
     if (isDrop == true)
     {

     }
     else
     {
         Move();
     }

 }

처음 보면 이 코드가 "false니까 뭔가 예외처리인가?"라고 햇갈릴 수 있다.

하지만 isDrop은 예외처리용 변수가 아니라 "상태(state)"를 나타내는 변수다.

 

왜 기본값을 false로 시작하나?

블록의 흐름을 생각해보면 생성됨, 좌우로 움직임, 떨어짐, 충돌 등  이과정에서 블록은 대부분의 시간동안 '아직 떨어지지않은 상태'이고, Drop()이라는 특정 이벤트가 발생한 뒤에만 상태가 바뀐다.

그래서 대부분의 시간 = false, 특정 이벤트(Drop)에서만 true 이흐름이 자연스럽기 때문에 isDrop의 기본값을 false로 둔다.

 

예외처리랑 햇갈리는 이유

if (isFirst == true)
{
    return;
}

이건 "특정 조건에서는 이 로직을 아예 실행하지 마라"라는 예외(가드) 처리이다.

반면 isDrop은 한번 걸러내고 끝내는 예외X, 계속 유지되는 현재 상태O  라는 점에서 성격이 완전히 다르다.

 

IF문 안이 비어 있는게 낯선 이유

if (isDrop == true)
{

}
else
{
    Move();
}

"이미 떨어진 상태라면 아무것도 하지말고, 아직 떨어지지 않았다면 움직여라."

즉, if(isDrop == true)는  무언가 하라는 조건이 아니라, Move를 하지말아야하는 상태를 표현한것이다.


예외처리

Spawner.cs의 코드

block.isFirst = isFirstBlock;
isFirstBlock = false;

이코드는 "이 블록이 예외 대상인지 아닌지 딱 한번 결정해준다"

 

Block.cs의 코드

 // 대충 처음이면 리턴하고 처음 아니면 아래 코드 진행
 if(isFirst == true)
 {
     return;
 }

 

 if (collision.transform.CompareTag("Plane"))
 {
     Debug.Log("게임오버");
 }

//제일 처음 떨어지는 블록이 plan과 닿았을때는 "게임오버"가 되면 안된다

 if (collision.transform.CompareTag("Block"))
 {
     Debug.Log("블럭끼리 닿음");
     GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezeAll;
 }

여기서의 if (isFirst == true) 코드는 " 예외 대상이면 이 함수는 아무 일도 안하고 끝낸다"

 

이 둘은 이렇게 연결되돼 있다.

 

[Spawner]
  └─ 너는 첫 블록이야? (isFirstBlock)
        ↓ 값 전달
[Block]
  └─ 아, 난 첫 블록이구나 (isFirst)
        ↓
  └─ 그럼 충돌 판정 무시

 

결론: Spawner는 ‘예외 대상’을 결정하고, Block은 ‘예외일 때 행동하지 않는다'.

 


간단한 UI추가해서 블럭이 쌓일때마다 1점씩 추가하기(숙제)

 

1.Canvas생성

Hierarchay창에서 빈공간 우클릭 -> UI에서 Canvas 선택 ->그러면 Canvas,EvantSystem이 자동으로 생성됨

 

2. Text생성

생성된 Canvas 오브젝트를 우클릭 -> UI에서 Text-TextMeshPro선택 -> 처음 사용시 "Import TMP Essentials"팝업이 뜨면 Import 클릭

 

3. Text 설정

생성된 Text 오브젝트 선택 -> Inspector에서 Text Input에 "Score:0" 입력

 

4.ScoreManager 오브젝트 생성

Hierarchy 빈 공간 우클릭 -> Create Empty(빈오브젝트 생성) -> 이름을 "ScoreManager"로 변경 -> ScoreManager 스크립트 드래그해서 추가 -> Score Text 필드에 위에서 만든 Text 오브젝트를 드래그

'수업' 카테고리의 다른 글

20260225-1  (0) 2026.02.26
260114  (0) 2026.01.17
261010  (0) 2026.01.10

+ Recent posts