Четверг, 13 Мая 2021, 19:57

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Модератор форума: beril  
Форум игроделов » Движки для разработки игр и сложные системы разработки » Unity » Постоянная привязка объекта к сетке (Округление позиции объекта после его остановки)
Постоянная привязка объекта к сетке
cnstntnДата: Вторник, 24 Ноября 2015, 02:07 | Сообщение # 1
заслуженный участник
Сейчас на сайте
Всем привет!
Игровое поле поделено на клетки. Строго по клеткам расставлены стены.
Как заставить объект всегда попадать в проход между стенами, чтобы его позиция всегда округлялась до нужного значения. Как бы плавное перемещение с остановкой в нужной точке.

Всем спасибо.
berilДата: Вторник, 24 Ноября 2015, 03:07 | Сообщение # 2
Я не ленивый, я — энергосберегающий
Сейчас нет на сайте
Если правильно понял то тебе нужна интерполяция Vector.Lerp



Накодил? Убери за собой!
Инвентарь в Unity(UI)
Инвентарь в Unity(GUI)
cnstntnДата: Суббота, 28 Ноября 2015, 00:48 | Сообщение # 3
заслуженный участник
Сейчас на сайте
beril, как вариант.. Но не совсем то.
Мне нужно что бы каждый шаг объекта равнялся, допустим 0,5. Следовательно если объект сделает 2 шага, то он пройдет 1,0.

Добавлено (28 ноября 2015, 00:48)
---------------------------------------------
Я так понимаю это какой-то заговор. Добыл знания, не делись ими ни в коем случае!
Для чего тогда этот форум нужен, если никто не может дать ответ?

Как это выглядит в Construct2
Люди добрые, как cделатьть то же самое, но в C# ?

mopoДата: Суббота, 28 Ноября 2015, 08:41 | Сообщение # 4
был не раз
Сейчас нет на сайте
Привет!

Может это поможет. Тык

Там чувак рассказывает про сетку 10x10.


Источник усталости - не в теле, а в уме. Ты можешь гораздо больше, чем думаешь.
cnstntnДата: Воскресенье, 29 Ноября 2015, 16:33 | Сообщение # 5
заслуженный участник
Сейчас на сайте
Вопрос остается открытым. Ап! так сказать

Как округлить до десятых позицию объекта после его остановки?
p.s. порой элементарные вещи кажутся невыполнимыми... печаль sad
seamanДата: Воскресенье, 29 Ноября 2015, 18:25 | Сообщение # 6
старожил
Сейчас нет на сайте
Цитата
порой элементарные вещи кажутся невыполнимыми... печаль

Все просто от недостатка образования. Учите язык в котором работаете...
x = ((int)(x * 10))/10;
Учтите что это - после остановки. Если нужно дискретное смещение, нужно действовать по другому.


Сообщение отредактировал seaman - Воскресенье, 29 Ноября 2015, 18:26
cnstntnДата: Понедельник, 30 Ноября 2015, 00:50 | Сообщение # 7
заслуженный участник
Сейчас на сайте
seaman, это не помогает! я уже спрашивал вас, на вашем канале ютьюб =)
язык конечно учить надо... иначе далеко не уедешь
seamanДата: Понедельник, 30 Ноября 2015, 07:58 | Сообщение # 8
старожил
Сейчас нет на сайте
Что значит не помогает?
На канале не было условия "после остановки".
НА всякий случай полностью:
Код
var x = ((int)(transform.position.x * 10))/10;
var y = ((int)(transform.position.y * 10))/10;
transform.position = new vector3(x, y, transform.position.z);
cnstntnДата: Четверг, 03 Декабря 2015, 06:40 | Сообщение # 9
заслуженный участник
Сейчас на сайте
Цитата seaman ()
Что значит не помогает?

вставьте этот кусок кода в скрипт из вашего урока. будет он работать?

Добавлено (03 декабря 2015, 06:40)
---------------------------------------------
И так. Нашел я значит такой вот C# скрипт в этой теме
Кое что подрихтовал, для себя... Чтоб самому понятнее было. Но так и не допер, куда именно и к чему назначить привязку...

