Behavior - Invoke Unity Evnets옵션

Input Behavior를 Invoke Unity Events로 선택하면 다음과 같이 유저가 정의한 액션인 Move와 Attack이 Unity Event타입의 속성으로 표시된다. 일반적은 UI Button이벤트를 연결하는 방식이다. 공토으로 발생하는 3개의 이벤트도 같이 표시된다.

이상태에서는 스크립트에서 연결할 이벤트가 없으므로 PlayerCtrl을 다음과 같이 수정해준다.

#region SEND_MESSAGE #region UNITY_EVENTS 는 코드의 영역을 정의하는 전처리기 이다.

Invoke Unity Events를 선택했을때 넘어오는 파라미터는 InputAction.CallbackContex타입으로 입력값은 ReadValude<T>() 함수를 이용해 전달 받는다. Move Action을 Vector2로 정의했기 때문에 

Vector2 dir = ctx.ReadValue<Vector2>(); 와 같이 받아와야 한다. 나머지는 Send Messages 옵션과 동일하다

#pragma warning disable IDE0051 //함수나 변구를 정의후 사용하지 않는 경고문구를 비활성화하는 구문

using UnityEngine;
using UnityEngine.InputSystem;  //Inputsystem사용을 위해 추가된 namespace

public class PlayerCtrl : MonoBehaviour {
    private Animator anim;
    private Vector3 moveDir;

    void Start () {
        anim = GetComponent<Animator>();  //Animator컴포넌트를 연결
    }
    void Update () {
        if(moveDir != Vector3.zero) {
            transform.rotation = Quaternion.LookRotation(moveDir); //캐릭터회전
            transform.Translate(Vector3.forward * Time.deltaTime * 4.0f); //이동
        }
    }
#region SEND_MESSAGE
    void OnMove(InputValue value) {
        Vector2 dir = value.Get<Vector2>();
        moveDir = new Vector3(dir.x,0, dir.y);
        anim.SetFloat("Movement", dir.magnitude);
        Debug.Log($"Move = ({dir.x},{dir.y})");
    }
    void OnAttack() {
        Debug.Log("Attack");
        anim.SetTrigger("Attack");
    }
#endregion

#region UNITY_EVENTS
    public void OnMove(InputAction.CallbackContext ctx) {
        Vector2 dir = ctx.ReadValue<Vector2>();
        moveDir = new Vector3(dir.x,0,dir.y);
        anim.SetFloat("Movement", dir.magnitude);
    }
    public void OnAttack(InputAction.CallbackContext ctx) {
        Debug.Log($"ctx.phase={ctx.phase}");
        if (ctx.performed) {
            Debug.Log("Attack");
            anim.SetTrigger("Attack");
        }
    }
#endregion
}

스크립트에서 이벤트를 정의해 줬으니 이제 연결하자

Player Action 옆 ▶를 눌러 펼치면 Move(CallbackContex) List is Empty인데 +를 눌러준후 하이라키의 warrior를 끌어다 연결해준다. Attack도 끌어다 준다

이제 No Function을 눌러 OnMove와 OnAttack를 각각 연결해준다.

실행해보면 다음과 같이 3가지 상태가 차례로 호출되는 걸 확인할 수 있다.

 

Behavior - Send Message 옵션

Behavior 속성을 Send Messages로 선택하면 설정한 액션을 void On{액션명}() SendMessage함수를 이용해 호출한다. 

  • 특정 키가 들어오면, 특정한 함수를 자동으로 호출하는 방식
  • Broadcast Messages의 경우, 하위 계층에 있는 오브젝트들까지 제어를 할 수 있다.
  • 함수명이 "On + Actions name"으로 구성된다.
    • 앞에서 Move와 Attack액션을 정의했기 때문에 OnMove, OnAttack함수가 SendMessage를 통해 호출된다.

새로운 스크립트를 만들고 "PlayerCtrl"이라고 변경한다. Warrior에 연결해준다.

#pragma warning disable IDE0051 //함수나 변구를 정의후 사용하지 않는 경고문구를 비활성화하는 구문

