Перемещение корабля как в Space Rangers - Форум Игроделов
Чт, 02 Май 2024, 02:28 
 
Приветствую Вас Гость Главная | Регистрация | Вход
Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Форум Игроделов » UNITY3D » СКРИПТИНГ » Перемещение корабля как в Space Rangers
Перемещение корабля как в Space Rangers
KriatonuSДата: Чт, 24 Сен 2015, 14:26 | Сообщение # 1
Нет аватара
 
Сообщений: 16
Награды: 0
Репутация: 0
Статус: Offline
Народ помогите! Все мозги уже себе вынес.
Есть корабль, который перемещается только по X,Z. Под ним поверхность с тегом.
При нажатии мышки на поверхности, корабль должен плавно повернуться к месту нажатия,
затем набирая скорость подлететь к назначению с плавным торможением и соответственно остановиться.
С камерой RTS разобрался - а вот с кораблем никак.
Помогите пожалуйста с кодом и разъяснениями.
 
СообщениеНарод помогите! Все мозги уже себе вынес.
Есть корабль, который перемещается только по X,Z. Под ним поверхность с тегом.
При нажатии мышки на поверхности, корабль должен плавно повернуться к месту нажатия,
затем набирая скорость подлететь к назначению с плавным торможением и соответственно остановиться.
С камерой RTS разобрался - а вот с кораблем никак.
Помогите пожалуйста с кодом и разъяснениями.

Автор - KriatonuS
Дата добавления - 24 Сен 2015 в 14:26
VolkOrievithДата: Чт, 24 Сен 2015, 19:13 | Сообщение # 2
Нет аватара
 
Сообщений: 222
Награды: 0
Репутация: 53
Статус: Offline
Зачем делать два одинаковых поста в разных местах?
Уже ответил, в другом месте:
Пускаем луч в место щелчка мышью, затем направляем корабль туда.
Код

var Point : Vector3;
var speed : float;

functiom Update () {

if (Input.GetButtonDown ("Fire1")){
var ray : Ray = Camera.main.ScreenPointToRay(Input.mousePosition);
var hit :  RaycastHit;
           if (Physics.Raycast(ray, hit, 1000))
Point = hit.point;
}
if (Vector3.Distance (transform.position, Point) > 10){
transform.Rotate (0, Vector3.Normalize(transform.InverceTransformDirection ( Point - transform.position)).z * time.deltaTime * 5, 0);
transform.position += transform.forward * time.deltaTime * speed;
}
}


Копируй осторожнее, писал вслепую, наверное наделал ошибок) Но суть понятна.
Плавности ускорения и торможения нет, но их легко сделать самому.
 
СообщениеЗачем делать два одинаковых поста в разных местах?
Уже ответил, в другом месте:
Пускаем луч в место щелчка мышью, затем направляем корабль туда.
Код

var Point : Vector3;
var speed : float;

functiom Update () {

if (Input.GetButtonDown ("Fire1")){
var ray : Ray = Camera.main.ScreenPointToRay(Input.mousePosition);
var hit :  RaycastHit;
           if (Physics.Raycast(ray, hit, 1000))
Point = hit.point;
}
if (Vector3.Distance (transform.position, Point) > 10){
transform.Rotate (0, Vector3.Normalize(transform.InverceTransformDirection ( Point - transform.position)).z * time.deltaTime * 5, 0);
transform.position += transform.forward * time.deltaTime * speed;
}
}


Копируй осторожнее, писал вслепую, наверное наделал ошибок) Но суть понятна.
Плавности ускорения и торможения нет, но их легко сделать самому.

Автор - VolkOrievith
Дата добавления - 24 Сен 2015 в 19:13
KriatonuSДата: Чт, 24 Сен 2015, 20:30 | Сообщение # 3
Нет аватара
 
Сообщений: 16
Награды: 0
Репутация: 0
Статус: Offline
Сори за репост.
И огромное спасибо за ответ.
Но не срабатывает скрипт на JS
Переделал на шару, но объект поворачивается в ходе смещения, а не перед тем как начать двигаться и смещается только при зажатой клавише.
И кроме того уходит по оси Y - только.
Мне необходимо, что-бы он двигался по Х,Z, получая координаты мыши от луча падающего на Plane, который висит под сценой (невидимая плоскость)
Что здесь не так?:
Код
using UnityEngine;
using System.Collections;

