(유니티 자격시험 Unity GameDeveloper)3.이벤트함수/벡터/오일러/법선벡터/충돌/문법/오디오

2021. 12. 1. 00:50유니티 & C# 공부

반응형

이재현 강사님 강의 출처

 

총알생성위치/

1. 이벤트 함수

Awake 1. 최초. 스크립트가 실행될 때 한번만 호출
문제에서는 씬이 시작될 때라고 나옴.

2. 스크립트가 비활성화 되어도 실행함

3. 코루틴으로 실행 불가능
OnEnable 1. 오브젝트 또는 스크립트
  활성 될 때 호출

2. 이벤트 연결에 사용

3. 코루틴 불가능
start 1. 코루틴으로 실행 가능
Ienumerator start()가능

2. 스크립트가 활성화 되어야

호출 가능

3. Update 전에 한번만 호출

4. 모든 스크립트의 Awake가 다 실행된 후에 실행
OnDisable 1. 오브젝트 또는 스크립트
   비활성화 시 호출

2. 이벤트 종료에 사용

3. 코루틴 불가능
Update 화면에 렌더링 되는 주기
1초에 60번 호출
(단 하드웨어 성능에 따라
호출 횟수 차이 날 수 있음
따라서 플레이어 이동 등에
Time.deltaTime, 정규화벡터를 사용함)

* Time.deltaTime 
= 이전프레임~현재프레임까지 걸리는 시간 차이

*정규화벡터(단위벡터)
= 크기가 1인 벡터. 
1로 만들지 않으면 벡터의 길이가 길어져서 플레이어의 속도가 빨라지므로 사용
OnGUI 레거시 GUI 관련 함수를 사용 할 때 
FixedUpdate 1. 일정한 발생 주기

2. 계산주기 설정 가능
Project setting-Time-Fixed TimeStep 로 설정
  * TimeScle 0은 중단임.
   
LateUpdate 1. 모든 스크립트 Update
   호출 되고 한번 씩 호출

2. 후처리 작업

3. 스크립트 활성화 필요

4. 2개일 경우 우선 순위
   결정필요
  
 * 스크립트 실행순서 지정
   ProjectSetting -
   Script Execution Order로 맨 위 스크립트 부터 실행
   

 

2. 컴포넌트 캐시 처리

Update 등으로 수시로 호출 될 경우 , 불필요한 연산을 최소화하기 위해 미리 변수에 할당한다.

 

예) Rigidibody rb = Getcomponent<Rigidbody>();

    

 

참고 http://www.devkorea.co.kr/bbs/board.php?bo_table=m03_qna&wr_id=76886 

 

데브코리아

한국 게임개발자 커뮤니티

www.devkorea.co.kr

 

3. 캐릭터 이동 시 Local / Global 좌표 기준

transform.Translate(Vector3.forward  * 10속도, Spce.Seft)  = Local좌표 기준

transform.Translate(Vector3.forward  * 10속도, Spce.Word) = World좌표 기준

3. 정규화 벡터

 

 

4. 벡터, 정규화벡터(단위벡터)

벡터 = 방향을 나타내는 데어터 타입

 

정규화 벡터 = 단위벡터,     크기가 1 로 되어 있는 벡터       

벡터를 피타고라스의 정의로 구할 수 있음. 이때 1:1 x,y축 길이만큼의 기울기 벡터 값을 다 반영하면 (1.4141)로 벡터의 길이가 1보다 길어져서 플레이어 이동 시  빨라진다. 그래서 길이가 1인 값만 가져오게 하는 작업을 함

 

Vector3.normalized를 함

 

또한 하드웨어 성능따라 Update호출 횟수가 차이나므로 Time.deltaTime도 사용함.

 

대략적으로... 예를 들면

float h = Input.GetAixs("Horizontal");

float v = Input.GetAixs("Vertical"); 기준 축을 구하고

flot mouseRot = Input.GetAixs("MouseX"); //마우스 회전 축 할 거임

 

방향을 구한 후

vector3 dir = (vector3.forward * h )+ (vector3.right * v)      또는 new vector3(h,0,v)해도 됨 

 

이동 할 때 여기서 정규화 한번 시켜줌

transform.Translate(dir.normalized * speed * Time.deltaTime);     

 

--------------------------------

5. 회전