using UnityEngine;
using UnityEngine.InputSystem;  //Inputsystem사용을 위해 추가된 namespace

public class PlayerCtrl : MonoBehaviour {
    // Start is called before the first frame update
    void OnMove(InputValue value) {
        Vector2 dir = value.Get<Vector2>();
        Debug.Log($"Move = ({dir.x},{dir.y})");
    }
    void OnAttack() {
        Debug.Log("Attack");
    }
}

이제 키입력을 통해 애니메이션과 이동 처리 로직을 구현한다. PlayerCtrl 스크립트를 다음과 같이 수정한다.

스크립트는 키입력의 이벤트를 통해 애니메이션을 컨트롤 한다.

애니메이션은 Idel, Run, Attack 3가지 뿐이고 방향은 rotation시킨다.

float Movement파라메터를 이용 Idle과 Run애니메이션을 선택하고 bool Attack이 Attack애니메이션을 트리거해준다

#pragma warning disable IDE0051 //함수나 변구를 정의후 사용하지 않는 경고문구를 비활성화하는 구문

using UnityEngine;
using UnityEngine.InputSystem;  //Inputsystem사용을 위해 추가된 namespace

public class PlayerCtrl : MonoBehaviour {
    private Animator anim;
    private Vector3 moveDir;

    void Start () {
        anim = GetComponent<Animator>();  //Animator컴포넌트를 연결
    }
    void Update () {
        if(moveDir != Vector3.zero) {
            transform.rotation = Quaternion.LookRotation(moveDir); //캐릭터회전
            transform.Translate(Vector3.forward * Time.deltaTime * 4.0f); //이동
        }
    }
    void OnMove(InputValue value) {
        Vector2 dir = value.Get<Vector2>();
        moveDir = new Vector3(dir.x,0, dir.y);
        anim.SetFloat("Movement", dir.magnitude);
        Debug.Log($"Move = ({dir.x},{dir.y})");
    }
    void OnAttack() {
        Debug.Log("Attack");
        anim.SetTrigger("Attack");
    }
}

실행해보면 WASD로 이동하고 Space키로 공격하는걸 확인할 수 있다.

 

Behavior 속성

Player Input의 Behavior는 Input Action에셋에 정의한 액션이 발생했을 때 코드의 함수를 어떻게 실행시킬 것인지를 결정하는 속성으로 다음 네 가지가 있다.

  • Send Messages : Player Input 컴포넌트가 있는 게임 오브젝트에 SendMessage함수를 이용해 호출
  • Broadcast Messages  :  BroadcastMessage함수를 이용 하위에 있는 게임오브젝트의 함수도 호출
  • Invoke Unity Events: 액션별로 이벤트 연결 인터페이스가 생성되고 각각 호출하려는 함수를 연결해 사용
  •  Invoke C Sharp Events  :  C# 스크립트에서 이벤트를 직접 연결해 사용
  • 위 방식들을 스크립트에서 사용하기 위해서는 다음과 같은 네임스페이스 적용이 필요

위 4가지 Behavior속성은 입력장치의 연결, 해지 변경사항에 대해 다음과 같은 이벤트를 기본으로 호출한다.

  • OnDeviceLost
  • OnDeviceRegained
  • OnControlsChanged

 

Player Input 컴포넌트는 Input Action에서 정의한 액션이 발생했을대 코드와 연결해 해당 로직을 실행시킬 수 있는 기능을 처리한다. 하이라키뷰의 Warrior를 선택해 인스펙터뷰의 Add component에서 Player Input 컴포넌트를 추가한다. 추가하면 Warrior발에 동그라미가 표시된다

Player Input Component의 Actions Item의  오른쪽 ◉를 눌러 브라우저에서 우리가 만든 MainAction을 선택한다. 

Default Schema는 나중에 빌드할 때, 타겟 플랫폼에 맞게 다음과 같이 설정 해주면 된다.

구동될 환경에 따라 플랫폼 선택. 본 글에서 MOBILE은 설정 따로 안 했으므로 우선 PC 선택

물론 Any로 설정하면 알아서 설정되긴 한다.

