[Unity] 포톤 멀티 숨바꼭질 만들기 02

이정현·2021년 10월 3일
1

🔨 개발 내용

아래 화면을 보면 플레이어 옆에 랜턴이 둥둥 떠다니고 있음을 확인할 수 있다.

💡 플레이어가 랜턴을 왼손에 쥐고 다닐 수 있도록 수정하였으며, 오른쪽 어깨 옆에 지팡이가 떠다니도록 하였다.
💡 지팡이는 마우스 왼쪽 클릭을 할 시, 레이저가 발사된다.
💡 레이저가 플레이어와 충돌하면 해당 플레이어가 사라지도록 만들었다.
💡 플레이어와 같은 외형의 컴퓨터 플레이어를 추가하였다. (컴퓨터의 이동 스크립트는 아직 작성하지 않았다)

🦯 Wand 세팅


다음과 같이 지팡이를 밝히는 역할을 하는 Point Light만 Wand에 존재한다. 플레이어가 좌클릭을 할 시, 빔을 발사하도록 할 것이기 때문에 빈 오브젝트 Effect_RayCast를 생성한다.

좌클릭 시, Cylinder의 Scale을 늘리도록 하여 빔 형태로 나타나도록 할 것이다. 따라서 Effect_RayCast내에 3D Object>Cylinder를 추가하여 다음과 같이 인스펙터 창을 구성하였다. Capsule Collider는 삭제하도록 한다.(Raycast를 통해 충돌 결과를 출력할 것이기 때문)
설정을 완료 했다면 Effect_RayCast를 프리팹으로 만든다.



Wand 프리팹에 위에서 제작한 Effect_RayCast 프리팹을 넣고 적절한 위치에 배치한다. 또한 빈 오브젝트 Point를 만들어 빔을 발사할 위치에 배치하였다.
이제 Wand에 적용할 Effect_Raycast_Laser 스크립트를 작성하도록 한다.

using UnityEngine;
using Photon.Pun;

public class Effect_Raycast_Laser : MonoBehaviourPunCallbacks
{
    public GameObject point; //쏘는 위치
    public GameObject beam; //빔

    void Update()
    {
        if (!photonView.IsMine) return;

        if (Input.GetMouseButtonDown(0)) //좌 클릭 시
        {
            photonView.RPC("Laser", RpcTarget.Others, null);
            Laser();
        }
    }
    
    [PunRPC]
    void Laser()
    {
        RaycastHit hit;
        Debug.DrawRay(point.transform.position, beam.transform.forward * 1.0f, Color.red, 3.0f);
        if (Physics.Raycast(point.transform.position, beam.transform.forward, out hit, 1.0f))
        {
            . . .
        }
        beam.SetActive(true);
        beam.transform.localScale = new Vector3(1, 1, 40);
        Invoke("HideBeam", 1.0f);
    }
    void HideBeam()
    {
        beam.SetActive(false);
        beam.transform.localScale = new Vector3(1, 1, 1);
    }
}

위와 같이 스크립트를 작성하고 Wand에 추가한다.

위 화면처럼 필요한 GameObject를 스크립트에 넣어주고, Photon View, Photon Transform View를 Wand에 추가하여 화면의 인스펙터 창처럼 구성한다.


게임을 실행해보면 좌 클릭 시, 지팡이에서 빔이 나오는 것을 확인할 수 있다.

🤺 플레이어 랜턴, 지팡이 들기


플레이어의 프리팹을 open 한 화면이다. 왼손에는 랜턴을 들게하고 오른쪽 어깨 옆에는 지팡이가 따라 다니도록 배치하도록 한다.


플레이어의 spine을 타고 내려가 랜턴을 들기에 적당한 위치를 선택하고, 해당 위치 안에 랜턴 프리팹을 추가하였다.

랜턴을 든 모습을 자연스럽게 보이도록 하기 위해 랜턴의 상대 위치와 회전 값을 위의 인스펙터 창처럼 조정하였다.

위에서 랜턴을 추가했던 과정처럼 Wand 프리팹을 추가한다. 오른쪽 어깨 옆에 지팡이가 떠다니도록 하기위해 RightSoulder 아래에 Wand 프리팹을 추가하고, 상대위치와 회전 값을 약간 수정하였다.


게임을 실행한 후 씬을 살펴보면 랜턴과 지팡이가 설정한 위치에 있음을 확인할 수 있다.

🌠 레이저 충돌 처리

플레이어가 발사한 빔이 컴퓨터 또는 다른 플레이어와 충돌할 시, 해당 정보를 감독 스크립트에게 알리고, 감독 스크립트에서 이에대한 처리를 수행하도록 하고자 한다.

씬에 GameDirector라는 이름의 빈 오브젝트를 생성하고, GameDirector.cs 스크립트를 추가한다.
GameDirector.cs 코드는 아래와 같다.

using UnityEngine;

