Как двигать объект в unity
Перейти к содержимому

Как двигать объект в unity

Изменить позицию объекта через код

Unity. Transform

Задавать позицию объекта в коде можно через свойство transform.position .

// Задать позицию для текущего объекта void Update() < transform.position = new Vector3(8.768f, -1.74f, 0); >

Можно также не указывать точную позицию, куда надо переместить объект, а указать, например, на какое расстояние переместить объект направо.

// При каждом выполнении кода, объект будет сдвигаться направо на 1.50 void Update() < transform.position = transform.position + new Vector3(1.50f, 0, 0); >

Код выполняется для текущего объекта, для которого был создан скрипт. Можно изменить позицию указанного объекта через метод GameObject.Find() .

// Задать позицию для объекта с именем «name_object» void Start() < GameObject.Find("name_object").transform.position = new Vector3(8.768f, -1.74f, 0); >

Обновлено: 04 ноября 2020

Комментарии

Авторизуйтесь, чтобы добавлять комментарии

Перемещение объектов мышкой для 3D или 2D

Перемещение в трехмерном или двухмерном пространстве, с учетом физики объектов. В первую очередь решение будет интересно тем, кто делает 3D проект видом сверху, или 2D игрушку типа платформера. В первом варианте движение осуществляется по осям Х и Z, движение мыши по горизонтали и вертикали, соответственно. Колесико мыши для регулировки высоты. А во втором случаи, используется только движения мыши, без колесика, чтобы перемещать объект по осям Х и Y. Данный вариант заточен для объектов с физикой, в отличии от обычного изменения позиции, через трансформ, тут мы управляем позицией объекта, через Rigidbody.

Цепляем скрипт ObjectControl куда-нибудь:

using UnityEngine; using System.Collections; public class ObjectControl : MonoBehaviour < public string[] tags; // массив тегов, объекты которых можно двигать public Camera _camera; // основная камера сцены public enum ProjectMode ; public ProjectMode mode = ProjectMode.Project3D; public float step = 5; // шаг для изменения высоты в 3D private Transform curObj; private float mass; void Start () < if(mode == ProjectMode.Project2D) _camera.orthographic = true; >bool GetTag (string curTag) < bool result = false; foreach(string t in tags) < if(t == curTag) result = true; >return result; > void Update () < if(Input.GetMouseButton(1)) // Удерживать правую кнопку мыши < if(mode == ProjectMode.Project3D) < RaycastHit hit; Ray ray = _camera.ScreenPointToRay(Input.mousePosition); if(Physics.Raycast(ray, out hit)) < if(GetTag(hit.transform.tag) && hit.rigidbody && !curObj) < curObj = hit.transform; mass = curObj.GetComponent().mass; // запоминаем массу объекта curObj.GetComponent().mass = 0.0001f; // убираем массу, чтобы не сбивать другие объекты curObj.GetComponent().useGravity = false; // убираем гравитацию curObj.GetComponent().freezeRotation = true; // заморозка вращения curObj.position += new Vector3(0, 0.5f, 0); // немного приподымаем выбранный объект > > if(curObj) < Vector3 mousePosition = _camera.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, _camera.transform.position.y)); curObj.GetComponent().MovePosition(new Vector3(mousePosition.x, curObj.position.y + Input.GetAxis("Mouse ScrollWheel") * step, mousePosition.z)); > > else < RaycastHit2D hit = Physics2D.Raycast(_camera.ScreenToWorldPoint(Input.mousePosition), Vector2.zero); if(hit.transform != null) < if(GetTag(hit.transform.tag) && hit.rigidbody && !curObj) < curObj = hit.transform; mass = curObj.GetComponent().mass; curObj.GetComponent().mass = 0.0001f; curObj.GetComponent().gravityScale = 0; curObj.GetComponent().freezeRotation = true; curObj.position += new Vector3(0, 0.5f, 0); > > if(curObj) < Vector3 mousePosition = _camera.ScreenToWorldPoint(Input.mousePosition); curObj.GetComponent().MovePosition(new Vector3(mousePosition.x, mousePosition.y, curObj.position.z)); > > > else if(curObj) < if(curObj.GetComponent()) < curObj.GetComponent().freezeRotation = false; curObj.GetComponent().useGravity = true; curObj.GetComponent().mass = mass; > else < curObj.GetComponent().freezeRotation = false; curObj.GetComponent().mass = mass; curObj.GetComponent().gravityScale = 1; > curObj = null; > > >