Default Map은 현재 Player Input 컴포넌트가 부착된 오브젝트가 "주인공 캐릭터"이므로, 아까 생성했던 "PlayerActions" Map을 선택해주면 된다.

 

그 외에도 예를 들어, 펫(Pet)을 조종하고 싶다면, "PetActions" Map을 생성해줘서 키 바인딩을 해주고, 펫 오브젝트에 부착하여 설정해주면 될 것이다.

해당 게임 오브젝트가 입력받을 Action Maps를 선택

이로써, 키 입력 셋팅은 다 끝이 났다.

이제 입력 받은 키 내용을 스크립트(script)에 전달하고, 그 값에 따라 처리를 하는 코드 작성 작업이 남았는데

글이 길어졌으므로 다음 글에서 다루도록 한다.

 



새로운 Input System은 기존 Input Class와는 다른게 외부 입력장치와 동작하는 코드를 완벽하게 분리할 수 있다. 코드에서 어떤 입력장치로 부터입력됐는지를 확인할 필요가 없다. 다른 입력장치로 변경했을 경우 Biding 정보만 변경해 적용할 수 있기 때문에 코드의 수정없이 쉽게 적용이 가능하다.

입력 시스템 워크플로우

새로운 입력 시스템을 사용하는 방법은 다음 4가지 방법이 있습니다. 스크립트와 Asset을 적절히 같이 사용할 수 있습니다. 

Directly Reading Device States

Using Embedded Actions

Using an Actions Asset

Using an Actions Asset and PlayerInput Component

 

Input System의 구조

실습 텔플릿은 3D로 이름은 "Warrior"으로 새로운 프로젝트를 만들었다. (아래 New Input은 오타)

Project폴더에서 기존 Scenes를 01.Scenes로 변경하고 02.Scripts폴더를 생성한다.

 

Input System패키지 설치

[Window]->[Package Manager]를 선택해 Package Manager창을 연다.

Package Manager 왼쪽 상단 Packages: In Project 팝업을 눌러 Unity Registry를 선택한다.

아래 창에서 Input System를 찾아 오른쪽 Install을 눌러 설치한다.

설치가 끝나면 다이얼로그박스가 뜨는데 yes해주면 유니티가 재시작된다.

Active Input Handling 확인

메뉴[Edit]{Project Setting][Player]인스펙터뷰의 Other Settings안의 아래쪽 Active Input Handling이 Both로 잘되어 있다.

테스트 환경 제작

내려받은 Resources폴더에서 다음 2가지 패키지를 임포트 한다.

  • Resources/Models: Warrior 패키지
  • Resources/Textures:Images 패키지

하이라키뷰에서 Palne을 추가하고 Transform Scale을 (5,5,5)로 입력 가로, 세로의 크기를 50cm, 50cm로 설정한다. 

프로젝트 뷰의 Images/Magerials 폴더의 GridEmissive 머터리얼을 Plane에 연결한다.

프로젝트뷰의 Warrior/Models폴더의 Warrior_bindpose 모델을 하이라키뷰에 추가한다.

인스펙터뷰에서 Animator컴포넌트의 Controller Item의 ◉브라우저를 눌러 AnimationController_Warrior를 연결한다.

Input Action에셋

새로운 Input System을 사용하기 위해서는 먼저 Input Action 에셋을 생성해야한다. Input Action은 액션과 바인딩 정보를 정의하는 에셋으로 다음과 같이 2가지 방법으로 생성할수 있다.

  • 프로젝트뷰의+를 눌러Input Action을 선택
  • Warrior캐릭터에 Player Input 스크립터를 추가한 후 Input Action을 생성하는 Crate Action버튼을 클릭

02.Scripts하위에 InputAction폴더를 생성한후 Input Action에셋을 생성한다. 이름은 MainAction으로 바꾼다.

MainAction을 더블클릭하면 InputActions창이 열린다.

