예제 #1
0
        /// <summary>
        /// Ajoute un rail et le définit comme sélection actuelle
        /// </summary>
        /// <param name="railIndex">Index du prefab à ajouter, depuis la palette de rails</param>
        private GameObject AddRail(int railIndex)
        {
            // Récupération de la sélection actuelle
            GameObject selected     = Selection.activeGameObject;
            Rail       selectedRail = null;

            if (selected)
            {
                selectedRail = selected.GetComponent <Rail>();
                // null si l'objet sélectionné n'est pas un rail

                if (!selectedRail)
                {
                    // Recherche parmi les parents
                    selectedRail = selected.GetComponentInParent <Rail>();
                }

                if (selectedRail != null)
                {
                    // Can be null
                    RailAnchor anchor = selectedRail.GetAnchorForEndpoint(Rail.Endpoint.Default);

                    return(AddRail(railIndex, selectedRail, anchor));
                }
            }

            return(AddRail(railIndex, null, null));
        }
예제 #2
0
        /// <summary>
        /// Ajoute un rail au circuit
        /// TODO : éviter la redondance toRail = anchor.Parent
        /// </summary>
        /// <param name="prefab"></param>
        /// <param name="toRail"></param>
        /// <param name="anchor"></param>
        /// <returns></returns>
        public Rail AddRail(Rail prefab, Rail toRail = null, RailAnchor anchor = null)
        {
            // Vérification si on ajoute à un rail existant
            if (toRail != null && anchor != null)
            {
                // Si le rail possède déjà un rail à cet endroit
                if (!toRail.CanAppendRail(anchor))
                {
                    return(null);
                }
            }

            Rail newRail;

#if UNITY_EDITOR
            newRail = PrefabUtility.InstantiatePrefab(prefab) as Rail; // TODO tester le cast
#else
            newRail = Instantiate(prefab);
#endif

            // Créé à la suite d'un rail existant
            if (toRail)
            {
                toRail.AppendRail(newRail, anchor);
            }
            // Créé au centre du circuit (par défaut)
            else
            {
                newRail.transform.parent        = transform;
                newRail.transform.localPosition = Vector3.zero;
            }


            return(newRail);
        }
예제 #3
0
        /// <summary>
        /// Quitte le mode édition depuis la SceneView
        /// Rétablit l'outil précédement sélectionné et détruit l'éventuel Gismo de rail
        /// </summary>
        private void ExitSceneEditing()
        {
            SceneView.duringSceneGui -= OnSceneGUI;

            DestroyRailHandle();

            _focusedAnchor = null;

            Tools.current = _lastTool;
        }
예제 #4
0
        /// <summary>
        /// Ajoute un rail au circuit
        /// </summary>
        /// <param name="prefab"></param>
        /// <param name="toRail"></param>
        /// <param name="point"></param>
        /// <returns></returns>
        public Rail AddRail(Rail prefab, Rail toRail, Rail.Endpoint point)
        {
            if (toRail != null)
            {
                RailAnchor anchor = toRail.GetAnchorForEndpoint(point);

                if (anchor != null)
                {
                    return(AddRail(prefab, toRail, anchor));
                }
            }

            return(AddRail(prefab, null, null));
        }
예제 #5
0
        /// <summary>
        /// Connecte le RailAnchor à un autre
        /// </summary>
        /// <param name="withAnchor"></param>
        /// <param name="notifyOther"></param>
        public void Connect(RailAnchor withAnchor, bool notifyOther = true)
        {
            if (notifyOther)
            {
                withAnchor.NotifyConnection(this);
            }

#if UNITY_EDITOR
            // https://answers.unity.com/questions/155370/edit-an-object-in-unityeditor-editorwindow.html
            // Nécessaire d'utiliser SerializedObject pour conserver la valeur après un play
            var serializedAnchor = new SerializedObject(this);
            var connectionProp   = serializedAnchor.FindProperty("Connection");

            connectionProp.objectReferenceValue = withAnchor;

            serializedAnchor.ApplyModifiedProperties();
#else
            Connection = withAnchor;
#endif
        }
예제 #6
0
        /// <summary>
        /// Ajoute un rail et le définit comme sélection actuelle
        /// </summary>
        /// <param name="railIndex"></param>
        /// <param name="toRail"></param>
        /// <param name="anchor"></param>
        /// <returns></returns>
        public GameObject AddRail(int railIndex, Rail toRail, RailAnchor anchor)
        {
            // TODO : changer le type
            GameObject newRail = Circuit.AddRail(_railPalette[railIndex].GetComponent <Rail>(), toRail, anchor).gameObject;

            if (newRail)
            {
                // Sélectionne le nouveau rail
                GameObject[] newSelection = { newRail };
                Selection.objects = newSelection;

                Undo.RegisterCreatedObjectUndo(newRail, "Add Rail");

                return(newRail);
            }
            else
            {
                Debug.LogError("Impossible d'ajouter un rail à cet endroit");

                return(null);
            }
        }
