Unity - "Dynamic" Object pooling - c#

I'm making a small game for android and currently use a pooling system e.g. for enemies, projectiles etc.
As for now I'm Async loading in levels as you play the game which means no loading scene when venturing into a new zone.
Pool is created when new game is started or old save is loaded. It works fine but leaves one issue! With no loading scenes while playing, there's no time to populate pool other than at the beginning. As player could potentially play all the way though in one sitting, that means all pooled objects needs to be loaded and instantiated.
I realize "Dynamically" filling a pool kinda miss the whole idea of pooling in the first place, but I'm curious what solutions people have come up with. Instantiating enemies at level 1 that won't see use until level 10 seem wasteful.
Cheers :)

To extend on my comments, I made an example which you could implement into your code. The enable, disable and OnLevelFinishedLoading should go somewhere into your Level/SceneManager class.
This should stream in the pooled objects whenever you load a new scene.
void OnEnable()
{
SceneManager.sceneLoaded += OnLevelFinishedLoading;
}
void OnDisable()
{
SceneManager.sceneLoaded -= OnLevelFinishedLoading;
}
void OnLevelFinishedLoading(Scene scene, LoadSceneMode mode)
{
StartCoroutine(StartPoolingNextLevel(yourObjectPooler));
}
private IEnumerator StartPoolingNextLevel(YourObjectPoolerClass yourObjectPooler)
{
for (int i = 0; i < yourObjectPooler.AmountToPool; i++)
{
yourObjectPooler.PoolItem(); // psuedo code
yield return new WaitForEndOfFrame();
}
}

Related

My Coroutine stops after 'yield return new WaitForSeconds(.01f)'

I'm trying to make my coroutine load a scene, then almost immediately teleport the player to a specific location in the scene (Which is why I have .01f in the time). However, after
yield return new WaitForSeconds(.01f);
The code after it doesn't run. "After Coroutine" doesn't appear in my log and the teleporting doesn't run.
private IEnumerator Exiting()
{
SceneManager.LoadScene("Opening Stage");
Debug.Log("Scene loaded, lastPos: " + myLocation.getLastPos());
yield return new WaitForSeconds(.01f);
Debug.Log("After Coroutine");
myLocation.ReturnToLastPos();
}
Removing the LoadScene line makes it all work, teleporting and all. But loading the scene is needed and I've been trying to figure it out. I'm still relatively new to C# so if I don't understand your suggestions or comments, that's why. Thank you.

Issue with moving clients/players with Photon Networking in Unity

