Search Unity

[SOLVED with example] Sync GlobalLight and personal Flashlight Over the Network

Discussion in 'Multiplayer' started by Infinity_way, Jul 21, 2017.

  1. Infinity_way

    Infinity_way

    Joined:
    Mar 21, 2017
    Posts:
    17
    Hey!

    i've been having a hardtime trying to make a small co-op game, it's my first time trying this and although there are other questions about this in the forum, most seems to be pretty old or unsolved, can anyone please help me put a light on this ?

    This first script is meant to sync flashlights on the players, each player have its own flashlight that other players can see. Just won't work, players only see their own light.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Networking;
    5. using UnityStandardAssets.Characters.FirstPerson;
    6.  
    7. public class NetworkPlayer : NetworkBehaviour {
    8.  
    9.     public GameObject FPSCamera;
    10.     public CharacterController characterControler;
    11.     public FirstPersonController FPScontroler;
    12.  
    13.     //Related to the flashLight EachPlayer should carry. The "Luz" in this Script is the Flashlight ... yeah, named poorly.
    14.     [SerializeField] private Light Luz;
    15.     [SyncVar] private bool LightState;
    16.  
    17.     //The global Spotlight that should have its intensity changed according to.
    18.     public GameObject SpotLight;
    19.  
    20.     private void Start ()
    21.     {
    22.  
    23.         if (!isLocalPlayer) {
    24.             FPSCamera.SetActive (false);
    25.             characterControler.enabled = false;
    26.             FPScontroler.enabled = false;
    27.         }        
    28.     }
    29.  
    30.     private void Update ()
    31.     {          
    32.  
    33.         if (Input.GetButtonDown ("AniF"))
    34.         {
    35.             if (isLocalPlayer)
    36.             {
    37.                 Luz.enabled = !Luz.enabled;              
    38.                 Debug.Log (LightState);
    39.             }
    40.             GetLightValue ();
    41.             SendLightValue ();
    42.         }
    43.         if (Input.GetButtonDown ("AniE"))
    44.         {
    45.             if (isLocalPlayer)
    46.             {
    47.                 //This part should call the Method in the "UltimaLightCorrecting.cs" to change the intensity of the global "SpotLight".
    48.                 SpotLight .GetComponent<UltimaLightCorrecting>(). AddTheTHING();
    49.             }
    50.         }
    51.  
    52.  
    53.     }
    54.     private void GetLightValue()
    55.     {
    56.         if (!isLocalPlayer)
    57.         {
    58.             Luz.enabled = LightState;
    59.         }
    60.     }
    61.  
    62.     [ClientCallback]
    63.     private void SendLightValue()
    64.     {
    65.         if (isLocalPlayer == true)
    66.         {
    67.             CmdSendLightValue();
    68.         }
    69.     }
    70.  
    71.     [Command]
    72.     private void CmdSendLightValue()
    73.     {
    74.         LightState = Luz.enabled;
    75.     }
    76. }
    77.  

    And this is a Global light that should have its intensity changed for everyone ... also not working properly....

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Networking;
    5.  
    6. public class UltimaLightCorrecting : NetworkBehaviour {
    7.  
    8.     //The "SpotLight" on the other Script is called here named "Luz", But its the same object...
    9.     public Light Luz;
    10.     [SyncVar] public float IntLuz;
    11.  
    12.     void Update ()
    13.     {
    14.         ClientRecoverState ();
    15.         if (isServer) {
    16.             RpcClientSpread ();
    17.         }
    18.  
    19.     }
    20.  
    21.     //Am I suppose to use this?
    22.     [ClientRpc]
    23.     void RpcClientSpread ()
    24.     {
    25.         Luz.intensity = IntLuz;
    26.     }
    27.  
    28.     //or this?
    29.     [ClientCallback]
    30.     void ClientRecoverState ()
    31.     {
    32.         Luz.intensity = IntLuz;
    33.     }
    34.  
    35.     //This should be called by the "NetworkPlayer.cs" attached to the player.
    36.     public void AddTheTHING ()
    37.     {
    38.         CmdAddFloat();
    39.     }
    40.  
    41.     [Command]  
    42.     public void CmdAddFloat()
    43.     {
    44.         if (IntLuz <= 10) {          
    45.             IntLuz++;
    46.         } else
    47.         {
    48.             IntLuz = 0f;
    49.         }
    50.     }
    51. }
    52.  
    Thanks in advance for any help or advice given!
     
  2. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    2,689
    You should use Cmd's to toggle lights on the server. And then either listen to value change, or use Rpc to change light states on the other clients.

    Note that you don't need to sync SyncVar's manually, this will actually cause desynchronization. Also remember that SyncVars are Server->Client direction only.
     
    Infinity_way likes this.
  3. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    646
    A SyncVar controlled by the server should work OK for the light. The client can then tell the server when his light is on.

    Something like this
    1: Client tells Server light is On/Off by [Command]
    2: Server receives command and sets the SyncVar accordingly
    3: All clients receive the SyncVar hook and set the light.intensity or enabled.
     
    Infinity_way likes this.
  4. Infinity_way

    Infinity_way

    Joined:
    Mar 21, 2017
    Posts:
    17
    Thanks for the reply!

    i did some changes to the code, still don't know how to use the SyncVar Hook properly but i got some results...

    about the Flashlight:
    Opened 3 instances, every client see the host flashlight changing state but the client lights shows no change on each other screens.

    about the Global Light:
    Used a ClientRpc and the light changes intensity in all of them, but once i press "F" in any other instance, the value resets to that one instance, like the SyncVar is not syncing the "LightInt", its only that the Rpc changing the "LightExtern" value on the host and clients.

    I feel like i'm very close, what am i missing?

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Networking;
    5. using UnityStandardAssets.Characters.FirstPerson;
    6.  
    7. public class NetworkPlayer : NetworkBehaviour {
    8.  
    9.     public GameObject FPSCamera;
    10.     public CharacterController characterControler;
    11.     public FirstPersonController FPScontroler;
    12.  
    13.  
    14.     //Related to the flashLight EachPlayer should carry.
    15.     [SerializeField] private Light FlashLight;
    16.     [SyncVar] private bool LightState;
    17.  
    18.  
    19.     //Related to the Global Light every player should see.
    20.     [SyncVar] public int LightInt;
    21.     //This was suppost to be an output so other Lights could access it.
    22.     public static int LightExtern;
    23.  
    24.  
    25.  
    26.     private void Start ()
    27.     {
    28.  
    29.         if (!isLocalPlayer) {
    30.             FPSCamera.SetActive (false);
    31.             characterControler.enabled = false;
    32.             FPScontroler.enabled = false;
    33.         }        
    34.     }
    35.  
    36.     private void Update ()
    37.     {      
    38.             GetLightValue ();
    39.  
    40.         //FOR FLASHlIGHT
    41.             if (Input.GetButtonDown ("AniF"))
    42.             {
    43.                
    44.                 if (isLocalPlayer == true)
    45.                 {
    46.                 FlashLight.enabled = !FlashLight.enabled;                  
    47.                     Debug.Log (LightState);
    48.                 }              
    49.                 SendLightValue ();
    50.             }
    51.  
    52.         //FOR GLOBAL lIGHT
    53.             if (Input.GetButtonDown ("AniE"))
    54.             {
    55.                 if (isLocalPlayer == true)
    56.                 {              
    57.                 CmdAddIntGlobalLight();
    58.                 }
    59.         }
    60.  
    61.  
    62.     }
    63.     //FOR FLASHlIGHT.
    64.     private void GetLightValue()
    65.     {
    66.         if (!isLocalPlayer)
    67.         {
    68.             FlashLight.enabled = LightState;
    69.             //CmdGetLightValue ();
    70.             Debug.Log ("Not-Local Player from GetLightValue Executed - FlashLight Updated here.");
    71.         } else {
    72.             Debug.Log ("Local Player from GetLightValue Executed - Don't Update FlashLight here.");
    73.         }
    74.     }
    75.  
    76.     //FOR FLASHLIGHT. not in use.
    77.     [Command]
    78.     private void CmdGetLightValue()
    79.     {
    80.         FlashLight.enabled = LightState;
    81.     }
    82.     //FOR FLASHlIGHT.
    83.     private void SendLightValue()
    84.     {
    85.         if (isLocalPlayer == true)
    86.         {
    87.             CmdSendLightValue();
    88.             Debug.Log ("Cliente Call Executed.");
    89.         }  
    90.     }
    91.  
    92.     //FOR FLASHlIGHT.
    93.     [Command]
    94.     private void CmdSendLightValue()
    95.     {
    96.         LightState = FlashLight.enabled;
    97.         Debug.Log("Switched the FlashLight state.");
    98.     }
    99.        
    100.     //FOR GLOBAL lIGHT
    101.     [Command]
    102.     void CmdAddIntGlobalLight()
    103.     {
    104.         LightInt++;
    105.         Debug.Log (LightInt);
    106.         Debug.Log ("Added Intensity to Global Light.");
    107.         RpcLightIntSpread ();
    108.     }
    109.  
    110.     //FOR GLOBAL lIGHT
    111.     [ClientRpc]
    112.     public void RpcLightIntSpread()
    113.     {
    114.         LightExtern = LightInt;
    115.     }
    116. }
    117.  
     
  5. Infinity_way

    Infinity_way

    Joined:
    Mar 21, 2017
    Posts:
    17
    My problem is half solved.

    I managed to sync the Flashlights that each player carry but not the Global light and i'll explain a little better my limitations ...

    For now, the FlashLight sync code:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Networking;
    5. using UnityStandardAssets.Characters.FirstPerson;
    6.  
    7. public class NetworkPlayer : NetworkBehaviour {
    8.  
    9.     public GameObject FPSCamera;
    10.     public CharacterController characterControler;
    11.     public FirstPersonController FPScontroler;
    12.  
    13.  
    14.     //Related to the flashLight EachPlayer should carry.
    15.     [SerializeField] private Light FlashLight;
    16.     [SyncVar] private bool LightState;
    17.  
    18.     private void Start ()
    19.     {
    20.  
    21.         if (!isLocalPlayer) {
    22.             FPSCamera.SetActive (false);
    23.             characterControler.enabled = false;
    24.             FPScontroler.enabled = false;
    25.         } else {
    26.             Cursor.lockState = CursorLockMode.Locked;
    27.             Cursor.visible = true;
    28.         }
    29.     }
    30.  
    31.     private void Update ()
    32.     {      
    33.             GetLightValue ();
    34.             //FOR FLASHlIGHT
    35.             if (Input.GetButtonDown ("AniF"))
    36.             {
    37.                
    38.                 if (isLocalPlayer == true)
    39.                 {
    40.                 bool ChangState = !LightState;                  
    41.                 Debug.Log (LightState);
    42.                 CmdSendLightValue(ChangState);
    43.                 }              
    44.                 //SendLightValue ();
    45.                
    46.             }
    47.  
    48.  
    49.     //---------------------------------------------
    50.  
    51.     }
    52.     //FOR FLASHlIGHT.
    53.     private void GetLightValue()
    54.     {
    55.         FlashLight.enabled = LightState;
    56.     }
    57.  
    58.     //FOR FLASHlIGHT.
    59.     [Command]
    60.     private void CmdSendLightValue(bool ChangState)
    61.     {
    62.         LightState = ChangState;
    63.         Debug.Log("Switched the FlashLight state.");
    64.     }
    65.  
    66.  
    67.     //---------------------------------------------
    68.  
    69.        
    70.  
    71. }
    72.  

    So, the issue i'm having with the Global light is that i want that script to not be attached to the player so i have more flexibility to design the level. The issue comes cuz no object aside from the LocalPlayer has authority to use Commands, so i can't change the variable (set with [SyncVar]) of the script attached to the item in the scene. If i make the value Static, then [SyncVar] won't update across the board... so i'm kind of stucked with it.

    Spawning the objects from the server is also not an option, since i'd need to defy spawnpoints from everything and call from script, not being able to with them in the inspector.

    Is there any way to give a random Object authority enough so it can call [Commands] by its own? it another way around it?
     
  6. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    2,689
    You can change that variable by accessing it via object that has authority on the server. Just redirect it in [Command].
     
    Infinity_way likes this.
  7. Infinity_way

    Infinity_way

    Joined:
    Mar 21, 2017
    Posts:
    17
    You mean doing something like:

    Client/Host/Whatever > Mediator Server-only Script > Random Object ?

    i'll give it a shot right now, thanks for the quick answer!

    i was going for something more complicated lol like using a raycast to gather info from the object and forcefully change it, but i'm having issues with authority, identities and my client still can't change it ...

    My raycast attached to the camera, not the FPScontroller itself:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Networking;
    3.  
    4. public class Raycast : NetworkBehaviour//<----
    5. {
    6.     //The Raycast.
    7.     public static float DistanceFromTarget;//Use This.
    8.     public float ToTarget;
    9.  
    10.     //About the Target. -----------------------------------------------
    11.     [SerializeField] private GameObject ObjectHitted;//The real object hitted.
    12.     [SerializeField] private NetworkIdentity TargetId;
    13.  
    14.     public static string TargetName;//Use this.
    15.     public string ObjectName;
    16.    
    17.     //public string PuzzleType;
    18.  
    19.     //Triggers related to the Raycast.
    20.     public bool ReadyToHit;
    21.  
    22.     //About the Target. -----------------------------------------------
    23.  
    24.     void Update()
    25.     {
    26.             RaycastHit hit;
    27.             Vector3 forward = transform.TransformDirection (Vector3.forward) * 2.5f;
    28.             Debug.DrawRay (transform.position, forward, Color.blue);
    29.  
    30.             if (Physics.Raycast (transform.position, (forward), out hit))
    31.             {
    32.             //Gather Actual distance in Float.
    33.             ToTarget = hit.distance;
    34.             //Just to make it a norm.
    35.             DistanceFromTarget = ToTarget;
    36.                
    37.  
    38.             //Gather the Name of the Object hitting.
    39.             ObjectName = hit.collider.gameObject.name;
    40.             //Just to make it a norm
    41.             TargetName = ObjectName;
    42.  
    43.             }
    44.            
    45.             if (DistanceFromTarget <= 2.5f)
    46.             {
    47.  
    48.             //Gets the Proximity value from the UniversalPuzzle.cs.
    49.             ReadyToHit = UniversalPuzzle.Proximity;
    50.             //ReadyToHit = ObjectHitted.GetComponent<UniversalPuzzle> ().Proximity;
    51.  
    52.  
    53.             if (ReadyToHit == true)
    54.                 {
    55.                     if (Input.GetButtonDown ("AniE"))
    56.                     {
    57.                     //THIS IS THE TRUE BUSINESS.------------------------------------------------
    58.  
    59.                     //Gather the Actual GameObject.---------------------------------------------
    60.                     ObjectHitted = GameObject.Find (ObjectName);
    61.                     Debug.Log (DistanceFromTarget);
    62.                     Debug.Log ("Object Hitted is" + ObjectHitted);
    63.                     Debug.Log ("Object Name is" + TargetName);
    64.                     //Get the GameObject Raycast hit NetworkIndentity.
    65.                     TargetId = ObjectHitted.GetComponent<NetworkIdentity> ();
    66.                     Debug.Log (TargetId);
    67.                     //--------------------------------------------------------------------------
    68.  
    69.                     //Assing Authority.
    70.                     TargetId.AssignClientAuthority (connectionToClient);
    71.  
    72.                     ChangeTextoState();
    73.  
    74.                     //Remove Authority.
    75.                     TargetId.RemoveClientAuthority (connectionToClient);
    76.  
    77.                     Debug.Log ("Got here");
    78.                                    
    79.  
    80.  
    81.                     //--------------------------------------------------------------------------
    82.                     }
    83.                 }
    84.  
    85.             }
    86.  
    87.     }
    88.     //TODO:Need to be fixed from the Client side.
    89.     public void ChangeTextoState()
    90.     {
    91.         if (ObjectHitted.GetComponent<UniversalPuzzle> ().TextoState == true) {
    92.             ObjectHitted.GetComponent<UniversalPuzzle> ().TextoState = false;
    93.             Debug.Log ("Desligou");
    94.         } else {
    95.             ObjectHitted.GetComponent<UniversalPuzzle> ().TextoState = true;
    96.             Debug.Log ("Ligou");
    97.         }
    98.         Debug.Log ("O TextoState do UltimaPuzzle está" + ObjectHitted.GetComponent<UniversalPuzzle> ().TextoState);
    99.     }
    100.  
    101.     //---------- FINAL --------
    102. }
    103.  
    and the Object was like:


    Code (CSharp):
    1. public class UniversalPuzzle : NetworkBehaviour {
    2.  
    3.     public float TheDistance;//The distance calculated by the Raycast.
    4.     public GameObject PressEtoInteract;//Text Showing that it's ready to interact.
    5.     public static bool Proximity; //Verify proximity for activation.
    6.     public GameObject Texto1; //Text that should activate/deactivate.
    7.  
    8.     //RELATED  TO THE ACTVATION ------------------------------------------------
    9.     [SyncVar(hook="ChangeSyncValue")] public bool TextoState;            //Goes FROM server TO client.
    10.     public static bool ExternalBool;
    11.     //RELATED  TO THE ACTVATION ------------------------------------------------
    12.  
    13.     // Update is called once per frame
    14.     void Update () {
    15.        
    16.         TheDistance = Raycast.DistanceFromTarget;
    17.  
    18.         //Actvation of TEXTO1
    19.  
    20.         ExternalBool = TextoState;
    21.  
    22.         //-----------------------------------------------------------------
    23.  
    24.     //FOR RAYCAST CALCULATION and PERMITION.
    25.         if (TheDistance >= 2.5)
    26.         {
    27.             PressEtoInteract.SetActive(false);
    28.             Proximity = false;
    29.         }
    30.     }
    31.  
    32.     //FOR RAYCAST CALCULATION.
    33.     void OnMouseOver()
    34.     {
    35.  
    36.         //If closer than 2.5f, proximity gets true, therefore, "ReadyToHit" also becomes true.
    37.         if (TheDistance <= 2.5) {
    38.             PressEtoInteract.SetActive (true);
    39.             Proximity = true;
    40.         } else
    41.         {
    42.             PressEtoInteract.SetActive(false);
    43.             Proximity = false;
    44.         }
    45.     }
    46.  
    47.     //FOR RAYCAST CALCULATION.
    48.     void OnMouseExit()
    49.     {
    50.         PressEtoInteract.SetActive(false);
    51.         Proximity = false;
    52.     }
    53.  
    54.     //[ClientRpc]
    55.     [Client]
    56.     //[ClientCallBack]
    57.     //[Command]
    58.     void ChangeSyncValue(bool NewValue)
    59.     {
    60.         Debug.Log ("Hook Worked");
    61.         Texto1.SetActive(NewValue);
    62.     }
     
  8. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    2,689
    Well I meant you still need authority to issue commands. You can do something like:
    Client (Object with authority) -> CmdToSameObjectOnTheServer -> Obtain ref for that variable -> Server.Var change

    Code (CSharp):
    1. [Command]
    2. public void CmdChangeSomething(#BasicTypesForDataExchange#){
    3.     .. Access object here
    4.     ... Change var or call method or whatever
    5. }
     
    Infinity_way likes this.
  9. Infinity_way

    Infinity_way

    Joined:
    Mar 21, 2017
    Posts:
    17
    So, first of all i want to thank the forum for the answers given, i looked a lot to a solution out there but this thread really helped me to find a path to follow about it.

    I wanted to interact with object that i just added to the scene and attached a script to it, not needing to make the whole work happen in a huge script on the player and make the scene objects be a mere reference for where to access.

    Trying to make a box light a light globally from a script attached to the box wasn't working because the box, unless spawned by the server, wouldn't have authority to use [Commands] to change it's own SyncVar Variables. The solution lays on making the player a conduit for the commands, so the instead of making the box change things, the player "ask" the box what's going on inside it and change it himself. By asking the box for details i avoided having a HUGE script attached to player and can indeed store variables and information on scene objects, as long i program the Player to access it.

    The file itself lies here, there is a box and when you press E to interact with, it switch the light on/off.
    https://drive.google.com/file/d/0BxCMHTY0U6JFdGxnUjBSZExnZHM/view?usp=sharing

    i made lot of comments on the script itself on the file, but if you want to see it here:

    First, the NetworkPlayer which also controls the personal Flashlight
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Networking;
    5. using UnityStandardAssets.Characters.FirstPerson;
    6.  
    7. public class NetworkPlayer : NetworkBehaviour {
    8.  
    9.     public GameObject FPSCamera;
    10.     public CharacterController characterControler;
    11.     public FirstPersonController FPScontroler;
    12.  
    13.  
    14.     //Related to the flashLight EachPlayer should carry.
    15.     [SerializeField] private Light FlashLight;
    16.     [SyncVar] private bool LightState;
    17.  
    18.     private void Start ()
    19.     {
    20.  
    21.         if (!isLocalPlayer) {
    22.             FPSCamera.SetActive (false);
    23.             characterControler.enabled = false;
    24.             FPScontroler.enabled = false;
    25.         } else {
    26.  
    27.             //If you're the LocalPlayer this will lock the cursor in the center of the screen so i the "MouseOver" and "MouseExit" functions will work properly.
    28.             Cursor.lockState = CursorLockMode.Locked;
    29.             Cursor.visible = true;
    30.         }
    31.     }
    32.  
    33.     private void Update ()
    34.     {      
    35.             GetLightValue ();
    36.             //FOR FLASHlIGHT
    37.             if (Input.GetButtonDown ("AniF"))
    38.             {
    39.                
    40.                 if (isLocalPlayer == true)
    41.                 {
    42.                 bool ChangState = !LightState;                  
    43.                 Debug.Log (LightState);
    44.                 CmdSendLightValue(ChangState);
    45.                 }              
    46.                 //SendLightValue ();
    47.                
    48.             }
    49.  
    50.     //---------------------------------------------
    51.  
    52.     }
    53.     //FOR FLASHlIGHT.
    54.     private void GetLightValue()
    55.     {
    56.         FlashLight.enabled = LightState;
    57.     }
    58.  
    59.     //FOR FLASHlIGHT.
    60.     [Command]
    61.     private void CmdSendLightValue(bool ChangState)
    62.     {
    63.         LightState = ChangState;
    64.         Debug.Log("Switched the FlashLight state.");
    65.    }
    66.  
    67.     //---------------------------------------------        
    68.  
    69. }
    70.  
    Here is the script that is used to gather the information of the target, the method chosen to "ask" information to the box:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Networking;
    5.  
    6. public class Raycast : NetworkBehaviour//<----
    7. {
    8.     //The Raycast.
    9.     public static float DistanceFromTarget;//Use this when accessing from other scripts.
    10.     public float ToTarget;
    11.     //Triggers related to the Raycast.
    12.     public bool ReadyToHit;
    13.  
    14.     //About the Target. -----------------------------------------------
    15.     [SerializeField] private GameObject ObjectHitted;//The real object hitted.
    16.     [SerializeField] private NetworkIdentity TargetId;
    17.  
    18.     public static string TargetName;//Use this when accessing from other scripts.
    19.     public string ObjectName;
    20.  
    21.     public float PuzzleType;
    22.  
    23.     //About the Target. -----------------------------------------------
    24.  
    25.     //The "Mediator". -------------------------------------------------
    26.     [SerializeField] private GameObject ThisObject;
    27.     void Start ()
    28.     {
    29.         //ThisObject = this;
    30.     }
    31.  
    32.     //The "Mediator". -------------------------------------------------
    33.  
    34.     void Update()
    35.     {
    36.             RaycastHit hit;
    37.             Vector3 forward = transform.TransformDirection (Vector3.forward) * 2.5f; //is the length of the blue line that shows on the scene.
    38.             Debug.DrawRay (transform.position, forward, Color.blue); //the color of that line.
    39.  
    40.             if (Physics.Raycast (transform.position, (forward), out hit)) //Only works if it acutally hits something.
    41.             {
    42.             //Gather Actual distance in Float.
    43.             ToTarget = hit.distance;
    44.             //Just to make it a norm.
    45.             DistanceFromTarget = ToTarget;              
    46.  
    47.             //Gather the Name of the Object hitting.
    48.             ObjectName = hit.collider.gameObject.name;
    49.             //Just to make it a norm
    50.             TargetName = ObjectName;
    51.  
    52.  
    53.             }          
    54.             if (DistanceFromTarget <= 2.5f)
    55.             {
    56.  
    57.             //Gets the Proximity value from the UniversalPuzzle.cs.
    58.             ReadyToHit = UniversalPuzzle.Proximity;
    59.  
    60.             if (ReadyToHit == true)
    61.                 {
    62.                     if (Input.GetButtonDown ("AniE"))
    63.                     {
    64.                     //THIS IS THE TRUE BUSINESS.------------------------------------------------
    65.  
    66.                     //Gather the Actual GameObject.---------------------------------------------
    67.                     //Everything Works Here
    68.                     ObjectHitted = GameObject.Find (ObjectName);
    69.                     PuzzleType = ObjectHitted.GetComponent<UniversalPuzzle> ().PuzzleTypeInside;
    70.                     TargetId = ObjectHitted.GetComponent<NetworkIdentity> ();
    71.                     Debug.Log ("PuzzleType " + PuzzleType);
    72.                     Debug.Log ("Distance from the Raycast " + DistanceFromTarget);
    73.                     Debug.Log ("Object Hitted is" + ObjectHitted);
    74.                     Debug.Log ("Object Name is" + TargetName);
    75.                     Debug.Log ("The boolState from UltimaPuzzle is = " + ObjectHitted.GetComponent<UniversalPuzzle> ().boolState);
    76.                     Debug.Log ("The Object Network Target ID is " + TargetId);
    77.                     //--------------------------------------------------------------------------
    78.  
    79.                     /*I know i called many Components in the lines before, but you only really need provide the GameObject and the PuzzleType to the Mediator.
    80.                     Anything information this script can acess, the Mediator also is allow to gather, so we only need to give it a base where to look for and
    81.                     what to look for*/
    82.                     ThisObject.GetComponent<Mediator>().FilterPuzzleType(ObjectHitted, PuzzleType);
    83.  
    84.                     //--------------------------------------------------------------------------
    85.                     }
    86.                 }
    87.  
    88.             }
    89.  
    90.     }
    91.     //---------- FINAL --------
    92. }
    93.  
    This is the Script that is attached to the box, it's responsible for proving any information "asked" AND controlling the "Press E to interact" text that shows when you get closer:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Networking;
    5.  
    6. public class UniversalPuzzle : NetworkBehaviour {
    7.  
    8.     //FOR RAYCAST CALCULATION.--------------------------------------------------------------------------------
    9.  
    10.     public GameObject PressEtoInteract;//Text Showing that it's ready to interact.
    11.     public float TheDistance;//The distance calculated by the Raycast.
    12.     public static bool Proximity; //Verify proximity for activation.
    13.     public static string NameOfThisPuzzle;
    14.  
    15.     [SyncVar] public float PuzzleTypeInside = 1;
    16.  
    17.  
    18.     //Variables for Type 1 ------------------------------------------------
    19.     [Header("Variables related to the Type 1 Puzzletype")]
    20.     [SyncVar] public GameObject RandomObject; //Text that should activate/deactivate.
    21.     [SyncVar(hook="ChangeSyncValue")] public bool boolState; //Goes FROM server TO client.
    22.  
    23.     //RELATED  TO THE ACTVATION ------------------------------------------------
    24.  
    25.     void Start ()
    26.     {
    27.  
    28.     }
    29.     //The SyncVar hook calls the "ChangeSyncValue". and i called every Method i know to make the effect spread across the board.--------------
    30.     //I don't really know which one to use here ... so i called all of them lol.
    31.  
    32.     /*A quick Explanatio of how SyncVar hook works, everytime that one var changes, it automatically calls the Method assigned to the hook and
    33.      * the value inside (value here, whatever the name might be) is the new value of that var. */
    34.  
    35.     //TYPE 1 --------------------------------------------------------------------
    36.     public void ChangeSyncValue(bool NewValue)
    37.     {
    38.         Debug.Log ("Hook Worked Bool");
    39.         RandomObject.SetActive(NewValue);
    40.  
    41.         ChangeByClientCallBack (NewValue);
    42.         RpcChangeByRpc (NewValue);
    43.         CmdChangeByCommand (NewValue);
    44.     }
    45.     [ClientCallback]
    46.     void ChangeByClientCallBack(bool NewValue2)
    47.     {
    48.         RandomObject.SetActive(NewValue2);
    49.         Debug.Log ("CallBack Worked");
    50.     }
    51.  
    52.     [ClientRpc]
    53.     void RpcChangeByRpc (bool NewValue2)
    54.     {
    55.         RandomObject.SetActive(NewValue2);
    56.         Debug.Log ("Rpc Worked");
    57.     }
    58.  
    59.     [Command]
    60.     void CmdChangeByCommand (bool NewValue2)
    61.     {
    62.         RandomObject.SetActive(NewValue2);
    63.         Debug.Log ("Command Worked");
    64.     }
    65.     //TYPE 1 --------------------------------------------------------------------
    66.  
    67.  
    68.     //----------------------------------------------------------------------------------------------------------------------------------------
    69.        
    70.     void Update () {
    71.     //FOR RAYCAST CALCULATION.  
    72.         TheDistance = Raycast.DistanceFromTarget;
    73.     //For Raycast calculation - it directs to the Proximity variable is it's close enough to interact.
    74.  
    75.         //Do things
    76.  
    77.  
    78.     //FOR RAYCAST CALCULATION.--------------------------------------------------------------------------------
    79.         if (TheDistance >= 2.5)
    80.         {
    81.             PressEtoInteract.SetActive(false);
    82.             Proximity = false;
    83.         }
    84.     }
    85.        
    86.     void OnMouseOver()
    87.     {
    88.  
    89.         //If closer than 2.5f, proximity gets true, therefore, "ReadyToHit" also becomes true.
    90.         if (TheDistance <= 2.5) {
    91.             PressEtoInteract.SetActive (true);
    92.             Proximity = true;
    93.         } else
    94.         {
    95.             PressEtoInteract.SetActive(false);
    96.             Proximity = false;
    97.         }
    98.     }
    99.        
    100.     void OnMouseExit()
    101.     {
    102.         PressEtoInteract.SetActive(false);
    103.         Proximity = false;
    104.     }
    105.     //--------------------------------------------------------------------------------------------------------  
    106.  
    107. }
    108.  
    And here is the "Mediator", the script attached to the Player with LocalAuthority that process the information from the box:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Networking;
    5.  
    6. public class Mediator : NetworkBehaviour {
    7.  
    8.     [SerializeField] private GameObject GatherObj;
    9.     [SerializeField] private int GatherType;
    10.     [SyncVar] private int Currency;
    11.     private bool GatherBool;
    12.     private NetworkIdentity GatherID;
    13.  
    14.     public void FilterPuzzleType (GameObject TheObject, float Type)
    15.     {
    16.         if (Type == 1) {
    17.             CmdInputT1 (TheObject, Type);
    18.         }
    19.     }
    20.        
    21.  
    22.     [Command]
    23.     public void CmdInputT1 (GameObject TheObject, float Type)
    24.     {      
    25.         Debug.Log ("Went this far.");
    26.         if (TheObject.GetComponent<UniversalPuzzle> ().boolState == true) {
    27.             TheObject.GetComponent<UniversalPuzzle> ().boolState = false;
    28.             Debug.Log ("Off.");
    29.         } else {
    30.             TheObject.GetComponent<UniversalPuzzle> ().boolState = true;
    31.             Debug.Log ("On.");
    32.         }
    33.         Debug.Log ("boolState is " + TheObject.GetComponent<UniversalPuzzle> ().boolState);
    34.     }
    35. }
    36.  
    This problem is very simple... but was extremely hard to find a solution for, you guys taught me the logic to follow but i ended up writing the code myself cuz i couldn't find references for these. I still have tons to learn and i hope this help someone out there in need.
     
unityunity