#

Мы работаем в обычном режиме, несмотря на карантин!

Since 2008

#

Пример кода на Unity

Редакция Appfox

Редакция Appfox

Время чтения: 2 минуты

Оглавление

Пример 1

Код - это класс основного бота из мульти-аккаунтного Steam-бота. Здесь используется многопоточность которая позволяет распараллелить несколько задач.

using System;
using System.Threading;
using SteamApi;

namespace TestBot {
  /// <summary>
  /// Handler сообщений
  /// </summary>
  /// <param name="log">Уровень логгирования</param>
  /// <param name="message">Тело сообщения с Markdown разметкой</param>

  public delegate void TelegramMessageHandler(Telegram.TelegramLog log, string message);

  /// <summary>
  /// Основной Steam бот
  /// </summary>

  public class MainBot : SteamBot {
    private bool working = true;
    private Thread confirmationThread;

    /// <summary>
    /// Handler сообщений
    /// </summary>

    public TelegramMessageHandler MessageHandler;

    /// <summary>
    /// Инициализирует новый экземпляр класса MainBot
    /// </summary>

    /// <param name="dataFile">Файл с данными о боте</param>
    /// <param name="name">Имя бота<param>
    /// <param name="logging">Уровень логгирования</param>

    public MainBot(string dataFile, string name, LogOptions logging) : base(dataFile, name, logging) {
      confirmationThread = new Thread(confirmationThreadVoid);
    }

    /// <summary>
    /// Запускает поток подтверждений
    /// </summary>

    public void StartConfirm() {
      SteamApi.DoLog("Confirming through proxy");
      confirmationThread.Start();
    }

    private void confirmationThreadVoid() {
      try {
        while (working) {
          SteamApi.DoDebug("Fetching confirmations");
          var mainConf = SteamConfirm.GetConfirmations();

          foreach (var c in mainConf) {
            SteamConfirm.AcceptConfirmation(c);
          }

          SteamApi.DoDebug("Confirmation have fetched");
          Thread.Sleep(10000);
        }
      }
      catch (Exception e) {
        SteamApi.DoLog("EXCEPTION: " + e.Message);
        SteamApi.DoLog("EXCEPTION STACK TRACE: " + e.StackTrace);
        MessageHandler(Telegram.TelegramLog.Errors, string.Format("Ошибка:\n```\n{0}```", e));
        Thread.Sleep(10000);
        Environment.Exit(-1);
      }
    }

    protected override void mainThreadVoid() {
      try {
        while (working) {
          var incoming = SteamTrade.GetIncomingTradeoffers();

          foreach (var offer in incoming) {
            if (offer.ItemsTo.Count == 0 && offer.ItemsFrom.Count > 0) {
              SteamApi.DoDebug("Got new items from main bot. Accepting...");
              SteamTrade.AcceptIncomingTrade(offer.ID.ToString());
              SteamApi.DoDebug("Updating bot inventory");
            }
            else {
              SteamApi.DoDebug(string.Format("Strange tradeto satelite from: {0}. Declining...", offer.From));
              SteamTrade.DeclineIncomingTrade(offer.ID.ToString());
            }

            Thread.Sleep(10000);
          }
        }
      }        
      catch (Exception e) {
        SteamApi.DoLog("EXCEPTION: " + e.Message);
        SteamApi.DoLog("EXCEPTION STACK TRACE: " + e.StackTrace);
        MessageHandler(Telegram.TelegramLog.Errors, string.Format("Ошибка:\n```\n{0}```", e));
        Thread.Sleep(10000);
        Environment.Exit(-1);
      }
    }

    /// <summary>
    /// Остановка всех потоков бота (без ожидания завершения)
    /// </summary>

    public void Stop() {
      working = false;
    }
  }
} 

Пример 2

MyEvent и EventManager эти скрипты работают в паре друг с другом. Это собственная реализация ивентов.

PanelActivityController - демонстрирует работу MyEvent и EventManager. Скрипт принимает конкретный ивент и выполняет указанный набор действий. А конкретно включение отключение панелей.

using UnityEngine;
using System.Collections.Generic;
using System.Runtime.InteropServices;

public class EventManager {
  //UI
  public static string SHOW_ERROR_TEXT = "SHOW_ERROR_TEXT";
  public static string SET_ACTIVE_PANEL = "SET_ACTIVE_PANEL";
  public static string UPDATE_SELECTED_OBJECT_STATS = "UPDATE_SELECTED_OBJECT_STATS";

  // GAME
  public static string SHOW_UNPARRENT_WALL = "SHOW_UNPARRENT_WALL";
  public static string CHECK_PARENT_TO_CALC = "CHECK_PARENT_TO_CALC";
  public static string UPDATE_MAP_LINE = "UPDATE_MAP_LINE";
  public static string DELETE_MENU_OBJ = "DELETE_MENU_OBJ";
  public static string CLEAR_ALL_STAFF = "CLEAR_ALL_STAFF";
  public static string DELETE_OBJ = "DELETE_OBJ";
  public static string SAVE_OBJ = "SAVE_OBJ";
  public static string SAVE_OBJ_LOCAL = "SAVE_OBJ_LOCAL";

