Search code examples
c#unity-game-enginegame-engineunity3d-mirror

problem with mirror(particle system) unity, pls help:)


I have a problem with mirror, I'm making a online strategy game and you have buildings in the game, with those buildings you can make soldiers, now the buildings have a particles sim to work while they make more solider, but only the server can see the particles sim of its own buildings and the opponents, any ideas why?

that's the code for building smoke:

    #region data
    [SerializeField] private ParticleSystem[] Explotion = new ParticleSystem[2];
    [SerializeField] private Unit UnitPrefab;
    [SerializeField] private Transform position;
    [SerializeField] private Health MyHp;

    [SerializeField] private Image ProgressBar = null;
    [SerializeField] private TMP_Text QuaeText = null;

   [SerializeField] private float QDurition = 5f;
   [SerializeField] private float SpaceSpawn = 7f;
   [SerializeField] private int QMax = 5;
   [SerializeField] private float progressImageVelocity = 2;
    bool played = false;
    [SyncVar(hook = nameof(UpdateQText))] private int QuadeUnits;
    [SyncVar] private float Timer = 0f;
    private ParticleSystem Smoke = null;
    private RTSPlayer player;
    private float QProgress;

    #endregion

    //[ServerCallback]
    private void UpdateQText(int OldQ,int NewQ)
    {
        QuaeText.text = NewQ.ToString();
    }
    

    private void Update()
    {
        if(Smoke == null)
        {
            Smoke = GetComponentInChildren<ParticleSystem>();
        }
        if(player == null)
        {
            player = NetworkClient.connection.identity.GetComponent<RTSPlayer>();
        }

        if (isServer)
        {
            ProduceUnits();
        }

        if (isClient)
        {
            UpdateTimer();
        }

        if(QuadeUnits <= 0)
        {
            QuadeUnits = 0;
            Timer = 0;
            QProgress = 0;
            ProgressBar.fillAmount = 0;
        }
    }

    [Server]
    private void ProduceUnits()
    {
        if(QuadeUnits == 0) 
        {
            try
            {
                Smoke.Stop();
            }
            catch
            {

            }
            played = false;
            return;
        }
        try
        {
            if (!played)
            {
                print("playing");
                Smoke.Play();
                played = true;
            }
           
        }
        catch
        {

        }
        Timer += Time.deltaTime;
        if(Timer < QDurition) { return; }
        GameObject instance1 = Instantiate(UnitPrefab.gameObject, position.position, position.rotation);
        NetworkServer.Spawn(instance1, connectionToClient);
        Vector3 SpawnPlace = gameObject.transform.position * SpaceSpawn;
        SpawnPlace.y = 0;
        Movment ClearSpot = instance1.gameObject.GetComponent<Movment>();
        ClearSpot.ServerMoveUnit(SpawnPlace);
        instance1.gameObject.GetComponent<HPDispaly>().SetEnacled(false);
        QuadeUnits--;
        Timer = 0f;
    }

server client


Solution

  • This wasn't really useful but I found other code that helped me with this problem, if someone has the same problem here's the solution: Solution

    You need to make a syncVar bool and update the animator using it and not with just regular false/true calls, here's my new code:

          #region data
        [SyncVar(hook = nameof(HandleBuilding))] private bool IsBuildng = false;
        [SyncVar(hook = nameof(HandleExplotion))] private bool IsPlaying = false;
        [SerializeField] private ParticleSystem[] Explotion = new ParticleSystem[2];
        [SerializeField] private Unit UnitPrefab;
        [SerializeField] private Transform position;
        [SerializeField] private Health MyHp;
    
        [SerializeField] private Image ProgressBar = null;
        [SerializeField] private TMP_Text QuaeText = null;
    
       [SerializeField] private float QDurition = 5f;
       [SerializeField] private float SpaceSpawn = 7f;
       [SerializeField] private int QMax = 5;
       [SerializeField] private float progressImageVelocity = 2;
        bool played = false;
        [SyncVar(hook = nameof(UpdateQText))] private int QuadeUnits;
        [SyncVar] private float Timer = 0f;
       [SerializeField] private ParticleSystem Smoke = null;
        private RTSPlayer player;
        private float QProgress;
    
        #endregion
    
        //[ServerCallback]
        private void UpdateQText(int OldQ,int NewQ)
        {
            QuaeText.text = NewQ.ToString();
        }
        private void HandleBuilding(bool OldBool,bool NewBool)
        {
            Smoke.gameObject.SetActive(IsBuildng);
        }
    
        private void Update()
        {
            if(Smoke == null)
            {
                Smoke = GetComponentInChildren<ParticleSystem>();
            }
            if(player == null)
            {
                player = NetworkClient.connection.identity.GetComponent<RTSPlayer>();
            }
    
            if (isServer)
            {
                ProduceUnits();
            }
    
            if (isClient)
            {
                UpdateTimer();
            }
    
            if(QuadeUnits <= 0)
            {
                QuadeUnits = 0;
                Timer = 0;
                QProgress = 0;
                ProgressBar.fillAmount = 0;
            }
        }
    
        [Server]
        private void ProduceUnits()
        {
            if(QuadeUnits == 0) 
            {
                IsBuildng = false;
                played = false;
                return;
            }
            else
            {
                IsBuildng = true;
            }
            IsBuildng = true;
            Timer += Time.deltaTime;
            if(Timer < QDurition) { return; }
            GameObject instance1 = Instantiate(UnitPrefab.gameObject, position.position, position.rotation);
            NetworkServer.Spawn(instance1, connectionToClient);
            Vector3 SpawnPlace = gameObject.transform.position * SpaceSpawn;
            SpawnPlace.y = 0;
            Movment ClearSpot = instance1.gameObject.GetComponent<Movment>();
            ClearSpot.ServerMoveUnit(SpawnPlace);
            instance1.gameObject.GetComponent<HPDispaly>().SetEnacled(false);
            QuadeUnits--;
            Timer = 0f;
        }