Hello!
I'm encountering an issue with subtitles during a cutscene created using Timeline in Unity.
Here's the situation: I have a non-player character (NPC) speaking, and just before the NPC's speech ends, the Player starts talking. I have both subtitles visible at the same time - that's okay.
During this cutscene, the Player character gameobject is within the camera's viewport but remains invisible, as the Player is just a First-Person Camera.
This leads to a problem where the last NPC's Speech Playable Clip displays the text above the Player's position instead of above the NPC.
Here's how I have things set up:
I attempted to fix the problem by using the "Duplicate for each line?" option but found that this choice is only available for menus where "menuSource != MenuSource.UnityUiInScene."
Since I must use "Unity In Scene" menus, I'm unable to access this option.
As I write this now, I checked, and it also turned out that I'm in general unable to make a few NPCs speak at the same time.
My questions are:
Thank you,
Barnim
It looks like you're new here. If you want to get involved, click one of these buttons!
Comments
In-scene Menus reference a specific UI Canvas in the scene, as opposed to a prefab that has a separate instance each time it is spawned in.
Can you elaborate on the need for use of the In Scene option, as opposed to Prefab? I might be able to suggest a workaround if I understand the context.
I want my game to work on PC (flat screen) and VR - out of the box. For UI in VR, I'm using Canvas with render mode: World Space.
In the AC manual, it is written:
"If your Canvas' Render mode is World Space, you will need to use Unity Ui In Scene."
For this reason, I have prepared two prefabs, each prefab contains a set of all menus, and each has the same ConstantID numbers for the relevant elements, so they are automatically detected by the MenuManager:
When loading a scene, depending on whether I detect a VR device or not, I load the appropriate prefab into the scene via script.
Perhaps the Manual statement should be revised, as it's not technically a restriction. It's more to do with if your Menu was in a fixed position in the world, e.g. a UI overlay on a computer screen object in the scene.
Try using "Unity Ui Prefab" mode for your world-space Canvas - it should still work.
I tried using the "Unity Ui Prefab" mode for world-space Canvas and it actually works.
But now I have a problem with replacing prefabs after launching the application.
I wrote myself a class for replacing prefabs:
I use it in my script, which I run in the scene.
Here's an excerpt from my JagsGameEngine class:
In the Inspector, I filled the screenSpacePrefabs and worldSpacePrefabs lists with prefabs from the project.
And after running it, I noticed that the prefabs that are connected to MenuManager before launching the project are loaded into the game. During startup, they are replaced, but AC no longer takes them into account. Only after restarting the application are they loaded - for the obvious reason, which I wrote earlier.
A few months earlier, I experimented with replacing the entire MenuManager config. I had two versions of MenuManagerPC and MenuManagerVR. While starting the application, I determined which MenuManager to load, but it similarly did not work, because the one currently loaded into AC Game Editor was taken into account at startup. Then I hacked the system and forced an AC restart right after launch if a menu change was required. This was supposed to be a temporary solution. And as a result, I came up with the idea that I would use In-Scene UI for both UI versions: ScreenSpace and WordSpace. And everything worked until I discovered that in this configuration, Subtitles have one instance.
How can I have two separate UI versions, one for ScreenSpace and one for WorldSpace, using the Source mode: "Unity Ui Prefab", and load either one during the application startup depending on the needs?
At what point is the choice between the two made?
Though you need to be careful when swapping Manager assets at runtime, you should be OK to do this so long as you make the change before AC itself boots up. You can do this by setting your game's first scene to one that just assigns the intended Manager to AC's References asset, and then open the first scene that uses AC.
The alternative would be to have both variants of the Menu in the same Menu Manager, and pair their lock states so that only one is unlocked at a time.
When a Menu is locked, it will not turn on even when its "Appear type" condition is met.
Thank you for all your answers.
The first line of code in the OnEnable method of my class checks whether a VR device is detected. This class customizes the behavior of Input/UI/Menus according to the needs of my project and is loaded with each scene.
The idea of swapping out the MenuManager in the startup scene generally seems like a good one. It's relatively safe in terms of the potential for errors. However, it does add some complexity to both the development and testing of the UI in both variants. Specifically, I would have to manually switch the MenuManager each time I put on or take off the VR device while working on a particular scene.
For the sake of convenience, I've chosen to let menus adapt automatically or be manually toggled via a single checkbox. This comes with its own set of risks, but it's the path I'm currently on.
To manage this, I've duplicated all my menus and appended a "VR" suffix to distinguish between standard and VR-specific menus. I've created a custom class to allow for easier and safer menu referencing in the code, eliminating the need for excessive string hardcoding. While this solution is functional, it demands careful attention moving forward, particularly when using AC built-in methods to retrieve menus.
This approach also fills my logs with numerous "Cannot turn on menu XXXXXXXXX as it is locked" messages.
I initially considered simplifying things by duplicating menus with identical names and toggling the 'isLocked' setting based on the menu.PrefabCanvas.renderMode. However, this idea fell through because PlayerMenus.GetMenuWithName("menuName") doesn't check the 'isLocked' status and just returns the first matching menu it finds.
In summary, I'd prefer a more elegant solution that would allow for seamless swapping of Menus in MenuManager at runtime. It's unfortunate that this isn't possible, as it seems it should be - given that new menus can be constructed and registered with MenuManager in code during runtime, at least from what I've read in the documentation and code. I haven't delved deeply, so I may be mistaken.
Do you think it is possible that future updates might allow us to selectively disable debugger Info Logs for those that say 'Cannot turn on menu XXXXXXXXX as it is locked'? I'm aware that the CanDisplay method can be used to disable all Info level logs, but could there be an option to mute logs for each individual locked menu, for example via MenuManager options?
You can iterate through the GetMenus function to check for custom conditions:
Caution will need to be exercised - but the PlayerMenus component also has a RebuildMenus function that takes a MenuManager asset file as a parameter. This will destroy all existing runtime Menus, however. If you wanted to retain e.g. the on/off/locked states of the old Menus and apply them to the new, you'd need to do so manually.
I understand the intent here - though I feel a per-Menu option like that would be too cumbersome, particularly as it would chiefly be used for the 'locked' message and other messages would still be desirable to display.
After deep reflection and another experiment, I concluded that it's better to have two Menu Managers and switch them "on the fly."
I managed to do this elegantly = without the need to restart AC when launching the application. I do it during the Start() method, invoking the following method:
Like this:
The line
KickStarter.playerMenus.RebuildMenus(selectedMenuManager);
loads the Menu Manager at runtime.By setting
AdvGame.GetReferences().menuManager = selectedMenuManager;
, I not only load the Menu Manager into the editor but also ensure that changes made during runtime are saved back into that Manager.In my opinion, this looks good, and thanks to you, I have a better understanding of the potential consequences.
I decided to use this more as a development tool. For the build, I can easily disable it and apply this mechanism for loading the appropriate Menu Manager in the startup scene before AC is loaded.
This way, I eliminate all the headaches related to menu names - not only in the code but also in the Actions, keeping identical ConstantIDs, flood of logs about locked menus, and many other issues I had or could have had.
Thanks again for your help and your exhaustive answers!