Asset 스토어에서 PUN2-FREE를 검색해 추가하고 Package-Manager에서 다운로드후 임포트한다.

PUN 패키지 설치

임포트가 끝나면 AppID를 넣으라고 한다 Email은 넣어봤더니 안된다. Done이라고 나온다

PUN Wizard창은 메뉴에서 [Window]-[Photon Unity Networking]-[PUN  Wizard]를 선택해 열수 있다.

PUN 패키지는 프로젝트뷰의 Photon폴더에 설치되는데 PhotonSererSetting를 선택하면 AppID등 다양한 정보를 볼수 있다.

 

아직 카메라가 주인공을 따라가는 로직이 구현되지 않았다.

메뉴 [Windows]-[Package Manager]를 열고 Package:Unity Registry를 선택하고, Cinemachine 패키지를 설치한다.

이제 메뉴[GameIObject]를 열면 [Cinemachine]-Virtual Camera를 선택해서 하이라키뷰에 가상카메라를 추가하면

CM vcam1이 추가되는데 이를 선택하고 인스펙터뷰에서 Follow와 Look At에 하이라키뷰의 Player를 끌어다 놓는다.

Cinemachine Virtual Camera 컴포넌트의 설정을 다음과 같이 한다.

Body > Binding Mode는 Lock To Target On Assign, Follow offset (0,9,-4)

Aim > Tracked Object Offset (0,2,0), Dead Zone Width 0.1, Dead Zone Height 0.1로 설정한다.

이 숫치는 실행해보면 탑다운 방식 이다.   WASD키를 눌러보면 캐릭터가 이동하는데 카메라는 따라간다. 마우스를 움직여보면 캐릭터는 회전하지만 카메라는 회전하지 않는다.

AngryBotResources/Prefabs/Player을 씬뷰로 끌어다 놓는다.

Player와 Main Camera의 transform을 다음과 같이 조정한다.

 

Player Prefab은 이미 Character Controller컴포넌트가 이미 설정되어 있고 실행하면  Idle 애니메이션을 취하고 있다.

 

주인공 캐릭터 이동및 회전

프로젝트뷰에서 Scripts폴더안에 새로운 스크립트를 하나 만들고 이름을 Movement로 변경한다. 작성후 Player에 적용한다.

Player의 이동처리는 CharacterController의 SimpleMove함수를 이용한다.

        // 주인공 캐릭터 이동처리
        controller.SimpleMove(moveDir * moveSpeed);

Plane객체는 지정한 지점에 가상의 바닥을 생성한다.

        // 가상의 바닥을 주인공의 위치를 기준으로 생성
        plane = new Plane(transform.up, transform.position);

Turn() 함수에서는 ScreenPointToRay 함수를 이용해 마우스 커서의 위치값을 이용해 Ray를 생성한다.

        // 마우스의 2차원 좌푯값을 이용해 3차원 광선(레이)를 생성
        ray = camera.ScreenPointToRay(Input.mousePosition);

생성된 ray는 Plane.Raycast를 사용해 가상의 바닥으로 광선을 투사해 Ray.GetPoint로 닿은 지점을 계산한다.

// 가상의 바닥에 레이를 발사해 충돌한 지점의 거리를 enter 변수로 반환
plane.Raycast(ray, out enter);
// 가상의 바닥에 레이가 충돌한 좌푯값 추출
hitPoint = ray.GetPoint(enter);

가상의 바닥과 닿은 지점과 Player의 위치를 차이는 회전해야할 방향벡터이고 마우스 커서가 있는 지점으로 회전하게 된다.

// 회전해야 할 방향의 벡터를 계산
Vector3 lookDir = hitPoint - transform.position;
lookDir.y = 0;
// 주인공 캐릭터의 회전값 지정
transform.localRotation = Quaternion.LookRotation(lookDir);

이 방법은 가상의 바닥의 충돌지점을 얻어 오기 때문에 지상의 구조물을 포인팅하면 엉뚱한 곳으로 돈다.

 

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


public class Movement : MonoBehaviour {
    // 컴포넌트 캐시 처리를 위한 변수
    private CharacterController controller;
    private new Transform transform;
    private Animator animator;
    private new Camera camera;

    // 가상의 Plane에 레이캐스팅하기 위한 변수
    private Plane plane;
    private Ray ray;
    private Vector3 hitPoint;

    // 이동 속도
    public float moveSpeed = 10.0f;

    void Start() {
        controller = GetComponent<CharacterController>();
        transform = GetComponent<Transform>();
        animator = GetComponent<Animator>();
        camera = Camera.main;

        // 가상의 바닥을 주인공의 위치를 기준으로 생성
        plane = new Plane(transform.up, transform.position);
    }

    void Update() {
        // 자신이 생성한 네트워크 객체만 컨트롤
            Move();
            Turn();
    }

    // 키보드 입력값 연결
    float h => Input.GetAxis("Horizontal");
    float v => Input.GetAxis("Vertical");

    // 이동 처리하는 함수
    void Move() {
        Vector3 cameraForward = camera.transform.forward;
        Vector3 cameraRight = camera.transform.right;
        cameraForward.y = 0.0f;
        cameraRight.y = 0.0f;

        // 이동할 방향 벡터 계산
        Vector3 moveDir = (cameraForward * v) + (cameraRight * h);
        moveDir.Set(moveDir.x, 0.0f, moveDir.z);

        // 주인공 캐릭터 이동처리
        controller.SimpleMove(moveDir * moveSpeed);

        // 주인공 캐릭터의 애니메이션 처리
        float forward = Vector3.Dot(moveDir, transform.forward);
        float strafe = Vector3.Dot(moveDir, transform.right);

        animator.SetFloat("Forward", forward);
        animator.SetFloat("Strafe", strafe);
    }

    // 회전 처리하는 함수
    void Turn() {
        // 마우스의 2차원 좌푯값을 이용해 3차원 광선(레이)를 생성
        ray = camera.ScreenPointToRay(Input.mousePosition);

        float enter = 0.0f;

        // 가상의 바닥에 레이를 발사해 충돌한 지점의 거리를 enter 변수로 반환
        plane.Raycast(ray, out enter);
        // 가상의 바닥에 레이가 충돌한 좌푯값 추출
        hitPoint = ray.GetPoint(enter);

        // 회전해야 할 방향의 벡터를 계산
        Vector3 lookDir = hitPoint - transform.position;
        lookDir.y = 0;
        // 주인공 캐릭터의 회전값 지정
        transform.localRotation = Quaternion.LookRotation(lookDir);
    }
}

 

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폴더에 포함된 프로젝트를 사용해도 되지만 직접프로젝트를 생성해보겠다.

 

 

 

+ Recent posts