简体   繁体   English

在 Unity 中加载场景但无法加载场景 Android

[英]Scene loads in Unity but unable to Load Scene Android

My Game is working perfectly in Unity but when I export apk tp Android Mobile 2nd Scene doesn't load properly and does not work.我的游戏在 Unity 中运行良好,但是当我导出 apk tp Android Mobile 2nd Scene 时无法正确加载并且无法正常工作。

Please look at the image.请看图片。 It is the second Scene and not loaded properly and the Run button is not working which is working perfectly in unity play mode.这是第二个场景,未正确加载,运行按钮无法正常工作,在统一播放模式下运行良好。

enter image description here在此处输入图像描述

CODES ARE BELOW代码如下

SCENE 1 CODE#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
#if UNITY_ANALYTICS
using UnityEngine.Analytics;
#endif
#if UNITY_PURCHASING
using UnityEngine.Purchasing;
#endif

public class StartButton : MonoBehaviour
{
    public void StartGame()
    {
        if (PlayerData.instance.ftueLevel == 0)
        {
            PlayerData.instance.ftueLevel = 1;
            PlayerData.instance.Save();
#if UNITY_ANALYTICS
            AnalyticsEvent.FirstInteraction("start_button_pressed");
#endif
        }

#if UNITY_PURCHASING
        var module = StandardPurchasingModule.Instance();
#endif
        SceneManager.LoadScene("main");
    }
}

SCENE 2 CODE#

using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

#if UNITY_ANALYTICS
using UnityEngine.Analytics;
#endif

/// <summary>
/// State pushed on the GameManager during the Loadout, when player select player, theme and accessories
/// Take care of init the UI, load all the data used for it etc.
/// </summary>
public class LoadoutState : AState
{
    public Canvas inventoryCanvas;

    [Header("Char UI")]
    public Text charNameDisplay;
    public RectTransform charSelect;
    public Transform charPosition;

    [Header("Theme UI")]
    public Text themeNameDisplay;
    public RectTransform themeSelect;
    public Image themeIcon;

    [Header("PowerUp UI")]
    public RectTransform powerupSelect;
    public Image powerupIcon;
    public Text powerupCount;
    public Sprite noItemIcon;

    [Header("Accessory UI")]
    public RectTransform accessoriesSelector;
    public Text accesoryNameDisplay;
    public Image accessoryIconDisplay;

    [Header("Other Data")]
    public Leaderboard leaderboard;
    public MissionUI missionPopup;
    public Button runButton;

    public GameObject tutorialBlocker;
    public GameObject tutorialPrompt;

    public MeshFilter skyMeshFilter;
    public MeshFilter UIGroundFilter;

    public AudioClip menuTheme;


    [Header("Prefabs")]
    public ConsumableIcon consumableIcon;

    Consumable.ConsumableType m_PowerupToUse = Consumable.ConsumableType.NONE;

    protected GameObject m_Character;
    protected List<int> m_OwnedAccesories = new List<int>();
    protected int m_UsedAccessory = -1;
    protected int m_UsedPowerupIndex;
    protected bool m_IsLoadingCharacter;

    protected Modifier m_CurrentModifier = new Modifier();

    protected const float k_CharacterRotationSpeed = 45f;
    protected const string k_ShopSceneName = "shop";
    protected const float k_OwnedAccessoriesCharacterOffset = -0.1f;
    protected int k_UILayer;
    protected readonly Quaternion k_FlippedYAxisRotation = Quaternion.Euler (0f, 180f, 0f);

    public override void Enter(AState from)
    {
        tutorialBlocker.SetActive(!PlayerData.instance.tutorialDone);
        tutorialPrompt.SetActive(false);

        inventoryCanvas.gameObject.SetActive(true);
        missionPopup.gameObject.SetActive(false);

        charNameDisplay.text = "";
        themeNameDisplay.text = "";

        k_UILayer = LayerMask.NameToLayer("UI");

        skyMeshFilter.gameObject.SetActive(true);
        UIGroundFilter.gameObject.SetActive(true);

        // Reseting the global blinking value. Can happen if the game unexpectedly exited while still blinking
        Shader.SetGlobalFloat("_BlinkingValue", 0.0f);

        if (MusicPlayer.instance.GetStem(0) != menuTheme)
        {
            MusicPlayer.instance.SetStem(0, menuTheme);
            StartCoroutine(MusicPlayer.instance.RestartAllStems());
        }

        runButton.interactable = false;
        runButton.GetComponentInChildren<Text>().text = "Loading...";

        if(m_PowerupToUse != Consumable.ConsumableType.NONE)
        {
            //if we come back from a run and we don't have any more of the powerup we wanted to use, we reset the powerup to use to NONE
            if (!PlayerData.instance.consumables.ContainsKey(m_PowerupToUse) || PlayerData.instance.consumables[m_PowerupToUse] == 0)
                m_PowerupToUse = Consumable.ConsumableType.NONE;
        }

        Refresh();
    }