public class GameDirector : MonoBehaviour
{
    public void PlayerDead(GameObject player)
    {
        player.SetActive(false);
    }

    public void ComputerDead(GameObject computer)
    {
        computer.SetActive(false);
    }
}

아직 구현할 내용은 많지만 현재는 위와 같이 코드를 작성하였다. PlayerDead는 레이저에 맞은 플레이어를 비활성화 시키는 함수이며, ComputerDead는 레이저에 맞은 컴퓨터 플레이어를 비활성화 시킨다. GameDirector 스크립트의 이 함수는 위에서 작성하였던 Effect_Raycast_Laser.cs 스크립트에서 호출한다.

Effect_Raycast_Laser.cs 스크립트 내용을 다음과 같이 추가한다.

using UnityEngine;
using Photon.Pun;

public class Effect_Raycast_Laser : MonoBehaviourPunCallbacks
{
    public GameObject point; //쏘는 위치
    public GameObject beam; //빔
    GameObject director;

    private void Start()
    {
        director = GameObject.Find("GameDirector");
    }
    
    void Update()
    {
        if (!photonView.IsMine) return;

        if (Input.GetMouseButtonDown(0)) //좌 클릭 시
        {
            photonView.RPC("Laser", RpcTarget.Others, null);
            Laser();
        }
    }
    
    [PunRPC]
    void Laser()
    {
        RaycastHit hit;
        Debug.DrawRay(point.transform.position, beam.transform.forward * 1.0f, Color.red, 3.0f);
        if (Physics.Raycast(point.transform.position, beam.transform.forward, out hit, 1.0f))
        {
            if (hit.transform.tag == "Player")
            {
                Debug.Log("플레이어와 충돌!");
                GameObject player = hit.transform.gameObject;
                director.GetComponent<GameDirector>().PlayerDead(player);

            }
            else if (hit.transform.tag == "Computer")
            {
                Debug.Log("컴퓨터와 충돌!");
                GameObject computer = hit.transform.gameObject;
                director.GetComponent<GameDirector>().ComputerDead(computer);
            }
        }
        beam.SetActive(true);
        beam.transform.localScale = new Vector3(1, 1, 40);
        Invoke("HideBeam", 1.0f);
    }
    void HideBeam()
    {
        beam.SetActive(false);
        beam.transform.localScale = new Vector3(1, 1, 1);
    }
}

추가한 부분

GameObject director;
private void Start()
{
   director = GameObject.Find("GameDirector");
}
if (Physics.Raycast(point.transform.position, beam.transform.forward, out hit, 1.0f))
{
    if (hit.transform.tag == "Player")
    {
        Debug.Log("플레이어와 충돌!");
        GameObject player = hit.transform.gameObject;
        director.GetComponent<GameDirector>().PlayerDead(player);
    }
    else if (hit.transform.tag == "Computer")
    {
        Debug.Log("컴퓨터와 충돌!");
        GameObject computer = hit.transform.gameObject;
        director.GetComponent<GameDirector>().ComputerDead(computer);
    }
}

Start에서 감독 오브젝트를 받아온 후, 레이저와 충돌한 오브젝트의 tag가 무엇이냐에 따라 GameDirector 스크립트의 PlayerDead, ComputerDead 함수를 호출한다. 이때, 충돌한 오브젝트를 파라미터로 전달하도록 하였다.

🤖 컴퓨터 플레이어 추가

아직 컴퓨터 플레이어에 대한 스크립트는 작성하지 않았으며, 단순 스폰만 기능하도록 하였다. 후에 컴퓨터 플레이어에 대한 스크립트를 추가하도록 한다.

컴퓨터 플레이어의 프리팹은 위의 화면과 같다. 플레이어 스크립트와 Wand에 추가한 Effect_Raycast_Laser 스크립트만 제거하고 그외의 컴포넌트들은 동일하게 하였다.
컴퓨터 플레이어의 Tag는 Computer로 변경하였다.

지금까지 구현한 내용을 테스트 해보기 위해 NetworkManager 스크립트에서 컴퓨터 플레이어 10명을 생성하도록 코드를 다음과 같이 수정하였다.

    public override void OnJoinedRoom()
    {
        Transform[] positions = GameObject.Find("SpawnPosition").GetComponentsInChildren<Transform>();
        int idx;
        for(int i = 0; i< 10; i ++)
        {
            idx = Random.Range(1, positions.Length);
            PhotonNetwork.Instantiate("Computer Player", positions[idx].position, Quaternion.identity);
        }
        idx = Random.Range(1, positions.Length);
        PhotonNetwork.Instantiate("Player3", positions[idx].position, Quaternion.identity);
    }

🎮 실행화면


게임을 실행하면 위와 같이 컴퓨터 플레이어가 10명 생성이 된다.

마우스 좌클릭을 통해 지팡이에서 빔을 발사하면, 빔에 맞은 컴퓨터 플레이어가 사라지게 된다.

profile
개발자 꿈나무

0개의 댓글