https://github.com/IndieGameMaker/SpaceShooter2021

 

GitHub - IndieGameMaker/SpaceShooter2021: 절대강좌! 유니티 - 프로젝트

절대강좌! 유니티 - 프로젝트. Contribute to IndieGameMaker/SpaceShooter2021 development by creating an account on GitHub.

github.com

Resources/PhotonNetwork 폴더 하위에 있는 AngryBotResources 패키지를 임포트한다.

 

스테이지 설치와 라이트 매핑

AngryBotResources/Prefabs  폴더에 있는 Environment 프리팹을 하이라키 뷰로 드래그해 배치한다.

라이트 매핑을 위해 메뉴에서 [Window]-[Rendering]-[Lighting]을 선택해 라이팅 뷰를 연다. [Scene]탭을 선택하고 [New Lighting Settings] 버튼을 클릭해 SampleScene의 라이트 매핑 정보를 저장할 에셋을 생성한다. 생성된 라이팅에셋은 Scenes폴더로 이동시킨다.

라이팅 세팅 에셋을 생성하면 라이팅뷰의 Lighting Setting 옵션이 활성화된다. 좀더 빠른 라이팅 매핑을 위해 Lightmap Resolution 속성을 기본값이 40에서 10 또는 20 정도로 설정한다.

라이팅뷰 아래에 있는 [Generate Lighting] 버튼을 클릭해 라이트 맵 베이킹을 시작한다.

다음 화면은 베이킹후 라이트매핑이 완료된 화면이며 비네팅 효과로 모서리 부분이 어둡게 표현되었다.(약하게 하였다)

Bloom, Tonemapping 효과

Global Volume의 인스펙터뷰에서 [Add override] 버튼을  클릭해 Tonemapping을 추가한후 Mode Option을 체크후 ACES를 선택한다. 조명의 밝기를 HDR에서 사람이 인식할 수 있는 범위로 조정하는 효과를 말한다.

하이라키뷰의 Direct Light를 선택후 인스펙터뷰에서 [Light]-[Emission]-[Intensity]를 1에서2로 변경해서 밝게한다

다시  [Add override] 버튼을  클릭해 Bloom효과를 추가하고 Intensity를 1.5로 설정한다. 광원주위를 과장되게 표현하는 효과이다.

포스트 프로세싱 전후

 

이번 프로젝트는 비주얼 효과를 높인 URP을 적용한 프로젝트를 진행한다.

 

URP프로젝트 생성방법

처음부터 URP로 프로젝트를 생성해도 되지만 3D프로젝트를 생성후 URP로 변경하는 방법을 사용한다.

 

새프로젝트 생성

3D 템플릿을 선택후 이름을 'AngryBot2Net'으로 한다

 

Universal RP 패키지 설치및 URP설정

메뉴 [Window]-[Package Manager]에서

좌상 [Packages: Unity Registry] 선택후 목록에서 Universal RP를 선택하고 [Install]버튼을 클릭해서 설치한다.

Universal Render Pipeline Assets 생성및 설정

메뉴에서 [Assets]-[Create]-[Rendering]-[Universal Render Pipeline]-[Pipeline Asset(Forward Renderer)]를 선택한다.

필자의 버전은 2021.3.21f1인데 아래와 같이 설정했다.

이름 앞의 New를 제거한후 엔터키를 눌러 기본 에셋명으로 설정한다.  그럼 파일 2개가 보이는데 Redering Assets폴더를 만들고 이동시킨다.

메뉴[Edit]-[Project Settings ]를 선택해 Graphics 섹션의 맨위 Scriptable Render Pipeline Settings의 ◉눌러 브라우저에서 방금만든 URP에셋을 선택한다.

Player Settings - Quality 설정

Quality Section에서 Quality - High를 선택하고 Current Active Quality Level Name  ◉을 눌러 브라우저에서 URP에셋 선택 

포스트 프로세싱 설정

URP패키지를 설치하면 포스트 프로세싱을 할 수 있어 다양한 필터와 효과를 적용할 수 있다.

 

Post-processing 옵션 활성화

프로젝트뷰에서 Asset_Rendere를 선택하고 인스펙터뷰에서 Post-processing enabled가 체크되어 있는지 확인한다. Data도 연결되어 있는지 확인한다.

포스트 프로세싱 효과

하이라키뷰의 좌상+눌러 Global Volume을 선택한다.

새로생긴 Global Volume의 인스펙터를 보면 스크립터 컴포넌트가 포함되어 있는데 New를 누르면 자동 생성된다.

비네팅 효과

화면의 주변부를 어둡게 처리하는 효과

하이라키뷰의 Global Volume을 선택한 후 인스펙터 뷰의 Volume 컴포넌트 아래에 있는 [Add Override] 버튼을 클릭해 [Post-processing]-[Vignette]를 선택한다.

Vignette의 Intensity와 Smoothness를 적당히 조절하면 화면 주변이 어두워지지만 아직 Main Camera에 포스트 프로세싱을 적용하지 않아 게임 뷰에는 적용되지 않는다.

메인 카메라의 포스트 프로세싱 적용

하이라키뷰의 메인카메라를 선택하고 인스펙터뷰의 렌더링 - Post Processing을 켜면 게임뷰에서 표시된다.