public class ShipMove : MonoBehaviour {

public Vector3 Point;
private float Speed = 10;
private Ray ray;
private RaycastHit hit;
public GameObject Ship;
public Camera CAM;

void Update()
{
if (Input.GetKey(KeyCode.Mouse0))
{
ray = CAM.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
Point = hit.point;
}
if (Vector3.Distance(transform.position, Point) > 10)
{
Ship.transform.Rotate(0, Vector3.Normalize(transform.InverseTransformDirection(Point - transform.position)).z * Time.deltaTime * 5, 0);
Ship.transform.position += transform.forward * Time.deltaTime * Speed;
}
}
}
}
 
СообщениеСори за репост.
И огромное спасибо за ответ.
Но не срабатывает скрипт на JS
Переделал на шару, но объект поворачивается в ходе смещения, а не перед тем как начать двигаться и смещается только при зажатой клавише.
И кроме того уходит по оси Y - только.
Мне необходимо, что-бы он двигался по Х,Z, получая координаты мыши от луча падающего на Plane, который висит под сценой (невидимая плоскость)
Что здесь не так?:
Код
using UnityEngine;
using System.Collections;

public class ShipMove : MonoBehaviour {

public Vector3 Point;
private float Speed = 10;
private Ray ray;
private RaycastHit hit;
public GameObject Ship;
public Camera CAM;

void Update()
{
if (Input.GetKey(KeyCode.Mouse0))
{
ray = CAM.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
Point = hit.point;
}
if (Vector3.Distance(transform.position, Point) > 10)
{
Ship.transform.Rotate(0, Vector3.Normalize(transform.InverseTransformDirection(Point - transform.position)).z * Time.deltaTime * 5, 0);
Ship.transform.position += transform.forward * Time.deltaTime * Speed;
}
}
}
}

Автор - KriatonuS
Дата добавления - 24 Сен 2015 в 20:30
VolkOrievithДата: Пт, 25 Сен 2015, 18:09 | Сообщение # 4
Нет аватара
 
Сообщений: 222
Награды: 0
Репутация: 53
Статус: Offline
Vector3.Normalize(transform.InverseTransformDirection(Point - transform.position)) - это локальный (для объекта, на котором висит скрипт, то есть для корабля) вектор от корабля к Point. Чем его значение по z меньше, тем, значит, меньше его угол до направления к точке. Если по z он = 0, то, либо корабль смотрит на point, либо смотрит в обратную сторону. Если разложить "Vector3.Normalize(transform.InverseTransformDirection(Point - transform.position))" по составляющим, то получим:
Point - transform.position - направление в глобальной системе координат от корабля на точку.
transform.InverseTransformDirection получает из глобального локальный вектор. (таким способом можно найти, к примеру, скорость смещения самолета в бок)
Vector3.Normalize - находит единичный вектор.
Получается, что если корабль стоит боком к точке, Vector3.Normalize(transform.InverseTransformDirection(Point - transform.position)).z = +-1 (в зависимости от того, какой стороной корабль повернут)

напиши что-то типа
"если V3.N(tr.ITD( p - tr.p)).z < 0.2
перемешаем корабль.
иначе
поворачиваем корабль."

А что вы имели ввиду тут, я не понял.
"И кроме того уходит по оси Y - только. "

Все, разобрался.
Вы написали
Код
Ship.transform.Rotate(0, Vector3.Normalize(transform.InverseTransformDirection(Point - transform.position)).z * Time.deltaTime * 5, 0);

Раз у вас скрипт висит не на корабле, то пишем так:
Код
Ship.transform.Rotate(0, Vector3.Normalize(Ship.transform.InverseTransformDirection(Point - Ship.transform.position)).z * Time.deltaTime * 5, 0);  
а так же  
if (Vector3.Distance(Ship.transform.position, Point) > 10)  


Сообщение отредактировал VolkOrievith - Пт, 25 Сен 2015, 18:14
 
