В прошлый раз мы рисовали и делали линии физическим телом, используя haxeflixel. Сегодня сделаем почти тоже самое используя Unity5. Но повторятся мы не будем и набросаем прототип бесконечного раннера.
Не будем усложнять и сделаем нашего героя доблестным кругом с тремя отметками, дабы чувствовалась скорость вращения. (Добавляем Sprite Renderer с нашим мега-крутым кругом)
Добавим герою компоненты RigidBody2d и CircleCollider2d. И вот этот простой скрипт, задающий скорость вращения:
using UnityEngine; using System.Collections; //этот скрипт требует наличие RigidBody2d [RequireComponent (typeof (Rigidbody2D))] public class Hero : MonoBehaviour { private Rigidbody2D body; //Максимальная скорость вращения private const float MAX_ANGULAR_VEL = - 1400; void Awake () { //Кэшируем Rigidbody2D body = gameObject.GetComponent (); } void Update () { //Каждый кадр добавляем крутящий момент body.AddTorque (MAX_ANGULAR_VEL/10); //Ограничиваем крутящий момент максимальным значением if (body.angularVelocity < MAX_ANGULAR_VEL) { body.angularVelocity = MAX_ANGULAR_VEL; } } }
Теперь немного доработаем камеру. Добавим скрипт
using UnityEngine; using System.Collections; public class SimpleCameraMoving : MonoBehaviour { //Делаем так, чтобы наше private поле было видно в инспекторе [SerializeField] private Transform Hero; private Vector2 _startPoint; void Awake() { //Запоминаем начальное положение героя _startPoint = Hero.position; } void Update () { //двигаем камеру за героем, //сохраняя положение героя относительно камеры transform.position = new Vector3( Hero.position.x - _startPoint.x/2, transform.position.y, transform.position.z); } }
Это простейший скрипт слежения за объектом с сохранением относительного расположения (чтобы герой был не по центру экрана, а в том месте, где мы его располагаем изначально). Не забываем в инспекторе перетянуть нашего героя в поле Hero.
Теперь создаем объект, в котором мы будем рисовать.
– компонент LineRenderer , для которого необходимо создать материал. Материалу можно не задавать текстуру, а шейдер выставить Particles/Additive.
– компонент EdgeCillider2d – который и будет отвечать за нашу физику.
Настройки можно посмотреть на скриншоте. Поэкспериментировать самим – тоже не будет лишним.
Если в двух словах, то скрипт ждет пока кнопка мыши будет нажата, после этого каждый кадр записывает координаты мыши. По этим координатам отрисовывается линия. Так же эти точки передаются в edge collider, где по ним создается физика.
using UnityEngine; using System.Collections; using System.Collections.Generic; [RequireComponent (typeof (EdgeCollider2D), typeof(LineRenderer))] public class DrawLine : MonoBehaviour { private LineRenderer line; private bool isMousePressed; private List poinsOfLine; private Vector3 mousePos; private EdgeCollider2D collider; void Awake() { //кэшируем компоненты line = gameObject.GetComponent(); line.SetVertexCount(0); isMousePressed = false; poinsOfLine = new List(); collider = gameObject.GetComponent (); } void Update () { if(Input.GetMouseButtonDown(0)) { //если нажата кнопка мыши isMousePressed = true; //удаляем отрисовку линии line.SetVertexCount(0); //чистим сохраненные точки poinsOfLine.Clear(); //отключаем физику collider.enabled = false; } else if(Input.GetMouseButtonUp(0)) { isMousePressed = false; } if(isMousePressed) { mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); mousePos.z=0; // ограничение, которое позволяет рисовать только слева направо if (poinsOfLine.Count > 0 && mousePos.x < poinsOfLine[poinsOfLine.Count - 1].x) { return; } //сохраняем текущее расположение мыши poinsOfLine.Add (mousePos); //передаем точки для отрисовки в linerenderer line.SetVertexCount (poinsOfLine.Count); line.SetPosition (poinsOfLine.Count - 1, (Vector3)poinsOfLine [poinsOfLine.Count - 1]); if (poinsOfLine.Count > 1) { //создаем физику по нашим точкам collider.points = poinsOfLine.ToArray(); collider.enabled = true; } } } }
При беглом осмотре кода в глаза бросаются бесконечно растущие значения координат и разрастающиеся листы и массивы – все это в боевом проекте, при длительных игровых сессиях, приведет к неприятным последствиям. Но мы не забываем. что это прототип. Переписывать и оптимизировать будем когда начнем писать игру =)
Собственно это все, что я хотел рассказать.
Также я добавил на камеру bloom из standart assets (кстати, они в unity 5 бесплатные). И объект пола привязанный к камере, что бы наш доблестный герой не проваливался. Посмотреть, что получилось можно здесь WebGL (советую поставить Daft Punk на фоне =) )
UPD: У некоторых возникли проблемы с WebGL , вот билд с использованием UnityPlayer.