• Хостинг игровых серверов

    Максимальная производительность для ваших игровых серверов!

    Заказать сейчас

Помогите CUI - обновление элемента

Nick302

12 Мар 2023
10
0
6
25
А не подскажите как обновлять только элемент?
Пробовал удалять его и заново в контейнер добавлять и загружать контейнер но в таком случае получается что у игрока несколько контейнеров, и при закрытие одного остается второй
Поэтому в данный момент удаляется весь MyBackgroundName и выглядит это не красиво

Код:
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Command", "Cold", "1.0.0")]
    public class Command : RustPlugin
    {
        [PluginReference] private Plugin ImageLibrary;

        private CuiElementContainer container;

        [ChatCommand("command")]
        private void tesCommand(BasePlayer player)
        {
            container = new CuiElementContainer();

            //задний фон прозрачный
            var backgroundName = container.Add(new CuiPanel
            {
                CursorEnabled = true,
                RectTransform = {AnchorMin = "0 0", AnchorMax = "1 1"},
                Image =
                {
                    Color = "0 0 0 0.5", Material = "assets/content/ui/uibackgroundblur.mat",
                    Sprite = "assets/content/ui/ui.background.transparent.radial.psd"
                }
            }, "Overlay", "MyBackgroundName");

            //фон
            container.Add(new CuiElement
            {
                Parent = "MyBackgroundName",
                Components =
                {
                    new CuiRawImageComponent {Url = "Ваша ссылка"},
                    new CuiRectTransformComponent {AnchorMin = "0 0", AnchorMax = "1 1"},
                }
            });
 
            container.Add(getBut(), "MyBackgroundName", "aplus");

            //закрытие
            container.Add(new CuiButton
            {
                RectTransform = {AnchorMin = "0.8 0.8", AnchorMax = "0.9 0.9"},
                Button = {Close = "MyBackgroundName", Color = "0 0 0 0"},
                Text = {Text = ""}
            }, "MyBackgroundName");
            CuiHelper.AddUi(player, container);
        }

        public int a = 1;

        private CuiButton getBut()
        {
            CuiButton c = new CuiButton();
            c.RectTransform.AnchorMin = "0.56 0.42";
            c.RectTransform.AnchorMax = "0.64 0.47";
            c.Button.Command = "aplus";
            c.Button.Color = "1 0 0 1";
            c.Text.Text = $"A++ {a}";
            c.Text.Align = TextAnchor.MiddleCenter;
            return c;
        }


        void OnPlayerDisconnected(BasePlayer player, string reason)
        {
            CuiHelper.DestroyUi(player, "MyBackgroundName");
            player.ChatMessage("clear");
        }

        [ConsoleCommand("aplus")]
        void sndmss(ConsoleSystem.Arg args)
        {
            BasePlayer player = args.Player();
            a++;
            CuiHelper.DestroyUi(player, "MyBackgroundName");
            container.Add(getBut(), "MyBackgroundName", "aplus");
            CuiHelper.AddUi(player, container);
        }
    }
}
 
К сожалению, в Rust нельзя обновлять отдельные элементы интерфейса, не удаляя их и заново добавляя. Это связано с тем, что Rust использует библиотеку Cui для создания интерфейса, которая не предоставляет такую возможность.

Однако, вы можете создать функцию, которая будет обновлять весь контейнер, но при этом сохранять состояние элементов. Например, вы можете создать отдельный метод UpdateContainer(), который будет обновлять только текст кнопки:

C#:
private void UpdateContainer(BasePlayer player, int a)
{
    container = new CuiElementContainer();
    // ... код для создания заднего фона и других элементов ...
    container.Add(getBut(a), "MyBackgroundName", "aplus");
    CuiHelper.DestroyUi(player, "MyBackgroundName");
    CuiHelper.AddUi(player, container);
}

private CuiButton getBut(int a)
{
    CuiButton c = new CuiButton();
    c.RectTransform.AnchorMin = "0.56 0.42";
    c.RectTransform.AnchorMax = "0.64 0.47";
    c.Button.Command = "aplus";
    c.Button.Color = "1 0 0 1";
    c.Text.Text = $"A++ {a}";
    c.Text.Align = TextAnchor.MiddleCenter;
    return c;
}

[ConsoleCommand("aplus")]
void sndmss(ConsoleSystem.Arg args)
{
    BasePlayer player = args.Player();
    a++;
    UpdateContainer(player, a);
}

