Ykute Games
Ykute Games2w ago

Spawning 1 zombie per 5 seconds

How do I instantiating 1 zombie/object per 5 seconds? I know that sounds easy. But the problem is : when i put the script on the blank gameObject, its work. But all players will instantiating it too. So if there's 2 players, 2 zombies were spawned per 5 seconds. That means the more player, the more zombies, I don't want that. I want instantiating only 1 zombie per 5 seconds, even if the players are 5, 10, etc. How did i fix this issue?
7 Replies
kapa.ai
kapa.ai2w ago
Hi @Ykute Games. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To address your issue with spawning zombies in a multiplayer environment using Normcore, we need to consider ownership and server authority. Here's how you can approach this: 1. Use a single authoritative object to handle spawning: Create a dedicated "ZombieSpawner" object that will be responsible for spawning zombies. This object should have a RealtimeView component and be owned by a single client (preferably the first player to join the room). 2. Implement the spawning logic on this authoritative object: The spawning logic should only run on the client that owns the ZombieSpawner. Here's a basic implementation:
using UnityEngine;
using Normal.Realtime;

public class ZombieSpawner : RealtimeComponent
{
[SerializeField] private string _zombiePrefabName;
[SerializeField] private float _spawnInterval = 5f;

private float _nextSpawnTime;

private void Update()
{
// Only run the spawning logic if this client owns the spawner
if (realtimeView.isOwnedLocally)
{
if (Time.time >= _nextSpawnTime)
{
SpawnZombie();
_nextSpawnTime = Time.time + _spawnInterval;
}
}
}

private void SpawnZombie()
{
Realtime.Instantiate(_zombiePrefabName, ownedByClient: false);
}
}
using UnityEngine;
using Normal.Realtime;

public class ZombieSpawner : RealtimeComponent
{
[SerializeField] private string _zombiePrefabName;
[SerializeField] private float _spawnInterval = 5f;

private float _nextSpawnTime;

private void Update()
{
// Only run the spawning logic if this client owns the spawner
if (realtimeView.isOwnedLocally)
{
if (Time.time >= _nextSpawnTime)
{
SpawnZombie();
_nextSpawnTime = Time.time + _spawnInterval;
}
}
}

private void SpawnZombie()
{
Realtime.Instantiate(_zombiePrefabName, ownedByClient: false);
}
}
3. Set up the ZombieSpawner: - Create an empty GameObject in your scene and add the ZombieSpawner script to it. - Add a RealtimeView component to this GameObject. - Set the _zombiePrefabName to match the name of your zombie prefab in the Realtime Prefabs list. 4. Ensure the first player to join takes ownership: You can do this by modifying the ZombieSpawner script to request ownership if it's not owned:
private void Start()
{
if (!realtimeView.isOwnedLocally && Realtime.connected)
{
realtimeView.RequestOwnership();
}
}

public override void OnRealtimeModelReplaced(RealtimeModel previousModel, RealtimeModel currentModel)
{
base.OnRealtimeModelReplaced(previousModel, currentModel);

if (!realtimeView.isOwnedLocally && Realtime.connected)
{
realtimeView.RequestOwnership();
}
}
private void Start()
{
if (!realtimeView.isOwnedLocally && Realtime.connected)
{
realtimeView.RequestOwnership();
}
}

public override void OnRealtimeModelReplaced(RealtimeModel previousModel, RealtimeModel currentModel)
{
base.OnRealtimeModelReplaced(previousModel, currentModel);

if (!realtimeView.isOwnedLocally && Realtime.connected)
{
realtimeView.RequestOwnership();
}
}
This approach ensures that only one client (the owner of the ZombieSpawner) is responsible for spawning zombies, regardless of how many players are in the room. The spawned zombies themselves are not owned by any specific client, allowing all clients to see and interact with them. For more information on ownership and instantiation in Normcore, you can refer to the following documentation: - Ownership (https://normcore.io/documentation/room/ownership-and-lifetime-flags) - Realtime.Instantiate (https://normcore.io/documentation/realtime/realtime) Remember to add your zombie prefab to the Realtime Prefabs list in your Realtime component settings for this to work correctly. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@785692603684225025> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Mechabit
Mechabit2w ago
do a check for lowest client id before spawning or add a realtime view to the spawner and request ownership of it that way only 1 person will do the spawning
Ykute Games
Ykute GamesOP2w ago
@kapa.ai can i ask again? how do I make condition if realtimeview does not owned by anyone? ("None" status)
kapa.ai
kapa.ai2w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Certainly! To check if a RealtimeView is not owned by anyone (has a "None" ownership status), you can use the isUnownedSelf property. Here's how you can create a condition to check for this:
if (realtimeView.isUnownedSelf)
{
// The RealtimeView is not owned by anyone
// Your code here
}
if (realtimeView.isUnownedSelf)
{
// The RealtimeView is not owned by anyone
// Your code here
}
This property is available on both RealtimeView and RealtimeComponent classes RealtimeView documentation (https://normcore.io/documentation/reference/classes/Normal.Realtime.RealtimeView). Here's a brief explanation of what isUnownedSelf means: - When isUnownedSelf is true, it indicates that the RealtimeView (or RealtimeComponent) is not owned by any client. - This is equivalent to the "None" status you mentioned. If you want to check this condition and then potentially take ownership if it's unowned, you could do something like this:
if (realtimeView.isUnownedSelf)
{
// The RealtimeView is not owned by anyone
realtimeView.RequestOwnership();
}
if (realtimeView.isUnownedSelf)
{
// The RealtimeView is not owned by anyone
realtimeView.RequestOwnership();
}
Remember that RequestOwnership() is an asynchronous operation. The ownership change won't be immediate, but Normcore will assume it succeeds and allow you to make changes right away. If the server rejects the ownership request for any reason, those changes will be rolled back Requesting ownership documentation (https://normcore.io/documentation/room/ownership-and-lifetime-flags#requesting-ownership-of-a-realtimeview). I hope this helps clarify how to check for and handle unowned RealtimeViews in Normcore! ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@785692603684225025> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Ykute Games
Ykute GamesOP2w ago
thankyou dude 🙂 This was very helpfull! THANKYOUUUUUU 🥰