Background not tiling


My background isn’t tiling, but I checked 3 times if my code is correct, and it seems to be.

DialogueEditor.cs

using System;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEngine;

namespace RPG.Dialogue.Editor // can only access stuff up so Editor has acccess to RPG.Dialogue but not the other way around
{
    public class DialogueEditor : EditorWindow
    {
        static Dialogue selectedDialogue = null;
        [NonSerialized]
        GUIStyle nodeStyle;
        [NonSerialized]
        DialogueNode draggingNode = null;
        [NonSerialized]
        Vector2 draggingOffset;
        [NonSerialized] // because sometimes it still has the old creatingNode in there
        DialogueNode creatingNode = null;
        [NonSerialized]
        DialogueNode deletingNode = null;
        [NonSerialized]
        DialogueNode linkingParentNode = null;
        Vector2 scrollPosition;
        Rect editorViewport;

        [NonSerialized]
        bool isDraggingCanvas = false;
        [NonSerialized]
        Vector2 draggingCanvasOffset;


        [MenuItem("Window/Dialogue Editor")]
        public static void ShowEditorWindow()
        {
            GetWindow<DialogueEditor>(false,"Dialogue Editor");
        }

        [OnOpenAsset(1)]
        public static bool OnOpenAsset(int instanceID, int line)
        {
            Dialogue dialogue = EditorUtility.InstanceIDToObject(instanceID) as Dialogue;
            if (dialogue is null) { return true; } // we are handling the Callback and should not go further
            selectedDialogue = dialogue;
            ShowEditorWindow();
            return false;

        }

        private void OnEnable()
        {
            Selection.selectionChanged += OnSelectionChanged;

            nodeStyle = new GUIStyle();
            nodeStyle.normal.background = EditorGUIUtility.Load("node0") as Texture2D;
            nodeStyle.normal.textColor = Color.white;
            nodeStyle.padding = new RectOffset(20, 20, 20, 20);
            nodeStyle.border = new RectOffset(12, 12, 12, 12);
        }

        private void OnSelectionChanged()
        {
            Dialogue newDialogue = Selection.activeObject as Dialogue;
            if (newDialogue is null) { return; }
            selectedDialogue = newDialogue;
            Repaint();
        }

        private void OnGUI()
        {
            if(selectedDialogue == null)
            {
                EditorGUILayout.LabelField("No Dialogue Selected");
                
            }
            else
            {
                ProcessEvents();
                scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
                Debug.Log("ScrollPosition: " + scrollPosition);
                editorViewport = GUILayoutUtility.GetRect(selectedDialogue.editorCanvasSize,selectedDialogue.editorCanvasSize);
                Texture2D backgroundTexture = Resources.Load("background") as Texture2D;
                Rect backgroundTextureCoordinates = new Rect(0, 0, 
                    selectedDialogue.editorCanvasSize / selectedDialogue.editorBackgroundImageSize,
                    selectedDialogue.editorCanvasSize / selectedDialogue.editorBackgroundImageSize);
                Debug.Log($"Texture Coordinates: {backgroundTextureCoordinates.width} {backgroundTextureCoordinates.height}");
                GUI.DrawTextureWithTexCoords(editorViewport, backgroundTexture, backgroundTextureCoordinates);
                
                
                foreach (DialogueNode node in selectedDialogue.GetAllNodes())
                {
                    DrawConnections(node);
                }
                foreach (DialogueNode node in selectedDialogue.GetAllNodes())
                {
                    DrawNodes(node);
                }

                GUILayout.EndScrollView();

                if (creatingNode != null)
                {
                    Undo.RecordObject(selectedDialogue, "Added a new Node");
                    selectedDialogue.CreateNode(creatingNode);
                    creatingNode = null;
                }
                if(deletingNode != null)
                {
                    Undo.RecordObject(selectedDialogue, "Deleted a Node");
                    selectedDialogue.DeleteNode(deletingNode);
                    deletingNode = null;
                }
            }
            
        }
        void DrawNodes(DialogueNode node)
        {
            GUILayout.BeginArea(node.rect, nodeStyle);
            EditorGUI.BeginChangeCheck();
            EditorGUILayout.LabelField("Name:");
            string newName = EditorGUILayout.TextField(node.dialogueName == "" ? "Add a Name" : node.dialogueName);
            EditorGUILayout.LabelField("Text:");
            string newText = EditorGUILayout.TextArea(node.text == "" ? "Add Text!" : node.text, GUILayout.Height(100));

            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(selectedDialogue, "Update Dialogue Text");
                Undo.RecordObject(selectedDialogue, "Update Dialogue Name");
                node.dialogueName = newName;
                node.text = newText;
            }
            GUILayout.BeginHorizontal();
            Color standardColor = GUI.backgroundColor;
            GUI.backgroundColor = Color.red;
            if (selectedDialogue.GetNodesCount() > 1)
            {
                if (GUILayout.Button("Remove Node"))
                {
                    deletingNode = node;
                }
            }
            DrawLinkButton(node);
            GUI.backgroundColor = Color.green;
            if (GUILayout.Button("Add Child"))
            {
                creatingNode = node;
            }
            GUI.backgroundColor = standardColor;
            GUILayout.EndHorizontal();
            GUILayout.EndArea();

        }

