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.
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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityStandardAssets.Characters.FirstPerson;
public class NetworkPlayer : NetworkBehaviour {
public GameObject FPSCamera;
public CharacterController characterControler;
public FirstPersonController FPScontroler;
//Related to the flashLight EachPlayer should carry.
[SerializeField] private Light FlashLight;
[SyncVar] private bool LightState;
private void Start ()
{
if (!isLocalPlayer) {
FPSCamera.SetActive (false);
characterControler.enabled = false;
FPScontroler.enabled = false;
} else {
//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.
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = true;
}
}
private void Update ()
{
GetLightValue ();
//FOR FLASHlIGHT
if (Input.GetButtonDown ("AniF"))
{
if (isLocalPlayer == true)
{
bool ChangState = !LightState;
Debug.Log (LightState);
CmdSendLightValue(ChangState);
}
//SendLightValue ();
}
//---------------------------------------------
}
//FOR FLASHlIGHT.
private void GetLightValue()
{
FlashLight.enabled = LightState;
}
//FOR FLASHlIGHT.
[Command]
private void CmdSendLightValue(bool ChangState)
{
LightState = ChangState;
Debug.Log("Switched the FlashLight state.");
}
//---------------------------------------------
}
Here is the script that is used to gather the information of the target, the method chosen to “ask” information to the box:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class Raycast : NetworkBehaviour//<----
{
//The Raycast.
public static float DistanceFromTarget;//Use this when accessing from other scripts.
public float ToTarget;
//Triggers related to the Raycast.
public bool ReadyToHit;
//About the Target. -----------------------------------------------
[SerializeField] private GameObject ObjectHitted;//The real object hitted.
[SerializeField] private NetworkIdentity TargetId;
public static string TargetName;//Use this when accessing from other scripts.
public string ObjectName;
public float PuzzleType;
//About the Target. -----------------------------------------------
//The "Mediator". -------------------------------------------------
[SerializeField] private GameObject ThisObject;
void Start ()
{
//ThisObject = this;
}
//The "Mediator". -------------------------------------------------
void Update()
{
RaycastHit hit;
Vector3 forward = transform.TransformDirection (Vector3.forward) * 2.5f; //is the length of the blue line that shows on the scene.
Debug.DrawRay (transform.position, forward, Color.blue); //the color of that line.
if (Physics.Raycast (transform.position, (forward), out hit)) //Only works if it acutally hits something.
{
//Gather Actual distance in Float.
ToTarget = hit.distance;
//Just to make it a norm.
DistanceFromTarget = ToTarget;
//Gather the Name of the Object hitting.
ObjectName = hit.collider.gameObject.name;
//Just to make it a norm
TargetName = ObjectName;
}
if (DistanceFromTarget <= 2.5f)
{
//Gets the Proximity value from the UniversalPuzzle.cs.
ReadyToHit = UniversalPuzzle.Proximity;
if (ReadyToHit == true)
{
if (Input.GetButtonDown ("AniE"))
{
//THIS IS THE TRUE BUSINESS.------------------------------------------------
//Gather the Actual GameObject.---------------------------------------------
//Everything Works Here
ObjectHitted = GameObject.Find (ObjectName);
PuzzleType = ObjectHitted.GetComponent<UniversalPuzzle> ().PuzzleTypeInside;
TargetId = ObjectHitted.GetComponent<NetworkIdentity> ();
Debug.Log ("PuzzleType " + PuzzleType);
Debug.Log ("Distance from the Raycast " + DistanceFromTarget);
Debug.Log ("Object Hitted is" + ObjectHitted);
Debug.Log ("Object Name is" + TargetName);
Debug.Log ("The boolState from UltimaPuzzle is = " + ObjectHitted.GetComponent<UniversalPuzzle> ().boolState);
Debug.Log ("The Object Network Target ID is " + TargetId);
//--------------------------------------------------------------------------
/*I know i called many Components in the lines before, but you only really need provide the GameObject and the PuzzleType to the Mediator.
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
what to look for*/
ThisObject.GetComponent<Mediator>().FilterPuzzleType(ObjectHitted, PuzzleType);
//--------------------------------------------------------------------------
}
}
}
}
//---------- FINAL --------
}
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:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class UniversalPuzzle : NetworkBehaviour {
//FOR RAYCAST CALCULATION.--------------------------------------------------------------------------------
public GameObject PressEtoInteract;//Text Showing that it's ready to interact.
public float TheDistance;//The distance calculated by the Raycast.
public static bool Proximity; //Verify proximity for activation.
public static string NameOfThisPuzzle;
[SyncVar] public float PuzzleTypeInside = 1;
//Variables for Type 1 ------------------------------------------------
[Header("Variables related to the Type 1 Puzzletype")]
[SyncVar] public GameObject RandomObject; //Text that should activate/deactivate.
[SyncVar(hook="ChangeSyncValue")] public bool boolState; //Goes FROM server TO client.
//RELATED TO THE ACTVATION ------------------------------------------------
void Start ()
{
}
//The SyncVar hook calls the "ChangeSyncValue". and i called every Method i know to make the effect spread across the board.--------------
//I don't really know which one to use here ... so i called all of them lol.
/*A quick Explanatio of how SyncVar hook works, everytime that one var changes, it automatically calls the Method assigned to the hook and
* the value inside (value here, whatever the name might be) is the new value of that var. */
//TYPE 1 --------------------------------------------------------------------
public void ChangeSyncValue(bool NewValue)
{
Debug.Log ("Hook Worked Bool");
RandomObject.SetActive(NewValue);
ChangeByClientCallBack (NewValue);
RpcChangeByRpc (NewValue);
CmdChangeByCommand (NewValue);
}
[ClientCallback]
void ChangeByClientCallBack(bool NewValue2)
{
RandomObject.SetActive(NewValue2);
Debug.Log ("CallBack Worked");
}
[ClientRpc]
void RpcChangeByRpc (bool NewValue2)
{
RandomObject.SetActive(NewValue2);
Debug.Log ("Rpc Worked");
}
[Command]
void CmdChangeByCommand (bool NewValue2)
{
RandomObject.SetActive(NewValue2);
Debug.Log ("Command Worked");
}
//TYPE 1 --------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------------------------
void Update () {
//FOR RAYCAST CALCULATION.
TheDistance = Raycast.DistanceFromTarget;
//For Raycast calculation - it directs to the Proximity variable is it's close enough to interact.
//Do things
//FOR RAYCAST CALCULATION.--------------------------------------------------------------------------------
if (TheDistance >= 2.5)
{
PressEtoInteract.SetActive(false);
Proximity = false;
}
}
void OnMouseOver()
{
//If closer than 2.5f, proximity gets true, therefore, "ReadyToHit" also becomes true.
if (TheDistance <= 2.5) {
PressEtoInteract.SetActive (true);
Proximity = true;
} else
{
PressEtoInteract.SetActive(false);
Proximity = false;
}
}
void OnMouseExit()
{
PressEtoInteract.SetActive(false);
Proximity = false;
}
//--------------------------------------------------------------------------------------------------------
}
And here is the “Mediator”, the script attached to the Player with LocalAuthority that process the information from the box:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class Mediator : NetworkBehaviour {
[SerializeField] private GameObject GatherObj;
[SerializeField] private int GatherType;
[SyncVar] private int Currency;
private bool GatherBool;
private NetworkIdentity GatherID;
public void FilterPuzzleType (GameObject TheObject, float Type)
{
if (Type == 1) {
CmdInputT1 (TheObject, Type);
}
}
[Command]
public void CmdInputT1 (GameObject TheObject, float Type)
{
Debug.Log ("Went this far.");
if (TheObject.GetComponent<UniversalPuzzle> ().boolState == true) {
TheObject.GetComponent<UniversalPuzzle> ().boolState = false;
Debug.Log ("Off.");
} else {
TheObject.GetComponent<UniversalPuzzle> ().boolState = true;
Debug.Log ("On.");
}
Debug.Log ("boolState is " + TheObject.GetComponent<UniversalPuzzle> ().boolState);
}
}
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.