Повторю задачу. Есть игровое поле 26 на 26 клеток. Каждая клетка = 0.8 чего-то там (не знаю в чем измеряется пространство в юнити). Нужно что бы танк всегда останавливался на стыке клеток, то есть округлял свою позицию до 0.8. Но! При этом двигался плавно и округление позиции происходило в момент остановки.
Пункты остановок по оси "X - горизонтально": -9.6, -8.8, -8.0, -7.2, ... 0, 0.8, 1.6, ... 9.6. По оси "Z - вертикально" то же самое. (ось Z вместо Y потому что вид сверху 3D)

Помогите. Мозг закипает.

Код
using UnityEngine;
using System.Collections.Generic;

public class Tank : MonoBehaviour
{
    public float speed;
    public RuntimeAnimatorController[] controllers;

    // массив с текущими нажатыми клавишами (стрелки и wdsa)
    private List<KeyCode> _keysDown = new List<KeyCode>();
    // словарь направлений для аниматора
    private Dictionary<KeyCode, int> _keyDirection = new Dictionary<KeyCode, int>();
    // словарь осей, где каждой стрелочке на клавиатуре соответствует нужное число
    private Dictionary<KeyCode, int> _axixDirection = new Dictionary<KeyCode, int>();

    private int _direction;
    private Vector3 _move;

    private Transform _transform;
    private Animator _animator;

    void Start()
    {
        _transform = GetComponent<Transform>();
        _animator = GetComponent<Animator>();
        _animator.runtimeAnimatorController = controllers[0];
        _direction = 0;
        _move = transform.position;

        // назначаем, какой клавише - какое направление для аниматора
        // !!! возможно здесь нужно будет изменить числа местами
        _keyDirection.Add(KeyCode.UpArrow, 0);
        _keyDirection.Add(KeyCode.RightArrow, 1);
        _keyDirection.Add(KeyCode.DownArrow, 2);
        _keyDirection.Add(KeyCode.LeftArrow, 3);

        _keyDirection.Add(KeyCode.W, 0);
        _keyDirection.Add(KeyCode.D, 1);
        _keyDirection.Add(KeyCode.S, 2);
        _keyDirection.Add(KeyCode.A, 3);

        // назначаем, какой оси соответствует каждая стрелочка
        _axixDirection.Add(KeyCode.UpArrow, 1);
        _axixDirection.Add(KeyCode.RightArrow, 1);
        _axixDirection.Add(KeyCode.DownArrow, -1);
        _axixDirection.Add(KeyCode.LeftArrow, -1);

        _axixDirection.Add(KeyCode.W, 1);
        _axixDirection.Add(KeyCode.D, 1);
        _axixDirection.Add(KeyCode.S, -1);
        _axixDirection.Add(KeyCode.A, -1);
    }

    void Update()
    {
        // если нажата клавиша направления,
        // то заносим эту клавишу в массив
        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            _keysDown.Add(KeyCode.UpArrow);
        }

        if (Input.GetKeyDown(KeyCode.RightArrow))
        {
            _keysDown.Add(KeyCode.RightArrow);
        }

        if (Input.GetKeyDown(KeyCode.DownArrow))
        {
            _keysDown.Add(KeyCode.DownArrow);
        }

        if (Input.GetKeyDown(KeyCode.LeftArrow))
        {
            _keysDown.Add(KeyCode.LeftArrow);
        }

        if (Input.GetKeyDown(KeyCode.W))
        {
            _keysDown.Add(KeyCode.W);
        }

        if (Input.GetKeyDown(KeyCode.D))
        {
            _keysDown.Add(KeyCode.D);
        }

        if (Input.GetKeyDown(KeyCode.S))
        {
            _keysDown.Add(KeyCode.S);
        }

        if (Input.GetKeyDown(KeyCode.A))
        {
            _keysDown.Add(KeyCode.A);
        }

        // изначально танчик никуда не двигается
        float h = 0;
        float v = 0;

        // но если какая-нибудь стрелка нажата,
        // то двигаем танчик в том направлении,
        // куда указывает последняя зажатая стрелка
        if (_keysDown.Count != 0)
        {
            _direction = _keyDirection[_keysDown[_keysDown.Count - 1]];

            KeyCode lastkey = _keysDown[_keysDown.Count - 1];

            if (lastkey == KeyCode.RightArrow || lastkey == KeyCode.LeftArrow)
            {
                h = _axixDirection[lastkey];
            }

            if (lastkey == KeyCode.UpArrow || lastkey == KeyCode.DownArrow)
            {
                v = _axixDirection[lastkey];
            }

            if (lastkey == KeyCode.D || lastkey == KeyCode.A)
            {
                h = _axixDirection[lastkey];
            }

            if (lastkey == KeyCode.W || lastkey == KeyCode.S)
            {
                v = _axixDirection[lastkey];
            }
        }