1) Rotate - 특정 축을 기준 삼아, 속도 만큼 회전.    오일러각(0-360)으로 표현

  transform(축약형이라고 함..).Rotate ( vector3 Up, Time.deltatime);

  마우스 움직임 따라 한다면

 transform.Rotate(기준 축 * 마우스 좌우방향 * 회전 속도(일반 회전 속도보다 크게 하자 한 80이상..?) * Time.deltaTime);

 transform.Rotate(Vetcor3.Up * mouseX * turnRot * Time.deltaTime); 이렇게.

 

  쿼터니언으로 자동 변형되어 회전을 한다.

https://novlog.tistory.com/62  

 

[Unity] 오브젝트 회전 Rotation & Quaternion & eulerAngles (캐릭터 좌우 반전 코드)

#Quarternion & eluerAngles #transform.rotation #2D 캐릭터 좌우반전 예제 *개인적인 유니티 공부 내용을 기록하는 용도로 작성된 글 이기에, 잘못된 내용이 있을 수 있습니다. #Quarternion & eluerAngles 오..

novlog.tistory.com

 

 

 

  2) Quaternion 쿼터니언 =사원수(원소가 4개) = 복소수 를 확장한 4차원 벡터

  0-360 도 오일러 회전 시 x축, y축, z축 식으로 축 하나씩 회전을 하는데, 이 때 두가지 축이 겹쳐지면

  이상하게 다른 축으로 회전되거나 회전이 안되는 현상인 짐벌락을 방지해줌

 

  x,y,z, w축도 가지고 있음.

 

  유니티는 기본적으로 오일러 각 이용한 쿼터니언 회전(Transform.Rotation)을 하는데

  인스펙터창 debug모드로 볼 수는 있음

 

 

Quaternion.identity);   //identity는 회전 없도록

  Quternion.LookRotation(Vector3) 

  Quternion.Eular

  Quternion.Slerp 등 여러가지가 있음

  https://hub1234.tistory.com/21

 

[유니티] Euler, Quaternion 오일러각 쿼터니언 총 정리

[Unity] Euler, Quaternion 오일러각(짐벌락) 쿼터니언에 대하여! Unity의 Euler 각도는 x,y,z 3개 축을 기준으로 회전시키는 우리가 흔히 알고있는 각도계를 의미한다. 이 각도계를 사용하면 우리 모두 삽

hub1234.tistory.com

 

 

------------------

6. 법선 벡터 = 물체와 90도 이루는 벡터

(총알과 벽을 90도 마주보면서 파티클을 벽 밖으로 내게 하기.

 

다음 5번의 충돌함수에서 쓰는 Collision coll /Collider coll 중 coll에 법선 벡터 정보도 포함된다.

 

벽에 스크립트 부착함

  1) Vector3 변수명 = collider.GetContact(0).Point;    GetContact는 충돌지점 정보, Point = 충돌 지점

     총알 스페어 콜라이더와 90도 부딪힌 벽의 지점(Point)

     ( 살짝 부딪힌 벽 콜라이더 지점이 0번째(첫번째)인 것만 고름)

            

 

2)   Vector3 _normal = collider.GetContact(0).normal;    normal = 충돌지점 법선벡터 정보

    날아와서 충돌한 총알의 법선벡터를 구함    

    ( 충돌한 총알에서 방향이 뚫고 나간다고 함) 

      

 

3) 법선벡터가 이루는 각도를 쿼터니언으로 변환, 파티클은 총알이 날아온 방향과 반대로 해야 표시됨

     Quaternion.LookRotation(-1을 곱해 뒤집기 * _normal )

 

4) 게임오브젝트 동적 생성 (instantiate가 유일함)

   instantiate(오브젝트명, posion은 1)변수명,  rotation은 2)변수명) 

 

     GetContact에 대한 내용이 간단히 있는 사이트

      https://luv-n-interest.tistory.com/738

 

 

Collider에 대한 모든 것(기본) [Unity]

이번 글에서는 Collider의 종류와 쓰임 보다는 Collider가 무슨 역할을 하며 왜 필요한지.. 어떤 property를 가지고 있는지를 알아볼 것이다. 도대체 무엇인가? ++Unity.Engine 클래스에 포함되어 있다. RigidB

luv-n-interest.tistory.com

    

      GetContact 하위 항목 point, normal등 설명된 사이트

      https://hillier.tistory.com/14

 

[Unity] Collision Type 속성

