using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using TMPro;

public class CharacterManager : MonoBehaviour
{
    [Header("Тестовый режим")]
    public bool TEST = false;

    [System.Serializable]
    public class CharacterSkin
    {
        public string skinName;
        public Sprite pressedSprite;
        public Sprite releasedSprite;
        public bool isUnlocked = false;

        public int requiredMeters;
        public int requiredCoins;
        public int requiredStars;
        public int price;

        [HideInInspector]
        public bool isHiddenFromShop = false;
    }

    public List<CharacterSkin> characterSkins;
    private SpriteRenderer spriteRenderer;
    private int currentSkinIndex = 0;

    private bool isGameStarted = false;
    private bool isAttached = false;

    public GameManager gameManager;

    // public GameObject shopCanvas;
    // public Transform shopContent;
    // public GameObject shopItemPrefab;
    public Button resetSkinsButton;

    void Start()
    {
        spriteRenderer = GetComponent<SpriteRenderer>();

        if (gameManager == null)
        {
            gameManager = GameManager.Instance;
        }

        if (PlayerPrefs.HasKey("SelectedSkinIndex"))
        {
            currentSkinIndex = PlayerPrefs.GetInt("SelectedSkinIndex");
            if (currentSkinIndex < 0 || currentSkinIndex >= characterSkins.Count)
            {
                currentSkinIndex = 0;
            }
        }
        else
        {
            currentSkinIndex = 0;
        }

        LoadSkinUnlockStatus();

        if (characterSkins.Count > 0)
        {
            isAttached = true;
            UpdateCharacterSprite();
        }

        // InitializeShop();

        if (resetSkinsButton != null)
        {
            resetSkinsButton.onClick.AddListener(ResetSkinUnlocks);
        }
    }

    void Update()
    {
        if (!isGameStarted)
        {
            return;
        }

        if (gameManager.collectManager != null)
            gameManager.totalCoins = gameManager.collectManager.coinCount;

        if (gameManager.snitchText != null)
        {
            int stars;
            if (int.TryParse(gameManager.snitchText.text.Replace("x ", ""), out stars))
            {
                gameManager.totalStars = stars;
            }
        }

        if (Input.GetMouseButtonDown(0))
        {
            isAttached = true;
            UpdateCharacterSprite();
        }
        else if (Input.GetMouseButtonUp(0))
        {
            isAttached = false;
            UpdateCharacterSprite();
        }

        UpdateUI();
    }

    void UpdateUI()
    {
        // Можно добавить логику обновления UI, если требуется
    }

    public void StartGame()
    {
        isGameStarted = true;
    }

    public void SwitchSkin()
    {
        if (isGameStarted)
            return;

        if (characterSkins.Count == 0)
            return;

        int startingIndex = currentSkinIndex;
        int nextSkinIndex = (currentSkinIndex + 1) % characterSkins.Count;
        bool found = false;

        while (nextSkinIndex != startingIndex)
        {
            if (IsSkinAvailable(nextSkinIndex))
            {
                found = true;
                break;
            }
            nextSkinIndex = (nextSkinIndex + 1) % characterSkins.Count;
        }

        if (found && IsSkinAvailable(nextSkinIndex))
        {
            currentSkinIndex = nextSkinIndex;
            UpdateCharacterSprite();
            PlayerPrefs.SetInt("SelectedSkinIndex", currentSkinIndex);
            PlayerPrefs.Save();
        }
    }

    private bool IsSkinAvailable(int index)
    {
        if (TEST)
            return true;

        return characterSkins[index].isUnlocked;
    }

    /*
    public void OpenShop()
    {
        if (shopCanvas != null)
        {
            shopCanvas.SetActive(true);
        }
    }

    public void CloseShop()
    {
        if (shopCanvas != null)
        {
            shopCanvas.SetActive(false);
        }
    }
    */