예제 #7
0
        /// <summary>
        /// Gestion des évènements dans la SceneView
        /// </summary>
        /// <param name="sceneView">SceneView courante</param>
        private void OnSceneGUI(SceneView sceneView)
        {
            if (_addModeIndex == 1)
            {
                if (Event.current.type == EventType.MouseMove)
                {
                    // -----------------------------------------------------------------------------------
                    // Détection de la proximité du curseur avec une extrémité de rail libre
                    float lowestDistance = _maxDistanceSnap;

                    RailAnchor previouslySelectedAnchor = _focusedAnchor;

                    _focusedAnchor = null;


                    foreach (Rail rail in Circuit.GetRails())
                    {
                        foreach (RailAnchor anchor in rail.GetFreeConnections())
                        {
                            Vector2 guiPosition = HandleUtility.WorldToGUIPoint(anchor.Position);

                            float distance = Vector2.Distance(Event.current.mousePosition, guiPosition);

                            if (distance < lowestDistance)
                            {
                                _focusedAnchor = anchor;
                                lowestDistance = distance;
                            }
                        }
                    }
                    // -----------------------------------------------------------------------------------



                    // La sélection a changé
                    if (previouslySelectedAnchor != _focusedAnchor)
                    {
                        // Changement de la sélection d'anchor
                        if (_focusedAnchor != null)
                        {
                            if (_railHandle == null)
                            {
                                _railHandle = Instantiate(_railPalette[_selectedRailIndex]);
                            }

                            // Placement de ce rail selon l'anchor
                            _railHandle.transform.parent = _editorGameObject.transform;

                            _railHandle.GetComponent <Rail>().SetTransformFromAnchor(_focusedAnchor);
                        }
                        // On est sorti de la zone de sqélection, suppression du handle
                        else
                        {
                            DestroyRailHandle();
                        }
                    }



                    // Consomme l'Event
                    Event.current.Use();
                }
                else if (Event.current.type == EventType.MouseDown)
                {
                    // Un rail est prêt à être placé
                    if (_railHandle && _focusedAnchor)
                    {
                        // à bouger -------
                        GameObject newRail = AddRail(_selectedRailIndex, _focusedAnchor.Parent, _focusedAnchor);

                        if (newRail)
                        {
                            // Consomme l'Event
                            Event.current.Use();
                            _consumeNextMouseUp = true;

                            DestroyRailHandle();
                        }
                    }
                }
                else if (Event.current.type == EventType.MouseUp)
                {
                    if (_consumeNextMouseUp)
                    {
                        // Consomme l'Event
                        Event.current.Use();

                        _consumeNextMouseUp = false;
                    }
                }
            }
        }
예제 #8
0
        // Update is called once per frame
        void Update()
        {
            // Initialisation de la caméra à l'ajout du premier rail
            if (!_cameraInitialized)
            {
                if (_circuitEditor.Circuit.RailsCount > 0)
                {
                    ResetCamera();
                    _cameraInitialized = true;
                }
            }



            // Inputs \\

            // Évènements à la souris restreint à l'extérieur de l'UI
            if (!EventSystem.current.IsPointerOverGameObject())
            {
                Vector2 mousePos = Input.mousePosition;


                // Mouse move
                if (mousePos != _lastMousePos)
                {
                    if (_circuitEditor.AddMode == CircuitEditor.AddingMode.Scene && !editorCamera.IsMovingView)
                    {
                        // -----------------------------------------------------------------------------------
                        // Détection de la proximité du curseur avec une extrémité de rail libre
                        float lowestDistance = _maxDistanceSnap;

                        RailAnchor previouslySelectedAnchor = _focusedAnchor;

                        _focusedAnchor = null;


                        foreach (Rail rail in _circuitEditor.Circuit.GetRails())
                        {
                            foreach (RailAnchor anchor in rail.GetFreeConnections())
                            {
                                Vector2 guiPosition = editorCamera.Camera.WorldToScreenPoint(anchor.Position);

                                float distance = Vector2.Distance(mousePos, guiPosition);

                                if (distance < lowestDistance)
                                {
                                    _focusedAnchor = anchor;
                                    lowestDistance = distance;
                                }
                            }
                        }
                        // -----------------------------------------------------------------------------------


                        // La sélection a changé
                        if (previouslySelectedAnchor != _focusedAnchor)
                        {
                            // Changement de la sélection d'anchor
                            if (_focusedAnchor != null)
                            {
                                if (_railHandle == null)
                                {
                                    _railHandle = Instantiate(_circuitEditor.SelectedRail);
                                }

                                // Placement de ce rail selon l'anchor
                                _railHandle.transform.parent = _handlesRoot.transform;

                                _railHandle.GetComponent <Rail>().SetTransformFromAnchor(_focusedAnchor);
                            }
                            // On est sorti de la zone de sqélection, suppression du handle
                            else
                            {
                                DestroyRailHandle();
                            }
                        }
                    }



                    _lastMousePos = mousePos;
                }



                // Clic gauche
                if (Input.GetMouseButtonDown(0))
                {
                    // En mode scène, le clic gauche sert à l'ajout de rail
                    if (_circuitEditor.AddMode == CircuitEditor.AddingMode.Scene && !editorCamera.IsMovingView)
                    {
                        // Un rail est prêt à être placé
                        if (_railHandle && _focusedAnchor)
                        {
                            Rail newRail = _circuitEditor.AddRail(_focusedAnchor.Parent, _focusedAnchor);

                            if (newRail)
                            {
                                DestroyRailHandle();
                            }
                        }
                    }
                    // En mode clic, le clic gauche sert à la sélection
                    else if (_circuitEditor.AddMode == CircuitEditor.AddingMode.Click)
                    {
                        Ray ray = editorCamera.Camera.ScreenPointToRay(mousePos);


                        int layerMask = 1 << CircuitEditor.railLayer;


                        if (Physics.Raycast(ray, out RaycastHit hit, Mathf.Infinity, layerMask))
                        {
                            if (hit.collider.TryGetComponent(out Rail selectedRail))
                            {
                                // Le rail devient la nouvelle sélection
                                Selection = selectedRail;
                            }
                        }
                        else
                        {
                            // Clic dans le vide => déselection
                            Selection = null;
                        }
                    }
                }
            }
예제 #9
0
 /// <summary>
 /// Réplique la connection sur l'autre RailAnchor
 /// </summary>
 /// <param name="withAnchor"></param>
 public void NotifyConnection(RailAnchor withAnchor)
 {
     Connect(withAnchor, false);
 }