Collision - 충돌 collider - 충돌한 GameObject의 Collider Component (읽기전용) contacts - 물리엔진에 의해 생성되는 물체 간의 충돌지점. 접점은 여러개가 될 수 있음 -> 배열 타입 반환 ( ex 첫번째 충돌..

hillier.tistory.com

---------------------

      시험  - 컴포넌트 추가 법 

               Component > Physics - collider / rigidbody

7. 충돌

  1) 광선 Raycast 

  private RaycastHit hit;   //구조체, struct에 결과값 받아서 넘거줌

 

 //Physics.Raycast       //Physics은 콜라이더 있어야만 감지가능, 클래스임.

                               //제일 먼저 맞은 친구에 대한 정보를 return   

                                       > 내부적으로 임시 변수 만들므로 가비지 컬렉션이 생김
                            //RaycastAll은 배열로 모든 값을 리턴

                                      > 내부적으로 임시 변수 만들므로 가비지 컬렉션이 생김

                            가비지 컬렉션 안 쓸려고 한다면 RaycastNonAlloc 쓸 것.

                               단 배열과 개수까지 미리 셋팅 필요함
                               RaycastNonAlloc  미리 결과값을 배열로 만들어두고 배열로 담아서 리턴


                               정해진 개수보다 넘어가면 오류 !!

                                

 

    private RaycastHit hit;   구조체, struct에 결과값 받아서 넘거줌

                                      광선에 닿으면 true 값 리턴하므로 if로 받음.

 

    레이어마스크 

         계층구조 아님. 원래 1-7까지 막혀있었으나 현재는 풀어줌.

           if(Physics.Raycast(firePos.position,firePos.forward, out hit, 10f,  1<<8))  

            {
                <<는 비트연산자,    2진수는 2의 8승.  10진수는 256 왼쪽으로 8번 이동한다. 

                            1 << LayerMask.NameToLayer("Player"); 이렇게도 가능

                 ~ 1<<8 : Not 이며 8번 레이어 아닌 모두 다. 

 

                out = 참조해주는 값, C#


            }

 

   2)이벤트 

이벤트 =  콜백함수 = BackGround 시스템에서 체크하다가, 특정 조건 만족 시 자동으로 호출되는 함수

 콜백함수는 monobehaviou에서 파생됨

ex. Delegate, Fun<>, Action<> OncollisionEnter 같은 충돌함수

 

1) 충돌 함수 

   void OnTriggerEnter()     충돌해도 통과, 충돌만 감지.

     if(coll.compareTag("")){}

 

    void OnCollisionEnter(Collision coll) 이때 coll에 충돌 물체의 4.법선벡터 정보도 포함된다.

    if(coll.collider.compareTag(""){}

 

      comparTag에 관한 내용(가비지컬렉션)은 아래 하단 링크 참고

      (유니티 자격시험 Unity GameDeveloper)4. 애니메이션/유한상태머신/가비지콜렉션 GC (tistory.com)

 

(유니티 자격시험 Unity GameDeveloper)4. 애니메이션/유한상태머신/가비지콜렉션 GC

1.애니메이션  1) 애니메이션의 종류 Lagacy - 이전의 방식. 빠르고 라이트함. 코딩만 해서 유지보수가 까다롭다. Animation컴포넌트사용  ---------------------------------------------------  Mecanim Ani..

mowingnow.tistory.com

  

 

2) 충돌 감지 하려면, 날아오는 물체에는 무조건 Rigidbody가 있어야 되고, 두 물체 모두 collider컴포넌트 필요

   (안 움직이는 물체에 Rigidbody있어도 노상관, 있어도 됨)

 

