2025유니티수업

0513 유니티 1인칭, 콜라이더 뚫림 현상 관련, 코루틴, tuple(튜플)

버스창문 2025. 5. 13. 15:18

occulusion 0일때

 

1일때

 

오클루전 : 간접조명을 받는 정도를 그려놓은 것

위에 있는게 오클루전 맵인데, 검은색은 조명을 안받고 흰색은 조명을 많이 받게 해서 나무의 무늬등이 명확하게 드러남

 

 

 

 

 

모델에서 Scale Factor를 크게 하면 실제 모델 사이즈가 커짐

 

0.1일때

 

1일때

 

 

 

 

Ocullusion Culling(오큘루전 컬링)

카메라 시야에서 안보이게 처리하는 것

카메라의 시야가 다른곳에 있을 땐 숨김처리 하는것

 

 

 

각각에 레이어 부착

 

메인카메라에 있음

 

 

Mask에 Nothing해두면

아무것도 안잡힘

 

체크하면 잡힘

 

 

 

 

[Header("좌우 위아래 회전")]
[Range(0,100)]
public float Xsensitivity = 100f; //X축 감도
[Range(0,100)]
public float YSensitivity = 100f; //Y축 감도

 

 

저런 드래그 옵션이 생김

 

 

 

private void Rotating()
{
    xRot += Input.GetAxis(mouseX) * Xsensitivity * Time.deltaTime;
    yRot += Input.GetAxis(mouseY) * YSensitivity * Time.deltaTime;
    yRot = Mathf.Clamp(yRot, yMinLimit, yMaxLimit);

    //transform.Rotate(new Vector3(yRot, xRot, 0)); //마우스가 y로 돌아가면 x가 바뀌고 x로 돌아가면 y가 바뀜
    transform.localEulerAngles = new Vector3(yRot, xRot, 0);
}



localEulerAngles
local = 자신의 부모 오브젝트 기준
EulerAngles =  오일러각

회전을 주는 내용이고 , 이걸 쓸 땐 xRot이 누적해서 계속 대입되는 식으로 들어가야 함

오일러각은 축이 겹치는 짐벌락 현상이 나타날수 있다

짐벌락 : 어떤 축이 돌아가서 다른 두 축이 틀어져서 하나의 축처럼 움직이게 되게 꼬이는 현상

방지하려면 쿼터니언을 쓰면 된다고 함

 

 

if (Input.GetButtonDown(jump))
{
    //this.rb.AddForce(Vector3.up*300,ForceMode.Impulse);
    rb.velocity = Vector3.up * this.jumpForce; //velocity : 방향과 힘, 둘을 곱하면 됨
}

 

 

 

 

 

전구 느낌

 

세부조정

범위나 강도 세부조정 가능

 

 

rigidbody에 isKinematic

 : 물리 시뮬레이션은 구현하지 않는다

 

 

 

__________________________________________________________________________________________

콜라이더 뚫림 문제(프레임씹 문제)

그 속도 빠른게, 플레이어 조종 객체. 여러기가 아니라면 raycast 가 더 싸게 먹힘. 
속도만큼 raycast 해서 앞에 충돌체 있으면 충돌 지점에서 멈춰요.2023.02.02 16:21:59삭제


ㅇㅇ(14.34)물리업뎃시간을 줄여줘도 프레임씹에 의해 단 한 프레임에 콜라이더가 충돌 
콜라이더에 닫지 않고 통과하는 경우, 뚫고 지나가는건 동일한. 
그래서 raycast 를 이동 방향으로 쏴주는데, 완벽하게 체크하는 방법이 뒤로 쏴주는거임. 
이러면 한 프레임에 100m 이동해서 관통한 경우에도 충돌 지점을 찾아서 이동 위치를 보정할 수 있음.2023.02.02 16:27:26삭제


ㅇㅇ(175.119)어렵네... 방법찾아서 한번 해보겠음2023.02.02 16:30:07삭제


