Только в режиме Prefab Настраивает один игровой объект, пока остальные не будут вручную выбраны в окне иерархии. - PullRequest
0 голосов
/ 15 января 2019

Я создал кривую Безье с кодом ниже и сделал сборную кривую Безье. Я добавил несколько копий сборных на мою сцену. Когда я открываю оригинальный префаб в режиме префаба (я использую Unity 2019.1.0a8) и настраиваю любую из точек, это влияет только на один из префабов, изменения не распознаются в виде сцены, пока я не выберу другие объекты вручную.

Обратите внимание, что каждая из сборных копий поворачивается на угол, отличный от исходного сборного. Прежде чем повернуть копии, все они обновляются нормально, но после их поворота обновляется только одна копия, которая не повернута.

Я добавил SceneView.RepaintAll(); после вызова path.MovePoint(i, newPos); в методе Draw(), но он все еще не обновляет другие.

Может быть, я неправильно сериализовал переменные? Как я могу решить это?

Путь

    [System.Serializable]
public class Path {

[SerializeField, HideInInspector]
List<Vector2> points;

[SerializeField, HideInInspector]
public bool isContinuous;

public Path(Vector2 centre)
{
    points = new List<Vector2>
    {
        centre+Vector2.left,
        centre+(Vector2.left+Vector2.up)*.5f,
        centre + (Vector2.right+Vector2.down)*.5f,
        centre + Vector2.right
    };
}

public Vector2 this[int i]
{
    get
    {
        return points[i];
    }
}

public int NumPoints
{
    get
    {
        return points.Count;
    }
}

public int NumSegments
{
    get
    {
        return (points.Count - 4) / 3 + 1;
    }
}

public void AddSegment(Vector2 anchorPos)
{
    points.Add(points[points.Count - 1] * 2 - points[points.Count - 2]);
    points.Add((points[points.Count - 1] + anchorPos) * .5f);
    points.Add(anchorPos);
}

public Vector2[] GetPointsInSegment(int i)
{
    return new Vector2[] { points[i * 3], points[i * 3 + 1], points[i * 3 + 2], points[i * 3 + 3] };
}

public void MovePoint(int i, Vector2 pos)
{

    if (isContinuous)
    { 

        Vector2 deltaMove = pos - points[i];
        points[i] = pos;

        if (i % 3 == 0)
        {
            if (i + 1 < points.Count)
            {
                points[i + 1] += deltaMove;
            }
            if (i - 1 >= 0)
            {
                points[i - 1] += deltaMove;
            }
        }
        else
        {
            bool nextPointIsAnchor = (i + 1) % 3 == 0;
            int correspondingControlIndex = (nextPointIsAnchor) ? i + 2 : i - 2;
            int anchorIndex = (nextPointIsAnchor) ? i + 1 : i - 1;

            if (correspondingControlIndex >= 0 && correspondingControlIndex < points.Count)
            {
                float dst = (points[anchorIndex] - points[correspondingControlIndex]).magnitude;
                Vector2 dir = (points[anchorIndex] - pos).normalized;
            points[correspondingControlIndex] = points[anchorIndex] + dir * dst;
                }
            }
        }
    }

    else {
         points[i] = pos;
    }
}

PathCreator

public class PathCreator : MonoBehaviour {

[HideInInspector]
public Path path;


public void CreatePath()
{
    path = new Path(transform.position);
}
}   

PathEditor

[CustomEditor(typeof(PathCreator))]
public class PathEditor : Editor {

PathCreator creator;
Path path;

public override void OnInspectorGUI()
{
    base.OnInspectorGUI();
    EditorGUI.BeginChangeCheck();

    bool continuousControlPoints = GUILayout.Toggle(path.isContinuous, "Set Continuous Control Points");
    if (continuousControlPoints != path.isContinuous)
    {
        Undo.RecordObject(creator, "Toggle set continuous controls");
        path.isContinuous = continuousControlPoints;
    }

    if (EditorGUI.EndChangeCheck())
    {
        SceneView.RepaintAll();
    }
}

void OnSceneGUI()
{
    Input();
    Draw();
}

void Input()
 {
    Event guiEvent = Event.current;
    Vector2 mousePos = HandleUtility.GUIPointToWorldRay(guiEvent.mousePosition).origin;

    if (guiEvent.type == EventType.MouseDown && guiEvent.button == 0 && guiEvent.shift)
    {
        Undo.RecordObject(creator, "Add segment");
        path.AddSegment(mousePos);
    }
}

void Draw()
{

    for (int i = 0; i < path.NumSegments; i++)
    {
        Vector2[] points = path.GetPointsInSegment(i);
        Handles.color = Color.black;
        Handles.DrawLine(points[1], points[0]);
        Handles.DrawLine(points[2], points[3]);
        Handles.DrawBezier(points[0], points[3], points[1], points[2], Color.green, null, 2);
    }

    Handles.color = Color.red;
    for (int i = 0; i < path.NumPoints; i++)
    {
        Vector2 newPos = Handles.FreeMoveHandle(path[i], Quaternion.identity, .1f, Vector2.zero, Handles.CylinderHandleCap);
        if (path[i] != newPos)
        {
            Undo.RecordObject(creator, "Move point");
            path.MovePoint(i, newPos);
        }
    }
}

void OnEnable()
{
    creator = (PathCreator)target;
    if (creator.path == null)
    {
        creator.CreatePath();
    }
    path = creator.path;
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...