Постоянная привязка объекта к сетке
| |
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. порой элементарные вещи кажутся невыполнимыми... печаль
|
|
| |
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# в частности. А ссылки на сайт с абстрактными примерами не лучший помощник.
|
|
| |
|