Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   www.boolean.name > Программирование игр для компьютеров > Unity > Уроки

Ответ
 
Опции темы
Старый 16.11.2011, 09:27   #1
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,502
Написано 2,957 полезных сообщений
(для 5,222 пользователей)
Движение 2D космического корабля

Решил написать пример, как можно организовать управление перемещением 2D космическим кораблем.



Ссылка на Web-плеер: http://shgames.ru/unity/astro/

В аттаче пакадж со скриптом и сценой.

Скрипт собственно вот:
using UnityEngine;

public class 
SpaceShipController MonoBehaviour
{
    public 
float speed 5// максимальная скорость корабля в секунду
    
public float rotationSpeed 90// максимальный поворот в секунду
    
public Transform shipModel// сслыка на модель корабля (должна быть дочерним объектом)

    // значение вращения корпуса по умолчанию
    
private Quaternion _shipDefaultRotation;

    
// текущий поворот корпуса
    
private float _shipRotation 0;
    
// текущая скорость
    
private float _shipSpeed 0;

    public 
void Start()
    {
        
// сохраняем значение вращения корпуса по умолчанию
        
_shipDefaultRotation shipModel.localRotation;
    }

    public 
void Update()
    {
        
// скорость корабля с дампингом
        
_shipSpeed Mathf.Lerp(_shipSpeedMathf.Max(Input.GetAxis("Vertical"), 0), 0.1f);
        
// смещаем корабль в перед на нужную величину
        
transform.position += transform.forward _shipSpeed speed Time.deltaTime;

        var 
rot Input.GetAxis("Horizontal");
        
// вращаем корабль по оси Z
        
transform.rotation *= Quaternion.AngleAxis(rot rotationSpeed Time.deltaTimetransform.up);

        
// рассчитываем поврот корпуса корабля с дампингом
        
_shipRotation Mathf.Lerp(_shipRotation, -rot 300.1f);
        
// рассчитываем значение поворота корпуса
        
shipModel.localRotation _shipDefaultRotation Quaternion.AngleAxis(_shipRotationVector3.right);

    }

Желаю удачно разобраться
Вложения
Тип файла: zip AstroUnity.zip (45.5 Кб, 275 просмотров)
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Эти 5 пользователя(ей) сказали Спасибо pax за это полезное сообщение:
Friend123 (04.06.2012), Harter (17.11.2011), Nex (16.11.2011), Nuprahtor (21.11.2011), St_AnGer (29.04.2016)
Старый 16.11.2011, 09:46   #2
Amatsu
Дэвелопер
 
Аватар для Amatsu
 
Регистрация: 24.07.2008
Сообщений: 1,544
Написано 1,095 полезных сообщений
(для 2,704 пользователей)
Ответ: Движение 2D космического корабля

// Player class
public class Player {

  public GameObject move_pivot, rotate_pivot, model;
  public float yaw_speed,yaw_rotation,x_speed,z_speed;

  // Procedure of player creation
  public void Create() {
    move_pivot = new GameObject("player");
    rotate_pivot = new GameObject("player_rotate_pivot");
    rotate_pivot.transform.parent = move_pivot.transform; 

    model = Instantiate(player_mesh) as GameObject;
    model.transform.localScale = new Vector3(10, 10, 10);
    model.transform.name = "player_model";
    model.transform.parent = rotate_pivot.transform; 
  }
	
  // Procedure of player update
  public void Update(float yaw_acceleration, float speed_acceleration) {
			
    float width;

    if (Input.GetKey(KeyCode.LeftArrow)) {yaw_speed += -yaw_acceleration;};
    if (Input.GetKey(KeyCode.RightArrow)) {yaw_speed += yaw_acceleration;};

    yaw_speed *= 0.85F;
    yaw_rotation += yaw_speed;
    rotate_pivot.transform.localRotation = Quaternion.Euler(0, yaw_rotation, 0);

    model.transform.localRotation = Quaternion.Euler(0, 0, yaw_speed * 10);

    if (Input.GetKey(KeyCode.UpArrow)) {
      x_speed += (Mathf.Sin(((rotate_pivot.transform.transform.eulerAngles.y - 180) * Mathf.PI) / 180F) * speed_acceleration);
      z_speed += (Mathf.Cos(((rotate_pivot.transform.transform.eulerAngles.y - 180) * Mathf.PI) / 180F) * speed_acceleration);
    };

    x_speed *= 0.95F;
    z_speed *= 0.95F;

    width = ((float)Screen.width / (float)Screen.height) * 4.6F;

    if ((move_pivot.transform.position.x < -width) & (x_speed < 0)) {x_speed = 0;};			
    if ((move_pivot.transform.position.x > width) & (x_speed > 0)) {x_speed = 0;};
    if ((move_pivot.transform.position.z < -4.4F) & (z_speed < 0)) {z_speed = 0;};			
    if ((move_pivot.transform.position.z > 4.4F) & (z_speed > 0)) {z_speed = 0;};

    move_pivot.transform.Translate(x_speed, 0, z_speed);
  }
}
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Wegox (07.04.2012)
Старый 16.11.2011, 09:52   #3
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,502
Написано 2,957 полезных сообщений
(для 5,222 пользователей)
Ответ: Движение 2D космического корабля

2Amatsu Хоть бы описание какое написал.

UPD: твое движение не зависит от времени - следовательно будет работать на каждой машине с разной скоростью.

UPD2: Если конечно ты не изобрел свою версию твинига для Unity

UPD3: В моем примере только крен не зависит... надо бы потом поправить.
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Старый 16.11.2011, 09:54   #4
Amatsu
Дэвелопер
 
Аватар для Amatsu
 
Регистрация: 24.07.2008
Сообщений: 1,544
Написано 1,095 полезных сообщений
(для 2,704 пользователей)
Ответ: Движение 2D космического корабля

Сообщение от pax Посмотреть сообщение
2Amatsu Хоть бы описание какое написал.
Это код управления кораблем из Kefir Fighter, переложенный на юнити
(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо Amatsu за это полезное сообщение:
pax (16.11.2011), Wegox (07.04.2012)
Старый 16.11.2011, 10:01   #5
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,502
Написано 2,957 полезных сообщений
(для 5,222 пользователей)
Ответ: Движение 2D космического корабля

Еще хотел сказать - моделер из меня в блендере так себе. На работе больше нету софта. Там в скрипте вращение корпуса я реализовал через вектор Vector3.right - это потому, что модель корабля у меня не по осям повернута (не смог повернуть правильно в блендере ). Можете в сцене посмотреть что там не так. Если правильно модель ориентировать: Вектор вперед - Z, вектор вверх - Y. То тогда вместо Vector3.right подставляем Vector3.forward.
__________________
Blitz3d to Unity Wiki

Последний раз редактировалось pax, 16.11.2011 в 11:13.
(Offline)
 
Ответить с цитированием
Старый 16.11.2011, 10:08   #6
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,502
Написано 2,957 полезных сообщений
(для 5,222 пользователей)
Ответ: Движение 2D космического корабля

Небольшое дополнение (избавимся от "магических" чисел):
using UnityEngine;

public class 
SpaceShipController MonoBehaviour
{
    public 
float speed 5// максимальная скорость корабля в секунду
    
public float speedDamping 0.1f// дампинг скорости

    
public float rotationSpeed 90// максимальный поворот в секунду
    
public float rotationDamping 0.1f// дампинг вращения корпуса
    
public float maxRotationAngle 30f// максимальный укол крена корпуса

    
public Transform shipModel// сслыка на модель корабля (должна быть дочерним объектом)


    // значение вращения корпуса по умолчанию
    
private Quaternion _shipDefaultRotation;

    
// текущий поворот корпуса
    
private float _shipRotation;
    
// текущая скорость
    
private float _shipSpeed;

    public 
void Start()
    {
        
// сохраняем значение вращения корпуса по умолчанию
        
_shipDefaultRotation shipModel.localRotation;
    }

    public 
void Update()
    {
        
// скорость корабля с дампингом
        
_shipSpeed Mathf.Lerp(_shipSpeedMathf.Max(Input.GetAxis("Vertical"), 0), speedDamping);
        
// смещаем корабль в перед на нужную величину
        
transform.position += transform.forward _shipSpeed speed Time.deltaTime;

        var 
rot Input.GetAxis("Horizontal");
        
// вращаем корабль по оси Z
        
transform.rotation *= Quaternion.AngleAxis(rot rotationSpeed Time.deltaTimetransform.up);

        
// рассчитываем поврот корпуса корабля с дампингом
        
_shipRotation Mathf.Lerp(_shipRotation, -rot maxRotationAnglerotationDamping);
        
// рассчитываем значение поворота корпуса
        
shipModel.localRotation _shipDefaultRotation Quaternion.AngleAxis(_shipRotationVector3.right);

    }

__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Старый 16.11.2011, 12:57   #7
RegIon
Элита
 
Аватар для RegIon
 
Регистрация: 16.01.2010
Адрес: Новосибирск
Сообщений: 2,156
Написано 502 полезных сообщений
(для 1,012 пользователей)
Ответ: Движение 2D космического корабля

blender3d.org.ua Учись Блендеру,PAX.
__________________
Сайт: http://iexpo.ml
(Offline)
 
Ответить с цитированием
Старый 16.11.2011, 13:12   #8
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,502
Написано 2,957 полезных сообщений
(для 5,222 пользователей)
Ответ: Движение 2D космического корабля

Я не моделер
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо pax за это полезное сообщение:
L.D.M.T. (16.11.2011), Lestar (16.11.2011)
Старый 20.11.2011, 09:59   #9
pax
Unity/C# кодер
 
Аватар для pax
 
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,502
Написано 2,957 полезных сообщений
(для 5,222 пользователей)
Ответ: Движение 2D космического корабля

Итак часть вторая - пролет через края экрана.

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

1. Скрипт расчета области игры.
using UnityEngine;

// скрипт рассчитывает область, выходя за которую 
// корабль перемещается на другую сторону экрана
public class RectangleArea MonoBehaviour
{
    
// статическая переменная области, 
    // которая используется в скрипте RectangleAreaObject
    
public static Vector3 areaSize;
    public static 
Vector3 areaHalfSize;

    
// буферная область для перелета за экраном
    
public float bufferArea;

    
// считаем область каждый кадр, 
    // но по хорошему надо считать только при смене разрешения игры
    
public void Update()
    {
        
CalculateArea();
    }

    
// функция рассчета области
    
public void CalculateArea()
    {
        var 
cam Camera.mainCamera;
        var 
camTransform cam.transform;
        
// считаем что камера оп осям z и x не смещена, т.е. x и z равны нулю
        // само действи игры происходит в проскости x0z
        
var distance camTransform.position.y;
        var 
halfAngle cam.fov 0.5f;
        var 
height distance Mathf.Tan(halfAngle Mathf.Deg2Rad) * 2;
        var 
width height cam.aspect;
        
areaSize = new Vector3(width bufferArea20height bufferArea);
        
areaHalfSize areaSize 0.5f;
    }

    
// при нажатии Play можно увидеть саму область
    
public void OnDrawGizmos()
    {
        
Gizmos.DrawWireCube(Vector3.zeroareaSize);
    }

Вешаем этот скрипт на пустой объект, объект должен находиться в сцене, чтобы выполнялся расчет.
В примере буферная зона равна 10 единицам мира.

2. Скрипт для объектов.
using UnityEngine;

// скрипт необходимо вешать на каждый объект,
// который должен переходить через края экрана
public class RectangleAreaObject MonoBehaviour
{
    public 
void Update()
    {
        var 
size RectangleArea.areaSize;
        var 
halfSize RectangleArea.areaHalfSize;

        
// если координата объекта выходит за половину размера области, 
        // то смещаем объект в обратную сторону по этой координате на полный размер

        
if (transform.position.halfSize.x)
        {
            var 
pos transform.position;
            
pos.-= size.x;
            
transform.position pos;
        }
        else if (
transform.position.< -halfSize.x)
        {
            var 
pos transform.position;
            
pos.+= size.x;
            
transform.position pos;
        }

        if (
transform.position.halfSize.z)
        {
            var 
pos transform.position;
            
pos.-= size.z;
            
transform.position pos;
        }
        else if (
transform.position.< -halfSize.z)
        {
            var 
pos transform.position;
            
pos.+= size.z;
            
transform.position pos;
        }

    }

Этот скрипт вешаем на корабль на тот же объект, на котором висит контроллер корабля, написанный в предыдущем примере.

Собственно результат: http://shgames.ru/unity/astro_example2/

В аттаче доработанный пример.
Вложения
Тип файла: zip astro_example2.zip (47.7 Кб, 228 просмотров)
__________________
Blitz3d to Unity Wiki
(Offline)
 
Ответить с цитированием
Эти 3 пользователя(ей) сказали Спасибо pax за это полезное сообщение:
Lestar (20.11.2011), Nex (20.11.2011), Nuprahtor (21.11.2011)
Старый 04.06.2012, 10:37   #10
Friend123
AnyKey`щик
 
Регистрация: 04.06.2012
Сообщений: 1
Написано 0 полезных сообщений
(для 0 пользователей)
Ответ: Движение 2D космического корабля

Вот вопрос возник. Я пытался проделать похожее на своем корабле, он у меня крутится вокруг оси Z, но не поворачивается по Y. Это я так понимаю из-за того, что у вас объект сделан дочерним, а если его не делать дочерним, то что нужно поменять, чтобы работало как тут?
(Offline)
 
Ответить с цитированием
Старый 28.04.2016, 19:48   #11
Mopnex
AnyKey`щик
 
Регистрация: 28.04.2016
Сообщений: 1
Написано 0 полезных сообщений
(для 0 пользователей)
Ответ: Движение 2D космического корабля

А как сделать чтобы корабль так же летал, плавно входил в повороты, но не кнопками WASD а по клику мышки? чтобы летел в конкретно - заданную точку?
(Offline)
 
Ответить с цитированием
Старый 28.04.2016, 20:16   #12
Arton
Быдлокодер
 
Аватар для Arton
 
Регистрация: 05.07.2009
Адрес: Проспит
Сообщений: 4,495
Написано 1,968 полезных сообщений
(для 4,710 пользователей)
Ответ: Движение 2D космического корабля

Сообщение от Mopnex Посмотреть сообщение
А как сделать чтобы корабль так же летал, плавно входил в повороты, но не кнопками WASD а по клику мышки? чтобы летел в конкретно - заданную точку?
Как правило берутся координаты куда кликнул мышью, затем объект разворачивают в сторону точки и двигают к ней.
(Offline)
 
Ответить с цитированием
Старый 29.04.2016, 11:54   #13
Жека
Дэвелопер
 
Регистрация: 04.09.2005
Адрес: Красноярск
Сообщений: 1,374
Написано 489 полезных сообщений
(для 882 пользователей)
Ответ: Движение 2D космического корабля

Можно так.
Есть вектор скорости - это направление, в котором летит корабль.
По клику мышки запоминаем точку клика.
Далее рассчитываем угол поворота от текущего вектора скорости до линии, соединяющей текущее положение и точку клика.
Однако поворачиваем не сразу на весь этот угол, а на небольшую его часть.
В итоге получится плавный разворот.
Функция Lerp вроде как помогает получать дельту значения.
(Offline)
 
Ответить с цитированием
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +1, время: 09:02.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com