이 화면에 보이는 용어들을 짚어보자.

  • Control Scheme : 특정 키 입력을 사용하기 위해 필요한 요구사항의 집합. 예를 들어 키보드+마우스나, 게임패드+마우스처럼 특정 입력 도구 집합을 사용할 때, Action에 바인딩된 키를 다르게 할 수 있다. Scheme가 달라도 ActionMap과 Action 구조는 항상 같다.
  • Action Maps : UI에서 작동하는 키 입력 방식과 플레이어에게 필요한 키 입력 방식은 다르다. 작동 중인 Action Map을 변경함으로써 그걸 구현할 수 있다.
  • Action : 실제 액션 이름과 그에 할당된 키 값은 이곳에 작성한다.

 

Control Schemes

MainActions창 좌상을 보면 No Control Scheme을 눌러 Add Control Scheme을 선택 새로운 Scheme을 만들자

PC라는 이름만든후 List+를 눌러 Keyboard와 Mouse를 선택하고 Save한다.

다시 AddControl Scheme을 선택후 이름을 Mobile이라고 하고 List+ Screen을 추가하고 Save해준다

PC와 Mobile Scheme 2개가 만들어졌다.

 

Action Map및 Action 생성

게임에서 제어해야할 캐릭터는 이동및 공격 방어 같은 다양한 동작을한다. 이러한 개별 행동을 Action이라고 한다.

외부 입력을 받아 Action을 제어하기 위한 속성값을 Properties라고 한다. 쉽게 말하면 움직이게 할 키보드를 설정해주는 거다.

이런 외부입력의 속성값을 Action과 연결해주는걸 Biding이라고 한다.이동이라는 액션은 상하좌우의 동작이 필요하니 WASD 4개의 바인딩값이 필요하다. 또 상하좌우 화살표입력도 연결해줘야 하니 바인딩이 하나더 필요하다.

이러한 Action들의 집합이 Action Map이다. 

게임에서 외부 입력으로 제어해야할 객체는 하나일 수도 있지만 스타크래프트같이 여러개 일수도 있다. 이럴 경우는 Action Map을 더 만들어 대응할 수 있다.

 

Action Map+를 눌러 새로운 Action Map이 생성되면 이름을 PlayerActions으로 바꾼다.

Actions>New action를 더블클릭한후 Move로 지정한다.

WASD키를 사용하기 위해서 Action Type을  Button에서 Value로 변경한다.

Value로 변경하면 아래 Control Type을 Vector2로 변경한다.

Move액션 하위에 있는 No Biding항목을 Delete하고 +버튼을 눌러 메뉴에서 [Add UP/Down/Left/Right Composite]를 선택한다. (매뉴얼은 Add 2D Vector Composite였는데 바뀐것 같다)

바인딩 정보를 보기 싶게 하기 위해 2D Vector를 WASD로 변경한다.

바인딩 속성 설정

WASD 바인딩 하위에 자동생성된 Up, Down, Left, Right 옆에  표시된 <No Binding>표시는 아직 연결 정보가 없다는 거다.

우선 Up을 선택하고 Binding Path를 클릭하면 다양한 입력장치를 볼 수 있다. Keyboard를 선택한다

 

바인딩은 다음 3가지 방법으로  할수 있다.

계층구조에서 직접선택 - List메뉴에서 문자를 선택

[Listen]버튼 - Text Input에서 입력 문자를 필터링후 선택

[T]버튼 - <Keyboard>/d와 같이 문자열 변환된 정보를 보여준다. 편집이 가능하다는데 안해봤음.

하여간 적당히 WASD를 지정해보자.

 

이동동작의 바인딩 추가

캐릭터의 이동은 WASD뿐이 아니라 화살표키로도 가능해야 한다. 이럴때는  바인딩을 하나 더 추가하면된다.

이동에 관련된 바이딩이므로 Move옆 +를 눌러  [Add UP/Down/Left/Right Composite]추가한다

바인딩 이름을 "Arrow Key" 변경하고 화살표키를 맵핑해준다.

 공격 동작의 액션과 바인딩 추가

공격동작을 위해 Action + 버튼을 눌러 액션의 이름을 Attack로 지정한다. 공격은 스페이스키를 눌렀을때 동작하도록 한다.  Property의 Action Type은 기본값인 [Button]을 사용한다.

Attack Action하위 <No Binding>을 선택하고 Space를 연결해준다.