        private void DrawLinkButton(DialogueNode node)
        {
            if (linkingParentNode == null)
            {
                GUI.backgroundColor = Color.cyan;
                if (GUILayout.Button("Link"))
                {
                    linkingParentNode = node;
                }
            }
            else if (linkingParentNode == node)
            {
                GUI.backgroundColor = Color.yellow;
                if (GUILayout.Button("Cancel"))
                {
                    linkingParentNode = null;
                }
            }
            else if (linkingParentNode.children.Contains(node.uniqueID))
            {
                Undo.RecordObject(selectedDialogue, "Unlinking Node");
                GUI.backgroundColor = Color.yellow;
                if (GUILayout.Button("Unlink"))
                {
                    linkingParentNode.children.Remove(node.uniqueID);
                }
            }
            else
            {
                GUI.backgroundColor = Color.blue;
                if (GUILayout.Button("Child"))
                {
                    Undo.RecordObject(selectedDialogue, "Linking Node");
                    linkingParentNode.children.Add(node.uniqueID);
                    linkingParentNode = null;
                }
            }
        }

        void DrawConnections(DialogueNode node)
        {
            Vector3 startPosition = new Vector2(node.rect.xMax, node.rect.center.y);
            foreach (DialogueNode childNode in selectedDialogue.GetAllChildren(node))
            {
                Vector3 endPosition = new Vector2(childNode.rect.xMin, childNode.rect.center.y);
                Vector3 controlPointOffset = endPosition - startPosition;
                controlPointOffset.y = 0;
                controlPointOffset.x *= 0.8f;
                Handles.DrawBezier(startPosition, endPosition, 
                    startPosition + controlPointOffset, endPosition - controlPointOffset, 
                    Color.white, null, 4f);
            }
        }
            
        private void ProcessEvents()
        {
            if(Event.current.type == EventType.MouseDown && draggingNode == null)
            {
                draggingNode = GetNodeAtPoint(Event.current.mousePosition);
                if(draggingNode != null)
                {
                    draggingOffset = draggingNode.rect.position - Event.current.mousePosition;
                }
                if(draggingNode == null)
                {
                    isDraggingCanvas = true;
                    draggingCanvasOffset = Event.current.mousePosition + scrollPosition;
                }
            }

            else if(Event.current.type == EventType.MouseDrag && draggingNode != null)
            {
                Undo.RecordObject(selectedDialogue, "Change Node position");
                draggingNode.rect.position = Event.current.mousePosition + draggingOffset;
                GUI.changed = true; // tell GUI to update

            }
            else if (Event.current.type == EventType.MouseDrag && isDraggingCanvas)
            {
                scrollPosition = draggingCanvasOffset - Event.current.mousePosition;
                GUI.changed = true; // tell GUI to update

            }

            else if(Event.current.type == EventType.MouseUp && draggingNode != null)
            {
                draggingNode = null;
            }
            else if(Event.current.type == EventType.MouseUp && isDraggingCanvas)
            {
                isDraggingCanvas = false;
            }

        }
        private DialogueNode GetNodeAtPoint(Vector2 point)
        {
            DialogueNode foundNode = null;
            foreach (DialogueNode node in selectedDialogue.GetAllNodes())
            {
                if (node.rect.Contains(point+scrollPosition)) 
                {
                    foundNode = node;
                }
            }
            return foundNode;
        }
    }

    

}

Dialogue.cs

using System;
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEngine;

