Ответы пользователя по тегу Unity
  • Где лучше получать ввод - в Update или FixedUpdate?

    twobomb
    @twobomb
    Сделай ввод в FixedUpdate и посмотри на инпут лаг, и поймешь почему не стоит так делать. Хотя если не требуется динамичного управления, то вообще пофиг.
    p.s. ну это при условии дефолтной частоты вызовов, сколько она там 25 раз вызывается в сек?
    Ответ написан
    Комментировать
  • Как смягчить повороты объекта?

    twobomb
    @twobomb
    Ну естественно откуда там плавность если точки стоят друг возле друга и соеденены прямыми линиями.
    Вам нужно вашу линию преобразовывать в набор квадратичных или кубических кривых безье.
    И двигать нужно присваивая напрямую координаты получаемые из функции которая возвращает координату точки на кривой безье в определенном deltaT, и deltaT двигать одним шагом ну или если нужно делать ускорение,то плавно увеличивать шаг deltaT.
    P.S. Когда-то делал нечто подобное на канвасе, можешь выдрать себе функции получения точки на кривой и функцию интерполяции между двумя 4х точечными кривыми
    Ответ написан
    4 комментария
  • Почему анимация получается не плавной?

    twobomb
    @twobomb
    Ты имеешь ввиду залупленная анимация? Всего скорее потому-что по умолчанию юнити делает сглаженную кривую для точек анимации, открой кривые своей анимации выдели все точки нажми пкм и выбери линейную интерполяцию.
    Ответ написан
  • Как сделать ограничение сбора предметов?

    twobomb
    @twobomb
    public class rock_player : MonoBehaviour {
      static public int rock; 
      public const int MAX_ROCKS = 20; 
    
      [SerializeField]
      public Text TextRock {get { return rock.ToString();}}
    
      void Start(){
        rock = 0; 
      }
    }


    public class RockTrig : MonoBehaviour {
      public int ValueRock; 
    
      void OnTriggerEnter(Collider col) { 
      if(rock_player.rock + ValueRock > rock_player.MAX_ROCKS) {
            ValueRock -= rock_player.MAX_ROCKS - rock_player.rock;
             rock_player.rock = rock_player.MAX_ROCKS; 
    }else{
        rock_player.rock += ValueRock; 
        Destroy (gameObject);
    }
    
      }
    }
    Ответ написан
    Комментировать
  • Как сделать механику прокрутки вентиля?

    twobomb
    @twobomb
    Первое что приходит в голову, на объект вешаем обрабочик down, запоминаем координаты нажатия. и в бул пишем тру что начали крутить Далее на вешаем обработчик на move, там идет получение угла между координатами в которых нажами и текущими координатами и этот угол запоминается. Далее он сравнивается с углом в предыдущем вызове move и если этот угол больше значит крутим по часовой стрелке на смещение равное разнице этих углов к примеру, если меньше то наоборот ... Вешаем обработчик на up и в нем бул пишем фолс, что закончили крутить ну и можно кстате добавить еще один бул, что при отжатии кран начинает плавно возвращаться в исходное положение, закрываться там...
    P.S. Накидал пример на js ну там разберешься, прост юнити у меня нет, ну на ней будет куда проще это сделать
    Ответ написан
  • Как осуществить изменение цвета текста?

    twobomb
    @twobomb
    Прикольно, а оно вообще может работать? Вместе массива вы создаете лист, но не инициализируете его. Да еще и пытаетесь впихивать в него элементы как в массив. Но даже если инициализировать лист и добавлять элементы через метод Add, то всеравно работать не будет. Потому-что получение рандомного индекса стоит перед добавлением этих самых элементов, а значит там будет от 0 до 0....
    P.S. Попробуйте
    void ChangeColors()    {
            targetCountText.color =  (Color)new Color32(Random.Range(0,256), Random.Range(0,256) , Random.Range(0,256),255);
        }

    Если конечно рандомный цвет нужен не из определенного набора..
    Ответ написан
    1 комментарий
  • Что означает Pixels Per Unit?

    twobomb
    @twobomb
    100 пикселей на единицу будет означать, что спрайт, который будет равен 100 пикселям, будет равен 1 единице сцены. Это просто шкала, показывающая, сколько пикселей равно одной единице. Это может повлиять на такие вещи, как физика. Установка меньшего количества пикселей для единиц потребует больше усилий для перемещения на одну единицу, чем установка более высоких пикселей для единиц.

    Да, могут быть моменты, когда вы захотите манипулировать пикселями на единицу. Если у вас есть лист плитки размером 16x16 плиток, вы можете подумать о том, чтобы установить количество пикселей на единицу равным 16, чтобы, например, вы могли легко соединять плитки вместе в сцене.
    Ответ написан
    2 комментария
  • Как передать объект любого класса в метод?

    twobomb
    @twobomb
    Ну вродебы все же префабы наследуются от GameObject'a?
    Можно типа такого
    public void CellClick(GameObject o){
       if(o.GetType() == typeof(Car)){
          Car car = (Car)o ;
       //todo
      }
       if(o.GetType() == typeof(Animal)){
          Animal animal= (Animal)o ;
        //todo
      }
    }

    Если манипуляции однотипные, то можно интерфейсы прикрутить
    Ответ написан
    4 комментария
  • Как нормально реализовать подбор/показ предметов инвентарь?

    twobomb
    @twobomb
    У вас _item что передается аргументом, тот и добавляется в массив. А если вам их нужно 8шт, то их же нужно где-то взять. Как вариант передовать ид айтема, а в методе уже создавать. Типа такого
    public static void AddItem(int itemId, int Amount){
    	
    	int inventoryCellCount = 20;//Количество ячеек инвентаря
    	int maxCount = GetMaxCountById(itemId);//Получить максимальное кол-во стека для этого айтема по ид
    	
    	while(Amount > 0){
    		var item = Items.Find(item => item.id == itemId);
    		if(item == null || item.Amount == maxCount){
    			if(Items.Count >= inventoryCellCount)//Если ячейки инвентаря забиты
    				break;
    			item = CreateItemById(itemId);//создает итем по ид
    			Items.Add(item);			
    		}	
    		if(item.Amount + Amount > maxCount){		
    			Amount = Amount - (maxCount - item.Amount);
    			item.Amount = maxCount;
    		}
    		else{
    			item.Amount += Amount;
    			Amount = 0;
    		}
    	}
    }

    P.S. Ну и тут есть недостаток, допустим поднимаем предметов 80шт. а у нас места только на 20 и дальше инвентарь забивается. Тут нужно продумать обратную связь, ну типа банально возвращать остаточный Amount и записывать его в предмет на земле, если он равен нулю то удалять предмет с земле если больше нуля перезаписывать кол-во. Ну или радикальный метод удалять предмет с земли после подбора окончательно, а если всё не влезло то оно изчезнет просто, тут уже на ваш выбор...
    Ответ написан
  • Почему на модели появились черные пятна при переносе в Unity?

    twobomb
    @twobomb
    нормали неправильные, возможно стоит пересчитать в редакторе
    Ответ написан
    Комментировать
  • Не могу найти ошибку в реализации паттерна "Состояние" (StateMachine)?

    twobomb
    @twobomb
    public GameObject[] goArray;
    
            public void Awake(){
                foreach (var go in goArray)
                    go.GetComponent<Character>().isSelected = false;
            }
    
            public GameObject selected{//Вернет выделенного персонажа, если нет такого то null
                get{
                    foreach (var go in goArray)
                        if (go.GetComponent<Character>().isSelected)
                            return go;
                    return null;
                }
            }
    
            public void Update(){
                if (Input.GetMouseButtonDown(0)){
                    var hit = Ray();
                    if (hit.collider.gameObject.tag == "Agent"){
                        var _ch = hit.collider.gameObject.GetComponent<Character>();
                        if(selected != null)
                            selected.isSelected = false;
                        _ch.isSelected = true;
    
                    } else if (hit.collider.gameObject.tag == "Ground"){
                        if(selected != null)
                            selected.GetComponent<Character>().agent.SetDestination(hit.point);
                    }
                    else if (selected != null)
                            selected.isSelected = false;
                }
            }
    Ответ написан
  • Как в юнити определить, что GameObject был уничтожен, чтобы исключить взаимодействие с ним?

    twobomb
    @twobomb
    Ну вы пытаетесь получить доступ к уничтоженному gameobject, значит либо вам нужно при уничтожении удалять его из массива friend, либо может помочь получать этот массив каждый раз, возможно оно не будет искать удаленные типа такого
    ...
        friend = GameObject.FindGameObjectsWithTag("Friend"); 
          foreach (GameObject go in friend)
    ....
    Ответ написан
    1 комментарий
  • Как сделать так чтобы при отжатии определенной клавиши что то происходило?

    twobomb
    @twobomb
    Input.GetKeyUp
    if (Input.GetKeyUp("space"))
            {
                print("Space key was released");
            }
    Ответ написан
    Комментировать
  • Как правильно реализовать тормоз на машине?

    twobomb
    @twobomb
    Также как и разгон только в другую сторону. Или вектор поменяй назад или умножай на скорость со знаком минус
    Ответ написан
  • Как оформить код для подбора предметов в unity на телефон в 2D?

    twobomb
    @twobomb
    Как вариант, постоянно проверяем дистанцию к каждому предмету который можно подобрать. И если это дистанция меньше, чем дистанция подбора то кнопка отображается, иначе скрыть. Тоже самое когда нажимаешь подобрать, оно проверяет дистанцию и подбираем всё что находиться в зоне подбора.
    К примеру
    void update(){
             int takeDist = 100;//зона подбора
             bool isShowBtn = items.where(it=> getDist(player.x,player.y,it.x,it.y) <= takeDist ).count() > 0;
              if(isShowBtn)
                 //show btn
               else 
                   //hide
         }
    	public static double getDist(float x,float y,float x1,float y1){
    			return Math.Sqrt(Math.Pow(x1-x,2) + Math.Pow(y1-y,2));
    	}
    Ответ написан
  • Как сделать толчок от урона?

    twobomb
    @twobomb
    Ну судя по всему при событии OnCollisionEnter он присылает некие contacts, тоесть точки контакта, у каждой из них есть normal. Если это то что я думаю, а именно единичный вектор. То мы прибавляем к координатам ускорения объекта, эту нормаль умноженную на какое либо число. Чем больше это число, тем дальше отлетит объект, я думаю нормаль можно брать у первой точки контакта. Типа
    var force = 5;
    obj.velocity.x += collision.contacts[0].normal.x * force;
    obj.velocity.y += collision.contacts[0].normal.y * force;
    obj.velocity.z += collision.contacts[0].normal.z * force;

    Естественно это просто предположение. Возможно нужно нужно перемножить на -force
    Ответ написан
    Комментировать
  • Как сделать рандомное появление объектов в Unity?

    twobomb
    @twobomb
    Ну это могут быть псевдо рандомные места, тоесть собираем массив заранее определенный координат мест в которых могут появляться объекты и потом рандомом выбраем из массива. Ну а если совсем рандомные, то определеяем к примеру в каких диапазонах координат могут появляться объекты и рандомом определяем место. С формой тоже самое, заготавливаем определенное формы и выбираем рандомом
    Ответ написан
    Комментировать
  • Как сократить большие числа в Unity2d?

    twobomb
    @twobomb
    В кликере по любому будут настолько большие значение что ни в какие лонг лонги не влезут. Примерно накидал класс, нужно тестить...
    class LongNumber
        {
            public static readonly  String[] symbols =  { " ", "k", "m", "b", "$", "!", "#" };
            List<short> values = new List<short>();
    
            public LongNumber(){
                foreach(var s in  symbols )
                    values.Add(0);
            }
    
            public string getValue(bool isFull = false){//true полный вывод, false только более
                if (isFull)
                    return String.Join(" ",values.Select((v, i) => v + symbols[i]));
                var inx = symbols.Length;
                while(inx > 0 && values[--inx] == 0){};
                return String.Format("{0} {1}", values[inx], symbols[inx]);
            }
            public LongNumber add(long value, String sym = " "){//добавить
                if (value < 0){
                    sub(-value);
                    return this;
                }
                if (!symbols.Contains(sym))
                    throw new FormatException("Неизвестный символ");
                var inx = symbols.ToList().IndexOf(sym);
                value += values[inx];
                values[inx] = Convert.ToInt16(value % 1000);
                if (value >= 1000)
                {
                    if (inx == symbols.Length - 1)
                        throw new OverflowException("Достинуто максимально большое значение");
                    add(Convert.ToInt64(Math.Floor((double)value / 1000)), symbols[inx + 1]);
                }
                return this;
            }
    
            public static LongNumber valToNumber(long val,string sym = " "){//Число в LongNumber
                return new LongNumber().add(val,sym);
            }
    
            public bool isLarger(LongNumber ln){//Сравнение , true если this больше
                for (int i = values.Count - 1; i >= 0; i--)
                    if (values[i] > ln.values[i])
                        return true;
                    else if (values[i] < ln.values[i])
                        break;
                return false;
            }
    
            public LongNumber sub(long value, String sym = " "){//вычесть
                if (value < 0){
                    add(-value);
                    return this;
                }
                if (!symbols.Contains(sym))
                    throw new FormatException("Неизвестный символ");
                if(LongNumber.valToNumber(value,sym).isLarger(this))
                    throw new OverflowException("Вычитаемое число больше");
                var inx = symbols.ToList().IndexOf(sym);
                value = values[inx] - value;
                values[inx] = Convert.ToInt16(value%1000);
                if (value < 0){
                    if (values[inx] < 0)
                        values[inx] += 1000;
                    sub(Convert.ToInt64(Math.Ceiling(Math.Abs((double)value / 1000))), symbols[inx + 1]);
                }
                return this;
            }
        }


    class Program
        {
            static void Main(string[] args)
            {
                LongNumber ln = new LongNumber();
    
                Console.WriteLine(ln.getValue());
    
                ln.add(1000);
                Console.WriteLine(ln.getValue());
                ln.add(123456);
                Console.WriteLine(ln.getValue(true));            
                ln.add(1000,"m");
                Console.WriteLine(ln.getValue(true));
                ln.sub(124456);
                Console.WriteLine(ln.getValue(true));
                ln.sub(1,"b");
                Console.WriteLine(ln.getValue(true));
                ln.add(1234564564);
                Console.WriteLine(ln.getValue(true));
                ln.sub(234565000);
                Console.WriteLine(ln.getValue(true));
                ln.sub(999999564);
                Console.WriteLine(ln.getValue(true));
                ln.sub(-123);
                Console.WriteLine(ln.getValue());
                ln.add(-123);
                Console.WriteLine(ln.getValue());
                Console.ReadKey();
            }
        }


    0
    1 k
    456 124k 0m 0b 0$ 0! 0#
    456 124k 0m 1b 0$ 0! 0#
    0 0k 0m 1b 0$ 0! 0#
    0 0k 0m 0b 0$ 0! 0#
    564 564k 234m 1b 0$ 0! 0#
    564 999k 999m 0b 0$ 0! 0#
    0 0k 0m 0b 0$ 0! 0#
    123
    0


    P.S. Жаль в C# нет перегрузки операторов как в С++
    Ответ написан
  • Следование объекта за курсором?

    twobomb
    @twobomb
    Повесите на обработчик движения мыши вычисление угла между координатами мыши и к примеру центром вашего объекта, запомните этот угол.
    var angle  = Math.Atan2(mousey - objy, mousex - objx);

    Далее на каждой итерации двигаем на объект по этому направлению c нужной скоростью типа
    var speed = 10*deltaTime;
        objx += Math.cos(angle) * speed;
        objy += Math.sin(angle) * speed;

    Ну и в итоге можно еще добавить вычисление расстояния между последними координатами мыши и текущим положением объекта, и если оно меньше speed то делаем objx = lastmousex, objy = lastmousey... И проверку если координаты равны, то не двигать наш объект..
    Ответ написан
  • Как реализовать переходы между сгенерированными локациями(Unity 2D)?

    twobomb
    @twobomb
    Если берем майнкрафт или игры типа него, то для генерации игра использует seed(семя) обычное число от которого генерируются все последующие случайные числа, но эти случайные числа всегда в одинаковой последовательности что значит что мир будет выглядеть у всех одинаково, но стоит изменить хотя бы одну цифру последовательность генерации полностью меняется и мир совсем другой.
    По поводу сохранения, сохранять стоит только то что изменил игрок, поставил блок, разбил окно, выкинул оружие ну и естественно то что нужно, а мир сохранять не нужно он всегда будет одинаков если генерируется от одного числа.
    Ответ написан
    Комментировать