        _move.x = h;

        _move.z = v;
                
        _transform.Translate(_move * speed * Time.deltaTime);
    }

    void FixedUpdate()
    {
        _animator.SetInteger("direction", _direction);
    }

    void OnGUI()
    {
        // здесь ловим событие "отжатия клавиши"
        if (Event.current.type == EventType.KeyUp)
            _keysDown.RemoveAt(_keysDown.LastIndexOf(Event.current.keyCode));

        // это просто для теста, отображается список на экране,
        // текущих зажатых стрелочек
        foreach (KeyCode key in _keysDown)
        {
            GUILayout.Label(key.ToString());
        }

    }
}


Сообщение отредактировал cnstntn - Четверг, 03 Декабря 2015, 06:51
RutrapleДата: Четверг, 03 Декабря 2015, 13:01 | Сообщение # 10
почетный гость
Сейчас нет на сайте
cnstntn, не делай никогда поле с дробным шагом, почему не взять единицу за шаг?

Цитата
Нашел я значит такой вот C# скрипт

Выкинь, не бери чужие срипты без необходимости, пока делаешь для себя - разбирайся самостоятельно.

Цитата
и округление позиции происходило в момент остановки

Округление может происходить в любой момент времени и до остановки и во время. Так что это неправильная постановка задачи.
Да и по сути округление все же лучше использовать дабы отбрасывать дробную часть, а не округлять ее до 2 знаков после запятой, например.

Ну раз тебе надо с таким шагом, вот набросал быстро. Оно работает и вроде корректно.
И еще непонятно, почему ты не прислушался к beril, который тебе про Vector.Lerp говорил.

Не пример хорошего кода!
Код

    private Vector3 point = Vector2.zero;
    private bool isMove = false;

    void Update()
    {
       if (Input.GetKey(KeyCode.UpArrow))
       {
           if (!isMove)
           {
               isMove = true;
               float step = (float) Math.Round(transform.position.z, 1) + 0.8f;

               if (transform.position.z + 0.8f == 0.0f)
               {
                   step = 0;
               }

               point = new Vector3(0, 0, step);
           }
       }
       else if (Input.GetKey(KeyCode.DownArrow))
       {
           if (!isMove)
           {
               isMove = true;
               float step = (float) Math.Round(transform.position.z, 1) - 0.8f;

               if (transform.position.z - 0.8f == 0.0f)
               {
                   step = 0;
               }

               point = new Vector3(0, 0, step);
           }
       }

       if (transform.position != point)
       {
           transform.position = Vector3.MoveTowards(transform.position, point, 2.0f * Time.deltaTime);
       }
       else
       {
           isMove = false;
       }
   }


After Time
Last Of Time
Happy Pumpkin


Сообщение отредактировал Rutraple - Четверг, 03 Декабря 2015, 13:08
cnstntnДата: Четверг, 03 Декабря 2015, 22:31 | Сообщение # 11
заслуженный участник
Сейчас на сайте
Rutraple, спасибо.

Цитата Rutraple ()
Выкинь, не бери чужие скрипты без необходимости, пока делаешь для себя - разбирайся самостоятельно.

Поверь, необходимость была. Сколько людей, столько и методов решения поставленных задач. К тому же я так быстрее понимаю и разбираюсь.

Цитата Rutraple ()
Оно работает и вроде корректно.

Да работает, но рывками.

Цитата Rutraple ()
И еще непонятно, почему ты не прислушался к beril, который тебе про Vector.Lerp говорил.

Ну... Наверное потому что я только начал вникать в Unity и C# в частности. А ссылки на сайт с абстрактными примерами не лучший помощник.
Форум игроделов » Движки для разработки игр и сложные системы разработки » Unity » Постоянная привязка объекта к сетке (Округление позиции объекта после его остановки)
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2021 Рейтинг