Trouble understanding HLAPI concepts

Hi,

I started learning the new Unet API yesterday and have been making pretty good progress, but I’m stuck at a point and I’m not sure how to go forward. To learn I’ve been reading the documentation, watching GTGD’s tutorial series and dissecting the sample projects in the stickies. I’ve reached a point where I’m not quite sure if I correctly understand the basic concepts of the HLAPI properly so hopefully someone can point out any confusion I have.

I’m building a simple game where players throw boomerangs at dummies, in first person view. A player clicks the mouse, the boomerang is thrown, if it contacts any dummies they take damage, and the boomerang returns to the player. If a dummy has taken enough damage, it is destroyed and an explosion particle is instantiated at it’s place. To help with a visualization, below shows how the game works.

Here’s how I’ve implemented it, based on my current understanding, using the NetworkManager.

The players are spawned as a player prefab through the NetworkManager, and the Dummy and Boomerang prefab are also added to the Registered Spawnable Prefabs. The dummies are Scene Objects, placed in the scene with a network identity attached. So far so good. Here’s where I’m getting confused. To instantiate the boomerang, a script on the player calls a Command that instantiates the boomerang, and then calls NetworkSpawn on the instantiated object. From my understanding, this means that the boomerang is instantiated on the server, and then on each client without authority.

Attached onto the boomerang is a rigidbody and trigger box collider, and a script that can “damage” objects it contacts. When the boomerang collides with an object it checks if the object has an IDamageable interface, and if it does, it calls the TakeDamage method. What I want to happen is that the boomerang on the server contacts dummies on the server, and reduces their health on the server, and I think this is what’s happening. Players have no need to know how much health the dummies have.

And then, if the dummy has less than 0 health, I call NetworkServer.Destroy(gameObject) on it. In the same script I override OnNetworkDestroy() and instantiate a particle effect, which I think should make a particle on each client. So far I’m running into all sorts of problems where if I Debug.Log out the TakeDamage method it seems to be called on both the server and the client sometimes…and I’m just confused. Is the paradigm I’m using correct? Is my understanding close to being correct? :S

My other main question is when and when not to inherit from NetworkBehaviour. It seems to be only if you need all the override methods you do this, but I’m not sure if there’s a hard and fast rule (things that only exist on the server maybe? I don’t know), since in the example projects some objects do inherit and some just use MonoBehaviour.

Sorry if this is a huge megapost but I’ve been at this for hours without progress and getting frustrated, thanks for any help, it’s very appreciated.

Erik

1 Like

As far as I know, your thinking is correct.

To stop the TakeDamage log appearing twice, check you’ve disabled the boomerang’s scripts/triggers on the clients, and block the TakeDamage code with an authority check “if (!isServer) return;”.

OnNetworkDestroy will be called on the HOST - since it has a local client… Or do you have a non-host dedicate server?

Yea I considered that, since you have do sort of do that anyways for players (disable the input controller if it’s not the local player). This would achieve the desired behavior that I guess can be summed up as saying that the boomerang on the client is just a shell, with only it’s renderers and transforms being active, while the server would have all scripts active. Does Unet have anything built in to support this kind of relationship? It seems like a pretty common functionality, but since I’ve just begun exploring this I’m not sure how much is supposed to be supported by various built in classes and how much I’m supposed to code. This is especially since the documentation alludes to it not being too complex to convert a single player game to multiplayer, I was wary of going overkill and writing a bunch of code that is already in the built in classes.

No, I am using the local client as host and then another client connected to it. I’m sorry if that was unclear, I mostly meant that OnNetworkDestroy would be called on all clients, one of which is the host.