    public override void Exit(AState to)
    {
        missionPopup.gameObject.SetActive(false);
        inventoryCanvas.gameObject.SetActive(false);

        if (m_Character != null) Addressables.ReleaseInstance(m_Character);

        GameState gs = to as GameState;

        skyMeshFilter.gameObject.SetActive(false);
        UIGroundFilter.gameObject.SetActive(false);

        if (gs != null)
        {
            gs.currentModifier = m_CurrentModifier;

            // We reset the modifier to a default one, for next run (if a new modifier is applied, it will replace this default one before the run starts)
            m_CurrentModifier = new Modifier();

            if (m_PowerupToUse != Consumable.ConsumableType.NONE)
            {
                PlayerData.instance.Consume(m_PowerupToUse);
                Consumable inv = Instantiate(ConsumableDatabase.GetConsumbale(m_PowerupToUse));
                inv.gameObject.SetActive(false);
                gs.trackManager.characterController.inventory = inv;
            }
        }
    }

    public void Refresh()
    {
        PopulatePowerup();

        StartCoroutine(PopulateCharacters());
        StartCoroutine(PopulateTheme());
    }

    public override string GetName()
    {
        return "Loadout";
    }

    public override void Tick()
    {
        if (!runButton.interactable)
        {
            bool interactable = ThemeDatabase.loaded && CharacterDatabase.loaded;
            if(interactable)
            {
                runButton.interactable = true;
                runButton.GetComponentInChildren<Text>().text = "Run!";

                //we can always enabled, as the parent will be disabled if tutorial is already done
                tutorialPrompt.SetActive(true);
            }
        }

        if(m_Character != null)
        {
            m_Character.transform.Rotate(0, k_CharacterRotationSpeed * Time.deltaTime, 0, Space.Self);
        }

        charSelect.gameObject.SetActive(PlayerData.instance.characters.Count > 1);
        themeSelect.gameObject.SetActive(PlayerData.instance.themes.Count > 1);
    }

    public void GoToStore()
    {
        UnityEngine.SceneManagement.SceneManager.LoadScene(k_ShopSceneName, UnityEngine.SceneManagement.LoadSceneMode.Additive);
    }

    public void ChangeCharacter(int dir)
    {
        PlayerData.instance.usedCharacter += dir;
        if (PlayerData.instance.usedCharacter >= PlayerData.instance.characters.Count)
            PlayerData.instance.usedCharacter = 0;
        else if(PlayerData.instance.usedCharacter < 0)
            PlayerData.instance.usedCharacter = PlayerData.instance.characters.Count-1;

        StartCoroutine(PopulateCharacters());
    }

    public void ChangeAccessory(int dir)
    {
        m_UsedAccessory += dir;
        if (m_UsedAccessory >= m_OwnedAccesories.Count)
            m_UsedAccessory = -1;
        else if (m_UsedAccessory < -1)
            m_UsedAccessory = m_OwnedAccesories.Count-1;

        if (m_UsedAccessory != -1)
            PlayerData.instance.usedAccessory = m_OwnedAccesories[m_UsedAccessory];
        else
            PlayerData.instance.usedAccessory = -1;

        SetupAccessory();
    }

    public void ChangeTheme(int dir)
    {
        PlayerData.instance.usedTheme += dir;
        if (PlayerData.instance.usedTheme >= PlayerData.instance.themes.Count)
            PlayerData.instance.usedTheme = 0;
        else if (PlayerData.instance.usedTheme < 0)
            PlayerData.instance.usedTheme = PlayerData.instance.themes.Count - 1;

        StartCoroutine(PopulateTheme());
    }

    public IEnumerator PopulateTheme()
    {
        ThemeData t = null;

        while (t == null)
        {
            t = ThemeDatabase.GetThemeData(PlayerData.instance.themes[PlayerData.instance.usedTheme]);
            yield return null;
        }

        themeNameDisplay.text = t.themeName;
        themeIcon.sprite = t.themeIcon;

        skyMeshFilter.sharedMesh = t.skyMesh;
        UIGroundFilter.sharedMesh = t.UIGroundMesh;
    }

    public IEnumerator PopulateCharacters()
    {
        accessoriesSelector.gameObject.SetActive(false);
        PlayerData.instance.usedAccessory = -1;
        m_UsedAccessory = -1;

        if (!m_IsLoadingCharacter)
        {
            m_IsLoadingCharacter = true;
            GameObject newChar = null;
            while (newChar == null)
            {
                Character c = CharacterDatabase.GetCharacter(PlayerData.instance.characters[PlayerData.instance.usedCharacter]);

                if (c != null)
                {
                    m_OwnedAccesories.Clear();
                    for (int i = 0; i < c.accessories.Length; ++i)
                    {
                        // Check which accessories we own.
                        string compoundName = c.characterName + ":" + c.accessories[i].accessoryName;
                        if (PlayerData.instance.characterAccessories.Contains(compoundName))
                        {
                            m_OwnedAccesories.Add(i);
                        }
                    }

                    Vector3 pos = charPosition.transform.position;
                    if (m_OwnedAccesories.Count > 0)
                    {
                        pos.x = k_OwnedAccessoriesCharacterOffset;
                    }
                    else
                    {
                        pos.x = 0.0f;
                    }
                    charPosition.transform.position = pos;

                    accessoriesSelector.gameObject.SetActive(m_OwnedAccesories.Count > 0);

                    AsyncOperationHandle op = Addressables.InstantiateAsync(c.characterName);
                    yield return op;
                    if (op.Result == null || !(op.Result is GameObject))
                    {
                        Debug.LogWarning(string.Format("Unable to load character {0}.", c.characterName));
                        yield break;
                    }
                    newChar = op.Result as GameObject;
                    Helpers.SetRendererLayerRecursive(newChar, k_UILayer);
                    newChar.transform.SetParent(charPosition, false);
                    newChar.transform.rotation = k_FlippedYAxisRotation;

                    if (m_Character != null)
                        Addressables.ReleaseInstance(m_Character);

                    m_Character = newChar;
                    charNameDisplay.text = c.characterName;

                    m_Character.transform.localPosition = Vector3.right * 1000;
                    //animator will take a frame to initialize, during which the character will be in a T-pose.
                    //So we move the character off screen, wait that initialised frame, then move the character back in place.
                    //That avoid an ugly "T-pose" flash time
                    yield return new WaitForEndOfFrame();
                    m_Character.transform.localPosition = Vector3.zero;

                    SetupAccessory();
                }
                else
                    yield return new WaitForSeconds(1.0f);
            }
            m_IsLoadingCharacter = false;
        }
    }

    void SetupAccessory()
    {
        Character c = m_Character.GetComponent<Character>();
        c.SetupAccesory(PlayerData.instance.usedAccessory);

        if (PlayerData.instance.usedAccessory == -1)
        {
            accesoryNameDisplay.text = "None";
            accessoryIconDisplay.enabled = false;
        }
        else
        {
            accessoryIconDisplay.enabled = true;
            accesoryNameDisplay.text = c.accessories[PlayerData.instance.usedAccessory].accessoryName;
            accessoryIconDisplay.sprite = c.accessories[PlayerData.instance.usedAccessory].accessoryIcon;
        }
    }

    void PopulatePowerup()
    {
        powerupIcon.gameObject.SetActive(true);

        if (PlayerData.instance.consumables.Count > 0)
        {
            Consumable c = ConsumableDatabase.GetConsumbale(m_PowerupToUse);

            powerupSelect.gameObject.SetActive(true);
            if (c != null)
            {
                powerupIcon.sprite = c.icon;
                powerupCount.text = PlayerData.instance.consumables[m_PowerupToUse].ToString();
            }
            else
            {
                powerupIcon.sprite = noItemIcon;
                powerupCount.text = "";
            }
        }
        else
        {
            powerupSelect.gameObject.SetActive(false);
        }
    }

