Unity/Photon

03. Photon - ์‹ค์Šต 1 (1) player ์ƒ์„ฑ, ์œ„์น˜ ๋™๊ธฐํ™”

๐Ÿ”ท ์‹ค์Šต 1

room์— ์ž…์žฅํ•˜๋ฉด์„œ player ์ƒ์„ฑ

์œ„์น˜ ๋™๊ธฐํ™”

 

 

 

๐Ÿ”ถ Photon ๊ธฐ๋ณธ ์„ธํŒ…

- ํฌํ†ค ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ƒ์„ฑ

- ์•„์ด๋”” ๋ณต์‚ฌ

- ์œ ๋‹ˆํ‹ฐ PUN2 ํŒจํ‚ค์ง€ ์ž„ํฌํŠธ

- ์•„์ด๋”” ๋ถ™์—ฌ๋„ฃ๊ธฐ

 

 

 

๐Ÿ”ท ์ด๋™ ๋กœ์ง

- ๋นˆ๊ฒŒ์ž„์˜ค๋ธŒ์ ํŠธ ์ƒ์„ฑ : PhotonManager

- ์Šคํฌ๋ฆฝํŠธ ์ƒ์„ฑ : PhotonManager

- ๊ฒŒ์ž„์˜ค๋ธŒ์ ํŠธ์— ์Šคํฌ๋ฆฝํŠธ ์ถ”๊ฐ€

 

 

 

- ํ๋ธŒ ์ƒ์„ฑ : Floor

    - Scale : 10, 0.1, 10

 

 

 

- ๋นˆ๊ฒŒ์ž„์˜ค๋ธŒ์ ํŠธ ์ƒ์„ฑ : GameManager

- ์Šคํฌ๋ฆฝํŠธ ์ƒ์„ฑ : GameManager

- ๋นˆ๊ฒŒ์ž„์˜ค๋ธŒ์ ํŠธ์— ์Šคํฌ๋ฆฝํŠธ ์ถ”๊ฐ€

 

 

 

- ๋นˆ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ ์ƒ์„ฑ : SpawnPointGroup

    - Position : 0, 0.6, 0

    - ํ•˜์œ„์— ๋นˆ๊ฒŒ์ž„์˜ค๋ธŒ์ ํŠธ ์ƒ์„ฑ : SpawnPoint_1, SpawnPoint_2

    - ๋งˆ์ฃผ๋ณด๊ณ  ์žˆ๋„๋ก ์ ๋‹นํžˆ ์œ„์น˜ ์กฐ์ ˆ

- SpawnPoint_2

    - rotate : 0, 180, 0

 

 

 

- Player ๋งŒ๋“  ํ›„ Prefabํ™”

 

 

 

 

- ์Šคํฌ๋ฆฝํŠธ ์ƒ์„ฑ : PlayerCtrl

 

 

 

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

public class PlayerCtrl : MonoBehaviour
{
    private new Rigidbody rigidbody;

    private float v;
    private float h;
    private float r;

    [Header("์ด๋™ ๋ฐ ํšŒ์ „ ์†๋„")]
    public float moveSpeed = 8.0f;
    public float turnSpeed = 0.0f;
    public float jumpPower = 5.0f;

    private float turnSpeedValue = 200.0f;

    RaycastHit hit;

    IEnumerator Start()
    {
        rigidbody = GetComponent<Rigidbody>();

        turnSpeed = 0.0f;
        yield return new WaitForSeconds(0.5f);
        turnSpeed = turnSpeedValue;
    }

    // ํ‚ค ์ž…๋ ฅ
    void Update()
    {
        v = Input.GetAxis("Vertical");
        h = Input.GetAxis("Horizontal");
        r = Input.GetAxis("Mouse X");

        Debug.DrawRay(transform.position, -transform.up * 0.6f, Color.green);
        if (Input.GetKeyDown("space"))
        {
            if (Physics.Raycast(transform.position, -transform.up, out hit, 0.6f))
            {
                rigidbody.AddForce(Vector3.up * jumpPower, ForceMode.Impulse);
            }
        }
    }

