Unity3D UNET Урок 1 Подготавливаем проект

Первый урок(не считая вводный конечно) посвящен базовой настройке проекта. Все начинается с того, что нужно добавить стандартный ассет Characters, из которого возьмем в дальнейшем FpsController. Но ближе к телу сети…

Общая концепция UNET такая — есть сервер, а есть клиенты.


Сервером может быть как выделенная машина, так и обычный игрок. Во втором случае его называет хостом(host) — т.е. клиент+сервер.

Остальные игроки присоединяются к серверу и передают все данные через него. Это главное отличие от старой сети, где игроки обменивались данными напрямую.

Читать дальше →

Unity3D UNet Урок 0 Введение

Всем привет! Наконец-то дошли руки записать уроки по UNET. Вообще, сеть хорошая, но пока сырая. Однако знакомиться нужно уже сейчас. Дальше будет много вкусных плюшек от юнитястов, так что нужно подготовиться и заучить азы сети.

Коротко в уроке:
  • Где найти материал
  • Какая версия Unity3D подходит для UNET

Первый урок тут

Extensions методы для Photon Cloud и Unity3D

Одно из самых популярных свойств в PhotonCloud является CustomProperties для игроков и комнат.

Обычно их используют вот так:

        PhotonNetwork.player.SetCustomProperties(new Hashtable
        {
            {"points", 0},
            {"name", Storage.PlayerName},
        });


Здесь есть много минусов:
1. Всегда нужна задавать новое имя для синхронизации(+1 переменная)
2. Дублировать код для получения и записи значения
3. Приведение типов…

Воспользуемся методами расширений. Пишем enum и сами методы:

//список свойств для каждого игрока, которые нужно синхронизировать по сети
public enum PlayerProperty
{
    Kills,
    Dies,
    Name,
    Skin,
    WeaponLeft,
}

//методы расширения для PhotonPlayer
public static class PhotonPlayerExtensions
{
    //установить значение
    public static void Set<T>(this PhotonPlayer player, PlayerProperty prop, T val)
    {
        var props = new Hashtable();
        props["p" + (int)prop] = val;
        player.SetCustomProperties(props);
    }
    //получить значение
    public static T Get<T>(this PhotonPlayer player, PlayerProperty prop)
    {
        object val;
        if (player.customProperties.TryGetValue("p" + (int)prop, out val))
        {
            return (T)val;
        }

        return default(T);
    }
}


Очень просто расширять, никогда не будет дублирования ключа и удобно. Кому надоедает делать приведение типов, можете добавить пару тех же методов установки и получения значения.

Пример где-то в коде игры:


var kills = photonView.owner.Get<int>(PlayerProperty.Kills);
kills++;
photonView.owner.Set(PlayerProperty.Kills, kills);


Я привел пример для игроков, но таким же образом можно добавить методы и для комнат.

Удачи!

Размер admob bannera в Unity3D

Привет. Пока не забыл что и как делал, поделюсь хаком:)

В адмобе есть баннер 320х50 dp. Нам нужно отобразить его вверху экрана, а под ним кнопку. Если баннера нет, то сдвигаем кнопку вверх.

Вроде все просто, так? Знаем, осталось перевести по формуле в пиксели:

var pixelsHeight = 50 * Screen.dpi / 160f;

Но хер там! Есть еще кое что, о чем не написано(или я плохо искал). Если запустить этот код на смартфоне 480 х 800 с dpi 160, то ничего работать не будет:) Потому что теперь баннер стал 480x75dp. На планшетах всегда берется баннер 320х50 dp. Потратив на танцы с бубном не один час времени, делюсь решением проблемы:

Где то в и-нетах ходит вот такой классик:

using System;
using UnityEngine;
using System.Collections;

public static class DisplayUtils
{
    private const float DEFAULT_DPI = 160.0f;

    private const float MIN_TABLET_INCHES = 6.8f;

    public static int DpToPixel(this int dp)
    {
        // Convert the dps to pixels
        return (int)(dp * GetScale() + 0.5f);
    }

    public static int DpToPixel(this float dp)
    {
        // Convert the dps to pixels
        return (int)(dp * GetScale() + 0.5f);
    }

    public static int PixelToDp(this int px)
    {
        // Convert the pxs to dps
        return (int)(px / GetScale() - 0.5f);
    }

    public static int PixelToDp(this float px)
    {
        // Convert the pxs to dps
        return (int)(px / GetScale() - 0.5f);
    }

    private static float GetDPI()
    {
        return Screen.dpi == 0 ? DEFAULT_DPI : Screen.dpi;
    }

    private static float GetScale()
    {
        return GetDPI() / DEFAULT_DPI;
    }

    public static bool DeviceIsTablet()
    {
        float inches = (float)Math.Sqrt(Math.Pow(Screen.width / GetDPI(), 2) + Math.Pow(Screen.height / GetDPI(), 2));
        return inches > MIN_TABLET_INCHES;
    }
}


Наша логика:

    private float GetHeight(float pixelsScaler)
    {
        float w = Mathf.Min(Screen.height, Screen.width);//screen width

        float halfBannerSize = new Vector2(160,25);// --> 320x50 / 2

        float scaledHeight = Mathf.Floor(w / halfBannerSize.x) * halfBannerSize .y; //узнаем во сколько раз заскейлился баннер по горизонтали, т.к. скейлиться он кратно 160.

        //tablet
        if (DisplayUtils.DeviceIsTablet())
            return pixelsScaler * (halfBannerSize .y * 2f).DpToPixel();

        //phone
        return pixelsScaler * scaledHeight;
    }