ㅇㅇ(14.34)프레임씹에 의한 문제는 날림으로 만들면 꾀 많은 편인데, 예를 들면 ... 
승리의여신 니케도 프레임이 떨어지면 머신건을 든 캐릭의 공격력이 줄어드는 문제가 있음. 
공격 속도가 한프레임보다 작은 경우, 한프렘임에 공격 횟수 보정해줘야하는데 이걸 안해준거임. 
0.1초마다 때리고 한프레임이 0.2초가 걸렸으면 2대를 때려야하는데, 
그걸 그냥 0.1 공격 속도로 넣으면 버벅일때, (프레임이 낮아질때) DPS 가 떨어지게 됨. 
주로 개발 경력이 얼마 없는 플머가 게임을 만들거나 무지성으로 애니메이션 이벤트를 
사용한다던가 하면 쉽게 볼수 있는 문제.2023.02.02 16:32:23삭제


ㅇㅇ(14.34)쉽게 말하면 그냥. 이전 프레임 위치랑. 이동 후 위치 사이에 raycast 를 해서
콜라이더가 있는지 검사하는거임. 이전 위치에서 이동된 위치로 쏴서, hit 지점이 있으면 
거기서 막혀야되니까. 이동 위치를 raycast 가 hit 된 위치로 변경. 왜 전방으로 쏘면 안되냐면. 
lastframe 으로 하면 그건 그 전 프레임 속도지. 다음 프레임이 얼마나 느릴지 몰라서 
뚫고 나갈 가능성이 있기 때문임. (뭐 그래도 대부분 해결되긴 함) 그러나 완벽하게 막을려면 
이동 후, 이전 위치에서 현재 위치로 쏴야 정확함.2023.02.02 16:39:22삭제


ㅇㅇ(14.34)코루틴이나 루프문 돌릴때, WaitForEndOfFrame 값 저장해두고 하는 경우 많지? 
애도 비슷함. 마지막 프레임 속도를 저장하고 돌리는거기 때문에. 프레임드랍이 발생하면 
해당 값을 사용할 경우, 그걸로 인해 이런저런 문제점이 발생하게 됨. 최적화를 위해 
프레임 속도를 저장해놓고 코루틴을 돌리긴하지만, 그래도 될때가 있고, 
안될때(저걸 돌리는 시점에서 프레임 드랍 확률이 높은 경우)가 있지. 
~ 는 저장해두고 써야 퍼포먼스가 좋다. 뭐다 하는건 다. 상황에 따라 다른거고. 
컴퍼니 다니는 5년차 10년차 플머들도 간혹 실수하는 것들임.2023.02.02 16:43:30삭제


ㅇㅇ(175.119)레이캐스트 써서 한 90% 해결했다 고맙다

 

 

https://blog.joe-brothers.com/unity-how-to-prevent-player-going-through-walls-using-raycast/

 

