Home>

I am making a 3D TPS game in multiplayer.
I want the camera to follow when I move the player character, but that doesn't work.
Specifically, I want to get the player character object with the code on the camera side and use that information to make the camera follow, but this acquisition process does not work.
In multiplayer games, the camera needs to get the character object of its own player's instance (your camera shouldn't follow the characters of other players), but I'm having trouble doing this.

Multiplayer is implemented using Photon. I am using "PhotonNetwork.Instantiate" to create objects for the camera and player characters.
I will write below what kind of code is used to acquire the tracking target of the camera.

First, assign the object created by Photon.Network.Instantiate to the variable as shown below.

PlayerObj = PhotonNetwork.Instantiate ("PlayerObject", transform.position, Quaternion.identity, 0);


Next, in the script on the camera side,

target = GameObject.Find ("InstantiateObj"). GetComponent<InstantiateScript>(). PlayerObj


By writing, the object generated by PhotonNetwork.Instantiate is referenced, and the object of the player to be the tracking target is acquired.
I thought this would allow me to get my character object instead of other players.

When I ran it, the camera followed the player character without any problems if there was only one player.
However, if there are two or more players, the camera will not follow all players.
If there is only one player, it will follow without any problem, so the variable is not null.
I checked with Debug.Log, but even when there were multiple players and the camera did not follow, the object of the player character was assigned to the target variable.

I thought that the cause of this behavior was that there were multiple GameObjects with the same name, but I don't know how to verify this authenticity.
Does anyone know why this behaves when there are multiple players?

* The above code is a simplified code to explain the current situation in an easy-to-understand manner.
Below is the full text of the code i am actually using.

↓ This is the code to generate the player character and camera.

using System.Collections;
using System.Collections.Generic;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.SceneManagement;
// Inherit MonoBehaviourPunCallbacks instead of MonoBehaviour to receive Photon callbacks
public class SampleScene: MonoBehaviourPunCallbacks
{
    public GameObject unkoman {get;private set;}
    object [] unkomanInitData = new object [1];
    object [] cameraInitData = new object [1];
    private void Awake ()
    {
        SceneManager.sceneUnloaded + = OnSceneUnloaded;
        Debug.Log (PhotonNetwork.CurrentRoom);
        // Create your own network object at random positions after scene transition
        var StartPos = new Vector3 (Random.Range (-10f, 10f), 4f, Random.Range (-10f, 10f));
        unkomanInitData = GetUnkomanInitData ();
        cameraInitData = GetCameraInitData ();
        unkoman = PhotonNetwork.Instantiate ("UnkomanEmpty", StartPos, Quaternion.identity, 0, unkomanInitData);
        PhotonNetwork.Instantiate ("UnkomanCamera", unkoman.transform.position, Quaternion.identity, 0, cameraInitData);
    }
    object [] GetUnkomanInitData ()
    {unkomanInitData [0] = PhotonNetwork.LocalPlayer.ActorNumber;
        return unkomanInitData;
    }
    object [] GetCameraInitData ()
    {
        cameraInitData [0] = PhotonNetwork.LocalPlayer.ActorNumber;
        return cameraInitData;
    }
    private void Update ()
    {
        if (Input.GetKey (KeyCode.Return)) SceneManager.LoadScene ("UunkoStart");
    }
    void OnSceneUnloaded (Scene Uunko Battle)
    {
        PhotonNetwork.LeaveRoom ();
        Debug.Log (PhotonNetwork.CurrentRoom);
        Debug.Log ("Battle scene end");
        SceneManager.sceneUnloaded-= OnSceneUnloaded;
    }
}


↓ This is the code to attach to the camera.
In the upper Awake function, the tracking target acquisition process is performed.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
namespace CSharpScript
{
    // [ExecuteInEditMode, DisallowMultipleComponent]
    public class UnkomanCameraControl: MonoBehaviourPunCallbacks
    {
        private GameObject target;
        public Vector3 offset;
        [SerializeField] private float distance = 4.0f;
        [SerializeField] private float polarAngle = 87.0f;
        [SerializeField] private float azimuthalAngle = 270f;
        [SerializeField] private float minPolarAngle = 2.0f;
        [SerializeField] private float maxPolarAngle = 130.0f;
        [SerializeField] private float mouseXSensitivity = 5.0f;
        [SerializeField] private float mouseYSensitivity = 5.0f;
        void Awake ()
        {
            if (photonView.IsMine == false)
            {
                enabled = false;
                return;}
            target = GameObject.Find ("SampleScene"). GetComponent<SampleScene>(). Unkoman.transform.Find ("UnkomanA"). GameObject;
            Debug.Log (target);
        }
        void LateUpdate ()
        {
            if (target == null) return;
            updateAngle (Input.GetAxis ("Mouse X"), Input.GetAxis ("Mouse Y"));
            var lookAtPos = target.transform.position + offset;
            updatePosition (lookAtPos);
            transform.LookAt (lookAtPos);
           /*
            // Show/hide cursor&lock/unlock
            if (Input.GetKeyUp (KeyCode.Escape))
            {
                Cursor.visible = true;
                Cursor.lockState = CursorLockMode.None;
            }
            if (Input.GetMouseButtonDown (0))
            {
                Cursor.visible = false;
                Cursor.lockState = CursorLockMode.Locked;
            }
            * /
        }
        void updateAngle (float x, float y)
        {
            if (target == null) return;
            x = azimuthalAngle --x * mouseXSensitivity;
            azimuthalAngle = Mathf.Repeat (x, 360);
            y = polarAngle + y * mouseYSensitivity;
            polarAngle = Mathf.Clamp (y, minPolarAngle, maxPolarAngle);
        }

        void updatePosition (Vector3 lookAtPos)
        {
            if (target == null) return;
            var da = azimuthalAngle * Mathf.Deg2Rad;
            var dp = polarAngle * Mathf.Deg2Rad;
            transform.position = new Vector3
                (
                 lookAtPos.x + distance * Mathf.Sin (dp) * Mathf.Cos (da),
                 lookAtPos.y + distance * Mathf.Cos (dp),
                 lookAtPos.z + distance * Mathf.Sin (dp) * Mathf.Sin (da)
                );
        }
    }
}
  • Answer # 1

    Until now, the camera was also generated as a network object, and there were as many cameras as there were players in the scene, but when I stopped it and made only one camera in the scene, there is a problem even if there are multiple players. The camera now follows.