Ответы пользователя по тегу C#
  • Как привязывается C# к Unity?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Всё описанное вами есть в официальных туториалах и Standard Assets.
    Более продвинутые туториалы есть на сайте Catlike Coding.
    Ответ написан
    Комментировать
  • Как узнать сколько будет выполняться вызванная функция?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Создаётё нулевой счётчик, после обработки каждого файла его инкрементируете и считаете отношение обработанных файлов к общему количеству. Если про количество обработанных/необработанных файлов знает только функция, то можете пробросить в неё колбэк, который будет отдавать два числа при каждом изменении состояния счётчика, а вы снаружи эти числа будете как-то выводить на экран. Либо переделайте функцию так, чтобы она принимала на вход список файлов, тогда наружу надо будет отдавать только число обработанных файлов. Либо выводите прогресс на экран в самой функции, тут уж как хотите.
    Если говорить про конкретный способ вывода прогрессбара на экран, то в редакторе можно использовать EditorUtility.DisplayProgressBar, а в рантайме Slider.
    Ответ написан
    Комментировать
  • Unity3d ошибка с переключением камер?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Вы неправильно понимаете суть классов и компонентов, внимательно почитайте документацию. GameObject это не компонент, с помощью каста в другой класс нельзя магическим образом достать из него компонент, для этого существует специальный метод GameObject.GetComponent. Кроме того, в вашем случае конструкцию с FindGameObjectWithTag можно заменить вызовом Camera.main, результат будет такой же. Это не очень хорошая практика в контексте камер, но это уж вам решать. Что касаемо второй ошибки, она случается из-за того, что в вашем старте в первой строчке вызывается исключение, что обрывает поток метода, и все последующие строчки не вызываются, поэтому camera2 остаётся null.
    Ответ написан
    Комментировать
  • Куда пропадает рабочее пространство Unity?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Так работает ортографическая камера, если сильно приблизиться к объектам в сцене, то их начнёт отрезать ближней плоскостью камеры. Если переключить камеру сцены из двадэшного режима в тридэшный, то станет понятнее. Не очень очевидное поведение, но так уж есть. Для фокусировки на объектах можете использовать горячую клавишу F, либо двойной клик по объекту.
    Ответ написан
  • Unity rpg инвентарь, реализация?

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

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Для такого случая лучше использовать DateTime и TimeSpan вместе с шаблонами форматирования:
    using System;
    using UnityEngine;
    
    public class TimerTest : MonoBehaviour
    {
        public float timer = 90;
    
        private DateTime timerEnd;
    
        private void Start()
        {
            timerEnd = DateTime.Now.AddSeconds(timer);
        }
    
        private void Update()
        {
            TimeSpan delta = timerEnd - DateTime.Now;
            Debug.Log(delta.Minutes.ToString("00") + ":" + delta.Seconds.ToString("00"));
            if (delta.TotalSeconds <= 0)
            {
                Debug.Log("The END");
            }
        }
    }

    Важно помнить, что при таком способе не будет учитываться Time.timeScale, если он вам нужен, то можете аналогичным образом вместо DateTime сохранять float со временем, но тогда минуты придётся вычислять самостоятельно. Плюсовать deltaTime в апдейте не советую. Теоретически ещё можно использовать Timer, но я слышал, что он работает не на всех платформах.
    Ответ написан
    3 комментария
  • Как добавить в массив элементы?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Либо используйте Array.Resize:
    int oldLength = words.Length;
    Array.Resize(ref words, oldLength + newWords.Length);
    for (int i = 0; i < newWords.Length; i++)
    {
        words[i + oldLength] = newWords[i];
    }

    Либо вместо массива берите List:
    foreach (var newWord in newWords)
    {
        words.Add(newWord);
    }
    // Или так
    words.AddRange(newWords);
    Ответ написан
    3 комментария
  • Почему не всегда срабатывают OnTriggerEnter(), OnTriggerStay() и OnTriggerExit()?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Подозреваю, что прежде всего проблема в огромных размерах игрового мира, ваш радар еле-еле в экран влезает, юнити на таком масштабе плохо работает. Во-вторых имеет смысл в настройках Rigidbody поменять Collision Detection на Continuous или Continuous Dynamic, но учтите, что MeshCollider с такими настройками работать не умеет, так что его придётся заменить на сборный коллайдер из боксов и капсул. На худой конец можете триггеры заменить на ручной вызов Rigidbody.SweepTestAll, возможно, результат будет лучше.
    Ответ написан
    Комментировать
  • Как прочитать AudioClip из папки streamingassets?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Первая строчка в гугле
    On a desktop computer (Mac OS or Windows) the location of the files can be obtained with the following code:
    path = Application.dataPath + "/StreamingAssets";
    On iOS, use:
    path = Application.dataPath + "/Raw";
    On Android, use:
    path = "jar:file://" + Application.dataPath + "!/assets/";
    Ответ написан
  • Как включить Particle System -- Emission?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Вам надо выключать не модуль, а саму систему частиц. Модуль нужно выключать, если вы собираетесь руками спавнить частицы с помощью ParticleSystem.Emit. В вашем случае лучше дёргать Play, Pause и Stop в нужное время.
    Ответ написан
    Комментировать
  • Как доработать скрипт, так что бы уровень звука был одинаков на всех сценах?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Читайте мануал про Audio Mixer и меняйте громкость не через AudioListener.volume , а с помощью AudioMixer.SetFloat.
    Ответ написан
    1 комментарий
  • Как правильно сделать enum с собственным классом?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Вы плохо читали документацию:
    The approved types for an enum are byte, sbyte, short, ushort, int, uint, long, or ulong.

    Нельзя такие трюки в шарпе делать. Вы можете даже перегрузить оператор каста в int внутри Class, но такой код всё равно не скомпилируется.
    Ответ написан
    1 комментарий
  • Как сделать случайную генерацию объектов по координатам заданным в массиве unity?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Простейший способ выбора точки спавна - это дёргать Random.Range до тех пор, пока не получите нужное количество противников.
    using System.Collections.Generic;
    using UnityEngine;
    
    public class Spawner : MonoBehaviour
    {
        public List<Transform> spawnPoints = new List<Transform>();
        public List<GameObject> enemyPrefabs = new List<GameObject>();
        public int amountEnemies = 20;
    
        private void Start()
        {
            SpawnEnemies();
        }
    
        public void SpawnEnemies()
        {
            for (int i = 0; i < amountEnemies; i++)
            {
                Transform spawnPoint = GetRandomSpawnPoint();
                GameObject enemy = SpawnEnemy(spawnPoint);
            }
        }
    
        private Transform GetRandomSpawnPoint()
        {
            return spawnPoints[Random.Range(0, spawnPoints.Count)];
        }
    
        private GameObject SpawnEnemy(Transform spawnPoint)
        {
            // Сюда можно дописать использование пула для врагов или более сложный алгоритм выбора противника
            var prefab = enemyPrefabs[Random.Range(0, enemyPrefabs.Count)];
            return Instantiate(prefab, spawnPoint.position, spawnPoint.rotation);
        }
    }

    Важно понимать, что рандом это рандом, а значит враги будут распределены по всем доступным точкам спавна равномерно, а это не всегда то, что требуется для геймплея. Косвенно плотностью спавна можно управлять добавлением нескольких близких точек, но лучше для этого использовать взвешенный рандом.
    public T GetRandom<T>(List<T> list, List<float> weights)
    {
        if (list == null)
        {
            throw new ArgumentNullException("list");
        }
        if (list.Count == 0)
        {
            throw new ArgumentException("Empty list");
        }
        if (weights == null)
        {
            throw new ArgumentNullException("weights");
        }
        if (weights.Count == 0)
        {
            throw new ArgumentException("Empty weights");
        }
        if (list.Count != weights.Count)
        {
            throw new ArgumentException("List sizes must be equal");
        }
    
        if (list.Count == 1)
        {
            return list[0];
        }
    
        var cumulative = new List<float>(weights);
        for (int i = 1; i < cumulative.Count; i++)
        {
            cumulative[i] += cumulative[i - 1];
        }
    
        float random = Random.Range(0, cumulative[cumulative.Count - 1]);
        int index = cumulative.FindIndex(a => a >= random);
        if (index == -1)
        {
            throw new ArgumentException("Invalid weights");
        }
        return list[index];
    }

    Даже со взвешенным рандомом легко может случиться так, что все враги заспавнятся в одном месте, поэтому лучше использовать какой-то алгоритм ротации точек спавна. Для этого можно использовать Shuffle Bag, либо можно просто выкидывать использованные точки спавна из списка.
    Ответ написан
    Комментировать
  • Как сделать подбор предметов Unity?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Несколько замечаний, во-первых, нет нужды создавать отдельный вектор для положения мышки, можно сразу передавать Input.mousePosition. Во-вторых, по умолчанию maxDistance у Physics.Raycast это float.PositiveInfinity, ваш Mathf.Infinity можно убрать. В-третьих, для проверки тэгов лучше использовать CompareTag, он работает чуть быстрее.
    using UnityEngine;
    
    public class RaycastExample : MonoBehaviour
    {
        private void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                RaycastHit hit;
                if (Physics.Raycast(ray, out hit))
                {
                    if (hit.transform.CompareTag("PickUp"))
                    {
                        Destroy(hit.transform.gameObject);
                    }
                }
            }
        }
    }

    Касаемо вашей проблемы, я бы предложил вам подключиться дебаггером и проверить, что рейкасты попадают в объект, возможно, у вас слишком маленький коллайдер и луч банально по нему не попадает. Если это так, то вам надо либо увеличить коллайдер, либо использовать Physics.SphereCast.
    Ответ написан
    Комментировать
  • Как двигать объект до определенной точки при помощи rigidbody.velocity?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Если двигать физический объект через трансформ, то можно огрести глюки симуляции и лишние пересчёты физики. Двигайте лучше через Rigidbody.position или Rigidbody.MovePosition.
    Самостоятельно физические объекты двигаются только под действием сил, в вашем случае без циклов не обойтись.
    Ответ написан
    Комментировать
  • Как открепить компонент с го через C#?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Компоненты можно удалять с помощью Object.Destroy. Перевесить на другой объект их нельзя, можно только заново создать через AddComponent.
    Ответ написан
    1 комментарий
  • Как правильно в unity назначить родительский объект после Instantiate?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Input.mousePosition возвращает координаты мышки в пикселях и зависит от разрешения экрана. В зависимости от настроек CanvasScaler эти координаты могут и не совпадать с локальными координатами канваса. Для получения правильного положения мыши используйте RectTransformUtility.ScreenPointToWorldPointInRectangle и RectTransformUtility.ScreenPointToLocalPointInRectangle. А ещё лучше не обращаться к мышке напрямую, а использовать событийную систему через IDragHandler, тогда координаты всегда будут правильные, в документации даже есть пример с перетаскиванием.
    Ответ написан
    Комментировать
  • Как поворачивать 2D объект?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Сначала через Input.GetAxis достаёте горизонтальное и вертикальное положение джойстика, получаете вектор в плоскости XY. Потом с помощью Quaternion.FromToRotation получаете вращение вокруг оси Z.
    float horizontal = Input.GetAxis("Horizontal");
    float vertical = Input.GetAxis("Vertical");
    var vector = new Vector3(horizontal, vertical , 0);
    transform.rotation = Quaternion.FromToRotation(Vector3.up, vector);
    Ответ написан
    Комментировать
  • Как передвинуть объект в Unity 3D?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Все объекты на сцене двигаются одинаково - через изменение положения трансформа. Либо используете Transform.Translate, либо меняете Transform.position/Transform.localPosition напрямую. В 2d всё работает точно так же, просто не меняйте координату z, двигайте только в плоскости XY.
    Ответ написан
    Комментировать
  • Будет ли скрипт занесённый в префаб общим для всех объектов созданного этим префабом?

    BasmanovDaniil
    @BasmanovDaniil
    Геймдизайнер-телепат
    Скрипт не будет общим, у каждого инстанцированного префаба будет свой экземпляр класса. А проблема у вас в скрипте, вы считаете одинаковое расстояние для всех объектов:
    pointDistans = GameObject.Find("point").GetComponent<Transform>();
    ...
    distans = Vector3.Distance (pointDistans.position, camer.position);

    По всей видимости, вам нужно поменять строчку в апдейте:
    distans = Vector3.Distance (transform.position, camer.position);
    Ответ написан
    Комментировать