СообщениеVector3.Normalize(transform.InverseTransformDirection(Point - transform.position)) - это локальный (для объекта, на котором висит скрипт, то есть для корабля) вектор от корабля к Point. Чем его значение по z меньше, тем, значит, меньше его угол до направления к точке. Если по z он = 0, то, либо корабль смотрит на point, либо смотрит в обратную сторону. Если разложить "Vector3.Normalize(transform.InverseTransformDirection(Point - transform.position))" по составляющим, то получим:
Point - transform.position - направление в глобальной системе координат от корабля на точку.
transform.InverseTransformDirection получает из глобального локальный вектор. (таким способом можно найти, к примеру, скорость смещения самолета в бок)
Vector3.Normalize - находит единичный вектор.
Получается, что если корабль стоит боком к точке, Vector3.Normalize(transform.InverseTransformDirection(Point - transform.position)).z = +-1 (в зависимости от того, какой стороной корабль повернут)

напиши что-то типа
"если V3.N(tr.ITD( p - tr.p)).z < 0.2
перемешаем корабль.
иначе
поворачиваем корабль."

А что вы имели ввиду тут, я не понял.
"И кроме того уходит по оси Y - только. "

Все, разобрался.
Вы написали
Код
Ship.transform.Rotate(0, Vector3.Normalize(transform.InverseTransformDirection(Point - transform.position)).z * Time.deltaTime * 5, 0);

Раз у вас скрипт висит не на корабле, то пишем так:
Код
Ship.transform.Rotate(0, Vector3.Normalize(Ship.transform.InverseTransformDirection(Point - Ship.transform.position)).z * Time.deltaTime * 5, 0);  
а так же  
if (Vector3.Distance(Ship.transform.position, Point) > 10)  

Автор - VolkOrievith
Дата добавления - 25 Сен 2015 в 18:09
KriatonuSДата: Пт, 25 Сен 2015, 19:31 | Сообщение # 5
Нет аватара
 
Сообщений: 16
Награды: 0
Репутация: 0
Статус: Offline
Огромное спасибо - я разобрался. Вы мне очень помогли.

Добавлено (25 Сен 2015, 19:31)
---------------------------------------------
Вот работающий код, но пока без ускорения и торможения. Если кому интересно.
Благодарим VolkOrievith,
Кто хочет улучшить и дописать - кидаем ниже в посте.
Думаю многие будут благодарны

public class ShipMove : MonoBehaviour {

public Vector3 Point;
private float Speed = 5;
private float RotateSpeed = 0.001f;
private Ray ray;
private RaycastHit hit;
public GameObject Ship;
public Camera CAM;

void Update()
{
if (Input.GetKey(KeyCode.Mouse0))
{
ray = CAM.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, 100f) == true)
{
Point = hit.point;
}
}
if (Vector3.Distance(Ship.transform.position, Point) > 1) // Еслии мы нажали не на корабле.
{
if (hit.collider.tag == "Map") //Если луч коснулся карты
{
Point.y = 3;
Ship.transform.Rotate(0, Vector3.Normalize(Ship.transform.InverseTransformDirection(Point - Ship.transform.position)).x * Time.deltaTime * 720, 0);
Ship.transform.position += transform.forward * Time.deltaTime * Speed;
}
}
}
}

 
СообщениеОгромное спасибо - я разобрался. Вы мне очень помогли.

Добавлено (25 Сен 2015, 19:31)
---------------------------------------------
Вот работающий код, но пока без ускорения и торможения. Если кому интересно.
Благодарим VolkOrievith,
Кто хочет улучшить и дописать - кидаем ниже в посте.
Думаю многие будут благодарны

public class ShipMove : MonoBehaviour {

public Vector3 Point;
private float Speed = 5;
private float RotateSpeed = 0.001f;
private Ray ray;
private RaycastHit hit;
public GameObject Ship;
public Camera CAM;

void Update()
{
if (Input.GetKey(KeyCode.Mouse0))
{
ray = CAM.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, 100f) == true)
{
Point = hit.point;
}
}
if (Vector3.Distance(Ship.transform.position, Point) > 1) // Еслии мы нажали не на корабле.
{
if (hit.collider.tag == "Map") //Если луч коснулся карты
{
Point.y = 3;
Ship.transform.Rotate(0, Vector3.Normalize(Ship.transform.InverseTransformDirection(Point - Ship.transform.position)).x * Time.deltaTime * 720, 0);
Ship.transform.position += transform.forward * Time.deltaTime * Speed;
}
}
}
}


Автор - KriatonuS
Дата добавления - 25 Сен 2015 в 19:31
VolkOrievithДата: Пт, 25 Сен 2015, 20:55 | Сообщение # 6
Нет аватара
 
