- Home /
Rpc problems; passing a not-null variable value but in the Rpc the value is null
Hi, I'm using Netcode 1.0.0pre-6 and trying to pass a class instance into ServerRpc & ClientRpc and on the owner side the class instance has a value but on the server side and on the client side are null like so:
Here the Rpcs methods:
[ServerRpc]
private void UpGunServerRpc(Weapons.Guns.Gun g)
{
print($"input g is value is {g} from the server side");
UpGunClientRpc(g);
}
[ClientRpc]
private void UpGunClientRpc(Weapons.Guns.Gun g)
{
print($"input g is value is {g} from the client side");
if (IsOwner) {return;}
if (g == null) {return;}
this.Gun = g;
}
Here the class I'm trying to pass:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Netcode;
namespace BeanBoxers.Weapons.Guns
{
[System.Serializable]
public class Gun : MonoBehaviour, INetworkSerializable
{
public float Demege;
public float ReLoadTime;
public float ChangeCartridgeTime;
public int CartridgeSize;
public int BulletsLeft{get; private set;}
public float nearRange;
public float farRange;
public Vector3 position;
public Quaternion rotation;
public bool CanShoot{get; private set;} = true;
public bool isShooting{get; private set;} = false;
public bool IsAiming{get; private set;} = false;
public Vector3 AimPosition;
public Quaternion AimRotation;
protected float CurrentTime;
protected float NextAllowedShootingTime;
public float fildOfView{get; private set;} = 30f;
public UI.Particles.ParticleSystemController GunParticleSystem;
public GameObject RayStarter;
public GameObject RayPath;
private const int Mask = 8;
void Update()
{
//update the gun
if (!CanShoot && isShooting)
{
CurrentTime += Time.deltaTime;
if (CurrentTime >= NextAllowedShootingTime)
{
Debug.Log(name + ".CanShoot");
CanShoot = true;
isShooting = false;
}
}
}
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter {}
public void SetUp(GameObject RS, GameObject RP)
{
try
{
RS.GetComponent<NetworkObject>().Spawn();
}
catch {}
RayStarter = RS;
RayPath = RP;
this.setParent(RayStarter);
}
public virtual Player.PlayerMessenger[] CheckWhatRayHit()
{
RaycastHit hit;
Ray MyRay = new Ray(RayStarter.transform.position, RayPath.transform.position);
if (Physics.Raycast(MyRay, out hit, farRange))
{
if (hit.transform.gameObject.layer == Mask)
{
//check which player the ray hit and return the player object
Player.PlayerMessenger[] RetObj = {hit.collider.gameObject.GetComponent<Player.PlayerMessenger>()};
return RetObj;
}
}
return null;
}
public void setParent(GameObject father)
{
//get a father GameObject
//set gun parent
transform.parent = father.transform;
transform.localPosition = position;
}
public float TakeDemage(Vector3 pos, Vector3 HitPos) {
//get shooting position and hit position
//return the amount of an Demege
Vector3 vc3 = abc(HitPos - pos);
float HitDistans = Mathf.Sqrt((vc3.x * vc3.x + vc3.y * vc3.y + vc3.z * vc3.z));
float DisFromEnd = HitDistans - farRange;
if(Mathf.Abs(nearRange - HitDistans) <= Mathf.Abs(farRange - HitDistans))
{
DisFromEnd = nearRange - HitDistans;
}
if (DisFromEnd <= 0) {
return Demege;
}
else if(DisFromEnd <= 1)
{
return Mathf.Acos(DisFromEnd) * Demege / 90;
}
return 0;
}
private Vector3 abc(Vector3 v3) {
return new Vector3(Mathf.Abs(v3.x), Mathf.Abs(v3.y), Mathf.Abs(v3.z));
}
public bool Shoot()
{
if (BulletsLeft > 0 & CanShoot)
{
Debug.Log(name + ".Shoot");
// shoot the bullt
CurrentTime = 0;
BulletsLeft -= 1;
isShooting = true;
CanShoot = false;
NextAllowedShootingTime = ReLoadTime;
GunParticleSystem.StartParticles(.03f);
return true;
}
else
{
if (!isShooting)
{
Debug.Log(name + ".ReLoad");
//reload cartridge
CurrentTime = 0;
CanShoot = false;
NextAllowedShootingTime = ChangeCartridgeTime;
BulletsLeft = CartridgeSize;
isShooting = true;
}
return false;
}
}
public void Aim()
{
transform.localPosition = AimPosition;
transform.localRotation = AimRotation;
IsAiming = true;
}
public void Unaim()
{
transform.localPosition = position;
transform.localRotation = rotation;
IsAiming = false;
}
}
}
also I would be happy to know how I can do this:
NetworkVariable<Weapons.Guns.Gun> gun = new NetworkVariable<Weapons.Guns.Gun>();
Answer by VanToRiaXVII · Mar 16 at 03:40 PM
I'm not very familiar with Netcode since it's a brand new thing, but looking at how ServerRpcs work by default, you can only invoke them if you're the owner of the Network object. Your client Rpc probably doesn't have those privileges so it sees it as a null. If you changed the RequireOwnership attribute of your ServerRpc to false, it might work.
https://docs-multiplayer.unity3d.com/docs/advanced-topics/message-system/serverrpc/index.html#serverrpc-calls-and-ownership
it didn't work
but I don't want the RequireOwnership set as false,
the gun can be a NetworkVariable too but the problem is Weapons.Guns.Gun is nullable and you can create a NetworkVariable only for non-nullable types
do you think it can work?
Your answer
Follow this Question
Related Questions
Unity networking tutorial? 6 Answers
UNET Direct IP Connection not working 0 Answers
Unity Networking, connecting to sever problems :( 1 Answer
Can I run unity with this system? 3 Answers