Forum rules - please read before posting.

ConstantID prefab procedural issue

mekmek
edited January 2019 in Technical Q&A

I generate my map procedurally at runtime. I dynamically spawn a random amount of an object (prefab). This prefab has a ConstantID component, not set to retain in prefab. This object also has a Hotspot interaction that uses an AssetList and a parameter of that Hotspot object.

When I play this in the editor, it works perfectly. There are multiple prefabs generated and when I interact with each one individually, they work as intended (click on one, cue an animation on that specific instance).

When I play a compiled build of the game, it does not work correctly. When I interact with one of the instanced prefabs, it cues the animation on a different instance.

I was able to temporarily fix this problem by deleting the Constant ID from the prefab and re-adding it.

As an aside, I refer to it as ConstantID, but I am actually using Remember Transform and its Constant ID component:

When I examine the ID # on each instance in the hierarchy during Editor play, the IDs are different and look correct. As you can see above, I set the assignment to Automatic.

What would be the permanent solution?

Thanks!

Comments

  • Have you checked Unity's log files to try to find the reason for the difference between the build and the Editor? I can't see why you'd be getting different behaviour.

    Try checking both Save scene presence? and Retain in prefab?, and then entering in the prefab's ID into the Linked prefab ConstantID field that then appears. That should give better results when a given prefab is spawned multiple times within the scene.

  • Try checking both Save scene presence? and Retain in prefab?, and then entering in the prefab's ID into the Linked prefab ConstantID field that then appears. That should give better results when a given prefab is spawned multiple times within the scene.

    I've tried this, but it seems to work even worse now.

    I've started narrowing in on this, though. I've figured out (roughly) what allows everything to work just fine in the editor...

    When I call the following function (CheckForDuplicateIDs) after the level is generated, everything works perfectly in the editor:

    ConstantID[] allIDScripts = Objects.FindObjectsOfType <ConstantID>();
        foreach(ConstantID idScript in allIDScripts)
        {
        idScript.gameObject.SendMessage ("CheckForDuplicateIDs", SendMessageOptions.DontRequireReceiver);
        }
    


    https://i.gyazo.com/0a5f1fb24573d72c4aa1befd34d624e2.png

    If I do not call this function, then the problem also occurs in the Editor and not only in the Build.

    The problem is that when I've made a compiled build, with this function call activated like usual, it doesn't work correctly any more. It looks like the build is including this FixConstantIDs script, so that's not the problem.

  • Thanks for the details, this'll be enough for me to investigate. Please leave it with me for the moment, and I'll look into it.

  • Hi Chris - just wanted to see if you had a chance to look into this further?

  • Yes, though I'm currently torn on how to classify this issue.

    The CheckForDuplicateIDs method is a Editor-only function, so calling it through script at runtime won't work. IDs should generally only be called in Edit mode, since the generation at runtime has no meaning if they aren't constant.

    If you really do need to call this method, I'd suggest replacing the function call with the code inside it, i.e. copying over the CheckForDuplicateIDs, GetAllIDScriptsInHierarchy and SetNewID functions over and referring to local copies within your own script.

  • mekmek
    edited January 2019

    So I've tried replacing my function call with the code from AC's CheckForDuplicateIDs from ConstantID.cs, and also copied over GetAllIDScriptsInHierarchy and SetNewID as well.

    Pastebin of the new code

    Screenshot of Pastebin:

    Full size

    The script compiles without issue, but now neither in the editor nor in a build do the Hotspots/IDs work correctly.

    1) What do you see in the above Pastebin code that is incorrect? What did I do wrong that is making this not replicate the same functionality as when I simply called AC's CheckForDuplicateIDs?

    2) If the CheckForDuplicateIDs function was originally intended for editor-only, it sounds like my issue with the IDs is unusual. Do you have an idea for what is causing this, so that the IDs would not require fixing via this function?

    Much appreciated Chris -

  • What do you see in the above Pastebin code that is incorrect? What did I do wrong that is making this not replicate the same functionality as when I simply called AC's CheckForDuplicateIDs?

    You're not calling your FixIDs() function anywhere - at least not in this script. I can't say much from an image, though - if you want me to look properly I'll need the link to the code itself.

    If the CheckForDuplicateIDs function was originally intended for editor-only, it sounds like my issue with the IDs is unusual. Do you have an idea for what is causing this, so that the IDs would not require fixing via this function?

    As the thread has been only dealing with the ID issue, I'm not sure what it is exactly you're ultimately trying to achieve. Setting an ID at runtime isn't so helpful normally, because it needs to be persistent after restarting the game - so randomisation isn't going to be appropriate.

    I would recommend trying this first using AC's provided Actions/components. Create a new scene and test prefab to spawn, and attach a Remember Transform component. Check Save scene presence?, then enter in the same ID value into the Linked prefab ConstantID field. You should then be able to spawn/save multiple instances of it into the scene.

  • mekmek
    edited January 2019

    I did include a link to the actual code - above the image is a link to the pastebin.

    Here is the direct url:
    https://pastebin.com/vyjq38md

    I call FixIDs() from somewhere else, after I generate my level.

    I'm not trying to do anything special - using CheckForDuplicateIDs was an attempt to fix the regular AC ID system for procedurally generated prefabs, which has not been working for me.

    I did exactly as instructed.

    I have also placed this in Resources.

    This does not work. Every prefab now has the same ID.

  • I did include a link to the actual code - above the image is a link to the pastebin.

    Quite right, apologies.

    This does not work. Every prefab now has the same ID.

    And you're using Object: Add or remove to spawn them? If not, the RememberTransform's OnSpawn function will need to be called through script.

    What are your AC/Unity version numbers?

  • And you're using Object: Add or remove to spawn them? If not, the RememberTransform's OnSpawn function will need to be called through script.

    Ah, I wasn't aware you needed to call OnSpawn. I am using DunGen (https://assetstore.unity.com/packages/tools/utilities/dungen-15682) to generate my levels. I was letting this generate the world, assuming that just having the ConstantID/Remember on the instantiated object was sufficient. Sounds like I'd need to actually edit the generation in DunGen to use the OnSpawn function? If so, might make more sense for me to just roll my own interaction system - I understand that my use of AC might be outside of its original intention :)

  • Sounds like I'd need to actually edit the generation in DunGen to use the OnSpawn function?

    I expect so, but this system wasn't really designed for procedural generation. I don't know your exact needs, but you may well be off rolling your own.

  • edited May 2020

    Just out of curiosity have been any more updates in this issue?

    Will Calling the Remember Transform OnSpawn on every Dungen spawned item give them individual ConstantIDs in order to by saved and loaded?

    I've been "theorically trying" to work with Dungen and AC in order to make procedural hexmaps for years, and now with all the new AC functions is quite more feasible (component variables for example, very good for that).
    and today I was giving it another go.

    I Just being able to spawn, and Save and Load them via AC (that's quite nice) so I can procedurally generate 40 different/unique hextiles for example, and AC will save and load them mostly good, but of course is better If I can truly just duplicate the same instance.

  • Will Calling the Remember Transform OnSpawn on every Dungen spawned item give them individual ConstantIDs in order to by saved and loaded?

    This would be the equivalent of using the Object: Add or remove Action to spawn it, so yes - provided you've checked Save scene presence? in the Remember Transform component, and also given a non-zero Linked prefab ConstantID value.

    This value represents the ID of the prefab to re-spawn when loading save data, and is typically the same as that associated with the Remember Transform itself, provided you've checked Retain in prefab?.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.