I'm implementing a system in which a player can pickup an item from the game world. After picking the item up, I want to destroy the game object. To do this, I figured I'd make a ServerRPC that deletes the object, but the ServerRPC is not getting called. I tried making a ClientRPC as well, but that one isn't being called either. I noticed that it only gets called when the host of the game tries to pick up the item -- any ideas on how to fix this? The documentation is pretty bare but please let me know if I missed anything. Here is my code:
public override void Interact(GameObject player)
{
player.GetComponent<PlayerInventory>().AddItem(this.item);
Debug.Log("before");
TestClientRpc();
TestServerRpc();
}
[ServerRpc]
public void TestServerRpc()
{
Debug.Log("server");
// Destroy(gameObject);
}
[ClientRpc]
public void TestClientRpc()
{
Debug.Log("client");
// Destroy(gameObject);
}
EDIT: image of the components on the weapon
EDIT: This class extends a class that extends the networkbehaviour class. The objects are just sitting in the scene at start -- they are not spawned/instantiated (not sure if that matters or not).
The most plausible solution to this problem , either it is running into a error in some previous lines or as some other person pointed out , requireOwnership is not set to false .
For in depth analysis of MLAPI , https://youtube.com/channel/UCBStHvqSDEF751f0CWd3-Pg
I found the tutorial series on this channel best
I needed to add the following attribute to my ServerRpc:
[ServerRpc(RequireOwnership = false)]
since the player was not the owner of the item.
I have the same issue. Been looking at it for 2 days but I am inclined to think it is a bug to be honest.
I just spent 4+ hours banging my head against the wall because they didn't write this important info in the documentation. When calling ServerRpc from a client that doesn't own the Network Object, RPC attribute should be set to RequireOwnership = false.
For me the issue was that the GameObject(with NetwrokObject component) was sitting in the scene before starting the game, I couldn't use NetworkVariables nor ServerRpc. I think those are only usable on spawned object, but not sure. So I would say : either instantiate the object and add it to the NetworkManager or use normal variable on those objects.
Had the same issue but later realized I just forgot to inherit NetworkBehaviour
For Example:
using Unity.Netcode;
using UnityEngine;
class myObject : NetworkBehaviour {
public override void Interact(GameObject player)
{
player.GetComponent<PlayerInventory>().AddItem(this.item);
Debug.Log("before");
TestClientRpc();
TestServerRpc();
}
[ServerRpc]
public void TestServerRpc()
{
Debug.Log("server");
//Destroy(gameObject);
}
[ClientRpc]
public void TestClientRpc()
{
Debug.Log("client");
// Destroy(gameObject);
}
}
I had the same problem, where the ServerRpc wouldn't even be called. For me it worked after I made the GameObject that my script was attached to a prefab and added it to the NetworkManager's list of NetworkPrefabs.
Note: (I am using Netcode for GameObjects, I don't think it will be the same for other Multiplayer solutions)
Related
I managed to get some kind of multiplayer working with Unity Netcode which I understand is very new, but I'm running into a pretty big issue. I can't seem to be able to disconnect from the server instance. This causes an issue in which I load the game scene and the NetworkManager instance is spawned. Then I return to the main menu scene and load the game scene again, and now there are 2 NetworkManager instances which obviously causes errors.
I read in the docs that you can use this:
public void Disconnect()
{
if (IsHost)
{
NetworkManager.Singleton.StopHost();
}
else if (IsClient)
{
NetworkManager.Singleton.StopClient();
}
else if (IsServer)
{
NetworkManager.Singleton.StopServer();
}
UnityEngine.SceneManagement.SceneManager.LoadScene("MainMenu");
}
However all these stop functions don't seem to exist at all under the singleton. Am I missing a library or something?
For now I am using a workaround which is just disabling "Don't destroy" and then the NetworkManager is destroyed after switching scenes, but what if I wanted to keep it after switching a scene? Is there no way to control when the Server/Client is stopped? I'm assuming this is a bug but I just want to make sure.
void Disconnect()
{
NetworkManager.Singleton.Shutdown();
}
Disconnects clients if connected and stops server if running.
To answer your full question, you also need a Cleanup() function in your non-networked scene that checks for astray NetworkManager singletons and destroys them. This will avoid unnecessary duplication of network managers.
void Cleanup()
{
if (NetworkManager.Singleton != null)
{
Destroy(NetworkManager.Singleton.gameObject);
}
}
I don't know why my scene is not loading, can I get help?
When I press the button nothing happens.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class gamecontroller : MonoBehaviour
{
public Text points;
public void Start() {
points.text = Score.scoreval + " POINTS";
}
public void Restart() {
SceneManager.LoadScene("SampleScene");
Score.scoreval = 0;
}
public void Menu()
{
SceneManager.LoadScene("Menu");
Score.scoreval = 0;
}
}
Reason might be that you did not assign the scene in your build. This is an easy fix if this is the case. To check if it is, you can go to the Build Settings... under the File tab. Once in there, you should see the Scenes In Build category, in there you should also see your scene(s). If not, you will need to assign them by going to each scene and pressing Add Open Scenes. Once done, it should work properly from there.
Not sure if this is an issue, it has been a while since I have coded in C#. But, in my scene manager, I wrote the scenes name as such:
public void StartButton()
{
SceneManager.LoadScene(labScene);
}
Not sure if that matters, but I thought I might as well put that out there.
There seems to be a bug from Unity side as it has happened with me sometimes that whenever I'm trying to load the scene using the LoadScene method by passing the SceneName as the parameter, Unity throws up an error even when those scenes have been added in the Build Settings.
Removing the scenes from the build settings and adding them again is what worked for me. :)
User can place objects (prefabs) at runtime using hands/gaze.
Voice command ""Remove" should remove the current focussed (looked at) object.
I tried instantiating the objects and adding the Intractable script. But I am stuck add adding OnfocusEnter and OnfocusExit events at runtime.
Hooking up the events on the prefab wont work as the references are in the scene.
I worked this out over on GitHub and posting it here so we can remove it from the other sources.
I didn't tackle the voice input yet as I am not there yet on my own MRTK project.
This submission should cover this answer for MRTK under version RC1. This was a quick job just to show proof of concept - feel free to modify and go on with it but I won't be :)
For run-time placement you would just need to add a method to instantiate an object that contains all of the information I setup in this example. There were some other solutions in the GitHub channel, I've copied the links below (not sure how long they will be active). This example is assuming you have some sort of already default prefab with the MRTK interactable class part of it.
Other discussions on GitHub from Microsoft: https://github.com/microsoft/MixedRealityToolkit-Unity/issues/4456
Example Video is here: https://www.youtube.com/watch?v=47OExTOOuyU&feature=youtu.be
Example Unity Package is here: https://github.com/JShull/MRTKExamples
Based on #jShull answer I came up with a simple solution for what I needed. Since there is no global listener for focus events I basically made my own.
I also added an earlier discussion (before I posted the question here) with two Microsoft Developers of the Mixed Reality Toolkit which could help out of you are looking for more functionality: https://github.com/microsoft/MixedRealityToolkit-Unity/issues/4456
"Object" script that is a component of the object that needs to be removed or interacted with.
using Microsoft.MixedReality.Toolkit.Input;
using UnityEngine;
public class Object: MonoBehaviour, IMixedRealityFocusHandler
{
public GameManager _gameManager;
public void OnFocusEnter(FocusEventData eventData)
{
Debug.Log("Focus ON: " + gameObject);
_gameManager.SetFocussedObject(gameObject);
}
public void OnFocusExit(FocusEventData eventData)
{
Debug.Log("Focus OFF: " + gameObject);
_gameManager.ResetFocussedObject();
}
}
"GameManager" script functions that sets the focussedObject
public void SetFocussedObject(GameObject object)
{
focussedObject = object;
}
public void ResetFocussedObject()
{
focussedObject = null;
}
Remove Object function is connect to the "Remove" global speech command in the "Speech Input Handler" component. It just removes the "focussedObject" inside the GameManager.
I know this has been covered in the past, but I believe this issue is being caused by the update to Unity 5, thus deprecating the older information. No errors come up, but the debug won't come up. The public variable of 'pushBlockEnter' does become true visibly on the player script, but the pushBlock class will not recognize it no matter what. I just want to be able to check if a variable is true in one script from another script in Unity 5, any way of doing it would be fine. I'm sure it is something simple but I just can't figure it out...I should also mention that both scripts are on a different object. Thanks in advance!:
public class pushBlock : MonoBehaviour {
public Player playerScript;
void Update () {
if (GameObject.Find("Player").GetComponent<Player>().pushBlockEnter)
{
Debug.Log ("do something blahh");
//Do Anything
}
}
}
Figured it out:
GameObject playerReference = GameObject.Find("Player");
void Update(){
if (GameObject.Find("pushBlockCollider").GetComponent<pushBlockCollider>().inPushBlock){
Debug.Log ("got to pushblockCollider True");
}
I'm experiencing a certainly disturbing issue in the last hours.
It appears that every RPC call I do using an array (int, float, byte, etc) is crashing the whole engine.
I've made a little working example of how to reproduce, and I would like to know if it's certainly a bug, or if im doing something very wrong:
using UnityEngine;
using System.Collections;
public class NewBehaviourScript : MonoBehaviour {
// Use this for initialization
void Start () {
Network.InitializeServer(4, 25000, true);
networkView.RPC("test", RPCMode.All, new float[5]);
}
// Update is called once per frame
void Update () {
}
[RPC]
void test(float[] lol){
Debug.Log("received "+lol);
}
}
Using only this script in a Camera with a network view is enough to get the thing crashed. Did I do something wrong??
Thanks in advance!
It is a bug in 4.6.3 and 4.6.4 when i try to send a bytearray over an rpc in unity5 it does the job. Hope it helped
Using RPC call in Unity is restricted to certain types of parameters:
You can use the following variable types as parameters to RPCs:-
int float string NetworkPlayer NetworkViewID Vector3 Quaternion
So what you can do instead is serialize/convert the array to a string, and then back to array on the other side.
You need to add OnServerInitialized function to your class. And after that you can use networkView.RPC("test", RPCMode.All, new float[5]); in this function.
And also i can't see NetworkView instance in your class.
Like
public NetworkView networkView;
void OnServerInitialized(){
Debug.Log("Server initialized and ready");
networkView.RPC("test", RPCMode.All, new float[5]);
}