Networking problems

I’m trying to create a game where you can fly around as a plane and have to shoot other player’s plane.
If I host in the editor and join with a build and play window, I can shoot the other plane as the editor player and destroying parts also works. But when I swap into the other window, I can see the broken parts.
If I host in the build and play window and join as the edtior, I can’t deal damage to the other plane in the build and play window and I have an error message that says something like: no target assigned in turret script. If I then swap into the editor window and try shooting the build and play plane, I can’t deal damage either. So I am assuming it has something to do with the host.
So my 2 problems are: 1. Destroying parts doesn’t get synced; 2. Weird shooting and targetting behaviour depending on host.
Here’s my code:

Plane:

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

public class Plane : NetworkBehaviour {

    Rigidbody rb;

    public Camera cam;

    public float speed = 2000.0f;

    public List<PlanePart> parts;

    [SyncVar]
    public int mainPartHp;

    public KeyCode shootKey;

    void Start()
    {
        if (!isLocalPlayer)
        {
            gameObject.layer = 9;
            foreach (Transform t in gameObject.transform)
            {
                Debug.Log("Applying enemy layer to " + t.name);
                t.gameObject.layer = 9;
            }
        }
        else
        {
            gameObject.layer = 8;
            foreach (Transform t in gameObject.transform)
            {
                Debug.Log("Applying enemy layer to " + t.name);
                t.gameObject.layer = 8;
            }

        }
        rb = GetComponent<Rigidbody>();
    }

    public void DealDmgToPart(GameObject part, int damage)
    {
            Debug.Log("DealDmgToPart is called.");
            foreach (PlanePart p in parts)
            {
                if (p.part == part)
                {
                    p.hp -= damage;
                    Debug.Log(p.name + " took " + damage + " damage.");
                    if (p.hp <= 0)
                    {
                        p.part.SetActive(false);
                    }
                }
            }
    }

    void Update()
    {
        Fly();
        ManageParts();
    }

    void ManageParts()
    {
        #region HP
        if(isLocalPlayer) {
            foreach (PlanePart part in parts)
            {
                if (part.isMainPart)
                {
                    part.hp = mainPartHp;
                }

                if (!part.isMainPart && !part.count)
                {
                    part.count = true;
                    mainPartHp += part.hp;
                }

                if (part.isMainPart)
                {
                    part.hp = mainPartHp;
                }
            }
        }
        #endregion

    }

    void Fly()
    {
        if(isLocalPlayer) {
            if (mainPartHp > 0) {
                rb.velocity = transform.forward * Time.deltaTime * speed;

                speed -= transform.forward.y * Time.deltaTime * 100.0f;

                transform.Rotate(Input.GetAxis("Vertical") * 1.5f, 0.0f, -Input.GetAxis("Horizontal") * 1.5f);
            }
        }
    }

}

Turret:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

public class Turret : NetworkBehaviour {

    public Plane plane;
    public Camera cam;
    public int dmg = 10;
    public GameObject target;
    public ParticleSystem muzzleFlash;
    public LayerMask mask;
    public float fireRate = 15f;

    private float nextTimeToFire = 0f;

    void Update()
    {
        Shoot();
    }

    void Start()
    {
        /*if (!isLocalPlayer)
        {
            enabled = false;
        }*/
        plane = GetComponentInParent<Plane>();
    }

    public void Shoot()
    {
        RaycastHit hit;
        if (Physics.Raycast(cam.ScreenPointToRay(Input.mousePosition), out hit, 100000f, mask))
        {
            target = hit.collider.transform.gameObject;
        }
        else
        {
            target = null;
        }
        if(Input.GetKey(plane.shootKey) && target != null && Time.time >= nextTimeToFire && isLocalPlayer)
        {
            nextTimeToFire = Time.time + 1 / fireRate;
            Debug.Log("Trying to shoot");
            muzzleFlash.Play();
            
            if(target.GetComponentInParent<Plane>() != null)
            {
                Debug.Log("target has a plane script");
                Plane targetPlaneScript = target.GetComponentInParent<Plane>();
                CmdPlayerShot(dmg);
            }
        }
    }
    [Command]
    void CmdPlayerShot(int damage)
    {
        Debug.Log("CmdPlayerShot has been executed.");
        target.GetComponentInParent<Plane>().DealDmgToPart(target, damage);
    }
}

PlanePart:

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

[System.Serializable]
public class PlanePart {

    public string name;
    public int hp;
    public bool isMainPart;
    public bool destroyed;
    public GameObject part;

    public bool count;
}

CameraSetup:

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

public class CameraSetup : NetworkBehaviour {

    void Start()
    {
        if (!isLocalPlayer)
        {
            gameObject.SetActive(false);
        }
    }

}

Hello… so i hope i can help a little bit

If you hit the other player you call “CmdPlayerShot(dmg)” with the [Command]-Attribute. This means this function get executed on the script on the server / host. (command get sended over network with params).
So now you are in the player-script of your client on the host Pc.

Now you will call “DealDmgToPart” with “target”, but target is the target the host pc calculatet in his shootfunction. (this could not be the same, becouse of latency, interpolation, etc)

So a possible solution is you can rewrite “CmdPlayerShot(int damage)” to "CmdPlayerShot(int damage, int planePartIndex), so that the server can search the plane part. Then you will need a function like an client rpc call or a syncvar with hook which can tell the clients if a part was destroyed. UNet is a little bit tricky and complicated, and difficult to explain. I hope this helps, you can aks me if you have another question.