[Unity, C#] Raycast를 사용해 벽 통과 방지하기

유니티로 게임 개발을 하다 보면, 플레이어와 벽에 모두 collider(콜라이더)를 넣었음에도 불구하고 플레이어를 벽으로 계속 돌진시키면 플레이어가 벽을 통과하는 현상이 발생한다. 이는 Transform.

blog.joe-brothers.com

 

 

 

 

3초뒤에 문이 닫히게 코루틴 사용

IEnumerator DoorCloseRoutine()
{
    yield return new WaitForSeconds(3.0f);

    this.DoorMoving(false, "doorshut");
}

 

yield return -> 시간 기다리게 할때 쓰는식

따로 yield break가 있는데 그건 코루틴이 종료됨

저 코드대로면 3초 기다리고 DoorMoving 코드 사용

if (other.gameObject.CompareTag(player))
{
    DoorMoving(true , "dooropen");
    StartCoroutine(this.DoorCloseRoutine());
}

문이 열림과 동시에 StartCoroutine을 사용해서 문 닫을 준비하고 문을 닫음

 

update쪽에서 시간 재면서 뭐 하는것의 상위호환 코드

나중엔 Dotween이라는 더 상위호환이 있음

 

 

________________________________________________________________________

 

tuple

public static void A2() 
{
    //tuple

    var tuple = (234, 123,"123");

}

자료형 상관 없이 뭐든 배열로 묶는것

반드시 var로 선언

 

 

개수 안맞으면 에러남

public static void A3() 
{
    var unnamed = ("슈퍼", 9999);
    var named = (Name: "배트", Age: 46);
    Console.WriteLine(named);
    named = unnamed;

    Console.WriteLine(named);
}


result
(배트, 46)
(슈퍼, 9999)

바뀌는걸 볼수있음

static double GetDiscountRate(object client)
{

    return client switch
    {
        ("학생", int n) when n < 18 => 0.2, //학생 18세 미만
        ("학생", _) => 0.1, // 학생 18세 이상
        ("일반" , int n) when n < 18 => 0.1, // 일반 18세 미만
        ("일반" , _) => 0.05//일반 18세 이상
    };
}

스위치 식(패턴 매칭)

case없이 스위치문 이용

public static void A5() 
{
    var umBeolKi = (Job : "학생", Age: 17);
    var um = (Job : "학생", Age: 23);
    var Beol = (Job : "일반", Age: 17);
    var Ki = (Job : "일반", Age: 25);
    var umBeol = (Job : "일반asdf", Age: 25);
    Console.WriteLine(GetDiscountRate(umBeolKi));
    Console.WriteLine(GetDiscountRate(um));
    Console.WriteLine(GetDiscountRate(Beol));
    Console.WriteLine(GetDiscountRate(Ki));
    Console.WriteLine(GetDiscountRate(umBeol));
}
static double GetDiscountRate(object client)
{

    return client switch
    {
        ("학생", int n) when n < 18 => 0.2, //학생 18세 미만
        ("학생", _) => 0.1, // 학생 18세 이상
        ("일반" , int n) when n < 18 => 0.1, // 일반 18세 미만
        ("일반" , _) => 0.05//일반 18세 이상
    };
}



result
0.2
0.1
0.1
0.05
Unhandled exception. System.Runtime.CompilerServices.SwitchExpressionException: 
Non-exhaustive switch expression failed to match its input.

스위치에 안들어가있는걸 쓰려하면 에러가 남

 

 

 

 

 

1. 클래스 : 비슷한 것끼리 뭉쳐놓은것을 선언해 놓은것
    객체 : 그 클래스를 선언해 놓은것
   인스턴스 : 그 클래스를 new써서 새로 생성한것

2. A c = new B(); 부분에서 에러가 남
   B가 A를 상속받은거지 A는 B랑 아무런 연관이 없기때문에 A에다가 B를 넣으려하면 에러가 발생

3.this : 클래스 자신을 가리키고, .을 붙이면 static안붙은 애들을 불러서 쓸수 있음, 함수 등을 선언할때
         변수명이 매개변수와 겹치는 일을 피하기 위해 사용
  base : 상속받았을 때 부모클래스를 의미, 아무것도 상속받지 않았을 때 base입력시 object로 나옴

4. 구조체는 
     1. struct 키워드 맞음
     2. 구조체는 클래스와 달리 값 형식이기 때문에 그대로 복사하면 값 까지 전부 복사되는 깊은 복사가 이루어짐
     3. 참조형식 아님
     4. 메소드를 가질 수 있음.

5. 
struct ACSetting
{
    public double cur;
    public double tar;
    public readonly double Get()
    {
        tar = cur * 1.8 + 32;
        return tar;
    }
}

기존 값이 변수더라도 readonly라고 되어있는 함수 안에서는 변할 수 없다.

6.
다형성 : 한가지 이름이 다양한 기능을 할 수 있다.
          오버라이딩을 하면 부모 클래스에 있던 어떤 함수가 자식 클래스에선 다른 역할을 하게 만들 수 있다.

7.
static double GetDiscountRate(object client)
{

    switch (client)
    {
        case ("학생", int n):
            if(n < 18)
            {
                return 0.2;
            }
            else
            {
                return 0.1;
            }
        case ("일반", int n):
            if (n < 18)
            {
                return 0.1;
            }
            else
            {
                return 0.05;
            }
        default:
            return 0;
    }

}

5번을 몰랐음

 

readonly함수라는게 머리속으로 안그려져서

 

 

함수 선언에 readonly가 포함되어 있다면, 이는 특정 프로그래밍 언어에서 함수 내부에서 상태를 변경하지 않도록 제한하는 역할을 할 가능성이 큽니다. 하지만 readonly는 일반적으로 변수나 속성에 적용되는 키워드이며, 함수 자체에 직접 적용되는 경우는 드뭅니다.

실제로 잘 안쓴다함

 

    class TestMon
    {

    }
    class Test : TestMon
    {

    }
    
    public static void A6()
{
    TestMon a = new Test();
    Test b = new TestMon();
}

2번 틀림

 

b에 더 많은 기능이 있는데 더 적은 기능이 있는 부모클래스를 넣으려하면 기능에 다 할당되지 않아 오류가 남