Сообщений: 222
Награды: 0
Репутация: 53
Статус: Offline
Ускорение - торможение.
я на JS пишу, мне так привычнее)
Делай переменную "currentSpeed"
Через "Mathf.Lerp ( from : float, to : float, time.deltaTime * ускорение)"
делаешь
Код

var  acceleration : float;

// Update
currentSpeed = Mathf.Lerp ( currentSpeed, Speed, time.deltaTime * acceleration);
заменяешь
Ship.transform.position += transform.forward * Time.deltaTime * currentSpeed;

Mathf.Lerp ( a, b, c) смешивает числа a и b в соотношении a*c + b*(1 - c)

то есть, если написать n = Mathf.Lerp ( 2, 4, 0.5), то n будет = 3
если написать n = Mathf.Lerp ( 2, 4, 0.0), то n будет = 2
если написать n = Mathf.Lerp ( 2, 4, 1.0), то n будет = 4

Можно реализовать по другому.
пусть переменная speed = 0;
объявляешь переменную acceleration (ускорение)

при нажатии мыши записываешь расстояние от корабля до точки (Допустим переменная называется startDist).
пусть настоящее растояние от коробля до точки будет currentDist.

Пускаешь корабль.
Пока currentDist > startDist / 2
speed += acceleration * time.deltaTime; (ускоряешь)
когда станет currentDist < startDist / 2 (пройдена половина пути)
speed -= acceleration * time.deltaTime; (замедляешь)

Действуй, злодействуй)
 
СообщениеУскорение - торможение.
я на JS пишу, мне так привычнее)
Делай переменную "currentSpeed"
Через "Mathf.Lerp ( from : float, to : float, time.deltaTime * ускорение)"
делаешь
Код

var  acceleration : float;

// Update
currentSpeed = Mathf.Lerp ( currentSpeed, Speed, time.deltaTime * acceleration);
заменяешь
Ship.transform.position += transform.forward * Time.deltaTime * currentSpeed;

Mathf.Lerp ( a, b, c) смешивает числа a и b в соотношении a*c + b*(1 - c)

то есть, если написать n = Mathf.Lerp ( 2, 4, 0.5), то n будет = 3
если написать n = Mathf.Lerp ( 2, 4, 0.0), то n будет = 2
если написать n = Mathf.Lerp ( 2, 4, 1.0), то n будет = 4

Можно реализовать по другому.
пусть переменная speed = 0;
объявляешь переменную acceleration (ускорение)

при нажатии мыши записываешь расстояние от корабля до точки (Допустим переменная называется startDist).
пусть настоящее растояние от коробля до точки будет currentDist.

Пускаешь корабль.
Пока currentDist > startDist / 2
speed += acceleration * time.deltaTime; (ускоряешь)
когда станет currentDist < startDist / 2 (пройдена половина пути)
speed -= acceleration * time.deltaTime; (замедляешь)

Действуй, злодействуй)

Автор - VolkOrievith
Дата добавления - 25 Сен 2015 в 20:55
KriatonuSДата: Сб, 26 Сен 2015, 10:59 | Сообщение # 7
Нет аватара
 
Сообщений: 16
Награды: 0
Репутация: 0
Статус: Offline
Отличная идея - спасибо. Завтра попробую - отпишусь.

Добавлено (26 Сен 2015, 10:59)
---------------------------------------------
Спасибо! Вот что получилось благодаря Вашему совету

public class ShipMove : MonoBehaviour {

public Vector3 Point;
private float Speed = 1;
private float RotateSpeed = 0.001f;
private Ray ray;
private RaycastHit hit;
public GameObject Ship;
public Camera CAM;
private float acceleration = 3;
private float StartDist;
private float CurentDist;
private float currentSpeed;
public float MaxSpeed;

void Update()
{
if (Input.GetKey(KeyCode.Mouse0))
{
StartDist = (Vector3.Distance(Ship.transform.position, Point));
CurentDist = (Vector3.Distance(Ship.transform.position, Point));

ray = CAM.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, 100f) == true)
{
Point = hit.point;
}
}
if (Vector3.Distance(Ship.transform.position, Point) > 1) // Если мы нажали не на корабле.
{
if (hit.collider.tag == "Map") //Если луч коснулся карты
{
print(Speed);
CurentDist = (Vector3.Distance(Ship.transform.position, Point));
if (CurentDist > (StartDist / 2)) // Ускорение
{
Speed += acceleration * Time.deltaTime;
if (Speed > MaxSpeed) { Speed = MaxSpeed; }
}
if (CurentDist < (StartDist / 2)) // Торможение
{
Speed -= acceleration * Time.deltaTime;
if (Speed < 0) { Speed = 0; }
}
if (Vector3.Distance(Ship.transform.position, Point) <= 1.5) //остановка
{
Speed = 0;
}
Point.y = 3;
Ship.transform.Rotate(0, Vector3.Normalize(Ship.transform.InverseTransformDirection(Point - Ship.transform.position)).x * Time.deltaTime * 720, 0);
Ship.transform.position += transform.forward * Time.deltaTime * Speed;
}
}
}
}