  public static string PARAM_SOURCE = "PARAM_SOURCE";
  public static string PARAM_VALUE = "PARAM_VALUE";
  public static string PARAM_ACTION = "PARAM_ACTION";

  public  class EventWrapper {
    public EventWrapper (OnEvent onEvent) {
      this.onEvent = onEvent;
    }

    public OnEvent onEvent;
    public delegate void OnEvent (MyEvent myEvent);
  }

  public static EventManager instance = new EventManager ();
  public Dictionary<string, List<EventWrapper>> listeners = new Dictionary<string, List<EventWrapper>> ();

  void Dispatch (MyEvent customEvent) {
    List<EventWrapper> tempList = new List<EventWrapper> ();
    tempList.AddRange (listeners [customEvent.type]);

    foreach (EventWrapper listener in tempList) {
      listener.onEvent (customEvent);
    }
  }

  void AddListener (string type, EventWrapper listener) {
    if (!listeners.ContainsKey (type)) {
      listeners.Add (type, new List<EventWrapper> ());
    }

    listeners [type].Add (listener);
  }

  public void DestroyAllListeners (string type) {
    if (listeners.ContainsKey (type)) {
      listeners [type].Clear ();
    }
  }

  void RemoveListener (string type, EventWrapper wrapper) {
    if (listeners.ContainsKey (type)) {
      listeners [type].Remove (wrapper);
    }
  }

  public void FireEvent (string type, object parameter) {
    if (listeners.ContainsKey (type)) {
      MyEvent event1 = new MyEvent (type, parameter);
      Dispatch (event1);
    }
  }

  public void FireEvent (string type) {
    FireEvent (type, null);
  }

  public void Listen (string type, EventWrapper handler) {
    AddListener (type, handler);
  }

  public void DestroyListener (string type, EventManager.EventWrapper wrapper) {
    if (wrapper != null) {
      RemoveListener (type, wrapper);
    }
    else {
      Debug.Log ( "Null listener for destroy type ");
    }
  }
}
using UnityEngine;
using System.Collections;

public class MyEvent {
  public string type;
  public object parameter;

  public MyEvent (string type, object parameter) {
    this.type = type;
    this.parameter = parameter;
  }

  public MyEvent (string type) {
    this.type = type;
  }
}

using UnityEngine;
using System.Collections;

[SerializeField]
public enum MenuState {
  Logo = 0,
  Enter = 1,
  Work = 2,
  Order = 3,
  Export = 4 
}

public class PanelActivityController : MonoBehaviour {
  public MenuState panel;
  protected GameObject content;
  EventManager.EventWrapper setPanelActivity;
  bool isActive = false;

  void OnEnable() {
    setPanelActivity = new EventManager.EventWrapper(delegate (MyEvent myEvent) {
      MenuState sentPanel = (MenuState)myEvent.parameter;
      UpdatePanelActivity(sentPanel);
    });

    EventManager.instance.Listen(EventManager.SET_ACTIVE_PANEL, setPanelActivity);
  }

  void OnDisable() {
    EventManager.instance.DestroyListener(EventManager.SET_ACTIVE_PANEL, setPanelActivity);
  }

  void Start() {
    content = transform.GetChild(0).gameObject;

    if (panel == MenuState.Logo) {
      content.SetActive(true); 
    }
    else {
      content.SetActive(false);
    }
  }

  void UpdatePanelActivity(MenuState sentPanel) {
    if (isActive == false) {
      if (sentPanel == panel) {
        content.SetActive(true);
        isActive = true;
      }
      else {
        content.SetActive(false);
         isActive = false;
      }
    }
    else {
      content.SetActive(false);
      isActive = false;
    }
  }
}

Небольшой UI менеджер. UI в приложении был построен на наборе окон и простом переключении между ними - https://yadi.sk/d/dCe-teU9AFtZhA

Скрипт плагинчика для работы с микрофоном. Изначально разрабатывался для работы с микрофоном на мобильных девайсах, но также подходит для работы на абсолютно любом устройстве, где есть микрофон. Суть в том, чтобы была возможность откалибровать микрофон и отлавливать событии, когда звука превышает громкость максимального откалиброванного звука, половину от этого значения - https://yadi.sk/d/7ff19RwwcgtV1Q

Командный менеджер - https://yadi.sk/d/1WcBt2sztzz9lA

Кусок кода скелетной анимации игровой сущности - https://www.dropbox.com/s/jtrntpvm6jfkx54/entity_animation.cpp?dl=0

Библиотека для сериализации/интроспекции для C/C++ - https://github.com/RostislavP/crealizer