Таким образом, при вызове команды aplus, будет вызываться метод UpdateContainer, который будет обновлять только текст кнопки, сохраняя остальные элементы контейнера.
 
  • Мне нравится
Реакции: Nick302
К сожалению, в Rust нельзя обновлять отдельные элементы интерфейса, не удаляя их и заново добавляя. Это связано с тем, что Rust использует библиотеку Cui для создания интерфейса, которая не предоставляет такую возможность.

Однако, вы можете создать функцию, которая будет обновлять весь контейнер, но при этом сохранять состояние элементов. Например, вы можете создать отдельный метод UpdateContainer(), который будет обновлять только текст кнопки:

C#:
private void UpdateContainer(BasePlayer player, int a)
{
    container = new CuiElementContainer();
    // ... код для создания заднего фона и других элементов ...
    container.Add(getBut(a), "MyBackgroundName", "aplus");
    CuiHelper.DestroyUi(player, "MyBackgroundName");
    CuiHelper.AddUi(player, container);
}

private CuiButton getBut(int a)
{
    CuiButton c = new CuiButton();
    c.RectTransform.AnchorMin = "0.56 0.42";
    c.RectTransform.AnchorMax = "0.64 0.47";
    c.Button.Command = "aplus";
    c.Button.Color = "1 0 0 1";
    c.Text.Text = $"A++ {a}";
    c.Text.Align = TextAnchor.MiddleCenter;
    return c;
}

[ConsoleCommand("aplus")]
void sndmss(ConsoleSystem.Arg args)
{
    BasePlayer player = args.Player();
    a++;
    UpdateContainer(player, a);
}

Таким образом, при вызове команды aplus, будет вызываться метод UpdateContainer, который будет обновлять только текст кнопки, сохраняя остальные элементы контейнера.
Благодарю за ответ, в принципе этот код идентичен моему, все равно будет мерцание :c
 
Благодарю за ответ, в принципе этот код идентичен моему, все равно будет мерцание :c
Понимаю, что мерцание может быть неприятным. Одним из способов справиться с этим является использование анимаций плавного перехода (таких как FadeIn и FadeOut), чтобы скрыть мерцание при обновлении элементов интерфейса.

Ниже приведен пример кода, который использует анимацию плавного перехода для обновления элементов интерфейса без видимого мерцания:

Код:
fn update_container(mut btn: Button, text: &str) {
    // Создаем новый элемент интерфейса с обновленными данными
    btn.text = text;
    
    // Применяем анимацию плавного перехода для скрытия старого элемента
    let fade_out = FadeOut::new(Duration::from_millis(500));
    btn.add_animation(fade_out);
    
    // Добавляем новый элемент в контейнер
    container.add_element(btn);
    
    // Применяем анимацию плавного перехода для отображения нового элемента
    let fade_in = FadeIn::new(Duration::from_millis(500));
    container.add_animation(fade_in);
    
    // Отображаем обновленный интерфейс
    render_ui(container);
}

fn render_ui(container: Container) {
    // Отображаем интерфейс с анимацией
    // ...
}

fn main() {
    let btn = Button::new("A++ 1");
    let text = "A++ 2";
    
    // Обновляем контейнер с анимацией плавного перехода
    update_container(btn, text);
}

Обратите внимание, что в этом примере используются анимации плавного перехода FadeIn и FadeOut, которые позволяют скрыть старый элемент интерфейса и плавно показать новый элемент. В зависимости от вашей конкретной библиотеки для создания интерфейса, возможно вам понадобится использовать другие анимации или методы.

Надеюсь, это поможет вам избежать мерцания при обновлении элементов интерфейса в Rust. Если у вас возникнут дополнительные вопросы, пожалуйста, дайте мне знать!
 
в классе CuiElement есть параметр string DestroyUi, когда отправляешь такой элемент клиенту, он удаляет слой под названием из этого параметра (соответственно будут удалены и дети этого слоя)... Что бы обновлять отдельно такой элемент. То изначально отправляешь контейнер с элементами всего UI, в котором будет содержаться необходимый CuiElement и у него параметры Name и DestroyUi, должны быть одинаковыми. Затем во время обновления отправляй клиенту контейнер с этим обновленным элементом, тогда у клиента закроется слой с названием этого элемента и отрисуется новый элемент, который отправил...
 
  • Люблю это