    /*
    void InitializeShop()
    {
        if (shopContent == null || shopItemPrefab == null)
        {
            return;
        }

        foreach (Transform child in shopContent)
        {
            Destroy(child.gameObject);
        }

        for (int i = 0; i < characterSkins.Count; i++)
        {
            CharacterSkin skin = characterSkins[i];

            if (skin.isHiddenFromShop)
                continue;

            GameObject item = Instantiate(shopItemPrefab, shopContent);
            item.transform.localScale = Vector3.one;

            Image skinImage = item.transform.Find("SkinImage").GetComponent<Image>();
            if (skinImage != null && skin.releasedSprite != null)
            {
                skinImage.sprite = skin.releasedSprite;
            }

            TextMeshProUGUI skinNameText = item.transform.Find("SkinNameText").GetComponent<TextMeshProUGUI>();
            if (skinNameText != null)
            {
                skinNameText.text = skin.skinName;
            }

            TextMeshProUGUI skinPriceText = item.transform.Find("SkinPriceText").GetComponent<TextMeshProUGUI>();
            if (skinPriceText != null)
            {
                skinPriceText.text = (TEST || skin.isUnlocked) ? "Выбрать" : $"Цена: {skin.price} монет";
            }

            Button purchaseButton = item.transform.Find("PurchaseButton").GetComponent<Button>();
            TextMeshProUGUI buttonText = purchaseButton.GetComponentInChildren<TextMeshProUGUI>();

            if (TEST || skin.isUnlocked)
            {
                buttonText.text = "Выбрать";
                purchaseButton.onClick.AddListener(() => SelectSkin(i));
            }
            else
            {
                buttonText.text = "Купить";
                purchaseButton.onClick.AddListener(() => PurchaseSkinByIndex(i));
            }
        }
    }
    */

    public void SelectSkin(int skinIndex)
    {
        if (skinIndex < 0 || skinIndex >= characterSkins.Count)
            return;

        CharacterSkin skin = characterSkins[skinIndex];

        if (TEST || skin.isUnlocked)
        {
            currentSkinIndex = skinIndex;
            UpdateCharacterSprite();

            PlayerPrefs.SetInt("SelectedSkinIndex", currentSkinIndex);
            PlayerPrefs.Save();

            // CloseShop();
        }
    }

    /*
    public void PurchaseSkinByIndex(int skinIndex)
    {
        if (skinIndex < 0 || skinIndex >= characterSkins.Count)
            return;

        CharacterSkin skin = characterSkins[skinIndex];

        if (skin.isUnlocked)
        {
            return;
        }

        GameManager gameManagerInstance = GameManager.Instance;

        if (gameManagerInstance == null)
        {
            return;
        }

        int currentMeters = Mathf.FloorToInt(gameManagerInstance.scoreScript.TotalMeters);
        int currentCoins = gameManagerInstance.totalCoins;
        int currentStars = gameManagerInstance.totalStars;

        if (currentMeters >= skin.requiredMeters &&
            currentCoins >= skin.requiredCoins &&
            currentStars >= skin.requiredStars &&
            currentCoins >= skin.price)
        {
            gameManagerInstance.totalCoins -= skin.price;
            skin.isUnlocked = true;
            SaveSkinUnlockStatus();
            gameManagerInstance.SavePlayerStats();
            InitializeShop();
        }
    }
    */

    void SaveSkinUnlockStatus()
    {
        for (int i = 0; i < characterSkins.Count; i++)
        {
            if (TEST)
            {
                PlayerPrefs.SetInt($"SkinUnlocked_{i}", 1);
                characterSkins[i].isUnlocked = true;
            }
            else
            {
                PlayerPrefs.SetInt($"SkinUnlocked_{i}", characterSkins[i].isUnlocked ? 1 : 0);
            }
        }
        PlayerPrefs.Save();
    }

