Рисование на 3D объекте проблема на Android - Unity C#

Всем привет! Столкнулся с такой проблемой: У меня есть 3D модель, на которой можно рисовать мышкой, как в Paint. В редакторе рисовка по 3D модели работает идеально ,то есть кисть с выбранной краской появляется там где и мышь, но когда дело доходит до Android ,то тут всё печально Пытаюсь рисовать пальцем по модельки ан не получается, кисть не спавнится и всё. Думал в начале о том, что может дело в векторе Input.mousePosition, который нельзя отследить на телефоне и решил его заменить на Input.touches[0].position и да после этого скрипт стал отлавнивать позицию в коде процесс рисования идёт, но на модели почему-то не отображается ,то есть кисть с выбранной краской не спавнится и всё В чем может быть проблема? Прикрепляю полученный код ниже:

    public enum ModePaint
    {
        CaseCameraMove,
        BrushPaint,
        StickerPaint,
        TextMeshWriteRead,
    }

    public CaseCamera caseCamera;
    public ColorPicker colorPicker;
    public Texture2D ClearTextureCase;
    public Button ButtonUndo, ButtonRedo,ButtonClear;
    public Image[] RoflPlitks;
    public TextMeshPro NameRoflCaseText;
    public GameObject[] SettingsInstuments;

    public User user;
    internal int CurrentCountTextures = 0;
    [SerializeField]internal List<Color[]> Textures = new List<Color[]>();
    private float BrushSize = 0.1f;
    private Texture2D PaintTexture;
    private Color BrushColor;
    private ModePaint modePaint;
    private RaycastHit rayhit;

    void OnMouseDown()
    {
        if (modePaint == ModePaint.StickerPaint)
        {
            if(Input.touchCount > 0 && (Input.touches[0].phase == TouchPhase.Began))
                Draw(Input.touches[0].position);
        }
    }
    void OnMouseDrag()
    {
        if(modePaint == ModePaint.BrushPaint)
        {
            if (Input.touchCount > 0 && (Input.touches[0].phase == TouchPhase.Stationary))
                Draw(Input.touches[0].position);
        }
    }
    void OnMouseUp()
    {
        if (modePaint == ModePaint.BrushPaint)
        {
            Textures.Add(PaintTexture.GetPixels());
            CurrentCountTextures = Textures.Count - 1;
        }
    }
    private void Start()
    {
        user = colorPicker.user;
        NameRoflCaseText.text = "";
        Clear();
    }
    internal void SetBrushSize(float cur)
    {
        BrushSize = cur;
    }
    internal void SetBrushColor(Color color)
    {
        BrushColor = color;
    }
    public void SelectModePaint(int GetHashCode)
    {
        foreach (Image i in RoflPlitks)
            i.color = Color.white;
        foreach (GameObject go in SettingsInstuments)
            go.SetActive(false);
        RoflPlitks[GetHashCode].color = Color.green;
        if(GetHashCode > 0)
            SettingsInstuments[GetHashCode - 1].SetActive(true);
        caseCamera.enabled = GetHashCode == 0;
        modePaint = (ModePaint)GetHashCode;
    }

    internal ModePaint GetModePaint()
    {
        return modePaint;
    }

    void FixedUpdate()
    {
        CheckUndoRedoClear();
    }

    public void ChangedTextNameRoflCase(InputField NameRoflCaseInputField)
    {
        NameRoflCaseText.text = NameRoflCaseInputField.text;
    }

    #region Undo / Redo
    private void CheckUndoRedoClear()
    {
        ButtonUndo.gameObject.SetActive(modePaint == ModePaint.BrushPaint || modePaint == ModePaint.StickerPaint);
        ButtonRedo.gameObject.SetActive(modePaint == ModePaint.BrushPaint || modePaint == ModePaint.StickerPaint);
        ButtonClear.gameObject.SetActive(modePaint == ModePaint.BrushPaint || modePaint == ModePaint.StickerPaint);
        ButtonUndo.interactable = CurrentCountTextures > 0;
        ButtonRedo.interactable = CurrentCountTextures+1 < Textures.Count;
        ButtonClear.interactable = Textures.Count > 1;
    }
    public void Undo()
    {
        PaintTexture.SetPixels(Textures[CurrentCountTextures - 1]);
        PaintTexture.Apply();
        CurrentCountTextures--;
    }
    public void Redo()
    {
        PaintTexture.SetPixels(Textures[CurrentCountTextures + 1]);
        PaintTexture.Apply();
        CurrentCountTextures++;
    }
    public void Clear()
    {
        if (PaintTexture == null)
            InizializationPaintTexture();
        else
            PaintTexture.SetPixels(ClearTextureCase.GetPixels());
        PaintTexture.Apply();
        Textures = new List<Color[]>();
        Textures.Add(ClearTextureCase.GetPixels());
        CurrentCountTextures = Textures.Count-1;
    }

    private void InizializationPaintTexture()
    {
        var tex = GetComponent<MeshRenderer>().sharedMaterial.mainTexture as Texture2D;
        PaintTexture = new Texture2D(tex.width, tex.height,TextureFormat.RGBA32,false);
        PaintTexture.filterMode = FilterMode.Bilinear;
        PaintTexture.SetPixels32(tex.GetPixels32());
        PaintTexture.Apply();
        GetComponent<MeshRenderer>().material.mainTexture = PaintTexture;
    }
    #endregion
    private void Draw(Vector3 pos)
    {
        Ray hit = caseCamera.GetComponent<Camera>().ScreenPointToRay(pos);
        if (Physics.Raycast(hit, out rayhit))
        {
            MeshRenderer rend = rayhit.transform.GetComponent<MeshRenderer>();
            MeshCollider meshCollider = rayhit.collider as MeshCollider;

            if (rend == null || rend.sharedMaterial == null || rend.sharedMaterial.mainTexture == null || meshCollider == null)
                return;

            Vector2 pixelUV = rayhit.textureCoord;

            pixelUV.x *= rend.material.mainTexture.width;
            pixelUV.y *= rend.material.mainTexture.height;

            int x = (int)pixelUV.x;
            int y = (int)pixelUV.y;
            //Expand where to draw on both direction
            if (modePaint == ModePaint.BrushPaint)
            {
                int radius = Mathf.RoundToInt(BrushSize * 100);
                float rSquared = radius * radius;
                //Expand where to draw on both direction
                for (int u = x - radius; u < x + radius + 1; u++)
                    for (int v = y - radius; v < y + radius + 1; v++)
                        if ((x - u) * (x - u) + (y - v) * (y - v) < rSquared)
                            PaintTexture.SetPixel(u, v, BrushColor);
                PaintTexture.Apply();
                if (CurrentCountTextures != Textures.Count - 1)
                {
                    for (int i = Textures.Count-1; i > CurrentCountTextures; i--)
                    {
                        Textures.RemoveAt(i);
                    }
                    CurrentCountTextures = Textures.Count;
                }
            }
            else if (modePaint == ModePaint.StickerPaint && user.StickersBuyes[colorPicker.CurrentStickerSelected])
            {
                    Texture2D sticker = rotate(CreateSticker());
                    // Map Ray(X, Y) - это процентное положение (варьируемое от 0 до 1) от выходного значения RayCast
                    // Умножив матрицу на ширину основной текстуры, мы получим плавающую версию матрицы.
                    // Спрайт CenterX координата, которую он должен быть преобразован в Int, и то же самое для координаты Y. 
                    int MainWidth = PaintTexture.width;// Мы определяем нашу ширину MainTexture
                    int MainHeight = PaintTexture.height;// Мы определяем нашу основную высоту текстуры
                    int SpriteCenterX = Mathf.FloorToInt(rayhit.textureCoord.x * MainWidth); // Мы определяем X SpriteCenter
                    int SpriteCenterY = Mathf.FloorToInt(rayhit.textureCoord.y * MainHeight);// Мы определяем центр Спрайта Y
                    int FirstPointX = SpriteCenterX - sticker.width / 2; // Определим первую точку (x,y) из...
                    int FirstPointY = SpriteCenterY - sticker.height / 2;// ...наш спрайт, это точка в левом нижнем углу
                    Color[] MainColor = PaintTexture.GetPixels(); // Мы собираем основные пиксели цвета текстуры в цветовом массиве
                    Color[] ResultColor = PaintTexture.GetPixels();// Мы собираем основные пиксели цвета текстуры в цветовом массиве...
                    Color[] SpriteColor = sticker.GetPixels();
                    // ...Вызывается результирующий цвет, который будет использоваться для смешивания цветных пикселей
                    int j = FirstPointY < 0 ? Mathf.Abs(FirstPointY) : 0;//если они нашей первой точки < 0, то j=положительное значение...
                                                                         // ......из первого пункта вы
                    while (j < sticker.height)
                    {
                        int i = FirstPointX < 0 ? Mathf.Abs(FirstPointX) : 0;//если X нашей первой точки < 0, то i=положительное значение...
                                                                             // ...из первой точки X
                        int PointY = FirstPointY + j;// Мы определяем координату Y нашего цветного пикселя в основной текстуре
                        if (PointY >= MainHeight)
                        {
                            j = sticker.height; // Мы заканчиваем цикл j, когда координата цветного пикселя Y достигает...
                            i = sticker.width; // ...MainTexture haight value а также мы заканчиваем цикл i
                        }
                        else
                        {
                            while (i < sticker.width)
                            {
                                int PointX = FirstPointX + i;// Мы определяем координату X нашего цветного пикселя в основной текстуре
                                if (PointX < PaintTexture.width)
                                {
                                    int MainInd = PointY * PaintTexture.width + PointX;// Мы преобразуем координаты X и Y из ...
                                                                                       //......цветной пиксель, расположенный на основной текстуре в массиве to Index
                                    int SpriteInd = j * sticker.width + i;//Мы преобразуем координаты локали X и Y...

                                    float ColorMixA = SpriteColor[SpriteInd].a;
                                    if(ColorMixA == 0)
                                        ResultColor[MainInd] = MainColor[MainInd];
                                    else
                                        ResultColor[MainInd] = SpriteColor[SpriteInd];
                                }
                                else { i = PaintTexture.width; }// Мы заканчиваем цикл i, если точка X>=основная текстура.ширина
                                i++;
                            }
                        }
                        j++;
                    }
                    PaintTexture.SetPixels(0,0,PaintTexture.width,PaintTexture.height,ResultColor);
                    PaintTexture.Apply();
                    if (CurrentCountTextures != Textures.Count - 1)
                    {
                        for (int i = Textures.Count - 1; i > CurrentCountTextures; i--)
                        {
                            Textures.RemoveAt(i);
                        }
                        CurrentCountTextures = Textures.Count;
                    }
                    Textures.Add(PaintTexture.GetPixels());
                    CurrentCountTextures = Textures.Count-1;
            }
        }
    }
    public Texture2D rotate(Texture2D original)
    {
        Texture2D flipped = new Texture2D(original.width, original.height,TextureFormat.RGBA32,false);
        for (int i = 0; i < flipped.width; i++)
        {
            for (int j = 0; j < flipped.height; j++)
            {
                flipped.SetPixel(flipped.height - i - 1, j, original.GetPixel(j, i));
            }
        }
        flipped.Apply();
        return flipped;
    }

    Texture2D CreateSticker()
    {
        return colorPicker.StickerPreview.sprite.texture as Texture2D;
    }
}

} Отвечу сразу на вопрос, если он возникнет, почему я пеку в Texture2D по пиксельно, а не использую декали. Так так данную текстуру мне нужно будет отправить на сервер, чтобы игрок перешедший во вкладку сообщество мог увидеть данную 3d модель с текстурой(которая подружается в процессе, если игрок выбрал эту модель из списка) Примечания:

  • Скрипт весит на 3D модели на которой я рисую
  • PaintCase текстура имеет галочку на Read-Write Enabled
  • На компьютере если указать Input.mousePosition в метод Draw всё работает!
  • Если тестировать данный код через Unity Remote ,то тоже почему-то всё работает, а вот на самом билде на андроид нет В чем может быть проблема? *Методы OnMouseDown OnMouseUp OnMouseDrag отлично срабатывают на Android при отладке. *Тестировалось на Android - смартфоне LG K7.
  • Билд использует API Graphics - OpenGLES2(может дело в нём?)

Ниже прикрепляю скриншоты, что в редакторе рисует,а на Android нет

Как мы видим в Unity Editor кнопка назад актива и при этом на кейсе есть краска

Как мы видим на Android кнопка назад активна а ничего не нарисовалось


Ответы (0 шт):