    public void ChangeConsumable(int dir)
    {
        bool found = false;
        do
        {
            m_UsedPowerupIndex += dir;
            if(m_UsedPowerupIndex >= (int)Consumable.ConsumableType.MAX_COUNT)
            {
                m_UsedPowerupIndex = 0; 
            }
            else if(m_UsedPowerupIndex < 0)
            {
                m_UsedPowerupIndex = (int)Consumable.ConsumableType.MAX_COUNT - 1;
            }

            int count = 0;
            if(PlayerData.instance.consumables.TryGetValue((Consumable.ConsumableType)m_UsedPowerupIndex, out count) && count > 0)
            {
                found = true;
            }

        } while (m_UsedPowerupIndex != 0 && !found);

        m_PowerupToUse = (Consumable.ConsumableType)m_UsedPowerupIndex;
        PopulatePowerup();
    }

    public void UnequipPowerup()
    {
        m_PowerupToUse = Consumable.ConsumableType.NONE;
    }


    public void SetModifier(Modifier modifier)
    {
        m_CurrentModifier = modifier;
    }

    public void StartGame()
    {
        if (PlayerData.instance.tutorialDone)
        {
            if (PlayerData.instance.ftueLevel == 1)
            {
                PlayerData.instance.ftueLevel = 2;
                PlayerData.instance.Save();
            }
        }

        manager.SwitchState("Game");
    }

    public void Openleaderboard()
    {
        leaderboard.displayPlayer = false;
        leaderboard.forcePlayerDisplay = false;
        leaderboard.Open();
    }
}

Question too vague, however, a few things come to mind: 1. Are you testing with outdated versions of Android SDK and then running on a newer android version on your phone?问题太模糊了,但是,我想到了一些事情:1.您是否使用过时版本的 Android SDK 进行测试,然后在您的手机上运行更新的 android 版本?

  1. Is the reverse the case?情况是否相反?

  2. Does your device have enough processing and gpu power to run the scene in question?您的设备是否有足够的处理能力和 gpu 功率来运行相关场景?

It would be helpful if you posted some logs and/or images.如果您发布一些日志和/或图像会很有帮助。

Due to lack of info I can only advise you to at least create build with second scene only (the one you can't load) and take a look at result.由于缺乏信息,我只能建议您至少只使用第二个场景(您无法加载的场景)创建构建并查看结果。

Please fill additional information (scene loading code, your first scene hierarchy as screensot etc.) so others could help you much better.请填写其他信息(场景加载代码、您的第一个场景层次结构作为屏幕截图等),以便其他人可以更好地帮助您。

Same issue Here.同样的问题在这里。

I stuck with the Endless Runner code which is the sample code in asset store.我坚持使用 Endless Runner 代码,它是资产商店中的示例代码。 ( https://assetstore.unity.com/packages/essentials/tutorial-projects/endless-runner-sample-game-87901 ) https://assetstore.unity.com/packages/essentials/tutorial-projects/endless-runner-sample-game-87901

I found ThemeDatabase.loaded and CharacterDatabase.loaded is all true in Unity but false in Android.我发现 ThemeDatabase.loaded 和 CharacterDatabase.loaded 在 Unity 中都是正确的,但在 Android 中是错误的。

So interactable will be false in Android.所以在 Android 中,interactable 将是错误的。 (bool interactable = ThemeDatabase.loaded && CharacterDatabase.loaded;) (bool 可交互 = ThemeDatabase.loaded && CharacterDatabase.loaded;)

CharacterDatabase.cs is below. CharacterDatabase.cs 如下。

using UnityEngine;
using UnityEngine.AddressableAssets;
using System.Collections;
using System.Collections.Generic;

/// <summary>
/// This allows us to store a database of all characters currently in the bundles, indexed by name.
/// </summary>
public class CharacterDatabase
{
    static protected Dictionary<string, Character> m_CharactersDict;

    static public Dictionary<string, Character> dictionary {  get { return m_CharactersDict; } }

    static protected bool m_Loaded = false;
    static public bool loaded { get { return m_Loaded; } }

    static public Character GetCharacter(string type)
    {
        Character c;
        if (m_CharactersDict == null || !m_CharactersDict.TryGetValue(type, out c))
            return null;

        return c;
    }

    static public IEnumerator LoadDatabase()
    {
        if (m_CharactersDict == null)
        {
            m_CharactersDict = new Dictionary<string, Character>();

            yield return Addressables.LoadAssetsAsync<GameObject>("characters", op =>
            {
                Character c = op.GetComponent<Character>();
                if (c != null)
                {
                    m_CharactersDict.Add(c.characterName, c);
                }
            });

            m_Loaded = true;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM