• Почему Win forms не отображает объекты, которые я создаю через код?

    HemulGM
    @HemulGM
    Delphi Developer, сис. админ
    Потому что нужно указать родителя, в котором будет отображаться контрол
    Ответ написан
    2 комментария
  • Как адекватно округлить Int до тысячи в сокращенной форме?

    vabka
    @vabka Куратор тега C#
    Токсичный шарпист
    textCost.text = ShortFormat((double) cost);
    
    // ...
    static string ShortFormat(double number) => number > 1000 ? $"{number/1000:F2}K" : number.ToString();
    Ответ написан
    Комментировать
  • Какая формула будет удобной для кликера?

    vabka
    @vabka
    Токсичный шарпист
    Я нашёл вариант с домноженим на 1.07, но у меня целочисленные числа.

    Перейти на числа с плавающей точкой.
    Но смысл в общем то такой, чтобы у игрока прогрессия по игре была нелинейной - в начале он должен видеть очень быстрый, чуть ли не экспоненциальный рост, а со временем должно образоваться плато.
    Ответ написан
    Комментировать
  • Почему TextMeshPro меняет все тексты разом?

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

    635a7197c245c234327838.png
    Ответ написан
    3 комментария
  • Как заставить камеру двигаться за игроком, но не вращаться с ним?

    @Ezekiel4
    Охотник на пиратов
    Если камера вращается вместе с игроком, вы добавили её в иерархию игрока. Если камера дёргается, то у вас либо рассинхрон с движением, либо само движение дёрганное.
    Ответ написан
    Комментировать
  • Как передать enum из другого класса?

    VoidVolker
    @VoidVolker
    Разработчик ПО и IT-инженер
    Документацию открыть и почитать? Неее, зачем? Попробовать тупо написать код и увидеть, что студия сразу предложит использовать нужное и даже список выпадающий покажет? Неее, зачем? https://learn.microsoft.com/ru-ru/dotnet/csharp/la...
    Ответ написан
    Комментировать
  • Как передать enum из другого класса?

    freeExec
    @freeExec
    Участник OpenStreetMap
    Так же как вы в case указывали
    Ответ написан
    Комментировать
  • Почему игрок улетает при ударе с уголком?

    @Ezekiel4
    Охотник на пиратов
    Без скриншотов и кода могу лишь предположить, что вы перемещаете подчинённого физике персонажа либо телепортацией (модификация transform.position), либо управляете скоростью (Rigidbody.velocity). Оба способа рабочие, но порочные, так как первый вообще не работает на физику, а второй может сделать то, что случилось у вас.

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

    Рекомендую обратить внимание на Rigidbody.AddForce с установкой ForceMode (или ForceMode2D для 2D). Вот небольшая подсказка:
    6340b16fc6720621507048.jpeg

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

    @Ezekiel4
    Охотник на пиратов
    Добавьте цилиндру Rigidbody и скрипт, который будет его вращать. Как-то так:

    using UnityEngine;
    
    [RequireComponent(typeof(Rigidbody))]
    public class RotateRigidbody : MonoBehaviour {
    
    	[SerializeField] private Rigidbody m_Rigidbody;
    	[SerializeField] private Vector3 m_Speed;
    
    	private void Start() {
    		m_Rigidbody = GetComponent<Rigidbody>();
    	}
    
    	private void FixedUpdate() {
    		m_Rigidbody.MoveRotation(Quaternion.Euler(m_Speed));
    	}
    }


    PS. если не хотите, чтобы он двигался, а лишь вращался, в настройках Rigidbody цилиндра поставьте три галочки на constraints-position x/y/z
    Ответ написан
    Комментировать
  • Почему после импорта из blender в unity размытая текустра?

    @kostya_gorshkov
    нужно импортировать в фомат fbx и для нормальности в блендер нужно наложить всё через UV EDITOR
    Ответ написан
    Комментировать
  • Как сделать адекватное рисование в unity?

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

    LittleBob
    @LittleBob
    public void SaveLvlList(string keyName, int CountStars)
        {
            PlayerPrefs.SetString(keyName, JsonUtility.ToJson(CountStars));
            PlayerPrefs.Save();
        }

    Нужно вызвать метод Save, иначе не сохранит значения.
    Ответ написан
    2 комментария
  • Почему не работает сохранение?

    freeExec
    @freeExec
    Участник OpenStreetMap
    PlayerPrefs.Save вызываешь?
    Ответ написан
  • Как использовать json?

    K0TlK
    @K0TlK
    Буллю людей.
    public GameObject[] ObjectsForDestroy;

    Что за объекты?

    Json в PlayerPrefs сохранять не надо, как и строки в принципе, сохраняй в отдельный файл.

    То, что у тебя в OnMouseDown происходит я вообще не понимаю
    Что за а? Что эта переменная вообще означает?
    .GetChild(0).GetChild(0) Когда у тебя порядок в иерархии поменяется, будешь искать ошибку.

    Про Manager, надеюсь, говорить не надо.

    TL;DR

    Создать пустую директорию
    private void CreateDirectory()
            {
                if (Directory.Exists(_directoryPath) == false)
                {
                    Directory.CreateDirectory(_directoryPath);
                }
            }


    Создать файл с нулевыми значениями
    private void CreateFile()
            {
                if (File.Exists(_path)) return;
                
                var json = JsonUtility.ToJson(CompleteStatus.Locked);
                    
                using (var writer = File.CreateText(_path))
                {
                    writer.Write(json);
                    writer.Close();
                }
            }



    Как использовать Json:

    Есть какой-то уровень:

    namespace Levels
    {
        public interface ILevel : IVisualization<ILevelView>
        {
            void Load();
            void Complete(CompleteStatus status);
        }
    }

    namespace Levels
    {
        public interface IVisualization<in TView>
        {
            void Visualize(TView view);
        }
    }



    Есть его вьюшка:

    namespace Levels
    {
        public enum CompleteStatus
        {
            Locked,
            Uncompleted,
            OneStar,
            TwoStars,
            ThreeStars
        }
        public interface ILevelView
        {
            void DrawCompletion(CompleteStatus status);
        }
    }



    Реализация уровня:

    Сохранение нужно вынести отдельно, но мне лень это делать.
    При вызове Load загружается уровень.
    При вызове Complete уровень завершается и сохраняется количество звезд на которое пройден уровень, у меня здесь максимум три звезды, если нужно сохранять какой-то счет, создавай структуру, которую будешь сохранять вместо перечисления.
    using System.IO;
    using UnityEngine;
    using UnityEngine.SceneManagement;
    
    namespace Levels
    {
        public abstract class Level : ILevel
        {
            private readonly string _name;
    
            private readonly string _path;
    
            private readonly string _directoryPath = $"{Application.persistentDataPath}/Saves";
    
            protected Level(string name)
            {
                _name = name;
                _path = $"{_directoryPath}/{_name}.json";
                CreateDirectory();
                CreateFile();
            }
    
            public void Load()
            {
                SceneManager.LoadScene(_name);
            }
    
            public void Complete(CompleteStatus status)
            {
                SaveStatus(status);
            }
    
            public void Visualize(ILevelView view)
            {
                view.DrawCompletion(LoadStatusFromJson());
            }
    
            private void CreateDirectory()
            {
                if (Directory.Exists(_directoryPath) == false)
                {
                    Directory.CreateDirectory(_directoryPath);
                }
            }
    
            private void CreateFile()
            {
                if (File.Exists(_path)) return;
                
                var json = JsonUtility.ToJson(CompleteStatus.Locked);
                    
                using (var writer = File.CreateText(_path))
                {
                    writer.Write(json);
                    writer.Close();
                }
            }
            
            private void SaveStatus(CompleteStatus status)
            {
                var json = JsonUtility.ToJson(status);
                File.WriteAllText(_path, json);
            }
            
            private CompleteStatus LoadStatusFromJson()
            {
                var file = File.ReadAllText(_path);
                return JsonUtility.FromJson<CompleteStatus>(file);
            }
            
        }
    }


    Собственно, так выглядит уровень:
    namespace Levels
    {
        public class SecondLevel : Level
        {
            public SecondLevel() : base(nameof(SecondLevel))
            {
            }
        }
    }



    Реализация вьюшки:

    т.к. это вьюшка, можно говнокодить как хочешь.
    На основании статуса у звезд устанавливается конкретный цвет и активность кнопки.
    using System;
    using UnityEngine;
    using UnityEngine.UI;
    
    namespace Levels
    {
        public class LevelView : MonoBehaviour, ILevelView
        {
            [SerializeField] private Image _firstStar, _secondStar, _thirdStar;
            [SerializeField] private Button _button;
            [SerializeField] private Color _inactiveStarColor, _activeStarColor;
            
            public void DrawCompletion(CompleteStatus status)
            {
                switch (status)
                {
                    case CompleteStatus.Locked:
                        _firstStar.color = _inactiveStarColor;
                        _secondStar.color = _inactiveStarColor;
                        _thirdStar.color = _inactiveStarColor;
                        _button.interactable = false;
                        break;
                    case CompleteStatus.Uncompleted:
                        _button.interactable = true;
                        _firstStar.color = _inactiveStarColor;
                        _secondStar.color = _inactiveStarColor;
                        _thirdStar.color = _inactiveStarColor;
                        break;
                    case CompleteStatus.OneStar:
                        _button.interactable = true;
                        _firstStar.color = _activeStarColor;
                        _secondStar.color = _inactiveStarColor;
                        _thirdStar.color = _inactiveStarColor;
                        break;
                    case CompleteStatus.TwoStars:
                        _button.interactable = true;
                        _firstStar.color = _activeStarColor;
                        _secondStar.color = _activeStarColor;
                        _thirdStar.color = _inactiveStarColor;
                        break;
                    case CompleteStatus.ThreeStars:
                        _button.interactable = true;
                        _firstStar.color = _activeStarColor;
                        _secondStar.color = _activeStarColor;
                        _thirdStar.color = _activeStarColor;
                        break;
                    default: throw new ArgumentException();
                }
            }
        }
    }



    И тест

    using System.Collections.Generic;
    using UnityEngine;
    
    namespace Levels
    {
        public class LevelList : MonoBehaviour
        {
            [SerializeField] private LevelView _levelViewPrefab;
            [SerializeField] private Transform _levelsParent;
    
            private ILevel[] _levels;
            
            private void Awake()
            {
                var first = new FirstLevel();
                var second = new SecondLevel();
                var third = new ThirdLevel();
                var fourth = new FourthLevel();
                var fifth = new FifthLevel();
                
                _levels = new ILevel[]
                {
                    first, second, third, fourth, fifth
                };
    
                //test
                first.Complete(CompleteStatus.OneStar);
                second.Complete(CompleteStatus.TwoStars);
                third.Complete(CompleteStatus.ThreeStars);
                fourth.Complete(CompleteStatus.Uncompleted);
                fifth.Complete(CompleteStatus.Locked);
    
                VisualizeLevels(_levels);
            }
    
            private void VisualizeLevels(IEnumerable<ILevel> levels)
            {
                foreach (var level in levels)
                {
                    var view = Instantiate(_levelViewPrefab, _levelsParent);
                    level.Visualize(view);
                }
            }
        }
    }



    Так выглядит:
    63144a1583e29173450114.jpeg
    Ответ написан
    1 комментарий
  • Как проверить во что врезался рейкаст?

    @Ezekiel4
    Охотник на пиратов
    Переменная hit из вашего примера имеет тип RaycastHit (ссылочка на документацию), у которого есть свойство collider. Сам же метод Raycast возвращает логическое значение, определяющее, было ли касание в указанном направлении и расстоянии. Выглядеть это должно как-то так:
    if (Physics.Raycast(transform.position, _direction, out hit, 10f)) {
    	if (hit.collider == yourCollider) {
    		// some logic
    	}
    }

    Также это всегда можно совместить с TryGetComponent, если логика должна зависеть от определённого компонента, который может быть на цели (ссылочка). Как-то так:
    private MyComponent GetTarget() {
    	if (Physics.Raycast(transform.position, _direction, out hit, 10f))
    		if (hit.transform.TryGetComponent(out MyComponent m))
    			return m;
    	return null;
    }
    Ответ написан
    2 комментария
  • Почему у объекта может импульс применяться неправильно?

    K0TlK
    @K0TlK
    Буллю людей.
    Тебе не нужна здесь физика и AddForce тем более. Просто двигай пулю, изменяя позицию, лови столкновение через OnCollisionEnter и отражай направление движения.

    Пуля

    using UnityEngine;
    
    namespace Bullets
    {
        [RequireComponent(typeof(Rigidbody2D), typeof(Collider2D))]
        public class Bullet : MonoBehaviour, IBullet
        {
            [SerializeField] private float _speed = 5f;
            [SerializeField] private int _damage = 10;
            [SerializeField] private int _maxReflections = 5;
    
            private Rigidbody2D _rigidbody;
            private Vector2 _direction = Vector2.zero;
    
            private void Awake()
            {
                _rigidbody = GetComponent<Rigidbody2D>();
                _rigidbody.isKinematic = true;
                _rigidbody.useFullKinematicContacts = true;
            }
            
            public void Shoot(Vector2 direction)
            {
                _direction = direction.normalized;
            }
    
            private void FixedUpdate()
            {
                if (_direction == Vector2.zero) return;
    
                var deltaMovement = _direction * _speed * Time.deltaTime;
    
                _rigidbody.MovePosition(_rigidbody.position + deltaMovement);
            }
    
            private void OnCollisionEnter2D(Collision2D other)
            {
                if (other.transform.TryGetComponent(out IDamageable damageable))
                {
                    damageable.ApplyDamage(_damage);
                    Destroy();
                    return;
                }
    
                var normal = other.GetContact(0).normal;
                Reflect(normal);
            }
    
            private void Destroy()
            {
                Destroy(gameObject);
            }
    
            private void Reflect(Vector2 normal)
            {
                if (_maxReflections - 1 == 0) Destroy();
    
                _maxReflections--;
                _direction = Vector2.Reflect(_direction, normal).normalized;
            }
        }
    }



    И убогий скрипт оружия

    using UnityEngine;
    
    namespace Bullets
    {
        public class SomeGun : MonoBehaviour
        {
            [SerializeField] private Bullet _bulletPrefab;
            [SerializeField] private Transform _bulletOrigin;
            [SerializeField] private Camera _camera;
    
            private void Update()
            {
                LookAtMouse(Input.mousePosition);
    
                if (Input.GetKeyDown(KeyCode.Mouse0))
                {
                    Shoot();
                }
            }
    
            private void LookAtMouse(Vector3 mousePosition)
            {
                var gunScreenPosition = _camera.WorldToScreenPoint(transform.position);
                
                var direction = mousePosition - gunScreenPosition;
    
                direction.Scale(new Vector3(1, 1, 0));
    
                transform.up = direction;
            }
    
            private void Shoot()
            {
                var bullet = Instantiate(_bulletPrefab, _bulletOrigin.position, Quaternion.identity);
    
                bullet.Shoot(transform.up);
            }
        }
    }



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

    K0TlK
    @K0TlK
    Буллю людей.
    Ответ написан
    Комментировать
  • Почему в материале нет Projector > Multiply?

    freeExec
    @freeExec
    Участник OpenStreetMap
    Документация говорит, что нужно ставить Стандартные ассеты, которые счас правда считаются легаси

    https://docs.unity3d.com/Manual/class-Projector.html
    Ответ написан
    Комментировать
  • Как рекламные банеры заставлять пересоздаваться каждые 30 секунд?

    gluck59
    @gluck59
    Виртуальный глюк
    Не нужно этого делать. Пожалей посетителей.
    Ответ написан
    1 комментарий
  • Почему игра на телефоне видит свайпы через раз?

    freeExec
    @freeExec
    Участник OpenStreetMap
    Обложите свой код дебажными сообщениями, и тогда будете понимать, куда при свайпе код завернул и где не выполнился.
    Ответ написан
    2 комментария