Hi everyone, I am having a hard time figuring out how to make my character appear invisible over the network when they key is pressed to go into stealth mode. I tried using a command and rpc’s to change the renderers transparency on non localplayers but after four days I am very confused and could use some help…
This is the script. I tried calling a [Command] on line 89 that fires off some [Rpcs] but it doesn’t seem to do anything.
Also if I drop this into the update ();
if(!gameObject.transform.parent.gameObject.GetComponent().isLocalPlayer)
{
spriteRend.material.color = Color.clear;
}
It does pretty much what I want except for that I just need a way for it to only do that when the player who hit the key is goes into stealth mode instead of being invisible constantly.
So basically what I am trying to do is… on the local screen have my cool stealth effect graphics but on other players screens have my character appear to be invisible…Any advice would be amazing thank you - LordHamburger
Off the top of my head…
[SyncVar(hook="SyncVisibility")]
private bool isVisible;
private void SyncVisibility(bool isVisible)
{
this.isVisible = isVisible;
if(!isVisible)
//CODE GOES HERE TO TURN THE RENDERER OFF
else
//CODE GOES HERE TO TURN THE RENDERER ON
if(isLocalPlayer)
{
if(!isVisible)
//CODE GOES HERE TO TURN ON SPECIAL EFFECTS
else
//CODE GOES HERE TO TURN OFF SPECIAL EFFECTS
}
}
1 Like
Hm I could not get it to work, I could not get NetworkProximityChecker either It doesn’t seem to work for me.
Post your code…let’s have a look see.
1 Like
Thanks for taking a look I really appreciate it. I thought if I send a command and rpc then it would tell the server and other players that my character is invisible but no such luck ;(
everything server related is past line 128, and I called it on line 90.
Well first of all SyncVars are controlled by the server.
if ((Input.GetKeyDown(KeyCode.E)) && (!fading) && (!unstealthed))
{
isInvisible = true;
SyncVisibility(true);
So you need to remove the isInvisible = true;
because you declared that a SyncVar. With that said, make sure that your protecting your Update method. I’m assuming somewhere else you check to see if(isLocalPlayer)
before activating this script? If not, the beginning of your Update method should have something like:
if(!isLocalPlayer)
return;
That way the server/host isn’t controlling all the players. Next your line 90. There’s really no need to call a method that’s assigned as a hook. How it works is when the server changes the variable’s value, the change will be propagated to ALL connected clients (even the client that asked the server to make the change). So ALL client’s will have the hook called on that object. With that said, I urge you to look back to my earlier post.
public class NinjaStealth : NetworkBehaviour
{
[SyncVar(hook="SyncVisibility")]
private bool isVisible;
private float invisibleTime; //ONLY THE SERVER WILL USE THIS
private NetworkIdentity netIdentity;
void Start()
{
//STORE THIS INSTEAD OF REFRENCING IT EVERY FRAME
netIdentity = gameObject.transform.root.gameObject.GetComponent<NetworkIdentity>();
}
void Update()
{
//THIS ONLY RUNS ON THE SERVER
if(!isVisible && netIdentity.isServer)
{
//COUNT DOWN TIME REMAINING
invisibleTime -= Time.deltaTime;
//IF OUT OF TIME
if(invisibleTime <= 0.0f)
{
//GO BACK TO BEING VISIBLE
isVisible = true;
invisibleTime = 0.0f;
}
}
if(!netIdentity.isLocalPlayer)
return;
if(Input.GetKeyDown(KeyCode.E))
{
CmdGoInvisible(); //MAKE A REQUEST TO THE SERVER TO GO INVISIBLE
}
}
[Command]//COMMANDS ARE ONLY EXECUTED ON THE SERVER
private void CmdGoInvisible()
{
isVisible = false;
invisibleTime = 15.0f;
}
private void SyncVisibility(bool isVisible)
{
this.isVisible = isVisible;
if(!isVisible)
{
ColorChange();
}
else
{
//CODE GOES HERE TO TURN THE COLOR BACK TO NORMAL
}
if(isLocalPlayer)
{
if(!isVisible)
{
//CODE GOES HERE TO TURN ON SPECIAL EFFECTS
//START YOUR COROUTINE TO GO INVISIBLE HERE
}
else
{
//CODE GOES HERE TO TURN OFF SPECIAL EFFECTS
//START YOUR COROUTINE TO GO BACK TO BEING VISIBLE HERE
}
}
}
//THIS DOESN'T NEED TO BE AN RPC BECAUSE WE'RE CALLING IT AUTOMATICALLY IN OUR HOOK
private void ColorChange()
{
Material plainMat = Resources.Load("Default", typeof(Material)) as Material;
GetComponent<Renderer>().material = plainMat;
GetComponent<Renderer>().material.color = Color.clear;
}
}
1 Like
Oh man! I am so close thanks to your help! It’s just one problem left with it…On the LAN Client the invisibility works and the game object becomes invisible on the host’s screen when it goes into stealth. But the Host/Lan instance object does not become invisible on the clients instance screen when I try to stealth on that object… hehe
This is the current script
So just so I understand… You see yourself become invisible when you go invisible. But you don’t see others go invisible when they become invisible? In other words, Player A sees himself invisible when Player A goes invisible. But Player A doesn’t see Player B become invisible, when Player B goes invisible?
1 Like
I made this video to show you whats up 
Player A (LanClient) stealths and can see himself stealthed on the player B(LanHost) instance.
Player B (LanHost) stealths but remains visible the Player A(LanClient) instance ;(
Okay. Some changes.
- Line 35: Delete it. You don’t have a hook on it AND you don’t need it.
- Line 55: Change to if(!isVisible && netIdentity.isServer)
- Line 65: Delete it. You don’t need to set the timer to 0. You reset it inside the hook function.
Also, it looks like you added your NetworkIdentity to the GameObject this script is on? If so, you don’t need lines 37 and 49; and in lines like 55 you can just say if(!isVisible && isServer) . So long as the GameObject the script is attached to, has a NetworkIdentity, pieces of code like “isServer” or “isLocalPlayer” automatically reference the attached NetworkIdentity.
1 Like
Oh snap it works!!! You are awesome dude, thank you for sharing your knowledge and for helping me with this! I am gonna look over this tomorrow and really make sure it all sinks in. I will post the script here for others who want to learn from this thread. Thank you DRRosen3! 

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
public class NinjaStealth : NetworkBehaviour
{
[SyncVar(hook = "SyncVisibility")]
private bool isVisible = true;
[SyncVar(hook = "RestealthMethod")]
private bool canRestealth = true;
private bool canMove = true;
private bool canUnstealth;
private float restealthCountdown = 15;
private float invisibleTime;
private float alpha = 1.0f;
private float fadeSpeed = 1f;
private float duration = 1.0F;
new public Text guiText;
private Color colorStart = Color.white;
private Color colorEnd = Color.clear;
private Color m_Color;
private Material m_Material;
private Light directionalLight;
private Transform ninja;
public Transform smoke;
public ParticleSystem smokebomb;
public SpriteRenderer spriteRend;
public NinjaController ninjController;
void Start()
{
directionalLight = GameObject.FindGameObjectWithTag("Light").GetComponent<Light>();
ninja = GameObject.FindGameObjectWithTag("Ninja").transform;
m_Material = GetComponentInChildren<SpriteRenderer>().material;
smokebomb = gameObject.GetComponent<ParticleSystem>();
spriteRend = GetComponentInChildren<SpriteRenderer>();
ninjController = GameObject.FindGameObjectWithTag("Ninja").GetComponent<NinjaController>();
m_Color = m_Material.color;
}
void Update()
{
if (!isVisible && isServer)
{
invisibleTime -= Time.deltaTime;
if (invisibleTime <= 0.0f)
{
isVisible = true;
}
}
if (!canRestealth && isServer)
{
restealthCountdown -= Time.deltaTime;
if (restealthCountdown <= 0.0f)
{
canRestealth = true;
}
}
if (!isLocalPlayer)
return;
if (Input.GetKeyDown(KeyCode.E) && (canRestealth))
{
canRestealth = false;
canUnstealth = true;
CmdGoInvisible();
}
if (Input.GetKeyDown(KeyCode.R) && (canUnstealth) && (!isVisible))
{
CmdGoVisible();
}
}
[Command]
private void CmdGoVisible()
{
isVisible = true;
restealthCountdown = 15f;
canRestealth = false;
}
[Command]
private void CmdGoInvisible()
{
isVisible = false;
invisibleTime = 20.0f;
}
[Command]
private void CmdRestealthing()
{
canRestealth = true;
}
private void RestealthMethod(bool canRestealth)
{
this.canRestealth = canRestealth;
if(isLocalPlayer)
{
canRestealth = true;
}
}
private void SyncVisibility(bool isVisible)
{
this.isVisible = isVisible;
if (!isVisible)
{
ColorChange();
smoke.transform.parent = gameObject.transform;
smoke.position = gameObject.transform.position;
smoke.GetComponentInChildren<ParticleSystem>().Play();
smoke.parent = null;
}
else
{
GetComponentInChildren<Renderer>().material.color = Color.white;
}
if (isLocalPlayer)
{
if (!isVisible)
{
smoke.GetComponentInChildren<ParticleSystem>().Play();
smoke.parent = null;
StartCoroutine(AlphaFade());
}
else
{
StopCoroutine("AlphaFade");
StopCoroutine("FadeIn");
StartCoroutine(FadeOut());
StartCoroutine(Unstealth());
}
}
}
private void ColorChange()
{
GetComponentInChildren<Renderer>().material.color = Color.clear;
}
IEnumerator AlphaFade()
{
{
for (float f = 1f; f >= 0; f -= 0.1f)
{
m_Color.a = f;
gameObject.GetComponentInChildren<Renderer>().material.color = m_Color;
yield return new WaitForSeconds(.001f);
if (f < .1f)
{
directionalLight.intensity = 0;
Material newMat = Resources.Load("Smoke", typeof(Material)) as Material;
gameObject.GetComponentInChildren<Renderer>().material = newMat;
alpha = 1;
StartCoroutine(FadeIn());
yield return null;
}
}
}
}
IEnumerator FadeIn()
{
float ratio = 0;
while (ratio < 1)
{
ratio += Time.deltaTime * .5f;
directionalLight.intensity = .5f;
directionalLight.intensity = Mathf.Lerp(.5f, 0f, ratio);
yield return null;
}
}
IEnumerator FadeOut()
{
float ratio = 0;
while (ratio < 1)
{
ratio += Time.deltaTime * fadeSpeed;
directionalLight.intensity = 0f;
directionalLight.intensity = Mathf.Lerp(0, .5f, ratio);
yield return null;
}
}
IEnumerator Unstealth()
{
yield return new WaitForSeconds(.1f);
Material plainMat = Resources.Load("Default", typeof(Material)) as Material;
gameObject.GetComponentInChildren<Renderer>().material = plainMat;
smoke.GetComponentInChildren<ParticleSystem>().Stop();
}
}
Glad you got it working. Make sure to use code tags in your post though.