Merry Fragmas: Multiplayer FPS, Part 2

確認済のバージョン: 4.6

-

難易度: 中級

Merry Fragmas everyone! During this live training series, we will be building a multiplayer First Person Shooter game. We will be focusing on the animation, physics, networking (with Photon), and other tricks that make FPS games what they are. Content will range from beginner to intermediate+ (depending on what you consider difficult). We will be looking at a lot of scripting and a few pro features (though you should still be able to complete the training without pro). I have no idea how many days this will span, so I am scheduling it for 3. Please note that I do not know how many days will be required to complete this series and what is scheduled is just a guess. With that being said, let us crush our foes with holiday spirit! -Tutor: Mike Geig

Merry Fragmas: Multiplayer FPS, Part 2

中級 The Asset Store

NetworkManager Script

Code snippet

using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class NetworkManager : MonoBehaviour {

    [SerializeField] Text connectionText;
    [SerializeField] Transform[] spawnPoints;
    [SerializeField] Camera sceneCamera;

    GameObject player;
    
    void Start () {
    
        PhotonNetwork.logLevel = PhotonLogLevel.Full;
        PhotonNetwork.ConnectUsingSettings ("0.2");

    }

    void Update () {
        connectionText.text = PhotonNetwork.connectionStateDetailed.ToString ();
    }

    void OnJoinedLobby()
    {
        RoomOptions ro = new RoomOptions () {isVisible = true, maxPlayers = 10};
        PhotonNetwork.JoinOrCreateRoom ("Mike", ro, TypedLobby.Default);
    }

    void OnJoinedRoom()
    {
        StartSpawnProcess (0f);
    }

    void StartSpawnProcess (float respawnTime)
    {
        sceneCamera.enabled = true;
        StartCoroutine ("SpawnPlayer", respawnTime);
    }

    IEnumerator SpawnPlayer(float respawnTime)
    {
        yield return new WaitForSeconds(respawnTime);

        int index = Random.Range (0, spawnPoints.Length);
        player = PhotonNetwork.Instantiate ("FPSPlayer", 
                                           spawnPoints [index].position,
                                           spawnPoints [index].rotation,
                                           0);
        player.GetComponent ().RespawnMe += StartSpawnProcess;
        sceneCamera.enabled = false;
    }
}

PlayerNetworkMover Script

Code snippet

using UnityEngine;
using System.Collections;

public class PlayerNetworkMover : Photon.MonoBehaviour {

    public delegate void Respawn(float time);
    public event Respawn RespawnMe;

    Vector3 position;
    Quaternion rotation;
    float smoothing = 10f;
    float health = 100f;


    void Start () {
    
        if(photonView.isMine)
        {
            rigidbody.useGravity = true;
            GetComponent().enabled = true;
            GetComponent().enabled = true;
            GetComponent().enabled = true;
            GetComponentInChildren().enabled = true;
            foreach(SimpleMouseRotator rot in GetComponentsInChildren())
                rot.enabled = true;
            foreach(Camera cam in GetComponentsInChildren())
                cam.enabled = true;

            transform.Find("Head Joint/First Person Camera/GunCamera/Candy-Cane").gameObject.layer = 11;
        }
        else{
            StartCoroutine("UpdateData");
        }
    }

    IEnumerator UpdateData()
    {
        while(true)
        {
            transform.position = Vector3.Lerp(transform.position, position, Time.deltaTime * smoothing);
            transform.rotation = Quaternion.Lerp(transform.rotation, rotation, Time.deltaTime * smoothing);
            yield return null;
        }
    }

    void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
        if(stream.isWriting)
        {
            stream.SendNext(transform.position);
            stream.SendNext(transform.rotation);
            stream.SendNext(health);
        }
        else
        {
            position = (Vector3)stream.ReceiveNext();
            rotation = (Quaternion)stream.ReceiveNext();
            health = (float)stream.ReceiveNext();
        }
    }

    [RPC]
    public void GetShot(float damage)
    {
        health -= damage;
        if(health <= 0 && photonView.isMine)
        {
            if(RespawnMe != null)
                RespawnMe(3f);

            PhotonNetwork.Destroy (gameObject);
        }
    }

}

PlayerShooting Script

Code snippet

using UnityEngine;
using System.Collections;

public class PlayerShooting : MonoBehaviour {

    public ParticleSystem muzzleFlash;
    public GameObject impactPrefab;

    Animator anim;
    GameObject[] impacts;
    int currentImpact = 0;
    int maxImpacts = 5;
    bool shooting = false;
    float damage = 25f;


    // Use this for initialization
    void Start () {
    
        impacts = new GameObject[maxImpacts];
        for(int i = 0; i < maxImpacts; i++)
            impacts[i] = (GameObject)Instantiate(impactPrefab);

        anim = GetComponentInChildren ();
    }
    
    // Update is called once per frame
    void Update () {
    
        if (Input.GetButtonDown ("Fire1") && !Input.GetKey (KeyCode.LeftShift)) {
                
            muzzleFlash.Play();
            anim.SetTrigger ("Fire");
            shooting = true;
        }

    }

    void FixedUpdate()
    {
        if(shooting)
        {
            shooting = false;

            RaycastHit hit;
            
            if(Physics.Raycast(transform.position, transform.forward, out hit, 50f))
            {
                //print (hit.transform.name);
                
                if(hit.transform.tag == "Player")
                {
                    hit.transform.GetComponent().RPC ("GetShot", PhotonTargets.All, damage);
                }
                
                //cycle impact effects
                impacts[currentImpact].transform.position = hit.point;
                impacts[currentImpact].GetComponent().Play ();
                
                if(++currentImpact >= maxImpacts)
                    currentImpact = 0;
            }
        }
    }
}

関連するチュートリアル