Common issues and their solutions.
- Data Not Showing in UiPresenter
- Animations Not Playing
- UiConfig Not Added Error
- UI Flickers on Open
- Cancellation Not Working
- Getting Help
Symptoms: UI opens but data fields are empty or show default values.
// ❌ WRONG - Data not passed
await _uiService.OpenUiAsync<PlayerProfile>();
// ✅ CORRECT - Use generic overload with data
var data = new PlayerData { Name = "Hero", Level = 10 };
await _uiService.OpenUiAsync<PlayerProfile, PlayerData>(data);public class PlayerProfile : UiPresenter<PlayerData>
{
// ❌ MISSING - Must override OnSetData
// ✅ CORRECT
protected override void OnSetData()
{
nameText.text = Data.Name;
levelText.text = Data.Level.ToString();
}
}// ❌ WRONG - Missing <T> generic
public class PlayerProfile : UiPresenter
// ✅ CORRECT
public class PlayerProfile : UiPresenter<PlayerData>Symptoms: UI with AnimationDelayFeature opens/closes instantly without animation.
// ❌ MISSING - No feature component
public class AnimatedPopup : UiPresenter
{
}
// ✅ CORRECT - Require and reference the feature
[RequireComponent(typeof(AnimationDelayFeature))]
public class AnimatedPopup : UiPresenter
{
[SerializeField] private AnimationDelayFeature _animationFeature;
}Check in the Inspector:
Animation Componentis assignedIntro Animation Clipis assignedOutro Animation Clipis assigned
Alternative: Use TimeDelayFeature for simple delays without animation:
[RequireComponent(typeof(TimeDelayFeature))]
public class SimpleDelayedPopup : UiPresenter
{
[SerializeField] private TimeDelayFeature _delayFeature;
// Configure delay times in Inspector
}AnimationDelayFeature requires an Animation component on the GameObject.
- Add an
Animationcomponent to the presenter GameObject - Or use
AnimatorwithAnimationClipassets
Error: KeyNotFoundException: The UiConfig of type X was not added to the service
Cause: The UI type is not registered in your UiConfigs asset.
- Open your
UiConfigsScriptableObject asset - Add a new entry for your presenter type:
- Type: Select your presenter class
- Addressable Address: Set the Addressable key (e.g.,
UI/MyPresenter) - Layer: Set the depth layer number
- Save the asset
Verification:
// In UiConfigs inspector:
// Type: MyNewPresenter
// Addressable: Assets/UI/MyNewPresenter.prefab
// Layer: 2Symptoms: UI briefly appears at wrong position or state before proper display.
Cause: Prefab's root GameObject is active during initialization.
- Open your UI prefab
- Disable the root GameObject (uncheck the checkbox at top of Inspector)
- Save the prefab
The UI Service will enable it when ready to display.
Note: If creating UI dynamically:
var go = Instantiate(prefab);
go.SetActive(false); // Ensure disabled
_uiService.AddUi(go.GetComponent<UiPresenter>(), layer: 3, openAfter: true);Symptoms: CancellationToken doesn't stop UI loading.
// ❌ WRONG - Token not used
await _uiService.OpenUiAsync<Shop>();
// ✅ CORRECT - Pass the token
var cts = new CancellationTokenSource();
await _uiService.OpenUiAsync<Shop>(cancellationToken: cts.Token);Cancellation only works during the async load phase:
var cts = new CancellationTokenSource();
// Start loading
var task = _uiService.OpenUiAsync<Shop>(cts.Token);
// Cancel BEFORE await completes
cts.Cancel(); // ✅ Works if still loading
await task; // Already complete
cts.Cancel(); // ❌ Too late - no effectvar cts = new CancellationTokenSource();
try
{
await _uiService.OpenUiAsync<Shop>(cts.Token);
}
catch (OperationCanceledException)
{
// ✅ Handle cancellation
Debug.Log("Loading was cancelled");
}// ❌ BAD - Can open duplicates
void Update()
{
if (Input.GetKeyDown(KeyCode.I))
_uiService.OpenUiAsync<Inventory>().Forget();
}
// ✅ GOOD - Check visibility first
void Update()
{
if (Input.GetKeyDown(KeyCode.I) && !_uiService.IsVisible<Inventory>())
_uiService.OpenUiAsync<Inventory>().Forget();
}// ❌ WRONG - Service not initialized
private IUiServiceInit _uiService = new UiService();
async void Start()
{
await _uiService.OpenUiAsync<Menu>(); // Throws!
}
// ✅ CORRECT - Call Init first
void Start()
{
_uiService = new UiService();
_uiService.Init(_uiConfigs);
}// ❌ WRONG - Memory leak
void OnDestroy()
{
// Service still holds references
}
// ✅ CORRECT - Clean up
void OnDestroy()
{
_uiService?.Dispose();
}- Check Unity Console - Look for warnings/errors from UiService
- Verify Dependencies - Ensure UniTask and Addressables are installed correctly
- Review CHANGELOG - Check if recent version introduced breaking changes
- Search Issues - Your issue may already be reported on GitHub
Create an issue at GitHub Issues with:
- Unity version (e.g., 6000.0.5f1)
- Package version (from
package.json) - Code sample reproducing the issue
- Error logs (full stack trace)
- Steps to reproduce
Use GitHub Discussions to:
- Suggest new features
- Ask questions
- Share how you're using the package
When something isn't working, check these in order:
- UI Service is initialized with
Init(uiConfigs) - Presenter type is registered in
UiConfigs - Prefab is marked as Addressable
- Addressable address matches
UiConfigsentry - Prefab root GameObject is disabled
- UniTask and Addressables packages are installed
- No compilation errors in project
- Feature components (if any) are attached and configured