И еще вопрос по теме - Есть ли возможность проверять объект на неподвижность?
Просто блок остановки - мне не очень нравится ...

 
СообщениеОтличная идея - спасибо. Завтра попробую - отпишусь.

Добавлено (26 Сен 2015, 10:59)
---------------------------------------------
Спасибо! Вот что получилось благодаря Вашему совету

public class ShipMove : MonoBehaviour {

public Vector3 Point;
private float Speed = 1;
private float RotateSpeed = 0.001f;
private Ray ray;
private RaycastHit hit;
public GameObject Ship;
public Camera CAM;
private float acceleration = 3;
private float StartDist;
private float CurentDist;
private float currentSpeed;
public float MaxSpeed;

void Update()
{
if (Input.GetKey(KeyCode.Mouse0))
{
StartDist = (Vector3.Distance(Ship.transform.position, Point));
CurentDist = (Vector3.Distance(Ship.transform.position, Point));

ray = CAM.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit, 100f) == true)
{
Point = hit.point;
}
}
if (Vector3.Distance(Ship.transform.position, Point) > 1) // Если мы нажали не на корабле.
{
if (hit.collider.tag == "Map") //Если луч коснулся карты
{
print(Speed);
CurentDist = (Vector3.Distance(Ship.transform.position, Point));
if (CurentDist > (StartDist / 2)) // Ускорение
{
Speed += acceleration * Time.deltaTime;
if (Speed > MaxSpeed) { Speed = MaxSpeed; }
}
if (CurentDist < (StartDist / 2)) // Торможение
{
Speed -= acceleration * Time.deltaTime;
if (Speed < 0) { Speed = 0; }
}
if (Vector3.Distance(Ship.transform.position, Point) <= 1.5) //остановка
{
Speed = 0;
}
Point.y = 3;
Ship.transform.Rotate(0, Vector3.Normalize(Ship.transform.InverseTransformDirection(Point - Ship.transform.position)).x * Time.deltaTime * 720, 0);
Ship.transform.position += transform.forward * Time.deltaTime * Speed;
}
}
}
}

И еще вопрос по теме - Есть ли возможность проверять объект на неподвижность?
Просто блок остановки - мне не очень нравится ...


Автор - KriatonuS
Дата добавления - 26 Сен 2015 в 10:59
VolkOrievithДата: Вс, 27 Сен 2015, 11:58 | Сообщение # 8
Нет аватара
 
Сообщений: 222
Награды: 0
Репутация: 53
Статус: Offline
Я так понял, rigidbody вы не используете, так что можно мерить скорость в FixedUpdate.
переменная LatePosition (vector3)
переменная Velocity (vector3)
Код

void Start () {
LatePosition = transform.position;
}
void FixedUpdate () {
Velocity = (transform.position - LatePosition) / time.fixedDeltaTime;
LatePosition = transform.position;
}

Velocity - твоя скорость.
 
СообщениеЯ так понял, rigidbody вы не используете, так что можно мерить скорость в FixedUpdate.
переменная LatePosition (vector3)
переменная Velocity (vector3)
Код

void Start () {
LatePosition = transform.position;
}
void FixedUpdate () {
Velocity = (transform.position - LatePosition) / time.fixedDeltaTime;
LatePosition = transform.position;
}

Velocity - твоя скорость.

Автор - VolkOrievith
Дата добавления - 27 Сен 2015 в 11:58
Форум Игроделов » UNITY3D » СКРИПТИНГ » Перемещение корабля как в Space Rangers
  • Страница 1 из 1
  • 1
Поиск:
Загрузка...

Game Creating CommUnity © 2009 - 2024