В текущем виде подходит только для игры, где используется гравитация, если нужно двигать объекты без нее, тогда следует удалить из скрипта строчки с useGravity и gravityScale.

Перемещение объекта по нажатии кнопки в Unity3d на C#

Сегодня поговорим про движение объекта по нажатию кнопки на экране в Unity3D. Эта тема очень проста, но часто используется в разного рода играх.

Для начала давайте создадим пустой 3D проект. Открываем Unity, нажимаем кнопку в правом верхнем углу с надписью «New». В поле «Project name» указываем название проекта. В строке «Location» указываем расположение проекта на диске. Ниже поля «Location» ставим флажок «3D» и нажимаем «Create project».

image

Затем создаем куб который будет заменять нам землю (GameObject->3D Object->Cube). Потом сделаем его более плоским и растянем. Открываем окно «Inspector», выделяем наш куб, в параметре «Transform» пункт «Scale» задаем x:10, y:0.2, z:10. У нас должно получится такое полотно:

Теперь перемещаем камеру на координаты x:0,y:5,z:0. Затем поворачиваем ее на 90 градусов по оси x. Затем нам нужно создать объект который мы будем перемещать. Создаем сферу (GameObject->3D Object->Sphere), задаем параметр «Position» в «Transform» как x:0, y:1, z:0. После этого чтобы лучше видеть нашу сцену ищем на вкладке «Hierarchy» объект с именем «Directional Light» и задаем ему параметр «Rotation» в «Transform» как x:180, y:-30, z:0. Наш проект теперь должен выглядеть вот так:

Теперь нам нужна кнопка, по нажатию которой мы будем определять двигать ли наш объект. Сначала создаем экран на котором будет располагаться наша кнопка (GameObject->UI->Canvas). Следующий этап — создаем кнопку (GameObject->UI->Button). Затем надо написать скрипт для перемещения нашей сферы. В окне «Project» выбираем «Create», а там выбираем C# Script. Далее приведен код:

using System.Collections; using System.Collections.Generic; using UnityEngine; public class Move : MonoBehaviour < //Наш объект. public GameObject Sphere; //Целочисленная переменная определяющая дистанцию перемещения. public int S; //Метод который будет выполнятся по нажатию нашей кнопки. public void OnButtonDown() < //Задаем нашей переменной целочисленное значение 1 или 2. S = Random.Range(1, 2); //Перемещаем наш объект на S расстояние по оси x. Sphere.transform.Translate(S, 0, 0); >>

Сначала создаем переменную нашего объекта для перемещения. Вторая переменная — это расстояние на которое мы будем перемещать объект. Публичный метод «OnButtonDown» отвечает за перемещение при нажатии кнопки. Сначала задаем переменной S значение 1 или 2, после чего двигаем объект по оси X на S расстояние.

Затем выделяем нашу кнопку, в панели «Inspector» в самом низу нажимаем кнопку «Add Component», выбираем в «Scripts» наш код. Далее в компоненте «Button» снизу в пункте «On Click ()» нажимаем «+». Нажимаем на получившееся окно в параметре «On Click ()» в поле, где стоит «None (Object)». В нем выбираем нашу кнопку. Вот как это должно выглядеть:

Потом в нашем параметре «On Click ()» выбираем блок в котором стоит «No Function», внутри него выбираем название нашего кода, а в нем выбираем метод «OnButtonDown()». Теперь когда кнопка настроена переходим к коду. В окне «Inspector» должен отображаться компонент с названием нашего кода. В поле «Sphere» выбираем нашу сферу. Вот что должно получится:

Затем в окне «Game» нажимаем на «Maximize On Play». Теперь нажимаем на кнопку запуска игры. На экране отображается наша кнопка. Если кликнуть по ней, то наша сфера переместится по оси X.

Большое спасибо за прочтение публикации. Надеюсь, Вы приобрели для себя новые знания.

