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

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Вы можете вручную модифицировать текстуру. Зная X/Y пикселя, вы можете вызвать SetPixel (https://docs.unity3d.com/ScriptReference/Texture2D...) и указать ему нужный цвет. Делая это цикле в корутине, вы можете сделать эффект плавным.
    Ответ написан
    Комментировать
  • Как реализовать автоматическую самонаводящуюся стрельбу в unity 3d?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Вам нужна точка выстрела и позиция цели. Далее вам нужно получить направление к цели, а значит из координат игрока вычтите координаты прицела. Чтобы скорость была удобной и контролируемой, нормализуйте получившийся вектор, после чего умножьте на скорость. Если вы хотите стрелять по параболе вверх, то придётся высчитать {y} угол выстрела. Дальше вам осталось добавить снаряду Rigidbody и либо тащить его в FixedUpdate с помощью velocity, либо дать пинок через AddForce.

    Если на снаряде будет коллайдер, то вы сможете регистрировать попадания коллайдерами.
    Ответ написан
    Комментировать
  • Как создать текстуру и поместить ее на объект в unity2d?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Текстура представлена классом Texture2D. Для начала вы создаёте экземпляр класса, указывая его целочисленные высоту и ширину. Затем используйте метод SetPixel(x, y, color), чтобы перекрасить пиксель в нужный цвет. В конце вызываете Apply, чтобы применить. Например, вот так можно создать белый круг:

    using UnityEngine;
    
    public class DynamicCircle : MonoBehaviour {
    
    	public SpriteRenderer spriteRenderer;
    	[Min(1)] public int textureWidth = 100;
    	[Min(1)] public int textureHeight = 100;
    	public Color defaultColor = Color.white;
    
    	private Texture2D _circleTexture;
    
    	private void Start() {
    		CreateCircleTexture();
    	}
    
    	private void CreateCircleTexture() {
    		_circleTexture = new Texture2D(textureWidth, textureHeight);
    
    		var center = new Vector2(textureWidth / 2, textureHeight / 2);
    		var radius = textureWidth / 2;
    
    		for (int y = 0; y < _circleTexture.height; y++) {
    			for (int x = 0; x < _circleTexture.width; x++) {
    				float distanceToCenter = Vector2.Distance(new Vector2(x, y), center);
    
    				if (distanceToCenter <= radius) {
    					_circleTexture.SetPixel(x, y, defaultColor);
    				} else {
    					_circleTexture.SetPixel(x, y, Color.clear);
    				}
    			}
    		}
    
    		_circleTexture.Apply();
    
    		spriteRenderer.sprite = Sprite.Create(_circleTexture, new Rect(0.0f, 0.0f, textureWidth, textureHeight), new Vector2(0.5f, 0.5f), 100.0f);
    	}
    }
    Ответ написан
    Комментировать
  • Что добавить в код, чтобы музыка воспроизводилась согласно требованиям?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Вы можете использовать таймер, который будет отсчитывать время с последнего "быстрого" клика. Если это время превышает определенный порог, музыка останавливается. Проверку можно организовать, например, в Update.
    Ответ написан
    1 комментарий
  • Как оптимизировать события с большим количеством вещей?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    То, о чём вы говорите - не столько оптимизация игры, сколько рефакторинг проекта. Для начала можете попробовать обобщить логику насколько это возможно, используя ООП. Например, если у вас есть помидор, который можно взять и кнопка, на которую можно нажать, то вам достаточно всего одного скрипта с рейкастом, 'Interactor', который будет по рейкасту искать 'Interactable' цель. Но на самом деле целью будет Tomato или Button, которые наследуют Interactable и его базовые методы, например, Interact(), который будет вообще по-разному реализован, но запускаться будет одинаково. А если вы захотите добавить возможность садиться в автомобиль, то сделаете всё через тот же скрипт.

    В процессе вы также можете вооружиться паттернами, например, SOLID, и строить проект наперёд так, чтобы в будущем было легче добавлять новый функционал и он не ломал старый.
    Ответ написан
    Комментировать
  • Как обратится к объектам на карте?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Если у вас всё движение завязано на вызовы Update/FixedUpdate/LateUpdate, то вы можете остановить всю игру (меню будет кликабельно), просто написав:

    Time.timeScale = 0;

    Только потом не забудьте вернуть обратно на 1 при рестарте.
    Ответ написан
  • Как исправить ошибку nullreferenceexception: object reference not set to an instance of an object?

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

    Сама же ошибка от того, что скрипту не удаётся найти самому ссылку на Rigidbody2D объекта вот в этой строке:
    if (_rigidbody.velocity.y >= 0) // вот тут, '_rigidbody'
                {
                    gameObject.GetComponent<SpriteRenderer>().sprite = _raisingSprite;
                }
                else
                {
                    gameObject.GetComponent<SpriteRenderer>().sprite = _fallSprite;
                }


    А ну и ПС. между gameObject.GetComponent и GetComponent нет разницы - это одно и то же, просто во втором случае gameObject, можно сказать, вызывается неявно.
    Ответ написан
    Комментировать
  • Как сделать перетаскивание объектов в юнити 3д?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Первое - вам нужно получить ссылку на объект, который хотите двигать. Самый простой способ - кинуть рейкаст из камеры, получить объект и проверить его по тегу. Можно запариться с автоматическим поиском.. типа игра будет автоматически выделять ближайший объект и просто нажимая на кнопку вы взаимодействуете именно с ним.
    Тут нет правильного или не правильного способа, это разный геймплей, просто сделайте так как в вашей игре будет по вашему мнению лучше.

    Дальше вещь нужно перетащить. Учитывая платформу и условия, скорее всего это будет происходить путём вращения и движения самого персонажа, а объект будет просто привязан к игроку с сохранением относительного положения и поворота.. а это словно намекает на то, чтобы взять и на период переноски назначить transform.parent свойству объекта transform игрока, который вы вращаете.
    Ответ написан
    Комментировать
  • Почему не переключаются сцены в Unity?

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

    Если вы используете асинхронную загрузку, убедитесь, что вы правильно обрабатываете завершение загрузки сцены и не блокируете основной поток. И вообще проверьте на всякий случай, не слетели ли настройки сцен в Build Settings.

    Чтобы не тратить кучу времени, попробуйте также создать просто пустую сцену, и вызвать переход на неё на целевом устройстве. Если он перейдёт, значит вопрос именно с настройкой конечной сцены.

    Можно ещё проверить логи через ADB/AndroidStudio+Logcat. Без логов реально сложно сказать точнее что там не так, но с озвученного ранее уже можно начать проверку.
    Ответ написан
    Комментировать
  • При запуске вылетает игра Unity Android. В движке всё хорошо. Что делать?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Проверить можно через логи. Экспортируйте проект в Android Studio и запустите на встроенном эмуляторе свою игру. Там есть вкладка (окно) Logcat.
    Ответ написан
    Комментировать
  • Из-за чего ломается скрипт?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Ошибка в использовании пустой ссылки:
    // вместо
    public static List<Vector2> colliderPositions;
    
    // напишите
    public static List<Vector2> colliderPositions = new List<Vector2>();


    Это не связано с вашим вопросом, но есть ещё одна ошибка. Перед тем как проверять "с чем луч столкнулся", стоит проверить, а столкнулся ли он вообще хоть с чем-то.
    if (hitInfo.collider == null) {
    	// то же как в блоке else
    } else if (hitInfo.collider.CompareTag("Mirror")) {
    // ... ну и так далее
    Ответ написан
    Комментировать
  • Почему значение статической переменной не меняется?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Если источник имеет коллайдер, результатом вы всегда будете получать источник. Только поэтому у вас не выпала NullPointerException. Метод Physics2D.Raycast всегда возвращает объект, но его поле collider может быть пустым (null), если луч ушёл в пустоту, тогда попытка вызвать метод collider.CompareTag вообще провалится.
    Если не хотите сильно заморачиваться, просто создайте слой, например, Player и повесьте его на игрока. Таким образом вы заодно избавитесь от необходимости проверять тег.
    https://docs.unity3d.com/ScriptReference/Physics2D...
    Как вы можете увидеть по ссылке выше, метод имеет перегрузку:
    // поле класса
    public LayerMask playerLayer;
    // метод из примера
    RaycastHit2D hitInfo = Physics2D.Raycast(ray2D.origin, ray2D.direction, 10, playerLayer);
    Ответ написан
    Комментировать
  • Как реализовать множественную фильтрацию OfType c LINQ?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Обратите внимание на метод Concat(). С его помощью можно красиво объединять результаты фильтрации.
    var methods = assembly
        .GetTypes()
        .SelectMany(t => t.GetMethods())
        .Where(m => m.GetCustomAttributes().OfType<UpdateHandleAttribute>()
            .Any(v => (v.GetType().GetProperty("Data").GetValue(v).ToString() == data || 
                v.GetType().GetProperty("Data").GetValue(v).ToString() == "*") 
                && v.GetType().GetProperty("State").GetValue(v).ToString() == state.Id.ToString()))
        .Concat(assembly.GetTypes()
            .SelectMany(t => t.GetMethods())
            .Where(m => m.GetCustomAttributes().OfType<AnotherAttribute>().Any()));
    Ответ написан
    Комментировать
  • Какими способами можно реализовать рандомное движение нпс по карте UNITY 2D?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Скорее всего, задачка менее тривиальная чем "выбрать случайные координаты в рамках некоторого радиуса" и/или "двигаться к случайным координам (например) по кривой Бернштейна".

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

    Но было бы здорово, уточни вы детальнее задачу.
    Ответ написан
    Комментировать
  • Как сделать переход между сценами в unity 3d?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Самый простой способ, пометить игрока как DontDestroyOnLoad. Такие объекты переносятся.
    Способ чуть сложнее в том, чтобы вы определили данные игрока для переноса в некую структуру, затем сериализовали перед и десериализовали после перехода.
    Ответ написан
    Комментировать
  • Как сделать чтобы партикал двигался за игроком?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    В этой строке:
    Instantiate(bl_ParticalBlood, transform.position + new Vector3(horizontalInput, verticalInput, 0), Quaternion.identity);

    Добавьте в конец
    Instantiate(bl_ParticalBlood, transform.position + new Vector3(horizontalInput, verticalInput, 0), Quaternion.identity, transform);

    При условии, что сам скрипт на игроке висит.
    Ответ написан
    Комментировать
  • Как найти Image в Unity3D?

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Учитывая, что
    .GetComponent<Image>();
    Может вернуть null без уведомлений, но не сработает, если объект найден не будет, у вас может быть одно из:
    а) Объект не найден вообще и ошибка на эту строку указывает;
    б) Не найден компонент;
    в) Компонент был удалён в промежутке между созданием объекта и вызовом метода столкновения.

    Рекомендую вам взять на вооружение замечательную функцию вкладки Inspector: режим Debug.
    Пример, компонент Image

    64177f43a8eb0086475123.png


    Сперва проверьте, получается ли полем crosshairImage ссылка на Image. Затем удостоверьтесь, что она остаётся на месте до и в момент столкновения. Если она не находится, то одно из двух:
    а) у вас есть несколько объектов с указанным тегом и первым находится объект без Image
    б) она создаётся после попытки её найти, пример: другой класс в Start её создаёт, но этот старт вызывается раньше. В настройках проекта это можно исправить (порядок выполнения скриптов).

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

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    На курсах обычно дают один из двух вариантов:

    1) Из текущего здоровья отнимают дельту и затем проверяют, не упало ли здоровье в условие:
    public int healthCurrent;
    
    public void OnHealthChanged(int healthDelta)
    	healthCurrent -= healthDelta;
    	// update health bar
    	if (healthCurrent <= 0) {
    		// death
    	}
    }

    В этом варианте у вас может быть ошибка в условии. Например в примере ниже реально можно попасть в ситуацию, когда персонаж стал бессмертным:
    public int healthCurrent;
    
    public void OnHealthChanged(int healthDelta)
    	if (healthCurrent > 0) {
    		healthCurrent -= healthDelta;
    		// update health bar
    		if (healthCurrent < 0) {
    			// death
    		}
    	}
    }

    2) Через Mathf.Clamp:
    public int healthCurrent;
    public int healthMaximum;
    
    public void OnHealthChanged(int healthDelta)
    	healthCurrent = Mathf.Clamp(healthCurrent - healthDelta, 0, healthMaximum);
    	// update health bar
    	if (healthCurrent == 0) {
    		// death
    	}
    }


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

    @Ezekiel4
    Охотник на пиратов и сборщик монолитов
    Вам так или иначе нужно какое-то событие, например, "игрок сместился" или "прошёл один кадр" или что-то ещё. Если у вас игра типа террарии, где параллакс опирается на движение игрока, то вместо слушания клавиш можете сделать как-то так:
    1) Запоминаем где игрок
    2) Смотрим, насколько далеко он сместился от этой точки
    3) Смещаем слои фона на эквивалентные величины

    Если же эффект автоматический, как в раннерах, то всё ещё проще:
    1) Отсчитываем паузу (таймер, обновление экрана или что-то ещё)
    2) Смещаем слои фона на величины их скорости движения
    Ответ написан
    Комментировать
  • Как сделать Хватание предметов как в People Playground на Unity?

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

    Среди первых видосов на ютубе по вашему запросу вот два примера:
    1) Как можно сделать: https://www.youtube.com/watch?v=pzaxC-P3sgs
    2) Как делать не нужно: https://www.youtube.com/watch?v=zEfahR66Pa8

    Код вам не напишут не из вредности, есть слишком много ньюансов, которые относятся к конкретной реализации механики в разных играх. Ну и дело это не на пять минут. Возможно, вы сможете найти что-то похожее на ваш запрос среди дополнений на unity asset store или его аналоге. Ну или обратиться на тот же фриланс.
    Ответ написан
    Комментировать