    // ๋ฌผ๋ฆฌ์  ์ฒ˜๋ฆฌ
    void FixedUpdate()
    {
        Vector3 dir = (Vector3.forward * v) + (Vector3.right * h);
        transform.Translate(dir.normalized * Time.deltaTime * moveSpeed, Space.Self);
        transform.Rotate(Vector3.up * Time.smoothDeltaTime * turnSpeed * r);
    }

}

- ์Šคํฌ๋ฆฝํŠธ ์ž‘์„ฑ

 

 

 

- rigidbody ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€

- PlayerCtrl ์Šคํฌ๋ฆฝํŠธ ์ถ”๊ฐ€

- ํ”Œ๋ ˆ์ด์–ด ์›€์ง์ด๋Š”์ง€ ํ™•์ธ

 

 

 

- Player ์•„๋ž˜์— ๋นˆ๊ฒŒ์ž„์˜ค๋ธŒ์ ํŠธ ์ƒ์„ฑ : CamPivot

    - Position : 0, 2, 0

 

 

 

- ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ : Photon View, Photon Transform View

- Apply All

- ํ•˜์ด์–ด๋ผํ‚ค ์ฐฝ์—์„œ player ์‚ญ์ œ

 

 

 

๐Ÿ”ท ํฌํ†ค ์—ฐ๊ฒฐ๋˜๋ฉด ํ”Œ๋ ˆ์ด์–ด ์ƒ์„ฑ

- Resources ํด๋” ์ƒ์„ฑ

- Player ํ”„๋ฆฌํŒน Resources ํด๋”๋กœ ์ด๋™

 

 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;

public class GameManager : MonoBehaviour
{
    public static GameManager instance = null;
    public bool isConnect = false;

    private void Awake()
    {
        if (instance == null)
        {
            instance = this;
            DontDestroyOnLoad(this.gameObject);
        }
        else if (instance != this)
        {
            Destroy(this.gameObject);
        }
    }

    void Start()
    {
        StartCoroutine(CreatePlayer());
    }

    void Update()
    {


    }

    IEnumerator CreatePlayer()
    {
        yield return new WaitUntil(() => isConnect);

        GameObject playerTemp = PhotonNetwork.Instantiate("Player", Vector3.one, Quaternion.identity, 0);
    }
}

- GameManager ์Šคํฌ๋ฆฝํŠธ ์ˆ˜์ •

 

 

 

- ์ปดํฌ๋„ŒํŠธ ์ถ”๊ฐ€ : Photon View

 

 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;

public class PhotonManager : MonoBehaviourPunCallbacks
{
    private readonly string gameVersion = "v1.0";
    private string userId = "Ojui";

    private void Awake()
    {
        // ๊ฒŒ์ž„ ๋ฒ„์ „ ์ง€์ •
        PhotonNetwork.GameVersion = gameVersion;

        // ์„œ๋ฒ„ ์ ‘์†
        PhotonNetwork.ConnectUsingSettings();
    }

    void Start()
    {
        Debug.Log("00. ํฌํ†ค ๋งค๋‹ˆ์ € ์‹œ์ž‘");
        PhotonNetwork.NickName = userId;
    }
    public override void OnConnectedToMaster()
    {
        Debug.Log("01. ํฌํ†ค ์„œ๋ฒ„์— ์ ‘์†");
        PhotonNetwork.JoinRandomRoom();

    }

    public override void OnJoinRandomFailed(short returnCode, string message)
    {
        Debug.Log("02. ๋žœ๋ค ๋ฃธ ์ ‘์† ์‹คํŒจ");

        // ๋ฃธ ์†์„ฑ ์„ค์ •
        RoomOptions ro = new RoomOptions();
        ro.IsOpen = true;
        ro.IsVisible = true;
        ro.MaxPlayers = 30;


        // ๋ฃธ์„ ์ƒ์„ฑ > ์ž๋™ ์ž…์žฅ๋จ
        PhotonNetwork.CreateRoom("room_1", ro);
    }

