Home > Blockchain >  Unity GameObject "flash" after SetActive on Android Project
Unity GameObject "flash" after SetActive on Android Project

Time:04-20

I have a project that use Android to display Unity Player. So I export Untiy project as Android module which implemented by Android Application.

I create buttons in Android Activity which contains UnityPlayer, And when I click button, it send a message to Unity Player to invoke C# function, just like this:

findViewById(R.id.btnChange).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mUnityPlayer.UnitySendMessage("ScriptHolder", "ChangeSkin", "");
        }
    });

And the function named "ChangeSkin" is just to change some GameObjects' active. Just like this:

void ChangeSkin()
{
    int prefab;
    if (_currentPrefab == PREFAB_DEFAULT)
    {
        prefab = PREFAB_PRINCESS;
    }
    else
    {
        prefab = PREFAB_DEFAULT;
    }
    ShowSkin(prefab);
}

private void ShowSkin(int prefab)
{
    _currentPrefab = prefab;
    foreach (var item in _defaultDressList)
    {
        item.SetActive(prefab == PREFAB_DEFAULT);
    }

    foreach (var item in _princessDressList)
    {
        item.SetActive(prefab == PREFAB_PRINCESS);
    }
}

And something weird happening: when I click button to change the person's cloth in Unity, the GameObjects which called SetActive(true) show at the position above the right position for a frame and become normal, it looks like they flash. Here is the gif of the project demo:

demo

It looks like the position offset is equal to the height of status bar. If I create a button on Unity Scene and call "ChangeSkin" function, everything will be OK.

I tried all I can to fix this but not succeed. So I hope you will help me, thx.

CodePudding user response:

You should check your Unity layout. If you have a layout group that has content size fitter component, and the child objects also have it (content size fitter), this could cause these glitches.

CodePudding user response:

I fixed this problem by using a flag (or trigger). Just like this:

    // set value true to trigger ChangeSkin() in Update(),
    // instead of invoke ChangeSkin() directly
    private bool _changingSkinTrigger = false;

    void ChangeSkin()
    {
        if (_currentPrefab == PREFAB_DEFAULT)
        {
            _currentPrefab = PREFAB_PRINCESS;
        }
        else
        {
            _currentPrefab = PREFAB_DEFAULT;
        }

        _changingSkinTrigger = true;
    }

    void Update()
    {
        if (_changingSkinTrigger)
        {
            _changingSkinTrigger = false;
            ShowSkin();
        }
    }

    private void ShowSkin()
    {
        foreach (var item in _defaultDressList)
        {
            item.SetActive(_currentPrefab == PREFAB_DEFAULT);
        }
        foreach (var item in _princessDressList)
        {
            item.SetActive(_currentPrefab == PREFAB_PRINCESS);
        }
    }

Thank @AndriyMarshalek for enlightening me.

  • Related