Jump to content

Terrain loader delay in build


Gustavo
 Share

Go to solution Solved by Mike P,

Recommended Posts

 

I have a terrain of 5 x 1 tiles and loading option od runtime.

I place the custom player in one end of the terrain, lets say terrain 0, and all the terrain unloaded. While i enter run in unity thi terrsons load as expected. BUT if i build this project this same project does not work.

The cystom player falls into the water as it takes more time in the build than in unity editor. ( should this be all the way around?).

I also set a delay in enabling the custom llsyer rigidbody of 50 seconds, and this also did not work in built project.

As suggested previously i unloaded all the terrains before build the project.

And also i included all the terrains scenes in the build.

Any suggestions?

My workaround was to place a stone below the custom player in the msin scene  so it would be loaded at the begining. This worked fine, but i think it should work the same way as in runtime.

Link to comment
Share on other sites

5 hours ago, Gustavo said:

 

I have a terrain of 5 x 1 tiles and loading option od runtime.

I place the custom player in one end of the terrain, lets say terrain 0, and all the terrain unloaded. While i enter run in unity thi terrsons load as expected. BUT if i build this project this same project does not work.

The cystom player falls into the water as it takes more time in the build than in unity editor. ( should this be all the way around?).

I also set a delay in enabling the custom llsyer rigidbody of 50 seconds, and this also did not work in built project.

As suggested previously i unloaded all the terrains before build the project.

And also i included all the terrains scenes in the build.

Any suggestions?

My workaround was to place a stone below the custom player in the msin scene  so it would be loaded at the begining. This worked fine, but i think it should work the same way as in runtime.

Its hard to say exactly, this would be the correct thing to do. 
Unload the scenes, add the scenes to the build settings, etc. 

That would force me to believe that the player is not set up correctly. 

You could check the Terrain Loader Manager in the Gaia Runtime and make sure that the Terrain Loader Component has the player and its set tp Runtime Always. 

I did run a test and its working for me. Maybe you can compare settings to see what could potentially be the matter. 
image.png
image.png
image.png
 

Link to comment
Share on other sites

the settings are a bit differnt since i use the current gaia pro 2021 version.

in this version i dont see under the runtime, the object Player, which has (accordingly to the secon scrren shot) the script gaia scene player.

In my custom player gaia only added 2 scripts :

image.thumb.png.e0da0f847112b19cc8dde7a4e48a87b7.png

 

and the terrain loader is like you showed:

image.thumb.png.415889c0539de1c6b776f8cbc55342ab.png

 

I also added the scenes involved in the build:

image.thumb.png.d6ad823d8dde644f70e3181a56769e30.png

 

Link to comment
Share on other sites

  • Solution

@Gustavo You could do a hack of the Wait For Terrain Load script and subscribe to the terrain loading events and once the terrain is loaded enable the rigidbody components. I did this for my current project (20x20 tiles) and it works without fail regardless of where the player is position and without any terrain loaded under the player at run-time or build.  There is a bit of a bug in the PW wait for terrain load script with validation the player into the scene as it's testing the bounds of terrains but all references refer back to the gaia player GO and/or Gaia Runtime GO which because it finds them on the terrain (not yet loaded) dismisses the actual functionality of the script so it actually activates before it should or never activates. So I hacked their script and added in the events like the "loading screen script does" and works just fine.  The script is not yet "clean" but works perfectly as I stated, regardless of where you position the player in the world. You can unload all terrains and go into play mode or build and player will not spawn until the terrain is completely loaded.

here is my hack of PWs Wait for Terrain Load script with the above mentioned subscription events:

    //using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

