|
16.01.2011, 14:06
|
#1
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Расширение редактора Unity
Что-то нет настроя на серьезное программирование сегодня... так что решил поделиться опытом расширения редактора Unity.
Пример я выбрал такой не очень сложный, но и немного интересный. Мы с Вами научимся расширять редактор под свои задачи, в частности мы попробуем создать редактируемую кривую Безье третьего порядка.
Теория по кривым Безье находится тут
А нам понадобится одна формула:
Выглядит эта кривая таким вот образом:
Имеется 4 опорных точки, подставляя которые в вышеприведенную формулу и изменяя параметр t можно вычислить положение на кривой.
Первый шаг.
Подготовим компонент, выполняющий расчет и отображение кривой когда объект выбран:
Bezier.cs
using UnityEngine;
public class Bezier : MonoBehaviour { // опорные точки кривой public Vector3 P0 = Vector3.zero; public Vector3 P1 = new Vector3(0, 0, 1); public Vector3 P2 = new Vector3(1, 0, 1); public Vector3 P3 = new Vector3(1, 0, 0);
// интерполяция по кривой используя формулу кривой Bezier третьего порядка public Vector3 Evaluate(float t) { float t1 = 1 - t; return t1 * t1 * t1 * P0 + 3 * t * t1 * t1 * P1 + 3 * t * t * t1 * P2 + t * t * t * P3; }
// существует два события, которые можно использовать для отображения // "не визуального" объекта - OnDrawGizmos и OnDrawGizmosSelected // первый выполняется всегда, второй - когда объект выбран // функции рисования находятся в классе Gizmos public void OnDrawGizmosSelected() { // отобразим кривую как 50 сегментов Gizmos.color = Color.green; for (int i = 1; i < 50; i++) { float t = (i - 1f) / 49f; float t1 = i / 49f; Gizmos.DrawLine(Evaluate(t), Evaluate(t1)); } } }
Добавив созданный компонент какому-либо объекту сцены и выбрав его мы увидим результат:
Второй шаг
Скрипты для редактора Unity должны быть помещены в отдельную папку с названием Editor. Где создавать такую папку выбирайте сами. Папок с именем Editor может быть сколько угодно в проекте.
При компиляции проекта Unity создает отдельную сборку для Editor-скриптов и они не попадут в построенное приложение.
Итак что мы хотим добавить нашему компоненту, чтобы работа с ним была удобнее?
Мне на ум приходят следующие возможности:
1. Перемещать точки кривой в сцене.
2. Отобразить дополнительно длину кривой во время редактирования в инспекторе.
Чтобы создать расширение компонента, надо создать класс, унаследованный от класса Editor и добавить ему атрибут CustomEditor в котором указать тип нашего компонента. Все эти классы находятся в пространстве имен UnityEditor.
Для того чтобы добавить функционал в сцену мы воспользуемся событием OnSceneGUI, а для отображения длины кривой - OnInspectorGUI (эта функция является перегружаемой):
Editor/BezierEditor.cs
using UnityEngine; using UnityEditor;
[CustomEditor(typeof(Bezier))] public class BezierEditor : Editor { // данная функция выполняет отрисовку инспектора компонента public override void OnInspectorGUI() { // выполняем отрисовку инспектора по умолчанию DrawDefaultInspector();
// ссылка на компонент Bezier bezier = target as Bezier; if (bezier) { // вычисляем длину кривой так же по 50-ти отрезкам float length = 0; for (int i = 1; i < 50; i++) { float t = (i - 1f) / 49f; float t1 = i / 49f; length += (bezier.Evaluate(t) - bezier.Evaluate(t1)).magnitude; }
// отображаем длину кривой в инспекторе GUILayout.Label(string.Format("Curve length: {0}", length)); } }
// отрисовка в сцене, здесь в отличии от компонента, где мы использовали // для отрисовки класс Gizmos используется клас Handles (манипуляторы) public void OnSceneGUI() { Bezier bezier = target as Bezier; if (bezier) { //Нарисуем линии манипуляторов Handles.DrawLine(bezier.P0, bezier.P1); Handles.DrawLine(bezier.P2, bezier.P3);
// Для каждой контрольной точки создаем манипулятор в виде сферы Quaternion rot = Quaternion.identity; float size = HandleUtility.GetHandleSize(bezier.P0) * 0.2f; bezier.P0 = Handles.FreeMoveHandle(bezier.P0, rot, size, Vector3.zero, Handles.SphereCap); bezier.P1 = Handles.FreeMoveHandle(bezier.P1, rot, size, Vector3.zero, Handles.SphereCap); bezier.P2 = Handles.FreeMoveHandle(bezier.P2, rot, size, Vector3.zero, Handles.SphereCap); bezier.P3 = Handles.FreeMoveHandle(bezier.P3, rot, size, Vector3.zero, Handles.SphereCap); }
// если мы двигали контрольные точки, то мы должны указать редактору, // что объект изменился (стал "грязным") if (GUI.changed) EditorUtility.SetDirty(target); }
}
Вот теперь мы должны быть довольны результатом.
Манипуляторы в сцене:
Длина кривой в инспекторе:
Конечная структура проекта:
Желаю всем удачи в исследовании Unity!
|
(Offline)
|
|
Эти 11 пользователя(ей) сказали Спасибо pax за это полезное сообщение:
|
Amatsu (21.11.2011), baton4ik (16.01.2011), Fatalix3d (23.02.2011), ffinder (17.01.2011), FireOwl (15.01.2012), Harter (15.01.2012), HolyDel (16.01.2011), Lestar (28.01.2012), maxturbo (09.03.2011), Nuprahtor (16.01.2011), Randomize (11.03.2012)
|
16.01.2011, 15:06
|
#2
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Расширение редактора Unity
И на javascript :
Bezier.js
// опорные точки кривой var P0 : Vector3 = Vector3.zero; var P1 : Vector3 = Vector3(0, 0, 1); var P2 : Vector3 = Vector3(1, 0, 1); var P3 : Vector3 = Vector3(1, 0, 0);
// интерполяция по кривой используя формулу кривой Bezier третьего порядка function Evaluate(t : float) : Vector3 { var t1 : float = 1 - t; return t1 * t1 * t1 * P0 + 3 * t * t1 * t1 * P1 + 3 * t * t * t1 * P2 + t * t * t * P3; }
// существует два события, которые можно использовать для отображения // "не визуального" объекта - OnDrawGizmos и OnDrawGizmosSelected // первый выполняется всегда, второй - когда объект выбран // функции рисования находятся в классе Gizmos function OnDrawGizmosSelected() { // отобразим кривую как 50 сегментов Gizmos.color = Color.green; for (var i = 1; i < 50; i++) { var t : float = (i - 1f) / 49f; var t1 : float = i / 49f; Gizmos.DrawLine(Evaluate(t), Evaluate(t1)); } }
Editor/BezierEditor.js
@CustomEditor(Bezier) class BezierEditor extends Editor { // данная функция выполняет отрисовку инспектора компонента override function OnInspectorGUI() { // выполняем отрисовку инспектора по умолчанию DrawDefaultInspector();
// ссылка на компонент var bezier : Bezier = target; if (bezier) { // вычисляем длину кривой так же по 50-ти отрезкам var length : float = 0; for (var i = 1; i < 50; i++) { var t : float = (i - 1f) / 49f; var t1 : float = i / 49f; length += (bezier.Evaluate(t) - bezier.Evaluate(t1)).magnitude; }
// отображаем длину кривой в инспекторе GUILayout.Label(System.String.Format("Curve length: {0}", length)); } }
// отрисовка в сцене, здесь в отличии от компонента, где мы использовали // для отрисовки класс Gizmos используется клас Handles (манипуляторы) function OnSceneGUI() { var bezier : Bezier = target; if (bezier) { //Нарисуем линии манипуляторов Handles.DrawLine(bezier.P0, bezier.P1); Handles.DrawLine(bezier.P2, bezier.P3);
// Для каждой контрольной точки создаемманипулятор в виде сферы var rot : Quaternion = Quaternion.identity; var size : float = HandleUtility.GetHandleSize(bezier.P0) * 0.2; bezier.P0 = Handles.FreeMoveHandle(bezier.P0, rot, size, Vector3.zero, Handles.SphereCap); bezier.P1 = Handles.FreeMoveHandle(bezier.P1, rot, size, Vector3.zero, Handles.SphereCap); bezier.P2 = Handles.FreeMoveHandle(bezier.P2, rot, size, Vector3.zero, Handles.SphereCap); bezier.P3 = Handles.FreeMoveHandle(bezier.P3, rot, size, Vector3.zero, Handles.SphereCap); }
// если мы двигали контрольные точки, то мы должны указать редактору, // что объект изменился (стал "грязным") if (GUI.changed) EditorUtility.SetDirty(target); }
}
|
(Offline)
|
|
Эти 7 пользователя(ей) сказали Спасибо pax за это полезное сообщение:
|
|
16.01.2011, 17:33
|
#3
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Расширение редактора Unity
Продолжаем расширять редактор.
Сейчас я хочу рассказать о том, как создавать собственные окна на основе реализации простой функции LookAt.
Я честно говоря не знаю, есть ли такая нативная функция (сочетание клавиш). Но на ее примере очень легко продемонстрировать то, как можно расширять редактор своими утилитами.
Итак что мы должны сделать, чтобы создать собственное окошко: - Создать класс унаследованный от класса EditorWindow, который находится в пространстве имен UnityEditor.
- Добавить статический метод создания окна.
- Пометить этот метод атрибутом MenuItem, чтобы зарегистрировать его в контекстном меню редактора.
- Реализовать у класса метод OnGUI, выполняющий отрисовку содержимого.
- Не забыть положить свой созданный класс в папку с названием Editor, т.к. это расширение редактора.
Итак реализация:
LookAtWindow.cs
using UnityEngine; using UnityEditor;
public class LookAtWindow : EditorWindow {
// Регистрируем пункт меню и функцию, выполняющую открытие окна [MenuItem("Window/Look At Window")] public static void CreateWindow() { LookAtWindow window = GetWindow<LookAtWindow>(); window.title = "Look At Window"; }
// объект для поворота public Transform source; // цель public Transform target;
// Функция отрисовки окна public void OnGUI() { // поле для указания исходного объекта GUILayout.BeginHorizontal(); GUILayout.Label("Source:", GUILayout.Width(120)); source = (Transform)EditorGUILayout.ObjectField(source, typeof(Transform)); GUILayout.EndHorizontal();
// поле для указания цели GUILayout.BeginHorizontal(); GUILayout.Label("Target:", GUILayout.Width(120)); target = (Transform)EditorGUILayout.ObjectField(target, typeof(Transform)); GUILayout.EndHorizontal();
// запоминаем текущий цвет GUI для восстановления Color oldColor = GUI.color;
// проверяем наричие объекта для поворота и цели bool flag = false; if (source == null || target == null) { GUI.color = Color.red; GUILayout.Label("Selcect Source and Target!"); flag = true; GUI.color = oldColor; }
// если цель является объектом if ((source == target) && !flag) { GUI.color = Color.red; GUILayout.Label("Source equals Target!"); GUI.color = oldColor; }
// Делаем кнопку неактивной если не выполняется условие GUI.enabled = !flag && (source != target);
// свободное место GUILayout.FlexibleSpace();
// кнопка, выполняющая действие if (GUILayout.Button("Look At")) { source.LookAt(target); }
// снова активируем GUI GUI.enabled = true; GUILayout.Space(8);
} }
Результаты.
Состав проекта:
Контекстное меню:
Само окно встроенное в оболочку:
Вот в принципе и все, о чем хотел рассказать. Удачи!
|
(Offline)
|
|
Эти 6 пользователя(ей) сказали Спасибо pax за это полезное сообщение:
|
|
17.01.2011, 00:27
|
#4
|
Дэвелопер
Регистрация: 10.09.2007
Сообщений: 1,442
Написано 793 полезных сообщений (для 1,460 пользователей)
|
Ответ: Расширение редактора Unity
Ну вот, отличный годный урок.
Прочитал с большим удовольствием.
Есть пара мелких моментов, на которые еще стоит обратить внимание.
1) target необходимо явно приводить к типу объекта, который мы хотим "инспектировать". По умолчанию он имеет тип object.
2) прекратить делать версии скриптов для UnityScript, чтобы не провоцировать людей изучать этот появившийся по недоразумению язык.
|
(Offline)
|
|
Эти 4 пользователя(ей) сказали Спасибо ffinder за это полезное сообщение:
|
|
23.02.2011, 15:23
|
#5
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Расширение редактора Unity
Сегодня хочу поделиться еще одним простым способом добавления собственных функций в редактор Unity, а именно использованию класса ScriptableWizard.
Так же как и в прошлый раз я реализую функцию LookAt, но с использованием других средств.
Итак разбираем код:
using UnityEditor; using UnityEngine;
public class LookAtWizard : ScriptableWizard { // две публичные переменные, которые будут параметрами визарда public Transform source; // объект для поворота public Transform target; // цель
// регистрация функции создания визарда в меню Unity [MenuItem("Window/Look At Wizard")] static void CreateWizard() { // создаем визард с одной кнопкой "Look At!" ScriptableWizard.DisplayWizard<LookAtWizard>("Look At", "Look At!");
// если необходимо реализовать вторую // кнопку, то можно воспользоваться // другой перегрузкой метода // ScriptableWizard.DisplayWizard<> // и реализовать функцию // void OnWizardOtherButton () }
// флаг успешной настройки визарда private bool _wizardOk = false;
// выполнение функции визарда - OnWizardCreate() void OnWizardCreate() { // выполняем только когда исходные данные верны if (_wizardOk) { source.LookAt(target); } }
// функция выполняется при создании визарда // и при изменении исходных данных пользователем void OnWizardUpdate() { _wizardOk = false; // один из параметров не указан if (source == null || target == null) { // helpString выдает подсказки пользователю helpString = "Selcect Source and Target!"; } // если цель и объект совпадают else if ((source == target) && (source != null) ) { helpString = "Source equals Target!"; } else { // все проверки пройдены helpString = "Press \"Look At!\"!"; _wizardOk = true; } } }
Не забываем называть скрипт правильно (LookAtWizard.cs) и положить его в папку с названием Editor.
Вот и результат:
|
(Offline)
|
|
Эти 5 пользователя(ей) сказали Спасибо pax за это полезное сообщение:
|
|
21.11.2011, 21:15
|
#6
|
Дэвелопер
Регистрация: 24.07.2008
Сообщений: 1,544
Написано 1,095 полезных сообщений (для 2,706 пользователей)
|
Ответ: Расширение редактора Unity
Как я понял, данный тип расширения редактора работает только в случае, если соответствующий скрипт положен в папку Editor конкретного проекта? То есть если загрузить другой проект - надстройки не будет? А нельзя ли реализовать постоянный апгрейд редактора, не принадлежащий к конкретному проекту?
з.ы. может я тупой и тут уже был ответ на этот вопрос. Но я не заметил
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
21.11.2011, 21:32
|
#7
|
Элита
Регистрация: 26.07.2008
Сообщений: 1,972
Написано 1,095 полезных сообщений (для 3,923 пользователей)
|
Ответ: Расширение редактора Unity
Можно все скрипты редактора загрузить в специальный пэккедж, который потом легко добавляется во все создаваемые проекты.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
21.11.2011, 22:13
|
#8
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Расширение редактора Unity
Официально такое не поддерживается.
|
(Offline)
|
|
15.01.2012, 21:14
|
#9
|
Нуждающийся
Регистрация: 14.01.2011
Сообщений: 72
Написано 9 полезных сообщений (для 44 пользователей)
|
Ответ: Расширение редактора Unity
Подскажите, а каким образом можно отследить событие нажатия правой кнопкой в окне сцены? Нужно, чтобы при нажатии отображался список - что-то типа контекстного меню.
|
(Offline)
|
|
15.01.2012, 21:45
|
#10
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Расширение редактора Unity
|
(Offline)
|
|
11.03.2012, 20:27
|
#11
|
Бывалый
Регистрация: 21.12.2008
Адрес: UA
Сообщений: 878
Написано 105 полезных сообщений (для 357 пользователей)
|
Ответ: Расширение редактора Unity
А если делать кривую из нескольких бизье или замкнутую фигуру, то как лучше кранить такую кривую?
По 4 вершины на один отрезок(как здесь) не очень удобно т.к. они будут связаны между собой.
Я так понимаю лучше хранить в виде списка таких вершин:
public class Vertex {
public Vector3 p = Vector3.zero;
public Vector3 dirA = Vector3.zero;
public Vector3 dirB = Vector3.zero;
}
Но все формулы для такого вида представления бизье p0, p1, p2, p3.
Я из-за этого даже разделить одну бизье на две не могу)
Конечно можно все время переводить из одного формата в другой, но это не очень удобно.
Да и не пойму как из p0,p1,p2,p3 создать две моих вершины.
|
(Offline)
|
|
11.03.2012, 21:11
|
#12
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Расширение редактора Unity
Очевидно же
v1 = new Vertex{ dirA = Vector3.zero, p = p0, dirB = p1 }
v2 = new Vertex{ dirA = p2, p = p3, dirB = Vector3.zero }
|
(Offline)
|
|
11.03.2012, 22:03
|
#13
|
Бывалый
Регистрация: 21.12.2008
Адрес: UA
Сообщений: 878
Написано 105 полезных сообщений (для 357 пользователей)
|
Ответ: Расширение редактора Unity
Только dirA и dirB это координаты относительно p.
Так что так будет:
a.p = p0;
a.dirA = p1-p0;
b.p = p3;
b.dirB = p2-p3;
a.dirB и b.dirA не восстановить из этих данных.
А как сделать, что бы при нажатии ctrl+z происходила отмена последнего изменение?
|
(Offline)
|
|
11.03.2012, 23:52
|
#14
|
Unity/C# кодер
Регистрация: 03.10.2005
Адрес: Россия, Рязань
Сообщений: 7,568
Написано 3,006 полезных сообщений (для 5,323 пользователей)
|
Ответ: Расширение редактора Unity
Сообщение от WISHMASTER35
А как сделать, что бы при нажатии ctrl+z происходила отмена последнего изменение?
|
http://unity3d.com/support/documenta...ence/Undo.html
|
(Offline)
|
|
13.03.2012, 00:17
|
#15
|
Бывалый
Регистрация: 21.12.2008
Адрес: UA
Сообщений: 878
Написано 105 полезных сообщений (для 357 пользователей)
|
Ответ: Расширение редактора Unity
Написал свой вариант редактирования замкнутых кривых.
т.к. в виде массива Vertex хранить кривую не очень удобно, то вернулся к классу Bezier)
using UnityEngine;
using System.Collections;
[System.Serializable]
public class Bezier {
public Vector3 p0;
public Vector3 p1;
public Vector3 p2;
public Vector3 p3;
public Bezier() {
}
public Bezier(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3) {
this.p0 = p0;
this.p1 = p1;
this.p2 = p2;
this.p3 = p3;
}
public Vector3 Evaluate(float t) {
t = Mathf.Clamp01(t);
float t1 = 1 - t;
return t1 * t1 * t1 * p0 +
3 * t * t1 * t1 * p1 +
3 * t * t * t1 * p2 +
t * t * t * p3;
}
}
using UnityEngine;
using System.Collections;
public class BezierFigure : MonoBehaviour {
public Bezier[] curves = new Bezier[0];
void OnDrawGizmos() {
Gizmos.color = Color.green;
for(int i=0; i<curves.Length; i++) {
Bezier a = curves[i];
DrawBezier(a);
}
}
private void DrawBezier(Bezier bezier) {
for(int i=0; i<30; i++) {
float t1 = i/30.0f;
float t2 = (i+1)/30.0f;
Vector3 a = bezier.Evaluate(t1);
Vector3 b = bezier.Evaluate(t2);
a = transform.TransformPoint(a);
b = transform.TransformPoint(b);
Gizmos.DrawLine(a, b);
}
}
public Bezier[] GetCurves() {
return curves;
}
public void SetCurves(Bezier[] curves) {
this.curves = curves;
}
}
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using System.Collections;
[CustomEditor(typeof(BezierFigure))]
public class BezierEditor : Editor {
public override void OnInspectorGUI() {
DrawDefaultInspector();
EditorGUIUtility.LookLikeControls();
BezierFigure figure = target as BezierFigure;
if( GUILayout.Button("Subdivide") ) {
Subdivide(figure);
Undo.RegisterUndo(target, "Bezier");
EditorUtility.SetDirty(figure);
}
}
private static void Subdivide(BezierFigure figure) {
List<Bezier> list = new List<Bezier>();
foreach( Bezier bezier in figure.GetCurves() ) {
Subdivide(list, bezier.p0, bezier.p1, bezier.p2, bezier.p3);
}
figure.SetCurves(list.ToArray());
}
private static void Subdivide(List<Bezier> list, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3) {
Vector3 p00 = p0;
Vector3 p01 = (p0+p1)/2;
Vector3 p02 = (p0+2*p1+p2)/4;
Vector3 p03 = (p0+3*(p1+p2)+p3)/8;
Vector3 p10 = (p0+3*(p1+p2)+p3)/8;
Vector3 p11 = (p3+2*p2+p1)/4;
Vector3 p12 = (p2+p3)/2;
Vector3 p13 = p3;
Bezier b1 = new Bezier(p00, p01, p02, p03);
Bezier b2 = new Bezier(p10, p11, p12, p13);
list.Add(b1);
list.Add(b2);
}
public void OnSceneGUI() {
BezierFigure figure = target as BezierFigure;
bool changed = false;
Bezier[] curves = figure.GetCurves();
for( int i=0; i<curves.Length; i++ ) {
Bezier a = curves[i];
Bezier b = curves[(i+1)%curves.Length];
changed |= BezierMoveHandle(figure.transform, a, b);
}
if(changed) Undo.RegisterUndo(target, "Bezier");
if (GUI.changed) EditorUtility.SetDirty(target);
}
private static bool BezierMoveHandle(Transform transform, Bezier b1, Bezier b2) {
Vector3 pos = transform.TransformPoint(b1.p3);
Vector3 dir1 = transform.TransformPoint(b1.p2);
Vector3 dir2 = transform.TransformPoint(b2.p1);
bool changed = BezierMoveHandle(ref pos, ref dir1, ref dir2);
b2.p0 = b1.p3 = transform.InverseTransformPoint(pos);
b1.p2 = transform.InverseTransformPoint(dir1);
b2.p1 = transform.InverseTransformPoint(dir2);
return changed;
}
private static bool BezierMoveHandle(ref Vector3 pos, ref Vector3 dir1, ref Vector3 dir2) {
Handles.DrawLine(pos, dir1);
Handles.DrawLine(pos, dir2);
Vector3 oldPos = pos;
Vector3 oldDir1 = dir1;
Vector3 oldDir2 = dir2;
float size = HandleUtility.GetHandleSize(pos) * 0.2f;
pos = Handles.FreeMoveHandle(pos, Quaternion.identity, size, Vector3.zero, Handles.SphereCap);
dir1 = Handles.FreeMoveHandle(dir1, Quaternion.identity, size, Vector3.zero, Handles.SphereCap);
dir2 = Handles.FreeMoveHandle(dir2, Quaternion.identity, size, Vector3.zero, Handles.SphereCap);
dir1 += pos-oldPos;
dir2 += pos-oldPos;
if(oldDir1 != dir1) {
dir1 -= pos;
dir2 -= pos;
dir2 = -dir1.normalized * dir2.magnitude;
dir1 += pos;
dir2 += pos;
} else if(oldDir2 != dir2) {
dir1 -= pos;
dir2 -= pos;
dir1 = -dir2.normalized * dir1.magnitude;
dir1 += pos;
dir2 += pos;
}
return pos != oldPos ||
dir1 != oldDir1 ||
dir2 != oldDir2;
}
}
Вот только из-за сериализациикласса Bezier при попытки вручную изменить ее координаты выскакивает ошибка: Using a SerializedProperty after the object has been deleted is not possible.
UnityEditor.Editor:DrawDefaultInspector()
BezierEditor:OnInspectorGUI() (at Assets/BezierLevel/Editor/BezierEditor.cs:10)
UnityEditor.DockArea:OnGUI() не пойму что не так. И кстате, на структуру сериализация не действовала(
И с Undo не все ясно. Если быстро пару раз нажать Subdivide, то не все изменения запоминаются(
Еще просто не пойму как оно запоминает изменения только тогда, когда я перестаю перетягивать вершину. Хотя RegisterUndo вызываю все время когда перетягиваю вершину.
Еще хорошо бы добавить возможность удалять и добавлять бизье в кривой, а то Subdevide много безье создает.
|
(Offline)
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 14:11.
|