Оглавление
Время чтения: 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
В студии AppFox можно подать заявку на программирование, создание игр или заказать разработку приложений https://appfox.ru/ и получить бесплатную консультацию по ценам и услугам.