#if GAIA_PRESENT || GAIA_PRO_PRESENT
    using Gaia;

    /// <summary>
    /// Helper script to wait until the terrain below a rigidbody is being loaded in before activating gravity and controller functionality on that rigidbody
    /// Hooks in with Gaia's Terrain Loader Manager, so Gaia is required for current functionality, otherwise, re-code to support non-gaia funtionality.
    /// </summary>
    public class zrWaitForTerrainLoad : MonoBehaviour {

        public bool debug = false;
        
        GameObject player;
        Rigidbody m_watchedRigidbody;
        TerrainScene m_terrainScene;

        bool m_invokeStarted = false;
    
        /// <summary>
        /// Delay until the rigidbody is activated after the terrain is loaded.
        /// </summary>
        public float m_activateDelay = 2f;
        private bool m_terrainLoaded = false;

        /// <summary>
        /// Adds abilility to add additional components here that need to be activated with the rigidbody, ie, controllers, etc..
        /// </summary>
        public List<MonoBehaviour> m_componentsToActivate = new List<MonoBehaviour>();

        // Called before the first frame update
        void Start() {

            if (debug) Debug.Log("transform.root.name: " + transform.root.name.Replace("Gaia Runtime", "G_Runtime") + ", transform.name: " + transform.name.Replace("Gaia Player", "G_Player"));

            m_watchedRigidbody = transform.GetComponent<Rigidbody>();
            //player = GameObject.FindGameObjectWithTag("Player");

            if (TerrainLoaderManager.TerrainScenes.Count > 0) {
                //Subscribe to Terrain Loader Managers load tracking events to monitor when the players rigidbody shold be invoked and player controls are enabled on the player
                TerrainLoaderManager.Instance.OnLoadProgressStarted += OnLoadProgressStarted;
                TerrainLoaderManager.Instance.OnLoadProgressUpdated += OnLoadProgressUpdated;
                TerrainLoaderManager.Instance.OnLoadProgressStarted += OnLoadProgressEnded;
                //TerrainLoaderManager.Instance.OnLoadProgressTimeOut += OnLoadProgressTimeOut;
            }
        }

        private void OnDestroy() {
            if (TerrainLoaderManager.TerrainScenes.Count > 0) {
                //Unsubscribe when the loading screen is destroyed and terrains are loaded
                TerrainLoaderManager.Instance.OnLoadProgressStarted -= OnLoadProgressStarted;
                TerrainLoaderManager.Instance.OnLoadProgressUpdated -= OnLoadProgressUpdated;
                TerrainLoaderManager.Instance.OnLoadProgressStarted -= OnLoadProgressEnded;
                //TerrainLoaderManager.Instance.OnLoadProgressTimeOut -= OnLoadProgressTimeOut;
            }
        }

        /// <summary>
        /// Called when a load progress tracking starts in the Terrain Loader Manager
        /// </summary>
        private void OnLoadProgressStarted() {
            m_watchedRigidbody.useGravity = false;
        }

        /// <summary>
        /// Called when the load progress tracking updates in the Terrain Loader Manager
        /// </summary>
        private void OnLoadProgressUpdated(float progress) {
            //failsafe in case the load progress end process is not being called
            if (progress >= 1) {
                OnLoadProgressEnded();
            }
        }

        /// <summary>
        /// Called when the load progress tracking ends in the Terrain Loader Manager
        /// </summary>
        private void OnLoadProgressEnded() {
            m_terrainLoaded = true;
        }

        /// <summary>
        /// Called when the load progress tracking times out in the Terrain Loader Manager
        /// </summary>
        /***************************
        private void OnLoadProgressTimeOut(List<TerrainScene> missingScenes) {
            foreach (TerrainScene terrainScene in missingScenes) {
                string regularReferences = "";
                string impostorReferences = "";

                foreach (GameObject regularGO in terrainScene.RegularReferences) {
                    regularReferences += regularGO.name + ", ";
                }

                foreach (GameObject impostorGO in terrainScene.ImpostorReferences) {
                    impostorReferences += impostorGO.name + ", ";
                }
            }
            OnLoadProgressEnded();
        }
        ******************/


        void Update() {
            // Terrain(s) Loaded.. Activate the players rigidbody and any additional components configured via the 'm_componentsToActivate' MonoBehavior List
            if (m_terrainLoaded && !m_invokeStarted) {
                m_terrainLoaded = false;
                Invoke("ActivateRigidbody", m_activateDelay);
            }
        }

        #region oldUpdate__disabled
        /****************
        void Update() {

            if (m_terrainScene != null && m_terrainScene.m_regularLoadState != LoadState.Loaded && updateTerrainCounter < terrainsHit) {
                m_watchedRigidbody.useGravity = false;
            } else {
                if (!m_invokeStarted) {
                    Invoke("ActivateRigidbody", m_activateDelay);
                }            
            }


            if (m_terrainScene != null) {
                Debug.Log("terrain scene: " + m_terrainScene.GetTerrainName() + ", load state: " + m_terrainScene.m_regularLoadState + ", hit: " + terrainsHit + ", uHit: " + updateTerrainCounter); ;
            }

            if (m_terrainScene.m_regularLoadState == LoadState.Loaded) { updateTerrainCounter++; }

        }
        *****************************/
        #endregion

        void ActivateRigidbody() {

            if (debug) Debug.Log("Activating Players RigidBody Functionality");
            foreach (MonoBehaviour component in m_componentsToActivate) {
                component.enabled = true;
            }

            Quaternion rot = Quaternion.identity;
            transform.localRotation = new Quaternion(0f, 0f, 0f, -9f);

            m_watchedRigidbody.useGravity = true;

            Destroy(this);
        }
    }
#endif

 

  • Like 1
Link to comment
Share on other sites

Thank you very much for sharing your work!!

It worked fantastic!!!!

 

All the best!!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...