namespace RPG.Dialogue.Editor // can only access stuff up so Editor has acccess to RPG.Dialogue but not the other way around
{
    public class DialogueEditor : EditorWindow
    {
        static Dialogue selectedDialogue = null;
        [NonSerialized]
        GUIStyle nodeStyle;
        [NonSerialized]
        DialogueNode draggingNode = null;
        [NonSerialized]
        Vector2 draggingOffset;
        [NonSerialized] // because sometimes it still has the old creatingNode in there
        DialogueNode creatingNode = null;
        [NonSerialized]
        DialogueNode deletingNode = null;
        [NonSerialized]
        DialogueNode linkingParentNode = null;
        Vector2 scrollPosition;
        Rect editorViewport;

        [NonSerialized]
        bool isDraggingCanvas = false;
        [NonSerialized]
        Vector2 draggingCanvasOffset;


        [MenuItem("Window/Dialogue Editor")]
        public static void ShowEditorWindow()
        {
            GetWindow<DialogueEditor>(false,"Dialogue Editor");
        }

        [OnOpenAsset(1)]
        public static bool OnOpenAsset(int instanceID, int line)
        {
            Dialogue dialogue = EditorUtility.InstanceIDToObject(instanceID) as Dialogue;
            if (dialogue is null) { return true; } // we are handling the Callback and should not go further
            selectedDialogue = dialogue;
            ShowEditorWindow();
            return false;

        }

        private void OnEnable()
        {
            Selection.selectionChanged += OnSelectionChanged;

            nodeStyle = new GUIStyle();
            nodeStyle.normal.background = EditorGUIUtility.Load("node0") as Texture2D;
            nodeStyle.normal.textColor = Color.white;
            nodeStyle.padding = new RectOffset(20, 20, 20, 20);
            nodeStyle.border = new RectOffset(12, 12, 12, 12);
        }

        private void OnSelectionChanged()
        {
            Dialogue newDialogue = Selection.activeObject as Dialogue;
            if (newDialogue is null) { return; }
            selectedDialogue = newDialogue;
            Repaint();
        }

        private void OnGUI()
        {
            if(selectedDialogue == null)
            {
                EditorGUILayout.LabelField("No Dialogue Selected");
                
            }
            else
            {
                ProcessEvents();
                scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
                Debug.Log("ScrollPosition: " + scrollPosition);
                editorViewport = GUILayoutUtility.GetRect(selectedDialogue.editorCanvasSize,selectedDialogue.editorCanvasSize);
                Texture2D backgroundTexture = Resources.Load("background") as Texture2D;
                Rect backgroundTextureCoordinates = new Rect(0, 0, 
                    selectedDialogue.editorCanvasSize / selectedDialogue.editorBackgroundImageSize,
                    selectedDialogue.editorCanvasSize / selectedDialogue.editorBackgroundImageSize);
                Debug.Log($"Texture Coordinates: {backgroundTextureCoordinates.width} {backgroundTextureCoordinates.height}");
                GUI.DrawTextureWithTexCoords(editorViewport, backgroundTexture, backgroundTextureCoordinates);
                
                
                foreach (DialogueNode node in selectedDialogue.GetAllNodes())
                {
                    DrawConnections(node);
                }
                foreach (DialogueNode node in selectedDialogue.GetAllNodes())
                {
                    DrawNodes(node);
                }

                GUILayout.EndScrollView();

                if (creatingNode != null)
                {
                    Undo.RecordObject(selectedDialogue, "Added a new Node");
                    selectedDialogue.CreateNode(creatingNode);
                    creatingNode = null;
                }
                if(deletingNode != null)
                {
                    Undo.RecordObject(selectedDialogue, "Deleted a Node");
                    selectedDialogue.DeleteNode(deletingNode);
                    deletingNode = null;
                }
            }
            
        }
        void DrawNodes(DialogueNode node)
        {
            GUILayout.BeginArea(node.rect, nodeStyle);
            EditorGUI.BeginChangeCheck();
            EditorGUILayout.LabelField("Name:");
            string newName = EditorGUILayout.TextField(node.dialogueName == "" ? "Add a Name" : node.dialogueName);
            EditorGUILayout.LabelField("Text:");
            string newText = EditorGUILayout.TextArea(node.text == "" ? "Add Text!" : node.text, GUILayout.Height(100));

            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(selectedDialogue, "Update Dialogue Text");
                Undo.RecordObject(selectedDialogue, "Update Dialogue Name");
                node.dialogueName = newName;
                node.text = newText;
            }
            GUILayout.BeginHorizontal();
            Color standardColor = GUI.backgroundColor;
            GUI.backgroundColor = Color.red;
            if (selectedDialogue.GetNodesCount() > 1)
            {
                if (GUILayout.Button("Remove Node"))
                {
                    deletingNode = node;
                }
            }
            DrawLinkButton(node);
            GUI.backgroundColor = Color.green;
            if (GUILayout.Button("Add Child"))
            {
                creatingNode = node;
            }
            GUI.backgroundColor = standardColor;
            GUILayout.EndHorizontal();
            GUILayout.EndArea();

        }