뷰의 위쪽 Save Asset을 눌러 저장한다.

 

렌더링 부하를 줄이는 다양한 컬링에 대해 알아보고 일인칭 시점에 렌더링 부하를 획기적으로 줄일 수 있는 오클루전 컬링 기능에 대해 소개한다.

Occlusion : 한물체가 다른 물체를 가리는 것 (한물체에 다른물체가 가려져 안보이는 것)

Culling : 도태시킨다(제거한다)

간단하게 정리하면 가려져 안보이는 물체는 렌더링 하지 않는 기법이다.

 

컬링방식은 다음과 같은 방법들이 있다.

프러스텀컬링,  거리비례에 의한 컬링, 오클루전 컬링

 

프러스텀컬링

절두체 컬링이라고도 하는데 카메라 시야 범위내의 물체만 렌더링하는 기법이다. 유니티에서 Main Camer 인스펙터뷰의 Field of view로 촬영범위를 조절할 수 있다.  

촬용범위 내에서도 Clipping Planes Near와 Clipping Planes Far를 조정해 일정거리 이내와 이상은 컬링할수 있다.

 위에 창에서 Far를 10으로 조정해보면 카메라의 절두체가 짤리면서 벽쪽이 보이지 않게 된다.

거리 비례에 의한 컬링

Player의 인스펙터뷰에 LOD Group 컴포넌트를 보면 10%미만은 Culled 되어 있다. 거리비례에 따라 해상도가 다른 모델을 사용하다가 10%미만에서는 렌더링 하지 않겠다는 뜻이다.

오클루전 컬링

가려진 물체는 렌더링 하지 않는 기능이다. 가려지는 장면이 별로 없는 스테이지에서는 괜히 부하만 증가시키는 역효과도 있다. 1인칭 시점 게임같이 장애물이 많은 게임에서 효과적이다.

MENU>Windows>Rendering>Occlusion Culling을 선택해 오클루젼뷰에서 Bake탭을 선택한후   Bake하면 기능이 실행된다.

 

오클루전 컬링 (유니티매뉴얼)

오클루전 컬링은 Unity가 다른 게임 오브젝트에 의해 뷰에서 완전히 가려진(오클루전된) 게임 오브젝트에 대한 렌더링 계산을 수행하지 못하도록 하는 프로세스입니다.

프레임마다 카메라는 씬의 렌더러를 검사한 후 그릴 필요가 없는 렌더러를 제외(컬링)합니다. 기본적으로 카메라는 절두체 컬링을 수행하여 카메라의 뷰 절두체에 속하지 않는 모든 렌더러를 제외합니다. 하지만 절두체 컬링은 렌더러가 다른 게임 오브젝트에 의해 가려지는지를 확인하지 않으므로, Unity가 최종 프레임에 표시되지 않는 렌더러에 대한 렌더링 작업에 CPU 및 GPU 시간을 여전히 낭비할 수 있습니다. 오클루전 컬링은 Unity가 이러한 낭비되는 작업을 수행하지 못하도록 방지합니다.

일반 절두체 컬링은 카메라 뷰 내의 모든 렌더러를 렌더링합니다.

오클루전 컬링은 더 가까운 렌더러에 의해 완전히 가려진 렌더러를 제거합니다.

오클루전 컬링을 사용하는 시기

오클루전 컬링이 프로젝트의 런타임 성능을 향상하는지 판단하려면 다음을 고려하십시오.

  • 낭비되는 렌더링 작업을 방지하면 CPU 및 GPU 시간을 모두 절약할 수 있습니다. Unity의 빌트인 오클루전 컬링은 CPU에서 런타임 계산을 수행하므로 절약되는 CPU 시간을 오프셋할 수 있습니다. 따라서 오클루전 컬링을 사용하면 오버드로우로 인해 프로젝트가 GPU 바운드일 때 성능이 향상될 가능성이 매우 높습니다.
  • Unity는 런타임 시점에 오클루전 컬링 데이터를 메모리에 로드합니다. 이 데이터를 로드할 만큼 충분한 메모리가 있는지 확인해야 합니다.
  • 오클루전 컬링은 작고 윤곽이 또렷한 영역이 견고한 게임 오브젝트에 의해 서로 명확하게 분리된 씬에서 가장 잘 작동합니다. 일반적인 예로는 복도로 연결된 방을 들 수 있습니다.
  • 오클루전 컬링을 사용하여 동적 게임 오브젝트를 가릴 수 있지만, 동적 게임 오브젝트는 다른 게임 오브젝트를 가릴 수 없습니다. 프로젝트가 런타임 시점에 씬 지오메트리를 생성하는 경우에는 Unity의 빌트인 오클루전 컬링이 프로젝트에 적합하지 않습니다.