pixelsScaler — это множитель. Я использовал ngui и у меня была жестко задана высота в 1136 пикселей. Так что я передавал в функцию значение:

    float h = Mathf.Max(Screen.height, Screen.width);
    float adj = 1136f / h;//1136 - UI высота

    var height = GetHeight(adj);//это уже UI координаты

    


Странно то, как скейлится баннер и что приходится делить пиксели на dp(когда считаем scaledHeight). Может кто-то нашел вариант лучше? или хотя бы объяснит почему так оно работает?)

Подробнее о сетевом протоколе передачи данных в Unity3D

Примечание от автора:
Вольный перевод статьи с блога

О том, что такое UNET можно прочесть здесь. В этой статье рассмотрим протокол передачи данных в UNET.

Когда мы начали проектировать новую сетевую библиотеку для Unity, мы хотели понять, какой она должна быть в идеале. Мы разделили наших пользователей на две группы:

1. Пользователи, которые хотят получить инструмент для настройки сети, требующий минимум усилий и затрат для настройки (в идеале, без усилий вообще).

2. Пользователи, которые работают с сетевыми играми и желающие иметь мощный и гибкий инструмент.

Основываясь на этих группах, мы разделили нашу сетевую библиотеку на две различные части: HLAPI (high-level(высокоуровневый) API) и LLAPI (low-level(низкоуровневый) API).

Читать дальше →

NGUI Next-Gen UI 3.8.0



В данной теме буду публиковать обновления для плагина NGUI для Unity3. Если хотите получать сообщение об обновлении, подписывайтесь на тему.

Ссылка на assetstore — перейти

NGUI 3.8.0: скачать

Если вам понравился плагин, рекомендую купить его!

Анонс UNET – новая технология для сетевого взаимодействия от Unity

Unity Networking
Примечание от автора:
Это вольный перевод статьи с блога Unity от 12 мая 2014 года.

Несколько недель назад на конференции Unite Asia мы рассказали, что работаем над новым инструментом и сервисами для создания сетевых игр для Unity разработчиков. Рабочее название проекта — UNET, что означает Unity Networking. Мы стремимся к демократизации сетевых игр и хотим дать всем разработчикам возможность создавать сетевые игры любого типа и любой сложности.

Члены нашей команды по разработке сети работали над такими проектами, как Ultima Online, Lord of the Rings Online, Dungeons and Dragons Online, Marvel Heroes, Need for Speed Online и World of Warcraft до того, как присоединиться к команде Unity.

Читать дальше →

Arena: The Choice (Global Game Jam 2015)



Недавно проходил Global Game Jam и наша команда сделала сетевую игру. Страница проекта globalgamejam.org/2015/games/arena-choice

Использовали Unity3D и Photon Cloud! Исходный код открыт, пользуйтесь наздоровье!

Исходный код: bitbucket.org/asosnovskiy/arenathechoice

ЗЫ Если долго весит надпись Connecting… значит нет второго игрока. Запустите еще одну вкладку с игрой. К сожалению бота не успели сделать:(

Создание онлайн игры на Photon Cloud и Unity3D - 2 часть



Всем привет! Прошло достаточно времени с момента записи первой части. И в данном видео хотел бы поделиться последними обновлениями + вы узнаете о новых компонентах PhotonAnimatorView, PhotonTransformView.

r0.02:
UPDATED: фотон клауд обновлен до 1.50.3
UPDATED: улучшена производительность
NEW: добавлены боты!
NEW: добавлены анимации для ботов, мобов и игроков
FIX: проход в замке закрыт)
FIX: теперь мобы поворачиваются

Ссылка на код: bitbucket.org/asosnovskiy/lumberjacksonline
Ссылка на игру: devby.ru/lo
VK: vk.com/lumberjacksonline

Крупное обновление Photon Cloud 1.50


Не так давно компания exitgames выпустила очередную версию своего продукта — Photon Cloud 1.50. В этой обновлении содержится ряд новых вещей, о которых я хочу рассказать вам. В дальнейшем будут уроки по их использованию.

Список изменений:

Обновлено: Минимальная версия юнити Unity 4.3.4. Связано с поддержкой 2D и Mecanim.

Добавлено: Поддержка Mecanim! Новый компонент «PhotonAnimatorView» который умеет синхронизировать состояния аниматора.

Добавлено: PhotonTransformView, PhotonRigidbodyView, PhotonRigidbody2DView. Каждый из этих компонентов имеет ряд настроек для сглаживания передвижения. Реализация открыта и можно смело изменять:)

Добавлено: Новые демо: Mecanim, RpgMovement и 2D Jump and Run.

Добавлено: Новая возможность: Ownership Transfer(передача прав владения(знаю, криво звучит, но смысл именно в этом:))).

Добавлено: PhotonView.RequestOwnership() и .TransferOwnership(). Для каждого PhotonView вы можете указать, может ли этим объектом управлять только создатель или можно менять владельца объекта. Устанавливается опция с помощью поля OwnershipOption в окне инспектора.

Добавлено: Интерфейсы IPunObservable и IPunCallbacks для более удобной реализации фотоновских событий(наконец-то!).

Добавлено: Класс Photon.PunBehaviour который реализует интерфейс IPunCallbacks.

Изменено: Компонент PhotonView теперь содержит список объектов для сетевых операций. Можно, к примеру, разделить сетевую логику на несколько скриптов и добавить их в один список.

Полный список на английском — тут

Сейчас вышло еще два обновления(1.50.1 и 1.50.2). Они несут в себе фиксы и несколько незначительных изменений + в версии 1.50.2 добавлена возможность посылать зашифрованный RPC(PhotonView.RpcSecure()).

В скором времени постараюсь записать уроки по новым возможностям. Следите за новостями!