    void LoadSkinUnlockStatus()
    {
        for (int i = 0; i < characterSkins.Count; i++)
        {
            CharacterSkin skin = characterSkins[i];

            if (TEST)
            {
                skin.isUnlocked = true;
                PlayerPrefs.SetInt($"SkinUnlocked_{i}", 1);
            }
            else
            {
                if (skin.isHiddenFromShop)
                {
                    skin.isUnlocked = true;
                    PlayerPrefs.SetInt($"SkinUnlocked_{i}", 1);
                }
                else
                {
                    if (PlayerPrefs.HasKey($"SkinUnlocked_{i}"))
                    {
                        skin.isUnlocked = PlayerPrefs.GetInt($"SkinUnlocked_{i}") == 1;
                    }
                    else
                    {
                        PlayerPrefs.SetInt($"SkinUnlocked_{i}", skin.isUnlocked ? 1 : 0);
                    }
                }
            }
        }
        PlayerPrefs.Save();
    }

    public void ResetSkinUnlocks()
    {
        for (int i = 0; i < characterSkins.Count; i++)
        {
            if (characterSkins[i].isHiddenFromShop)
            {
                characterSkins[i].isUnlocked = true;
                PlayerPrefs.SetInt($"SkinUnlocked_{i}", 1);
            }
            else
            {
                characterSkins[i].isUnlocked = false;
                PlayerPrefs.SetInt($"SkinUnlocked_{i}", 0);
            }
        }

        currentSkinIndex = 0;
        PlayerPrefs.SetInt("SelectedSkinIndex", currentSkinIndex);
        PlayerPrefs.Save();

        LoadSkinUnlockStatus();
        // InitializeShop();
        UpdateCharacterSprite();
    }

    void UpdateCharacterSprite()
    {
        if (characterSkins == null || characterSkins.Count == 0)
        {
            Debug.LogError("Character skins list is empty or null.");
            return;
        }

        if (currentSkinIndex < 0 || currentSkinIndex >= characterSkins.Count)
        {
            currentSkinIndex = 0;
        }

        CharacterSkin currentSkin = characterSkins[currentSkinIndex];

        if (spriteRenderer == null)
        {
            Debug.LogError("SpriteRenderer is not assigned or missing on the GameObject.");
            return;
        }

        if (currentSkin == null)
        {
            Debug.LogError("Current skin is null.");
            return;
        }

        if (isAttached && currentSkin.pressedSprite != null)
        {
            spriteRenderer.sprite = currentSkin.pressedSprite;
        }
        else if (!isAttached && currentSkin.releasedSprite != null)
        {
            spriteRenderer.sprite = currentSkin.releasedSprite;
        }
        else
        {
            Debug.LogWarning("No sprite assigned for the current skin state.");
        }
    }

    public void MoveSkinUp(int index)
    {
        if (index <= 0 || index >= characterSkins.Count)
            return;

        var temp = characterSkins[index - 1];
        characterSkins[index - 1] = characterSkins[index];
        characterSkins[index] = temp;
    }

    public void MoveSkinDown(int index)
    {
        if (index < 0 || index >= characterSkins.Count - 1)
            return;

        var temp = characterSkins[index + 1];
        characterSkins[index + 1] = characterSkins[index];
        characterSkins[index] = temp;
    }

    void OnValidate()
    {
        if (Application.isPlaying)
        {
            SaveSkinUnlockStatus();
            // InitializeShop();
            UpdateCharacterSprite();
        }
    }
}


Этот скрипт вызывает 