오클루전 컬링의 작동 방식

오클루전 컬링은 Unity 에디터에서 씬에 대한 데이터를 생성한 후 런타임 시점에 해당 데이터를 사용하여 카메라가 볼 수 있는 요소를 결정합니다. 이러한 데이터 생성 프로세스를 베이크라고합니다.

오클루전 컬링 데이터를 베이크하면 Unity는 씬을 셀로 나누고 셀 내 지오메트리와 인접 셀 간의 가시성을 설명하는 데이터를 생성합니다. 그런 다음 Unity는 생성된 데이터의 크기를 줄이기 위해 가능한 경우 셀을 병합합니다. 베이크 프로세스를 설정하려면 오클루전 컬링 창에서 파라미터를 변경하고, 씬에서 오클루전 영역을 사용하십시오.

런타임 시점에 Unity가 베이크된 데이터를 메모리에 로드하고, Occlusion Culling 프로퍼티가 활성화된 각 카메라에 대해 해당 데이터에 대한 쿼리를 수행하여 카메라가 볼 수 있는 요소를 결정합니다. 오클루전 컬링이 활성화되면 카메라는 절두체 컬링과 오클루전 컬링을 둘 다 수행합니다.

SceneManager에서 씬을 통합할 수도 있지만 작업중 프로젝트뷰의 씬을 끌어다 통합시켜 볼 수 도 있다.

Play씬을 로드한후  Level_01씬을 하이라키뷰에다 끌어다 놓으면 간단하게 통합된다.

 

'유니티게임강좌 > 씬관리' 카테고리의 다른 글

[씬관리] 씬병합  (0) 2023.03.21
[씬관리] 씬분리  (0) 2023.03.20

7장 UI에서 만든 Main씬을 사용해 START 버튼을 누르면 Level_01과  Play 두개의 씬을 합쳐서 보여주는 로직을 구현하자. Main 씬을 열고 UIManager 스크립트를 다음과 같이 OnStartClick()을 추가한다.

public void OnStartClick() {
    SceneManager.LoadScene("Level_01");  //씬을 로딩하고
    SceneManager.LoadScene("Play", LoadSceneMode.Additive); //씬을 추가한다
}

SceneManager클래스는 동적으로 씬을 생성, 해제하거나 기존 씬을 호출하는 메서드를 제공한다. 사용을 위해서는 using UnityEngine.SceneManagement; 네임스페이스를 명시한다.

 

 

하이라키뷰에서 Button-Start를 선택하고 인스펙터에서 Button컴포넌트의 OnClick()에서 새로 만든 OnStartClick함수를 OnButtonClick대신 교체한다.

게임을 실행하고 Start 버튼을 클릭하면 호출하려는 씬이 없다는 에러가 난다 특정씬을 호출하려면 [Build Settings]의 씬 목록에 해당 씬을 등록해야 한다. 메뉴에서 [File]-[Build Setting...]를 선택해 프로젝트뷰의 Secene폴더에서 Main, Play, Level_01씬을 드래그해서 추가한다. 추가된씬중 최상단 씬이 제일 먼저 열린다. 창을 닫으면 자동으로 저장된다.

플레이하면 Main씬이 로딩되고 START를 누르면 하이라키에 LEVEL_01, PLAY씬으로 바끼고 게임화면이 실행된다. DontDestoryOnLoad씬은 GameManager를 싱글턴으로 구현했기 때문에 자동으로 생선된 씬이다. 

 