네트워크 게임을 개발하기위해 직접 서버를 제작해도 되겠지만 포톤이라는 네트워크엔진이 있다. 유료지만 PUN(Photon Unity Networking)의 경우 20명 동접사용자까지는 무료로 사용할 수 있다.

 

포톤클라우드 vs 포톤서버

포톤서버는 자신이 직접 서버를 운영할때 필요한 소프트웨어로 여기서는 서버서비스를 대행해주는 클라우드서비스를 사용한다.

 

포톤클라우드 환경 설정

계정생성

www.photonengine.com에  에 접속후 이메일 주소를 입력하면 가입절차가 완료된다. 수신된 이메일로 접속하면 계정이 활성화된다. 암호를 설정하고 웹페이지 우상단의 관리자화면 으로 접속한다 처음이라면 가운데 Create Project를 누른후 Multiplayer Game, Pun, AngryBot2Net을 입력후 새 어플리케이션을 작성한다. AppID가 만들어 지는데 잘 저장해 놓는다.

유니티 프로젝트 생성및 리소스추가

게임에 이용할 스테이지는 Resources/Templete폴더에 포함된 프로젝트를 사용해도 되지만 직접프로젝트를 생성해보겠다.

 

 

 

Input Debug는 입력 장치로부터 전달되는 값을 모니터링할 수 있는 기능이다.

입력값을 녹화 저장 로드 할수 있다.

메뉴 [windows] [Analysis][Input Debug]로 접근할 수 있다.

 

Input System은 PlayerInput 컴포넌트를 사용하는 방법과 PlayerInput컴포넌트 없이 직접 InputAction을 생성하고 액션을 정의하는 방식이 있다. 새로운 스크립트를 만들고 PlayerCtrlByEvent로 이름변경한다.

UnityEngine.InputSystem 네임스페이스를 명시하고 이동과 공격 액션을 저장할 변수를 선언한다.

    private InputAction moveAction;  //액션 저장용 변수
    private InputAction attackAction; //액션 저장용 변수

InputAction창에서 정의했던 액션을 InputAction()함수를 사용해 정의한다. moveAction은 WASD및 방향키등 여러가지 binding을 구현해야 하므로 moveAction.AddCompositeBinding()를 이용해 binding해야한다. ".With()" 메소드를 사용해 추가할 수 있다. 여기서는 방향키는 추가하지 않았다. 바인딩타입이 2DVector이므로 "2DVector"를 parameter로 사용하였다.

moveAction = new InputAction("Move", InputActionType.Value);
//Move 액션의 복합 바인딩 정보 정의
moveAction.AddCompositeBinding("2DVector")
.With("Up", "<Keyboard>/w")
.With("Down", "<Keyboard>/s")
.With("Left", "<Keyboard>/a")
.With("Right", "<Keyboard>/d");

attackAction = new InputAction("Attack",
                               InputActionType.Button,
                               "<Keyboard>/space");

액션의 preformed,cancled 이벤트에 람다식을 연결하는 방식은 이전과 같습니다.  action의 활성화를 해주어야 합니다.

moveAction.Enable();
attackAction.Enable();

PlayerCtrlByEvent 전체 코드입니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerCtrlByEvent : MonoBehaviour {
    private InputAction moveAction;
    private InputAction attackAction;

    private Animator anim;
    private Vector3 moveDir;

    // Start is called before the first frame update
    void Start() {
        anim = GetComponent<Animator>();

        //Move 액션 생성 및 타입 설정
        moveAction = new InputAction("Move", InputActionType.Value);

        //Move 액션의 복합 바인딩 정보 정의
        moveAction.AddCompositeBinding("2DVector")
        .With("Up", "<Keyboard>/w")
        .With("Down", "<Keyboard>/s")
        .With("Left", "<Keyboard>/a")
        .With("Right", "<Keyboard>/d");

        //Move 액션의 performed, canceled 이벤트 연결
        moveAction.performed += ctx => {
            Vector2 dir = ctx.ReadValue<Vector2>();
            moveDir = new Vector3(dir.x, 0, dir.y);
            //Warrior_Run 애니메이션 실행
            anim.SetFloat("Movement", dir.magnitude);
        };

        moveAction.canceled += ctx => {
            moveDir = Vector3.zero;
            anim.SetFloat("Movement", 0.0f);
        };

        //Move 액션의 활성화
        moveAction.Enable();

        //Attack 액션 생성
        attackAction = new InputAction("Attack",
                                       InputActionType.Button,
                                       "<Keyboard>/space");

        //Attack 액션의 performed 이벤트 연결
        attackAction.performed += ctx => {
            anim.SetTrigger("Attack");
        };
        //Attack 액션의 활성화
        attackAction.Enable();
    }

    // Update is called once per frame
    void Update() {
        if (moveDir != Vector3.zero) {
            //진행 방향으로 회전
            transform.rotation = Quaternion.LookRotation(moveDir);
            //회전한 후 전진방향으로 이동
            transform.Translate(Vector3.forward * Time.deltaTime * 4.0f);
        }
    }
}

 

하이라키뷰에 warrior모델을 하나 더 끌어다 놓고 Animator컴포넌트에 AnimationController_Warrior컨트롤러를 연결하고 PlayerCtrlByEvent 스크립트도 연결한다.

2개의 warrior가 Input System의 구현은 다르지만 동일하게 동작하는 걸 확인할 수 있다.

 

+ Recent posts