    public override void OnCreatedRoom()
    {
        Debug.Log("03. ๋ฐฉ ์ƒ์„ฑ ์™„๋ฃŒ");
    }

    public override void OnJoinedRoom()
    {
        Debug.Log("04. ๋ฐฉ ์ž…์žฅ ์™„๋ฃŒ");
        GameManager.instance.isConnect = true;
    }

}

- GameManager.instance.isConnect = true; ์ถ”๊ฐ€

 

 

 

- play ํ•ด๋ณด๋ฉด Player ์ƒ์„ฑ๋จ

- Floor๊ฐ€ ์ข์•„์„œ Scale ์กฐ์ ˆ : 50, 0.1, 50

 

 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;

public class GameManager : MonoBehaviour
{
    public static GameManager instance = null;
    public bool isConnect = false;
    public Transform[] spawnPoints;

    private void Awake()
    {
        if (instance == null)
        {
            instance = this;
            DontDestroyOnLoad(this.gameObject);
        }
        else if (instance != this)
        {
            Destroy(this.gameObject);
        }
    }

    void Start()
    {
        StartCoroutine(CreatePlayer());
    }

    void Update()
    {


    }

    IEnumerator CreatePlayer()
    {
        yield return new WaitUntil(() => isConnect);

        spawnPoints = GameObject.Find("SpawnPointGroup").GetComponentsInChildren<Transform>();

        Vector3 pos = spawnPoints[PhotonNetwork.CurrentRoom.PlayerCount].position;
        Quaternion rot = spawnPoints[PhotonNetwork.CurrentRoom.PlayerCount].rotation;

        GameObject playerTemp = PhotonNetwork.Instantiate("Player", pos, rot, 0);
    }
}

- ์ƒ์„ฑ ์œ„์น˜ ์กฐ์ ˆ

 

 

 

๐Ÿ”ท ์นด๋ฉ”๋ผ Follow

- ์Šคํฌ๋ฆฝํŠธ ์ƒ์„ฑ : SmoothFollow

 

 

 

using UnityEngine;

namespace UnityStandardAssets.Utility
{
	public class SmoothFollow : MonoBehaviour
	{

		// The target we are following
		[SerializeField]
		public Transform target;
		// The distance in the x-z plane to the target
		[SerializeField]
		private float distance = 10.0f;
		// the height we want the camera to be above the target
		[SerializeField]
		private float height = 5.0f;

		[SerializeField]
		private float rotationDamping;
		[SerializeField]
		private float heightDamping;

		// Use this for initialization
		void Start() { }

		// Update is called once per frame
		void LateUpdate()
		{
			// Early out if we don't have a target
			if (!target)
				return;

			// Calculate the current rotation angles
			var wantedRotationAngle = target.eulerAngles.y;
			var wantedHeight = target.position.y + height;

			var currentRotationAngle = transform.eulerAngles.y;
			var currentHeight = transform.position.y;

			// Damp the rotation around the y-axis
			currentRotationAngle = Mathf.LerpAngle(currentRotationAngle, wantedRotationAngle, rotationDamping * Time.deltaTime);

			// Damp the height
			currentHeight = Mathf.Lerp(currentHeight, wantedHeight, heightDamping * Time.deltaTime);

			// Convert the angle into a rotation
			var currentRotation = Quaternion.Euler(0, currentRotationAngle, 0);

			// Set the position of the camera on the x-z plane to:
			// distance meters behind the target
			transform.position = target.position;
			transform.position -= currentRotation * Vector3.forward * distance;

			// Set the height of the camera
			transform.position = new Vector3(transform.position.x ,currentHeight , transform.position.z);

			// Always look at the target
			transform.LookAt(target);
		}
	}
}

 

 

 

- SmoothFollow ์Šคํฌ๋ฆฝํŠธ ์ถ”๊ฐ€

    - Distance, Height, Rotation Damping, Height Damping ์ ๋‹นํžˆ ์กฐ์ ˆ

 

 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
