• Существует ли уже платформа VR для windows для работы?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Да есть, например Virtual Desktop, только смысла от них пока мало, потому что разрешение vr-дисплеев не позволяет комфортно читать тексты. Подождите ещё пару лет.
    Ответ написан
    1 комментарий
  • Как сделать "хвост" за ассетом?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Для этой цели есть специальный компонент - TrailRenderer. Ещё хвосты делают с помощью ParticleSystem, но для вашего случая частицы меньше подходят.
    Ответ написан
    Комментировать
  • Как сделать так, чтобы разные ассеты падали в случайном порядке?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Создаёте список объектов, выбираете случайный с помощью Random.Range:
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Example : MonoBehaviour
    {
        public List<GameObject> prefabs = new List<GameObject>();
    
        private void Update()
        {
            Spawn();
        }
    
        private void Spawn()
        {
            var prefab = prefabs[Random.Range(0, prefabs.Count)];
            Instantiate(prefab);
        }
    }
    Ответ написан
    2 комментария
  • Как плавно сместить объект на определенное расстояние в unity3d?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Вариантов несколько, например можете использовать Vector3.Lerp:
    using UnityEngine;
    
    public class Example : MonoBehaviour
    {
        public Vector3 fromPosition = Vector3.zero;
        public Vector3 toPosition = Vector3.one;
        public float speed = 1;
    
        private float progress;
    
        private void Update()
        {
            progress += Time.deltaTime*speed;
            transform.position = Vector3.Lerp(fromPosition, toPosition, progress);
        }
    }
    Ответ написан
    6 комментариев
  • Как в Unity3d сделать так, чтобы клон одного ассета не спавнился в корне другого?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    На падающих объектах скорее всего есть коллайдеры, да? Используйте Physics.CheckSphere, если в случайно выбранной точке уже есть объект, то выкидываете её и выбираете новую. Делайте так в цикле, пока не найдёте свободное пространство, либо количество итераций не превысит какой-то порог, например сто циклов. В большинстве случаев этого будет достаточно.
    Ответ написан
    2 комментария
  • Что лучше для UE4?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Большую часть да, можно, но что-то всё равно придётся писать на плюсах. Блюпринты позволяют управлять только существующими сущностями, в игре масштаба PUBG стандартных средств точно не хватит.
    Ответ написан
    Комментировать
  • Дайте пожалуйста статью для настройки Unity под мобильную игру?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Не бывает таких статей, настройки всегда зависят от конкретного проекта. Из обязательных настроек только bundle id, без него юнити будет ругаться при сборке. Плагины для сборки под мобильники не обязательны, всё работает и без них. Под разрешением, как я понял, вы имеете в виду базовое разрешение канваса для интерфейса. Разрешение зависит от целевых устройств и типа вашей игры, может быть у вас в игре всего две кнопки, и те векторные, тогда вам нет особого смысла заморачиваться с масштабированием и разными вариантами интерфейса под разные экраны. Нету какого-то единого рецепта, нужно смотреть по ситуации.
    Ответ написан
    Комментировать
  • Как умножить текстуры в шейдере Unity?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Шейдеры для прожекторов работают точно так же, просто uv-карта рассчитывается по-другому:
    Projector/Multiply
    Shader "Projector/Multiply"
    {
        Properties
        {
            _ShadowTex("Cookie", 2D) = "gray" {}
            _FalloffTex("FallOff", 2D) = "white" {}
            // Добавляем свойство
            _MaskTex("Mask", 2D) = "white" {}
        }
        Subshader
        {
            Tags {"Queue"="Transparent"}
            Pass
            {
                ZWrite Off
                ColorMask RGB
                Blend DstColor Zero
                Offset -1, -1
    
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #pragma multi_compile_fog
                #include "UnityCG.cginc"
                
                struct v2f
                {
                    float4 uvShadow : TEXCOORD0;
                    float4 uvFalloff : TEXCOORD1;
                    UNITY_FOG_COORDS(2)
                    float4 pos : SV_POSITION;
                };
                
                float4x4 unity_Projector;
                float4x4 unity_ProjectorClip;
                
                v2f vert (float4 vertex : POSITION)
                {
                    v2f o;
                    o.pos = UnityObjectToClipPos(vertex);
                    o.uvShadow = mul(unity_Projector, vertex);
                    o.uvFalloff = mul(unity_ProjectorClip, vertex);
                    UNITY_TRANSFER_FOG(o,o.pos);
                    return o;
                }
                
                sampler2D _ShadowTex;
                sampler2D _FalloffTex;
                // Добавляем переменную, чтобы использовать текстуру внутри прохода
                sampler2D _MaskTex;
                
                fixed4 frag (v2f i) : SV_Target
                {
                    fixed4 texS = tex2Dproj(_ShadowTex, UNITY_PROJ_COORD(i.uvShadow));
                    texS.a = 1.0 - texS.a;
    
                    fixed4 texF = tex2Dproj(_FalloffTex, UNITY_PROJ_COORD(i.uvFalloff));
                    fixed4 res = lerp(fixed4(1, 1, 1, 0), texS, texF.a);
    
                    // Сэмплируем текстуру
                    fixed4 mask = tex2Dproj(_MaskTex, UNITY_PROJ_COORD(i.uvShadow));
                    // Применяем маску
                    res *= mask;
    
                    UNITY_APPLY_FOG_COLOR(i.fogCoord, res, fixed4(1, 1, 1, 1));
                    return res;
                }
                ENDCG
            }
        }
    }

    Чтобы лучше понять что из себя представляют uvShadow и uvFalloff, можете вывести их на экран во фрагментном шейдере:
    fixed4 frag (v2f i) : SV_Target
    {
        float2 uvShadow = UNITY_PROJ_COORD(i.uvShadow);
        float2 uvFalloff = UNITY_PROJ_COORD(i.uvFalloff);
        return fixed4(uvShadow, 0.0, 1.0);
        //return fixed4(uvFalloff, 0.0, 1.0);
    }
    Ответ написан
    1 комментарий
  • Unity как сделать тени?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Стандартными средствами Unity - никак. Проще всего дорисовать её на спрайте кнопки, но если рисовать не хотите, то либо ищите плагин, либо пишите шейдер.
    Ответ написан
    Комментировать
  • В каком порядке изучать математические дисциплины?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    В старших классах проходят степенные функции, тригонометрию, производные и интегралы, без этих знаний ни вектор в плоскости не повернёшь, ни кружок в шейдере не нарисуешь, так что лучше повторить. Чтобы закрепить эти знания, погуглите или возьмите в библиотеке сборник задач по математике для поступающих в вузы. В подобных книжках обычно задачи слишком сложные, на практике такие не встречаются, так что решать всё не обязательно.

    Если ещё не читали, то прочтите статью Линейная алгебра для разработчиков игр, ещё могу посоветовать этот доклад с GDC. Для лучшего понимания трёхмерной графики очень полезно научиться моделить примитивные вещи в трёхмерном редакторе, а ещё лучше попробовать процедурно сгенерировать какую-нибудь сферу или кубик.

    Кроме того, для расширения кругозора советую погулять по ссылкам википедии про вычислительную геометрию. Какие-то вещи стоит попробовать написать самому (например, алгоритм пересечения отрезков), а про какие-то достаточно просто знать - с той же триангуляцией можно месяцами возиться, для таких вещей лучше брать готовую библиотеку.
    Ответ написан
    Комментировать
  • Как не находить через тэг объекты у которых в названии "Preview Scene"?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    По всей видимости, вы находите служебные объекты редактора. Если они скрыты в иерархии, то можете проверить Object.hideFlags и отсеять те, у которых выставлен флаг HideInHierarchy.
    Ответ написан
    9 комментариев
  • Как открыть несколько проектов Unity сразу?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Все новые версии юнити по умолчанию показывают окно выбора проекта, раз у вас не так, то, возможно, сломались настройки редактора, попробуйте включить-выключить галку "Load Previous Project on Startup". Если не помогает, то можете запускать редактор с зажатой кнопкой Alt, она покажет окно выбора проекта независимо от настроек.
    Ответ написан
    Комментировать
  • Как правильно деинтегрировать json в Unity, полученный с помощью SendMessage?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Нужно разобрать json в понятный для шарпа формат. Можно сделать это с помощью встроенного JsonUtility, либо можно скачать любой из миллиона json-парсеров, и использовать его. Что-то есть на Assett Store, но многие парсеры живут на гитхабе или собственном сайте.
    Ответ написан
  • Алгоритм упаковки продуктов, при разных комбинациях?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Это называется Задача о ранце или Knapsack problem. Советую начать с википедии, чтобы понять разные подтипы этой задачи, потом можете почитать примеры кода на Rosetta Code. Ещё могу предложить код из моего тулкита, он для чуть более простой задачи, вам придётся поменять алгоритм сравнения, если захотите его использовать.
    spoiler
    /// <summary>
    /// Knapsack problem solver for items with equal value
    /// </summary>
    /// <typeparam name="T">Item identificator</typeparam>
    /// <param name="set">
    /// Set of items where key <typeparamref name="T"/> is item identificator and value is item weight</param>
    /// <param name="capacity">Maximum weight</param>
    /// <param name="knapsack">Pre-filled knapsack</param>
    /// <returns>
    /// Filled knapsack where values are number of items of type key.
    /// Tends to overload knapsack: fills remainder with one smallest item.</returns>
    /// <remarks>
    /// https://en.wikipedia.org/wiki/Knapsack_problem
    /// </remarks>
    public static Dictionary<T, int> Knapsack<T>(Dictionary<T, float> set, float capacity,
        Dictionary<T, int> knapsack = null)
    {
        var keys = new List<T>(set.Keys);
        // Sort keys by their weights in descending order
        keys.Sort((a, b) => -set[a].CompareTo(set[b]));
    
        if (knapsack == null)
        {
            knapsack = new Dictionary<T, int>();
            foreach (var key in keys)
            {
                knapsack[key] = 0;
            }
        }
        return Knapsack(set, keys, capacity, knapsack, 0);
    }
    
    private static Dictionary<T, int> Knapsack<T>(Dictionary<T, float> set, List<T> keys, float remainder,
        Dictionary<T, int> knapsack, int startIndex)
    {
        T smallestKey = keys[keys.Count - 1];
        if (remainder < set[smallestKey])
        {
            knapsack[smallestKey] = 1;
            return knapsack;
        }
        // Cycle through items and try to put them in knapsack
        for (var i = startIndex; i < keys.Count; i++)
        {
            T key = keys[i];
            float weight = set[key];
            // Larger items won't fit, smaller items will fill as much space as they can
            knapsack[key] += (int) (remainder/weight);
            remainder %= weight;
        }
        if (remainder > 0)
        {
            // Throw out largest item and try again
            for (var i = 0; i < keys.Count; i++)
            {
                T key = keys[i];
                if (knapsack[key] != 0)
                {
                    // Already tried every combination, return as is
                    if (key.Equals(smallestKey))
                    {
                        return knapsack;
                    }
                    knapsack[key]--;
                    remainder += set[key];
                    startIndex = i + 1;
                    break;
                }
            }
            knapsack = Knapsack(set, keys, remainder, knapsack, startIndex);
        }
        return knapsack;
    }
    Ответ написан
    2 комментария
  • Unity 3D NavMesh Как построить путь с изменяющейся траекторией?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Вариант первый: использовать NavMesh Link или Off Mesh Link и обновлять их динамически при движении платформы. Такой вариант подойдёт, если путь один и платформа будет притормаживать в крайних положениях, чтобы дождаться агентов. Агенты при этом должны будут постоянно обновлять свой путь.
    Вариант второй: использовать те же самые компоненты, но оставлять связи статическими и разруливать всё внутри агента. То есть просто прокидываете связь через пропасть вдоль пути платформы, а дальше агент найдёт этот путь, пойдёт по нему, увидит рейкастом дырку, остановится, потом дождётся момента пока дырка пропадёт и прыгнет или шагнёт на платформу. По той же логике он сможет и спрыгнуть с платформы.
    Ещё можно комбинировать оба варианта, но это скорее зависит от вашего геймплея, может быть вам не нужны слишком умные агенты.
    Ответ написан
    Комментировать
  • Что быстрее рендерится-спрайты или модели?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Какая целевая платформа? Абстрактно в вакууме один квад это, конечно, меньше чем сотня треугольников, но квад будет рисоваться с прозрачностью, и, может быть, у вас специфика такая, что вам овердроу от прозрачности страшнее чем дополнительные треугольники. А вообще говоря, на такие вопросы ответить только профайлер, сделайте тестовую сцену и посмотрите, гадать в таких вещах вредно. В контексте мобильников три тыщи полигонов это достаточно мало, при грамотном батчинге и не сильно жирных шейдерах оно быстро отрисуется. Может быть по результатам теста окажется, что вам и не нужно со спрайтами извращаться.
    Ответ написан
    3 комментария
  • Можно ли так использовать интерфейсы в unity?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Нормальный подход, так много где делают, просто мало кода видели, вот и кажется странным. Более того, его используют не только для атакующих, но и атакуемых, например, делают интерефейс IDamageable и при нанесении урона работают с ним, а логика нанесения повреждений скрывается в конкретном классе.
    P. S. Attack пишется с двумя t.
    Ответ написан
    4 комментария
  • Что выбрать для создания логического квеста?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Такие решения нужно принимать исходя из доступных ресурсов. Умеете хорошо рисовать - выбирайте 2D, умеете хорошо моделить - выбирайте 3D. Двадэшные спрайты сильно быстрее и дешевле в производстве, чем модели, но анимировать их может быть сложнее, тут зависит от технологии: скелетная анимация или спрайтовая. Кроме анимации технология влияет на скорость итерации, если, например, захотите поменять одежду персонажу, то со спрайтовой анимацией придется перерисовывать все атласы, со скелетной такого может и не быть, но всё зависит от используемых инструментов. С трёхмерными моделями в плане анимаций проще, при желании вообще можно найти готовые, но тридешность тянет за собой кучу других проблем: большая нагрузка на видеокарту, стилистические ограничения, возня с освещением и т. п. Если говорить про квесты, то часто идут на компромисс: героев моделят, а задники рисуют плоскими. Ещё иногда фоны моделят, но потом рендерят в текстуру и дорисовывают в фотошопе.

    Кроме того, многое зависит от ваших стилистических предпочтений, какой-то картинки проще добиться с помощью моделей, а какую-то проще нарисовать руками. При желании, конечно, можно шейдерами и постэффектами всё изменить до неузнаваемости, но не факт, что вы захотите усложнять пайплайн рендера. Для абстрактного квеста в вакууме, я бы советовал двигать в сторону двадэшной скелетной анимации, так вы быстрее всего сможете сделать прототип, а для того, чтобы разнообразить и оживить картинку, есть много трюков, посмотрите доклад от разрабов Broken Age.
    Ответ написан
    1 комментарий
  • Выбор языка для разработки концептуальных решений в сфере строительства с использованием VR?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Современные VR-приложения чаще всего делают с использованием игровых движков. Среди самых популярных движков сейчас Unity и Unreal, поддержка виртуальной реальности в них включается галочкой, что несравнимо проще, чем интегрировать SDK вручную. В Unity пишут на C#, в Unreal на C++, кроме того, в обоих движках есть средства для визуального программирования. Если сравнивать языки по сложности для новичка, то я бы советовал C#, на плюсах ногу отстрелить всё-таки сильно проще.
    Ответ написан
    2 комментария