        private void DrawLinkButton(DialogueNode node)
        {
            if (linkingParentNode == null)
            {
                GUI.backgroundColor = Color.cyan;
                if (GUILayout.Button("Link"))
                {
                    linkingParentNode = node;
                }
            }
            else if (linkingParentNode == node)
            {
                GUI.backgroundColor = Color.yellow;
                if (GUILayout.Button("Cancel"))
                {
                    linkingParentNode = null;
                }
            }
            else if (linkingParentNode.children.Contains(node.uniqueID))
            {
                Undo.RecordObject(selectedDialogue, "Unlinking Node");
                GUI.backgroundColor = Color.yellow;
                if (GUILayout.Button("Unlink"))
                {
                    linkingParentNode.children.Remove(node.uniqueID);
                }
            }
            else
            {
                GUI.backgroundColor = Color.blue;
                if (GUILayout.Button("Child"))
                {
                    Undo.RecordObject(selectedDialogue, "Linking Node");
                    linkingParentNode.children.Add(node.uniqueID);
                    linkingParentNode = null;
                }
            }
        }

        void DrawConnections(DialogueNode node)
        {
            Vector3 startPosition = new Vector2(node.rect.xMax, node.rect.center.y);
            foreach (DialogueNode childNode in selectedDialogue.GetAllChildren(node))
            {
                Vector3 endPosition = new Vector2(childNode.rect.xMin, childNode.rect.center.y);
                Vector3 controlPointOffset = endPosition - startPosition;
                controlPointOffset.y = 0;
                controlPointOffset.x *= 0.8f;
                Handles.DrawBezier(startPosition, endPosition, 
                    startPosition + controlPointOffset, endPosition - controlPointOffset, 
                    Color.white, null, 4f);
            }
        }
            
        private void ProcessEvents()
        {
            if(Event.current.type == EventType.MouseDown && draggingNode == null)
            {
                draggingNode = GetNodeAtPoint(Event.current.mousePosition);
                if(draggingNode != null)
                {
                    draggingOffset = draggingNode.rect.position - Event.current.mousePosition;
                }
                if(draggingNode == null)
                {
                    isDraggingCanvas = true;
                    draggingCanvasOffset = Event.current.mousePosition + scrollPosition;
                }
            }

            else if(Event.current.type == EventType.MouseDrag && draggingNode != null)
            {
                Undo.RecordObject(selectedDialogue, "Change Node position");
                draggingNode.rect.position = Event.current.mousePosition + draggingOffset;
                GUI.changed = true; // tell GUI to update

            }
            else if (Event.current.type == EventType.MouseDrag && isDraggingCanvas)
            {
                scrollPosition = draggingCanvasOffset - Event.current.mousePosition;
                GUI.changed = true; // tell GUI to update

            }

            else if(Event.current.type == EventType.MouseUp && draggingNode != null)
            {
                draggingNode = null;
            }
            else if(Event.current.type == EventType.MouseUp && isDraggingCanvas)
            {
                isDraggingCanvas = false;
            }

        }
        private DialogueNode GetNodeAtPoint(Vector2 point)
        {
            DialogueNode foundNode = null;
            foreach (DialogueNode node in selectedDialogue.GetAllNodes())
            {
                if (node.rect.Contains(point+scrollPosition)) 
                {
                    foundNode = node;
                }
            }
            return foundNode;
        }
    }

    

}

SO Configuration

While your code doesn’t look much like the code in the repo, it does - in its own right - look fine. You pasted the same code twice, though. Can you fix Dialogue.cs so we can see that instead of DialogueEditor.cs twice?

Also, what does this output?

Nevermind, I replicated it in my own project. The problem is when you imported the ‘background’ image. You have to change the Wrap Mode from Clamp to Repeat

image

It was easy for me to find because I didn’t use a background image in my own editor but drew the lines manually. To replicate the issue I had to import the background image, too, and that’s how I discovered the source of your discomfort

1 Like

Thanks, that fixed it :slight_smile:

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms