Ответы пользователя по тегу Unity
  • Как реализовать комнату в unity?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Вам на сервере нужен пул (список объектов) комнат. Когда игрок будет создавать комнату, она добавится в список, когда будет искать, список будет перебираться. Когда игра начнётся, комната скроется, когда закончится - удалится из списка.
    Ответ написан
    Комментировать
  • Как загрузить изображение из приложения на телефон?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Определитесь с форматом изображения для сохранения. Обычно используют формат *.png, но и для других есть готовые решения. В качестве папки для сохранения можете использовать persistentDataPath или выбрать что-то своё. По итогу получится:
    // imageTitle - имя файла, например, time stamp
    string pathToFile = Application.persistentDataPath + "/" + imageTitle + ".png";

    Далее выберите изображение, которое вам нужно, представив его как тип Texture2D (напишите, если вам нужно что-то другое). И используйте метод типа:
    using System.IO;
    
    // ...
    
    public bool SavePNG(Texture2D texture, string pathToFile) {
    	if (!File.Exists(pathToFile)) {
    		byte[] bytes = texture.EncodeToPNG();
    		File.WriteAllBytes(pathToFile, bytes);
    		return true;
    	}
    	return false;
    }

    Если же потом прямо из приложения нужно прочитать внешнюю картинку, то:
    public static Texture2D LoadPNG(string pathToFile) {
    	Texture2D texture = null;
    	if (File.Exists(pathToFile)) {
    		byte[] fileData = File.ReadAllBytes(pathToFile);
    		texture = new Texture2D(2, 2);
    		texture.LoadImage(fileData);
    	}
    	return texture;
    }
    Ответ написан
  • Как переместить курсор мыши по середине экрана?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Задачу можно решить минимум тремя способами. Какой способ использовать - выбирайте сами.

    Способ 1
    В классе Cursor наличествует свойство lockState, определяющее поведение и видимость курсора. Сохранив в него значение CursorLockMode.Locked, вы переместите курсор в центр ОКНА ИГРЫ и скроете. Затем туда нужно сохранить значение Cursor.lockState = CursorLockMode.None, что разблокирует курсор и сделает видимым. Есть только одна проблема - эта операция работает не мгновенно, потому применить их последовательно не получится. Выглядеть код будет как-то так

    using UnityEngine;
    
    public class MouseCenteringExample : MonoBehaviour {
    
    	private void Start() {
    		Cursor.lockState = CursorLockMode.Locked;
    		Invoke("UnlockCursor", 0.05f);
    	}
    
    	private void UnlockCursor() => Cursor.lockState = CursorLockMode.None;	
    
    }


    Способ 2
    Если вы используете New Input System, то вам доступна опция InputState.Change, которую, в контексте вашей задачи, можно использовать так:

    using UnityEngine;
    
    public class MouseCenteringExample : MonoBehaviour {
    
    	private void Start() {
    		var center = Screen.safeArea.center;
    		Mouse.current.WarpCursorPosition(center);
    		InputState.Change(Mouse.current.position, center);
    	}
    
    }


    Способ 3
    Можно воспользоваться поддержкой нативных библиотек ОС. Правда, тут придётся подключить платформозависимую компиляцию. Например, для Windows:

    using System.Runtime.InteropServices;
    using UnityEngine;
    
    public class MouseCenteringExample : MonoBehaviour {
    
    #if UNITY_STANDALONE_WIN
    
    	[DllImport("user32.dll")]
    	static extern bool SetCursorPos(int X, int Y);
    
    	private void Start() {
    		var center = Screen.safeArea.center;
    		SetCursorPos((int)center.x, (int)center.y);
    	}
    
    #endif
    
    }
    Ответ написан
    2 комментария
  • Можно ли защитить Unity-игру от вскрытия ассетов через всякие assetRipper и тд?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Нет совершенной защиты. Величина защиты кореллирует лишь с тем, сколько сил и ресурсов нужно условному злоумышленнику (или группе), чтобы произвести взлом. То, что вы можете сделать - идентифицировать критические точки своего приложения, найти векторы атаки и подумать, что с каждой из них можно сделать (и будет ли это целесообразно?).

    Если же вас беспокоит сохранность ресурсов, то просто забейте. Если ваш звук проигрывается - его можно записать. Если ваша картинка показывается, её можно заскринить. Заметьте, для этого даже взламывать не нужно - приложение само отображает эти ресурсы.

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

    Если же вам нужна рекомендация, которая сделает ваши приложения безопасней - никогда не храните в PlayerPrefs чувствительные данные.
    Ответ написан
    1 комментарий
  • Из-за чего ошибка при сохранении в unity эффектов?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Вам нужно установить URP или UDRP. Для этого зайдите в Package Manager, выберите Unity Registry и один из вышеперечисленных.
    Если они у вас уже есть, перейдите в меню Edit/Project Settings, слева раздел Graphics. В самом верху будет поле "Scriptable Render Pipeline Settings". Там нужно указать ассет пайплайна, который вы используете.
    Ответ написан
  • Как использовать JWT в Unity?

    @Ezekiel4 Автор вопроса
    Охотник на пиратов и сборщик монолитов
    Задал тот же вопрос ещё в паре мест, посоветовали установить Postman и полазить по внутренностям сайта через F12.
    Как оказалось, токен надо отправить в заголовок, а перед самим токеном поставить "JWT ". Надеюсь, это кому-то поможет.
    Ответ написан
    Комментировать
  • Что не так с Input Field-TMP в Unity?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    TextMeshProUGUI и есть текст, это не поле ввода. Поле ввода - это TMP_InputField. Попробуйте:

    using TMPro;
    using UnityEditor;
    using UnityEngine;
    
    public class Calc : MonoBehaviour {
    
    	[SerializeField] private TMP_InputField m_inputField;
    	[SerializeField] private TextMeshProUGUI m_text;
    
    	public void OnCalculate() {
            ExpressionEvaluator.Evaluate(m_inputField.text, out int result);
            m_text.text = result.ToString();
    	}
    }
    Ответ написан
    1 комментарий
  • Как избежать зависания во время выполнения огромного цикла for?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Так или иначе, вам придётся делать задачу в фоне. Если одна корутина работает долго, разбейте задачу на несколько корутин, каждой делегируйте свою часть. Если принципиально важно всё делать в один поток, делайте работу до вызова результата и сохраните в кэш, после просто показав результат.

    Если данные варианты вам не подходят и вы хотите обойтись прогрессбаром, то разбейте задачу на шаги, в вашем случае шаги итерации, и после завершения каждого добавляйте +1/к-во шагов к величине прогресса, просто вызывая это в конце блока цикла.
    Ответ написан
    Комментировать
  • Как сделать физическое перемещение персонажа по локальным осям?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Если хотите взаимодействовать в движении с коллайдерами, то про перемещения через transform можете забыть, используйте rigidbody или character controller, смотря что больше подходит.
    По поводу осей. Глобальные оси вызываются через Vector3, например Vector3.up - это вектор (0;1;0). В случае Vector2 всё тоже самое, только без z.
    Оси же самого объекта вызываются через его transform: та же ось вперёд - transform.forward в стандартном 3д или transform.up в стандартном 2д.

    Движение же будет выглядеть как-то так:
    // z is vertical axis (3d; y for 2d), x is horizontal axis
    rigidBody.velocity = transform.forward * z + transform.right * x;
    Ответ написан
    Комментировать
  • Unity 2d. У меня возникает следующая проблема. Можете, пожалуйста, объяснить, что не так?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Кратко: у вас дубликат класса, переименуйте этот или найдите другой класс с таким же именем.

    Детально: есть такая штука, namespace. Грубо говоря, это каталог всех классов, которые к нему принадлежат. Вы namespace явно не задаёте, поэтому этот (а возможно и другие) класс лежат в так называемом global namespace. Чтобы всё правильно работало, в рамках одного пространства имён каждый класс должен иметь уникальное название. Ошибка говорит о том, что у вас уже есть такой класс.
    Если для вас принципиально важно иметь два класса с одинаковым названием, один из их переместите в другое пространство имён:

    public namespace MyNamespace {
    
        public class MyClass {
            //code
        }
    }


    Чтобы потом этот класс использовать в другом коде, укажите директиву:

    using MyNamespace;
    Ответ написан
    1 комментарий
  • Как сделать управление в Unity персонажем (ошибка в коде)?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Добрый вечер. Замените

    Player.transform.position += Player.transform.forward * speed * Time.deltaTime;

    На
    transform.position += transform.forward * speed * Time.deltaTime;

    И поменяйте значение скорости, хотя бы на

    public float speed = 50;
    Ответ написан
    2 комментария
  • Как создать сенсорную кнопку Escape в Юнити?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Вынесите реализацию паузы в отдельный public метод. Затем откройте свой UI Button и прокрутите в инспекторе вниз, пока не увидите поле On Click, чуть ниже будет кнопка +, жмите. Появится такая схема:
    625d3da8287f0344210173.png
    В левое нижнее поле перетащите объект, на котором висит скрипт с паузой. Затем в выпадающем списке справа сверху выберите свой класс и метод паузы.

    Вы просили код, выглядеть это будет так. До:
    private void Update() {
    	if (Input.GetKeyDown(KeyCode.Escape)) {
    		// your code
    	}
    }

    После:
    private void Update() {
    	if (Input.GetKeyDown(KeyCode.Escape))
    		OnPauseStart();
    }
    
    public void OnPauseStart() {
    	// your code
    }


    PS. Если хотите, можете попробовать повесить функцию на кнопку back
    private void Update() {
        if (Application.platform == RuntimePlatform.Android) {
            if (Input.GetKeyDown(KeyCode.Escape)) {
    			// your code
            }
        }
    }
    Ответ написан
    1 комментарий
  • Как моментально скинуть значения rotation к нулям?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Попробуйте
    transform.eulerAngles = new Vector3(x, y, z);
    Ответ написан
  • Если скачать бесплатно платный ассет, то как об этом могут узнать?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    От более лёгкого, не требующего специальных знаний или навыков, до более сложного:
    * текстуры
    * анимации
    * модельки, рельеф
    * графические интерфейсы, диалоговые окна
    * звуки, музыка
    * внутриигровые процессы, механики
    * частицы
    * шейдеры
    * оставленные неиспользуемые ресурсы
    * строение проекта и именование ресурсов
    * идентичность кода или его структуры/логики при обфускации

    В любом случае, всегда должно быть заинтересованное лицо, которое а) найдёт за что зацепиться, б) не поленится что-то с этой инфой сделать. Если речь идёт о бесплатном проекте, то всем пофиг. Если о платном, то тогда вопрос, насколько ваш продукт с ним конкурирует и насколько оригинал беспокоится об авторских правах (привет Nintendo).
    Ответ написан
  • Как происходит передача хода от игрока к игроку в компьютерной настольной игре?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Делается это двумя шагами:

    1. Данные - некий указатель на то, чей сейчас ход. Можно сделать, например, булевой переменной (прим. крестики-нолики : ход крестика false, нолика true), числом (прим. ммо игра: id игрока), или перечислением (прим. варкрафт: RedPlayer, BluePlayer, TealPlayer, etc). Можно и другими (символ, строка-имя, IP или что-то ещё).

    2. Условие - каждый ход игра проверяет, какой игрок ходит.
    Как это работает - каждый игрок может ходить, но игра ходом это не считает (ничего не меняется). Например, просто тапы по экрану, на которые игра не будет реагировать, если этот игрок не соответствует игроку, чей сейчас ход.

    Представьте шахматы. Если текущий игрок белый, то чёрный, конечно, может пользоваться мышкой/тачскрином, но ничего происходить не будет. И напротив, аналогичные действия белого оппонента игра будет принимать.
    Ответ написан
    Комментировать
  • Почему не работает проверка на столкновение объектов?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Чек-лист, что стоит проверить:
    1. Висит ли подходящий тег на объекте?
    2. Есть ли на объекте коллайдер?
    3. Включена ли галочка isTrigger хотя бы на одном из двух коллайдеров? (т.к. OnTriggerEnter2D)
    4. Находятся ли коллайдеры в одной плоскости (обычно, Z)?
    5. Висит ли скрипт, фрагмент из которого указан в коде выше, на объекте, который ставится?
    6. Не хранится ли в ссылке TowerPistol null?
    7. Является ли ссылка (TowerPistol) корректной ссылкой на нужный объект?

    Если на объекте висит Rigidbody, можете попробовать поменять Collision Detection на Interpolate.

    Если всё проверено, а проблема осталась, попробуйте изменить метод OnTriggerEnter2D на OnTriggerStay2D.
    Ответ написан
    Комментировать
  • Как ровно выставить пиксельные плитки в Unity?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Меню Edit -> Grid and Snap Settings.
    World Snap - это глобальная сетка, Increment Snap - это виртуальная сетка, по которой вы расставляете объект. Поставьте значение шага (Move x-y-z) соответствующие размеру вашего объекта. Выделите объект и нажмите "All axes" в том же окне. После чего включите инструмент Move Tool (панель сверху) и с зажатой клавишей Ctrl попробуйте подвигать ваш объект за стрелки.

    Если же речь идёт не о паре десятков, а о сотнях объектов, то лучше изучите тайлмапы, из ответа LittleBob
    Ответ написан
  • Как прикрепить в Unity 2d коллайдер, к движущемуся объекту?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Повесь коллайдер на само лезвие или сделай дочерний пустой объект с коллайдером нужных размеров. Когда родительский объект (топор) будет двигаться, он автоматически будет подтягивать все дочерние.
    Ответ написан
    Комментировать
  • Не работает функция Flip, что делать?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Сделайте один рут объект, на котором будет весь основной фарш (движение + твёрдое тело + коллайдеры). Объекты с графикой сделайте дочерними.
    При повороте персонажа делайте не флип, а вращение по оси Y рут объекта. Как-то так (x - это ввод с оси "Horizontal"):
    if (x != 0)
        transform.eulerAngles = new Vector3(transform.eulerAngles.x, x > 0 ? 0 : 180, transform.eulerAngles.z);
    // если оси X/Z без вращения, то можно так:
    if (x != 0)
        transform.eulerAngles = new Vector3(0, x > 0 ? 0 : 180, 0);
    Ответ написан
    Комментировать
  • Как определить расстояние между несколькими объектами в 2d?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Ваши монстры идут по вейпоинтам в определённом порядке. Это значит, что у каждого монстра должно быть состояние, которое говорит о том, куда сейчас монстр стремится. Если предположить, что вейпоинты у вас в массиве, то состояние - это индекс следующего вейпоинта. В таком случае вы можете брать всех монстров с максимальным индексом, и, пользуясь Vector3.Distance, определять отдалённость от целевого вейпоинта всех проверяемых монстров. Затем выбрать наименьшее из них.
    Ответ написан
    Комментировать