Problem with identifying local players
I am making a multiplayer game and I am trying to have it so the local player cannot shoot himself, but can still shoot the client players. So I basically assigned the local player to have a tag of "Local Player", and a layer of "Local Player", and for the clients to have a tag and layer as "Remote Player". In the hierarchy it seems to be assigning the tag and layers correctly, but only the player that is lan host can actually do damage to other players, while clients cannot do damage to the host. Any help is appreciated and I will add my scripts down below.
// I try to assign the local and non local players.
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Networking;
using UnityEngine;
[RequireComponent(typeof(PlayerMotor))]
public class PlayerController : NetworkBehaviour {
public AudioListener listener;
[SerializeField]
[SyncVar]
public float speed = 5f;
private PlayerMotor motor;
[SerializeField]
private float lookSensitivity = 3f;
[SerializeField]
private Camera cam;
// Use this for initialization
void Start () {
motor = GetComponent<PlayerMotor> ();
cam = GetComponent<PlayerMotor> ().cam;
if (!isLocalPlayer) {
cam.enabled = false;
listener.enabled = false;
gameObject.tag = "RemotePlayer";
gameObject.layer = LayerMask.NameToLayer ("RemotePlayer");
gameObject.GetComponent<shootSpell> ().enabled = false;
}
}
void Update () {
if (!isLocalPlayer) {
return;
}
MovePlayer ();
}
}
// This is my damage script
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Networking;
using UnityEngine;
public class hitDetection : NetworkBehaviour {
public int damage;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnTriggerEnter (Collider col) {
if (col.GetComponent<Collider>().tag == "LocalPlayer") {
Physics.IgnoreLayerCollision (LayerMask.NameToLayer ("Spell"), LayerMask.NameToLayer ("LocalPlayer"));
}
if (col.GetComponent<Collider>().tag == "RemotePlayer") {
var hit = col.gameObject;
var health = hit.GetComponent<Health> ();
if (health != null) {
health.TakeDamage (damage);
}
Destroy (gameObject);
}
}
}
// health script
using System.Collections;
using System.Collections.Generic;
using UnityEngine.Networking;
using UnityEngine;
public class Health : NetworkBehaviour {
public const int maxHealth = 100;
[SyncVar]
public int currentHealth = 0;
public NetworkStartPosition[] spawnPoints;
// Use this for initialization
void Start () {
currentHealth = maxHealth;
spawnPoints = FindObjectsOfType<NetworkStartPosition> ();
}
void OnConnectedToServer () {
RpcRespawn ();
}
// Update is called once per frame
void Update () {
}
public void TakeDamage (int amount) {
if (!isServer) {
return;
}
currentHealth -= amount;
if (currentHealth <= 0) {
RpcRespawn ();
currentHealth = maxHealth;
}
}
[ClientRpc]
public void RpcRespawn () {
if (isLocalPlayer) {
Vector3 spawnPoint = Vector3.zero;
if (spawnPoints != null) {
spawnPoint = spawnPoints [Random.Range (0, spawnPoints.Length)].transform.position;
}
transform.position = spawnPoint;
}
}
Shouldn't line 21 of your damage script be done at the start? You're setting it to ignore collision as a boolean between 2 layers so it'll be set to that for the entire scene, no need for it on every collision.
But I don't think the problem is in your layers, I think something is wrong with the way you're damaging the players. If you posted your health.TakeDamage function I think i could help you better as I was running into a few issues like that myself.
Ok I updated the question to have my health script included, thanks for the help!
Answer by Glurth · Feb 10, 2017 at 05:31 PM
This code:
public void TakeDamage (int amount) {
if (!isServer) {
return;
}
Is, I would suspect, the cause of the issue you described: "but only the player that is lan host can actually do damage to other players"
Since it will exit, rather than proceed to do damage, if NOT the server (I assume lan-host, is the Server).
Exactly this, you're telling your game to ignore the code below if the user isn't the host
I removed that part of code but it still seems to have the same issue, whoever is host does not take damage while the clients can take damage and attack themselves. I appreciate the help however!
Possibly make it a ClientRpc function, that way you're telling the server to run the function on the clients so they should all reflect the same value. You'd think the SyncVar would do the trick but if not then it's worth a shot.