3) Collider컴포너트는 충돌 검출 속도가 가장 빠른 콜라이더 부터 사용을 권함

   1위  Spherer Collider (가장 빠름. 반지름 r값으로 감지)

   2위 Capsule Collider

   3위 Box Collider

 

   그 외 Mesh Collider

   (많은 폴리곤에 적용 시 부하가 큼. 3차원 형상정보/모델링 정보를 다 가져오기 때문. 단순메시에

    적용할 것을  권장)

  Wheel(지면 닿을 때 마찰계수 등 계산), Terrain Collider(카메라 각도 따라 조밀한정도를 처리해준다.)

 

   문제

 4) Collider컴포넌트 프로퍼티로

    Center  pivot 기준점으로 이동함

    Derection    축 결정 할 수 있음(X,Y,Z)

 

 5)  특정 함수 실행 시 조건 걸 때 

    예 - 특정 함수는 플레이어가 몬스터에게 맞고 점수 0일때 실행되야 하는데, 이미 죽었으나 계속 충돌되면 

          함수 실행될 수 있으므로, 충돌함수 내 조건 걸 때 주의

 

      Void OnTriggerEnter()

      {        //플레이어가 먼저 죽었는데 계속 충돌되면 PlayerDie계속되므로

           if (플레이어hp변수명>0.0f && coll.CompareTag("PUNCH")) 
           {      함수();                  //currHp >0 조건도 추가

 

       }

 

8. Rigidbody 강체

    외부의 힘에 의해 변형되지 않는 물체임. 

    

  Rigidbody에서 속성을 업그레이드 한다면, Fixed Update에서 사용하는 것이 바람직함. 아래는 그 말의 출처.

https://a-game-developer0724.tistory.com/45

 

[Unity 3D] FixedUpdate (유도탄 만들기)

FixedUpdate - FixedUpdate도 Update와 마찬가지로 프레임마다 보통 여러 번 불리게 된다. 하지만 각각의 호출은 고정된 시간 간격을 기반으로 규칙적으로 표준화되어 일어난다. 가장 흔히 사용하는 경

a-game-developer0724.tistory.com

 

   Rigidibody rb = getcomponent<Rigidibody>();

   rb.AddForce(vector3) 는 글로벌 좌표계로 힘을 줘서 이동

   rb.AddRelativeForce(vector3)는 로컬 좌표계 기준으로 이동

 

 

   [Rigidibody강체의 프로퍼티]

   Mass  질량.  1kg이나 1g등의 무게 단위가 아님.

                    A물체가 mass1, B물체가 mass 10이라면 b가 10배 더 무거움

                    편의상 1kg으로 가정하는 것이 일반적

   Drag   공기저항, 이동 마찰계수

   Angular Drag    회전 마찰계수

   Use Gravity      중력,    중력수치 확인은 Edit-Project Setting- physics-gravity

   Is Kinematic     물리엔진 영향x, 운동역학= Transform컴포넌트로 이동할 때 사용.

                         스크립트로 z축을 매시간(Update)하는 경우

 

                         애니메이션으로 움직일 때 주기적 계산 필요 없으므로, 이 때 활성화 할 수 있음

 

   Interpolate       물리적인 움직임이 끊어질 때 보간(interpolate)해줌

                         update화면 렌더링 위치와 달라서 떨림현상(Jittering) 발생 시 보간해줌

                         * Interpolate : 이전 프레임의 Transform에 맞게 움직임을 부드럽게

                         * Exterpolate : 다음 프레임의 Transform 변화를 추정하여 부드럽게

 

유니티 ccd =Continous Collision Detection 이라고도 하는 거

   Collision Detection    너무 빠른 물체는 충돌 검출을 놓칠 수 있어, 세밀한 충돌을 검출하려는 옵션

                                 Discrete (Fized Update 0.02초 주기로 충돌 여부 검출)

                                 Continous (계속 측정한다.)

                                 Continous Dynamic (동적 장애물도 감지)

                                 Continous Speculative (예측/충돌 가능성을 확인)

 

Constraints 하위 항목에  Freeze Posion과 Rotation 이 있음

 

 

 

 

9. [컴포넌트].transform

 특정 오브젝트 컴포넌트가 담긴 변수에서, 다른 컴포넌트에 접근하고 싶다면

  예) MeshRenderer meshRender = GetComponent<MeshRenderer>();  이미 변수에 특정 컴포넌트임

 

     meshRender.transform 하여 바로 접근 가능하다.

 

 

10. 제너릭 타입 문법

   <추출하려는 유형>.();  이렇게 사용

       예) GetComponent<Animation>.();    List<>

   

          GetComponent("") as Animation 뭐 이런식으로 써도 된다고 하는데, 제너릭 문법을 더 선호한다고 함

 

 

11. 여러 문법들

 

 //var = 뒤에 나오는 데이터 타입을 추측할 수 있음, 베리에이블약자, 어떤 데이터타입이든지 다 설정가능

   foreach (var monster in monsters)  

 

 //GameObject[] monsters = GameObject.FindGameObjectsWithTag("MONSTER");
     var monsters = GameObject.FindGameObjectsWithTag("MONSTER");

 

 

   foreach(Gameobject 다른변수명 in 앞서 설정한 GameObject 변수명)

   GameObject[] monsters = GameObject.FindGameObjectsWithTag("MONSTER");

        foreach(GameObject monster in monsters) //한마리의 몬스터을 대상으로 
        {
            monster.SendMessage("YouWin",SendMessageOptions.DontRequireReceiver); 
            //몬스터 스크립트 안에 "You Win"함수 없으면 무시하고, 있으면 실행해줘
        }

 

     SendMessage("특정 스크립트 함수명", 없으면 무시하고 있으면 실행)

     monster.SendMessage("YouWin",SendMessageOptions.DontRequireReceiver); 
            //몬스터 스크립트 안에 "You Win"함수 없으면 무시하고, 있으면 실행해줘

 

      Null 연산자  (?.)

      GameObject.Find("SpawnPointGroup")에서 Find한 이름이 오타 날 경우 에러null 날 수 있으므로
        .?로  잘 찾았다면 뒤에것을 실행, 아니라면 실행 안한다. 
        이것은 주의깊게 사용해야 함
        points = GameObject.Find("SpawnPointGroup")?.GetComponentsInChildren<Transform>();

        // 이때 GetComponentsInChildren  는  부모까지도 포함해서 가져온다.

 #region 더 안전한 방법--------------
        ////이게 더 안전
        GameObject obj = GameObject.Find("SpawnPointGroup");

        if(obj != null)  
        {
            obj.GetComponentsInChildren<Transform>();
        }