'유니티게임강좌 > 씬관리' 카테고리의 다른 글

[씬관리] 멀티 씬 에디트 기능  (0) 2023.03.21
[씬관리] 씬분리  (0) 2023.03.20

지금까지 개발했던 씬을 분리해보자 이유는 협업시 분야별로 개발후 합칠 수 있기 때문이다. 예를 들어 UI, 레벨디자이너, 메인개발자 3명이 분야별로 동시에 개발을 진행할 수 있기 때문이다.

여기서는 게임로직씬과 스테이지씬으로 나누어 보겠다.

앞서  _STAGE에 spawnPointGroup역시 하위로 드래그해서 이동시킨다.

파일 Save로 씬을 저장한다.

Scenes폴더아래 Play를 Ctrl-D로 2개 카피해서 하나는 Play_Backup 다른하나는 Level_01로 이름을 바꾼다.

현재 열려있는 씬이 Play인지 확인하고 하이라키뷰의 _STAGE 게임오브젝트를 삭제한다. 그러면 Player와UI만 남는다.

Ctrl-S Save하고 Level_01씬을 로딩한다.

이번에는 _STAGE만 남겨두고 다지운다.

 

'유니티게임강좌 > 씬관리' 카테고리의 다른 글

[씬관리] 멀티 씬 에디트 기능  (0) 2023.03.21
[씬관리] 씬병합  (0) 2023.03.21

라이트매핑은 정적이므로 동적으로 움직이는 객체에는 적용할 수 없다. 물론 실시간 조명의 Culling Mask를 사용해 주인공에게만 조명 효과를 부여할 수 있지만 라이팅매핑이 적용된 간접광원 또는 그림자영역에 들어갔을때 밝은 조명이 비치는 부자연 스러운 장면이 연출된다.

이를 개선하기 위해 유니티는 라이트 프로브(Light Probes)라는 기능을 제공한다. 라이트프로브는 스테이지 조명이 있는 곳 주변에 라이트 프로브를 배치하고 라이트맵을 베이크할때 해당 라이트프로브에 주변부의 광원 데이터를 미리 저장해 둔다. 저장된 광원데이터는 실행시 근처를 지나치는 동적 객체에 광원 데이터를 전달해 해당 객체의 색상과 보간시켜 마치 실시간 조명과 같은 효과를 내는 방식이다.

 

Light Probe Group

라이트 프로브를 만들어 주인공을 밝게 만들어보다 하이라키뷰의 _STAGE를 선택해 메뉴에서 [Light]->[Light Probe Group]을 선택해 Light Probe Group를 생성한다. _STABE하위에 생성한 Light Probe Group의 Position이 (0,0,0)인지 다시한번 확인한다.

Light Probe는 바닥위에 위치해야 효과를 낼수 있다 따라서 Y를  1.2로 설정해 라이트프로브가 모두 바닥위에 배치되도록한다.

Edit Light Probes를 클릭하면 4개의 버튼이 나타나고 Select All 버튼을 클릭하면 라이트 프로브가 파란색으로 바낀다.

Duplicate Selected를 클릭하면 변화가 없어 보이지만 복사가 되었다 Transform축을 클릭해 이동한다.

Selected All - duplicate Selected를 반복해 Floor를 채워보자

Lighting 뷰에서 베이크 해보면 이제 Player가 Point Light색에 따라 변화하는 걸 알수 있다.

 

Anchor Override

라이트 프로브는 Player가 근접한 4개의 라이트 프로브에서 베이크된 조명값을 전달한다. 

Anchor Override기능을 이용해 보간되는 위치를 설정할 수 있다. 이 속성에 원하는 위치를 연결하면 그 위치부터 텍스처 색상이 보간되기 시작한다. 하이라키뷰의 Player를 선택하고 head를 열어 놓고 slade_mesh 3개를 선택하고 인스펙터의 Anchor Override 에 연결해준다

 

'유니티게임강좌 > 라이트매핑' 카테고리의 다른 글

[라이트매핑] 라이트매핑  (0) 2023.03.20
[라이트매핑] 광원 타입  (0) 2023.03.19

+ Recent posts