I'm making a game where players are put onto plates and random events happen to the plates/players. I've gone through a multitude of different networking solutions like UNET, Mirror, Mirror+Steamworks P2P but none of them really worked well (main issue being not being able to join via IP) so I settled on Photon. After Punv2 just wouldn't work on my project (an error in PhotonEditor.CS) I just used Punv1 which is working perfectly for the most part.
The issue right now is that I'm trying to spawn players on their owned plates but they only spawn on the first plate despite each plate being owned by a player (each plate has a script that specifies which player 'owns' it. This is being set correctly). This only seems to happen when I try to test with a real player/client. If I create a fake player by just spawning in the prefab and then running it, both players will be moved to their correct plate so it seems to be a networking issue.
Here's the code responsible for moving the players to their plates.
foreach (GameObject plate in spawnedPlates)
{
//Here we loop through each plate, get the player assigned to it and move the player to that plate.
GameObject player = plate.GetComponent<Plate>().assignedTo;
PlayerClientControl playerController = player.GetComponent<PlayerClientControl>(); // originally for UNET/Mirror. Left in incase I need it(had an RPC function that moved the player).
player.transform.position = plate.transform.position + new Vector3(0, 4, 0);
}
What am I doing wrong?
EDIT:
It seems they ARE being moved to the correct positions (or atleast, it's trying to move them to the correct position) via a debug print statement that prints where they are trying to be teleported to further cementing that this is a networking issue but I have no idea how to fix it.
I assume it's something to with host/client synchronization? If anyone could shed some light on this, that'd be great because I'm pulling my hair out over this.
If you inspect the player objects at runtime, it will probably give you a clue. I had the same and in my case I had InputAction attached to my players (taken from unity StarterAssets). The first player in the game was assigned keyboard and the second a controller. I solved it by disabling all the inputaction and enabling the one of the localplayer:
private void Awake()
{
photonView = GetComponent<PhotonView>();
if (photonView.IsMine)
{
// take control of the user input by disabling all and then enabling mine
var players = FindObjectsOfType<Player>();
foreach (Player player in players)
{
player.GetComponent<PlayerInput>().enabled = false;
}
GetComponent<PlayerInput>().enabled = true;

Unity:Time.timescale =0 not working

I am trying to display player tutorial when the user 1st starts the game using playerpref and want the game to be paused, the problem i am facing is that Time.timescale=0 is not pausing the game when placed inside start (tutorialCanvas gets displayed), but works when is called by a button(Pause button).
Following is the code I use
void Start()
{
if (PlayerPrefs.HasKey ("test4") ==false ) {
tutorialCanvas.SetActive (true);
Time.timeScale = 0;
}
}
Time.timeScale = 0 is really messed up for me so what i could recommend you is that if you just want to pause something like pausing a movement of a character then you can try it like this :
GameObject PlayerScript;
if(Input.GetKey(KeyCode.P)){
//lets disable the playermovement script only not the whole object
PlayerScript = GetComponent<PlayerMovement>().enabled = false;
}
I've been stucked there also so i made an alternative way. And you can also visit this one. If you want a free of that asset you can get it here
I had this issue recently, although it was only doing it on a build, and not in the editor. Changing timeScale to something like 0.0001f would fix it, but that wasn't a great solution. Creating an input settings asset (under Camera -> Player Input -> Open Input Settings) seemed to have fixed it for the builds.

Checking internet connection at runtime in Unity

How can I check internet connection inside Update Function in unity? I want to know whether the user is connected or not, and based on that just disable some functionality of my game.
Seems like there is no question like this been asked here before or if it is, it just checking the connection in Start function. Here is the code I have so far:
void Update () {
if (Application.internetReachability == NetworkReachability.NotReachable) {
Debug.Log ("No internet access");
} else {
Debug.Log ("internet connection");
}
}
#mjwills solution is right and it works OK, but nobody forces you to check connection every single frame of your game. You don't have to do that.
A better solution is to check connection when a button is clicked or when an event happens in your scene.
You need to run your Update function periodically.
http://unitylore.com/articles/timers-in-unity/ could be used for this:
using UnityEngine;
public class Timer : MonoBehaviour
{
public float waitTime = 1f;
float timer;
void Update ()
{
timer += Time.deltaTime;
if (timer > waitTime) {
if (Application.internetReachability == NetworkReachability.NotReachable) {
Debug.Log ("No internet access");
} else {
Debug.Log ("internet connection");
}
timer = 0f;
}
}
}
Unity's Application.internetReachability is not the best solution for internet detection as it was not designed for that purpose (as stated in the docs).
The proper way is to implement a technique called Captive Portal Detection, which is what all the major OS's use for their internet status detection. If implemented correctly, it can even detect when the network is restricted (hotels or airports) as it relies on HTTP requests of known content. Therefore it is far more reliable.
It is not that hard to implement. You need to make an HTTP request to a known "check page", and check whether the right content were returned.
However, if you want a complete, ready-to-use solution, you can check the asset Eazy NetChecker which I created for this purpose. It also has events and a custom editor. It is not free, but it is super cheap!

Unity Start nog called on real build

I've made a dice app as a project to learn to work with unity (it was so good in my eyes that I put it on the google play store) but when I downloaded it from there, the Start function of at least 2 scripts isn't called and I have no idea whether the other Start functions are being called.
Here you can see 2 of the Start functions that aren't called
void Start()
{
light = light.GetComponent<Light>();
GetComponent<Button>().onClick.AddListener(TaskOnClick);
rawImage = GetComponent<RawImage>();
isLockMode = false;
rawImage.texture = getIconLock(isLockMode);
}
void Start()
{
Screen.fullScreen = false;
Dice.AddDie();
Input.gyro.enabled = true;
GlobalConfig.onShowShadowsChanged += onShadowsEnabledChange;
}
They work when I use Unity Remote on my smartphone and they also work when I just use unity without the remote...
the first script is attached to a UI element and the second script is attached to an empty GameObject called 'App'
It's also even more weird because they used to work but then I switched pc's (but used the same code).
I think something is wrong with the building itself
Found out the problem, the build was generating two files, an .apk and an other .odb or somethingl ike that (might be another extension). I had to untick 'split application binary' in the player settings

Categories

Resources