#endregion-------------------------

 

 

 

 

     Resources.Load 리소스폴더 오브젝트 가져와서 생성

    //  monsterPrefab = Resources.Load("Monster") as GameObject; //as로 형변환 필요함, 요즘에는 안쓰는 방식
        // monsterPrefab = Resources.Load<GameObject>("Monster");
        monsterPrefab = Resources.Load<GameObject>("Prefabs/Monster"); //하위 폴더가 있다면 폴더경로도 지정

 

 

 

        지연 후 함수 호출 Invoke함수  > 중단은 cancleInvoke()등으로 가능
        InvokeRepeating("CreateMonster", 2f, createTime); //2초 dealy 후  3초 간격으로 메소드 호출

 

        //게터 세터로 값이 변환되면 강제 종료도 가능하다 함

 

 

 

 

12. 인스펙트 속성, 어트리뷰트 [Attribute]


  1) 인스펙트에 제목 작성하기 

      [Heaer("")]       

      공개 변수 또는 [SerializeField]적용된 private 변수

       https://answers.unity.com/questions/1719988/header-dont-show-up-in-the-unity-inspector.html

 

Header don't show up in the unity inspector - Unity Answers

 

answers.unity.com

 

  2) [HidenInInspector] 인스펙터에서 public변수 숨기기 . 유니티 자체 제공

                               한번이라도 인스펙터에서 수정된 적이 있다면 그 값을 저장하여 유지

  3) [System.NonSerialized] public 변수지만 숨김. using.system추가필요하나 좀 더 추천함,  c#에서 제공

    https://blog.naver.com/PostView.nhn?blogId=hana100494&logNo=221889047108&parentCategoryNo=&categoryNo=13&viewDate=&isShowPopularPosts=false&from=postView 

 

[Tip] 유니티 SerializeField 와 NonSerialized : HideInInspector보다 안전한

유니티에서 public 변수를 사용하면 인스펙터에서 변수에 접근이 가능하다는 것을 알 수 있을것이다. 그리...

blog.naver.com

  4) [SerializeField] 인스펙터에서 private변수 표시하기 

 

  5) [System.Serialized]  한 줄로 표시, 직렬화, 

  

  6) [Range(10f, 50f)] 10 - 50 범위로 슬라이드 바 생성

 

13. 오디오(Audio)

  AudioListner  듣는 역할 카메라에 있음. 씬에 하나만 존재해야 하므로 여러 카메라 추가 시 확인 필요

  AudioSource  소리 발생   

  (1 대 다수의 관계임)

 

  AudioClip 은 모노로 바꾸면 KB를 더 줄일 수 있음. 인스펙터 창 Fofrce To Mono를 체크, Apply하면 됨

 

  AudioClip.PlayOneShot(clip사운드, 볼륨0-1까지) 추천 

  총알 발사체(프로젝타일)이 다른 물체 충돌 후 총알 삭제되면, 소리가 끊어지므로

  중첩해서 소리 나도록 만들기

 

 도플러효과   시험 

    리서너의 위치 따라 무빙 사운드에 적용되는 주파수 전이량이 멀리, 주파수 상승

   (리스너와 거리(미터) 및 fall off 감소, 유형에 따른 사운드의 fall off는 틀린 대답이라고 함...)

 

 

  AudioSource 소리 전달 범위설정 할 수 있음

  3D sound Setting 프로퍼티 에서 설정 

    큰 원은 소리가 도달하는 범위(Max Distance)

    작은 원은 메인 카메라가 잘 들리는 범위(Min Distance)이며, 벗어날 수록 점점 감소됨 

    그래프에서 Listener를 통해  메인카메라가 어디 영역에 위치하는지 확인 가능

                   선이 오른쪽으로 가면서 낮아질 수록 소리 잘 안들림

반응형