using UnityStandardAssets.Utility;

public class PlayerCtrl : MonoBehaviour
{
    private new Rigidbody rigidbody;
    private PhotonView pv;

    private float v;
    private float h;
    private float r;

    [Header("์ด๋™ ๋ฐ ํšŒ์ „ ์†๋„")]
    public float moveSpeed = 8.0f;
    public float turnSpeed = 0.0f;
    public float jumpPower = 5.0f;

    private float turnSpeedValue = 200.0f;

    RaycastHit hit;

    IEnumerator Start()
    {
        rigidbody = GetComponent<Rigidbody>();
        pv = GetComponent<PhotonView>();

        turnSpeed = 0.0f;
        yield return new WaitForSeconds(0.5f);

        if (pv.IsMine)
        {
            Camera.main.GetComponent<SmoothFollow>().target = transform.Find("CamPivot").transform;
        }
        else
        {
            GetComponent<Rigidbody>().isKinematic = true;
        }
        turnSpeed = turnSpeedValue;
    }

    // ํ‚ค ์ž…๋ ฅ
    void Update()
    {
        v = Input.GetAxis("Vertical");
        h = Input.GetAxis("Horizontal");
        r = Input.GetAxis("Mouse X");

        Debug.DrawRay(transform.position, -transform.up * 0.6f, Color.green);
        if (Input.GetKeyDown("space"))
        {
            if (Physics.Raycast(transform.position, -transform.up, out hit, 0.6f))
            {
                rigidbody.AddForce(Vector3.up * jumpPower, ForceMode.Impulse);
            }
        }
    }

    // ๋ฌผ๋ฆฌ์  ์ฒ˜๋ฆฌ
    void FixedUpdate()
    {
        if (pv.IsMine)
        {
            Vector3 dir = (Vector3.forward * v) + (Vector3.right * h);
            transform.Translate(dir.normalized * Time.deltaTime * moveSpeed, Space.Self);
            transform.Rotate(Vector3.up * Time.smoothDeltaTime * turnSpeed * r);
        }
    }

}

- PlayerCtrl ์Šคํฌ๋ฆฝํŠธ ์ˆ˜์ •

 

 

 

- playํ•ด์„œ ์นด๋ฉ”๋ผ๊ฐ€ ์ž˜ ๋”ฐ๋ผ์˜ค๋Š”์ง€ ํ™•์ธ

 

 

 

๐Ÿ”ท Test

๐Ÿ”ถ Build & Settings

- Fullscreen Mode : Windowed

- Default Screen Width, Height : ์ ๋‹นํžˆ ์กฐ์ ˆ

 

 

 

- Ctrl + Shift + B > Build

 

 

 

- Builds ํด๋” ์ƒ์„ฑ > ํด๋” ์„ ํƒ

 

 

 

๐Ÿ”ถ Test

- ์‹คํ–‰ํŒŒ์ผ ํด๋ฆญ

- ์œ ๋‹ˆํ‹ฐ ํ”„๋กœ์ ํŠธ play

 

 

 

- ์กฐ์ž‘ ์‹œ ํ•ด๋‹น ์ฐฝ์˜ ํ”Œ๋ ˆ์ด์–ด๋งŒ ์›€์ง์ด๊ณ  ์ ํ”„ํ•˜๋Š”์ง€ ํ™•์ธ

- ์นด๋ฉ”๋ผ๊ฐ€ ํ•ด๋‹น ์ฐฝ์˜ ํ”Œ๋ ˆ์ด์–ด๋ฅผ ๋”ฐ๋ผ์˜ค๋Š”์ง€ ํ™•์ธ

- ํ”Œ๋ ˆ์ด์–ด์˜ ์›€์ง์ž„์ด ์ƒ๋Œ€๋ฐฉ ํ”Œ๋ ˆ์ด์–ด์—๊ฒŒ๋„ ๋ณด์ด๋Š”์ง€ ํ™•์ธ