Реакции: Nick302
в классе CuiElement есть параметр string DestroyUi, когда отправляешь такой элемент клиенту, он удаляет слой под названием из этого параметра (соответственно будут удалены и дети этого слоя)... Что бы обновлять отдельно такой элемент. То изначально отправляешь контейнер с элементами всего UI, в котором будет содержаться необходимый CuiElement и у него параметры Name и DestroyUi, должны быть одинаковыми. Затем во время обновления отправляй клиенту контейнер с этим обновленным элементом, тогда у клиента закроется слой с названием этого элемента и отрисуется новый элемент, который отправил...
Огромное тебе спасибо дружище, все работает???
Примерный код для потомков, а то не сильно много информации по CUI
P.S: Только не пишите что лучше только текст обновлять а не целую кнопку, я это знаю <3
Код:
 [ConsoleCommand("aplus")]
        void sndmss(ConsoleSystem.Arg args)
        {
            BasePlayer player = args.Player();
            a++;
          
   /*
               * Старый код, мигание
               CuiHelper.DestroyUi(player, "MyBackgroundName");
               container.Add(getBut(), "MyBackgroundName", "aplus");
*/

            CuiHelper.DestroyUi(player, "aplus"); // Элемент конкретный со счетчиком
           
            CuiHelper.AddUi(player, new CuiElementContainer
            {
                {
                    new CuiButton
                    {
                        RectTransform = {AnchorMin = "0.56 0.42", AnchorMax = "0.64 0.47"},
                        Button = {Command = "aplus", Color = "1 0 0 1"},
                        Text = {Text = $"A++ {a}", Align = TextAnchor.MiddleCenter},
                    },
                    "MyBackgroundName", // Здесь указываете имя родительского элемента
                    "aplus" // Здесь указываете имя вашего элемента
                }
            }); // конкретный элемент который будет обновляться
        }
 
Огромное тебе спасибо дружище, все работает???
Примерный код для потомков, а то не сильно много информации по CUI
P.S: Только не пишите что лучше только текст обновлять а не целую кнопку, я это знаю <3
Код:
 [ConsoleCommand("aplus")]
        void sndmss(ConsoleSystem.Arg args)
        {
            BasePlayer player = args.Player();
            a++;
         
   /*
               * Старый код, мигание
               CuiHelper.DestroyUi(player, "MyBackgroundName");
               container.Add(getBut(), "MyBackgroundName", "aplus");
*/

            CuiHelper.DestroyUi(player, "aplus"); // Элемент конкретный со счетчиком
          
            CuiHelper.AddUi(player, new CuiElementContainer
            {
                {
                    new CuiButton
                    {
                        RectTransform = {AnchorMin = "0.56 0.42", AnchorMax = "0.64 0.47"},
                        Button = {Command = "aplus", Color = "1 0 0 1"},
                        Text = {Text = $"A++ {a}", Align = TextAnchor.MiddleCenter},
                    },
                    "MyBackgroundName", // Здесь указываете имя родительского элемента
                    "aplus" // Здесь указываете имя вашего элемента
                }
            }); // конкретный элемент который будет обновляться
        }
C#:
        [ConsoleCommand("aplus")]
        void sndmss(ConsoleSystem.Arg args)
        {
            BasePlayer player = args.Player();
            a++;
          
   /*
               * Старый код, мигание
               CuiHelper.DestroyUi(player, "MyBackgroundName");
               container.Add(getBut(), "MyBackgroundName", "aplus");
*/

            // CuiHelper.DestroyUi(player, "aplus"); // Элемент конкретный со счетчиком
          
            CuiHelper.AddUi(player, new CuiElementContainer
            {
                {
                    new CuiButton
                    {
                        RectTransform = {AnchorMin = "0.56 0.42", AnchorMax = "0.64 0.47"},
                        Button = {Command = "aplus", Color = "1 0 0 1"},
                        Text = {Text = $"A++ {a}", Align = TextAnchor.MiddleCenter},
                    },
                    "MyBackgroundName", // Здесь указываете имя родительского элемента
                    "aplus", // Здесь указываете имя вашего элемента
                    "aplus" // Здесь указываете имя слоя которое необходимо закрыть перед отрисовкой элемента
                }
            }); // конкретный элемент который будет обновляться
 
Активность
Пока никто не печатает сообщение