SpriteRenderer is not assigned or missing on the GameObject.
0x00007ffa95cb61ed (Unity) StackWalker::ShowCallstack
0x00007ffa95cc61a9 (Unity) PlatformStacktrace::GetStacktrace
0x00007ffa96f2fd1e (Unity) Stacktrace::GetStacktrace
0x00007ffa974d856f (Unity) DebugStringToFile
0x00007ffa94de1655 (Unity) DebugLogHandler_CUSTOM_Internal_Log
0x0000028de4c91b2d (Mono JIT Code) (wrapper managed-to-native) UnityEngine.DebugLogHandler:Internal_Log_Injected (UnityEngine.LogType,UnityEngine.LogOption,UnityEngine.Bindings.ManagedSpanWrapper&,intptr)
0x0000028de4c919e3 (Mono JIT Code) UnityEngine.DebugLogHandler:Internal_Log (UnityEngine.LogType,UnityEngine.LogOption,string,UnityEngine.Object)
0x0000028de4c915fb (Mono JIT Code) UnityEngine.DebugLogHandler:LogFormat (UnityEngine.LogType,UnityEngine.Object,string,object[])
0x0000028de4c91340 (Mono JIT Code) UnityEngine.Logger:Log (UnityEngine.LogType,object)
0x0000028e4827d635 (Mono JIT Code) UnityEngine.Debug:LogError (object)
0x0000028e4827d4db (Mono JIT Code) CharacterManager:UpdateCharacterSprite () (at D:/UnityProject/WebShooter/Assets/Scripts/CharacterManager.cs:389)
0x0000028e4827cb7b (Mono JIT Code) CharacterManager:OnValidate () (at D:/UnityProject/WebShooter/Assets/Scripts/CharacterManager.cs:440)
0x0000028de5d11b68 (Mono JIT Code) (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr)
0x00007ffab39b697e (mono-2.0-bdwgc) mono_jit_runtime_invoke (at C:/build/output/Unity-Technologies/mono/mono/mini/mini-runtime.c:3445)
0x00007ffab38f8444 (mono-2.0-bdwgc) do_runtime_invoke (at C:/build/output/Unity-Technologies/mono/mono/metadata/object.c:3068)
0x00007ffab38f8530 (mono-2.0-bdwgc) mono_runtime_invoke (at C:/build/output/Unity-Technologies/mono/mono/metadata/object.c:3115)
0x00007ffa95bda224 (Unity) scripting_method_invoke
0x00007ffa95bb20f3 (Unity) ScriptingInvocation::Invoke
0x00007ffa95bb21de (Unity) ScriptingInvocation::InvokeChecked
0x00007ffa95c5c2a6 (Unity) SerializableManagedRef::CallMethod
0x00007ffa95b9d76c (Unity) MonoBehaviour::CheckConsistency
0x00007ffa95c9e5a4 (Unity) AwakeFromLoadQueue::InvokePersistentManagerAwake
0x00007ffa95c9fb19 (Unity) AwakeFromLoadQueue::PersistentManagerSingleQueueAwakeFromLoad
0x00007ffa95c9f61d (Unity) AwakeFromLoadQueue::PersistentManagerAwakeFromLoad_NoChecks
0x00007ffa95879f31 (Unity) LoadSceneOperation::CompleteAwakeSequence
0x00007ffa9587ce82 (Unity) LoadSceneOperation::PlayerLoadSceneFromThread
0x00007ffa9587b96e (Unity) LoadSceneOperation::IntegrateMainThread
0x00007ffa9587ea22 (Unity) PreloadManager::UpdatePreloadingSingleStep
0x00007ffa9587e5dd (Unity) PreloadManager::UpdatePreloading
0x00007ffa95858f13 (Unity) `InitPlayerLoopCallbacks'::`2'::EarlyUpdateUpdatePreloadingRegistrator::Forward
0x00007ffa95827d47 (Unity) ExecutePlayerLoop
0x00007ffa95827eb7 (Unity) ExecutePlayerLoop
0x00007ffa9582cfef (Unity) PlayerLoop
0x00007ffa9692dc4a (Unity) EditorPlayerLoop::Execute
0x00007ffa96944ae7 (Unity) PlayerLoopController::InternalUpdateScene
0x00007ffa9694689d (Unity) PlayerLoopController::UpdateSceneIfNeededFromMainLoop
0x00007ffa969406a1 (Unity) Application::TickTimer
0x00007ffa96f34a2a (Unity) MainMessageLoop
0x00007ffa96f3a702 (Unity) UnityMain
0x00007ff7253e2fba (Unity) __scrt_common_main_seh
0x00007ffb3fed257d (KERNEL32) BaseThreadInitThunk
0x00007ffb420eaf08 (ntdll) RtlUserThreadStart

помоги исправить

может добавим  ссылку на спрайт рендерер в скрипт?