Помогите. Плавное движение по сетке 3D объекта

Добрый день!
Помогите решить проблему. Нужно сделать игру — головоломку. Суть игры: есть платформа, окружённая стенами, на ней объекты, которые должны перемещаться по сетке . Одни объекты движутся по оси X, другие по оси Z (пример на скрине https://screenshare.ru/c74dfOWf). Единовременно перемещается только один объект, которому мы задаем движение свайпом. То есть, при свайпе предмет можно продвинуть на 1, 2 или более клеток, но объект не может остановиться в промежуточном положении. Важно что бы движение было плавным, имитирующее физический объект, и прекращалось, если на пути есть препятствие.
Я реализовал движение через изменение трансформ.position (при этом способе возникают проблемы c физикой, например когда объект упирается в другой коллайдер, он дергается и т.д) , но зато благодаря ему можно легко двигаться строго по клеткам. Не смог придумать как останавливать движение при столкновении с другим объектами (и что бы их не двигать).

Другим методом, через Физику (велосити, эдфорс) не смог реализовать движение по клеткам, и что бы не толкать другие предметы.
Подскажите пожалуйста решение. И какое решение в данном случае лучше, физическое или Нефизическое?

#1
0:33, 2 окт 2021

Привет! Насчёт того, какое решение лучше, думаю можно очень долго спорить. Я бы сделал одним из двух вариантов:
1. Физика с движением через трансформ, при столкновение с другими движение сразу останавливается. Чтобы друг друга не толкали, можно заморозить по нужным осям, или включать кинематику, пока стоят.
2. После свайпа сначала просчитывается точка, до которой должен доехать объект. Если там клеточное разбиением пространства, то нужную клетку найти попроще, но и так не очень сложно. Можно прям взять точку соприкосновения луча со следующим объектом и учитывая масштаб найти точку.

Первый вариант намного проще в реализации. Плюс можно двигать даже через transform, главное правильно обыграть столкновение.

#2
13:36, 2 окт 2021

Хм, разве вопрос с толканием объектов не решается через isKinematic = true?

Тот что вы тащите — этот флаг ставит себе false
Остальные — true

В итоге и столкновения будут, и статичные двигаться не будут.
Останавливать объект через Velocity = Vector.zero не работает?

#3
20:48, 2 окт 2021

Vadimicus
> И какое решение в данном случае лучше, физическое или Нефизическое?

Мое мнение — физика вам здесь не нужна, она только мешает.
Вы предварительно можете легко посчитать — возможно ли движение в данную клетку или нет. И если нет — то просто не начинать движение. А если да — то просто двигать кубик, не проверяя коллизии.
Само же движение можно делать и физикой, но так у вас будет накапливаться погрешности и ваши кубики выйдут за пределы клеток. Поэтому и само движение тоже лучше делать нефизическим.

#4
0:50, 25 окт 2021

Я новичок, но вспомнил, что делал по гайду простое что-то типа прототипа: https://f1t1l.itch.io/goldenage
Кораблики движуться по квадратам, путь самый короткий они выбирают сами, движение плавное.
код: https://github.com/F1T1L/Unity_projects/blob/main/TowerDefence_Go… ipts/Enemy.cs
Упрощенная версия только с поворотом к вражине лицом:

private IEnumerator SmoothLerp( float time, Enemy enemy) < Vector3 vectorToTarget = enemy.transform.position - transform.position; float angle = Mathf.Atan2( vectorToTarget.x, vectorToTarget.z) * Mathf.Rad2Deg; Quaternion q = Quaternion.AngleAxis( angle, Vector3.up); float elapsedTime = 0; while ( elapsedTime  time) < transform.rotation = Quaternion.Slerp( transform.rotation, q, ( elapsedTime / time)); elapsedTime += Time.deltaTime; yield return null; > >
StartCoroutine( SmoothLerp( 0.5f, enemy));

П.с.: Думаю для такой простой задачи физика не нужна, по крайней мере для прототипа. Её можно потом добавить как «фан» геймплей, что все разлетается куда попало от движения и тд.

#5
23:51, 25 окт 2021

нет тут физики и не надо даже её сюда цеплять. только хуже сделаете, делайте, как предлагал Зевс.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *