Topic: Regeneration Automation

https://infinity-code.com/sites/default/files/styles/full_post/public/images/news/2020.02.10%20-%20Real%20World%20Terrain%20Regeneration%20Automation.jpg?itok=RduetKZ0

One of the amazing things that sets Real World Terrain apart from similar assets is the ability to automate the generation and regeneration of terrains, textures, and objects using Real World Terrain API.
In this example, I will show how to automate rule-based texture regeneration.
Place the script in the Editor folder, and run Menu / RWT / Automator.

using System;
using System.Collections.Generic;
using InfinityCode.RealWorldTerrain;
using InfinityCode.RealWorldTerrain.Windows;
using UnityEditor;
using UnityEngine;

public class AutomatorExample : EditorWindow
{
    private RealWorldTerrainContainer container;
    private List<Rule> rules = new List<Rule>();
    private Vector2 scrollPosition;
    private int status = 0; // 0 - idle, 1 - execute, 2 - finalize
    private int executeIndex = -1;
    private bool finished = false;

    private void Execute()
    {
        if (container == null) return;
        if (container.terrains == null) return;
        if (rules.Count == 0) return;

        status = 1;
        executeIndex = -1;
        ExecuteNextTerrain();
    }

    private void ExecuteNextTerrain()
    {
        int ruleIndex = -1;
        Rule activeRule = null;
        RealWorldTerrainItem item = null;

        do
        {
            executeIndex++;
            if (executeIndex == container.terrainCount)
            {
                status = 2;
                Repaint();
                return;
            }

            item = container.terrains[executeIndex];

            for (int i = 0; i < rules.Count; i++)
            {
                Rule rule = rules[i];
                if (rule.Contains(item) && rule.textureResolution != item.prefs.textureSize.x)
                {
                    activeRule = rule;
                    ruleIndex = i;
                    break;
                }
            }
        } while (activeRule == null);

        finished = false;

        Debug.Log(item + ", Rule - " + ruleIndex);

        RealWorldTerrainWindow.OpenWindow(RealWorldTerrainGenerateType.texture, item);

        RealWorldTerrainWindow.prefs.textureSize = new RealWorldTerrainVector2i(activeRule.textureResolution, activeRule.textureResolution);
        RealWorldTerrainWindow.OnCaptureCompleted += OnCaptureCompleted;
        RealWorldTerrainWindow.OnCaptureCanceled += OnCaptureCanceled;

        RealWorldTerrainWindow.StartCapture();
    }

    private void OnCaptureCanceled()
    {
        UnsubscribeFromEvents();

        status = 2;
    }

    private void OnCaptureCompleted()
    {
        UnsubscribeFromEvents();

        finished = true;
        Repaint();
    }

    private void OnGUI()
    {
        if (status == 0) OnIdleGUI();
        else if (status == 1) OnWaitGUI();
        else if (Event.current.type == EventType.Repaint)
        {
            status = 0;
            Repaint();
        }
    }

    private void OnIdleGUI()
    {
        int rulesCount = rules.Count;
        int moveUp = -1;
        int moveDown = -1;

        container = EditorGUILayout.ObjectField("RWT Container", container, typeof(RealWorldTerrainContainer), true) as RealWorldTerrainContainer;

        try
        {
            scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
        }
        catch (Exception e)
        {
            Debug.Log(Event.current.type);
        }
        

        for (int i = 0; i < rulesCount; i++)
        {
            Rule rule = rules[i];

            EditorGUILayout.BeginHorizontal();

            EditorGUILayout.LabelField("From X", GUILayout.Width(50));
            rule.fromX = EditorGUILayout.IntField(rule.fromX);
            EditorGUILayout.LabelField("Y", GUILayout.Width(20));
            rule.fromY = EditorGUILayout.IntField(rule.fromY);

            EditorGUILayout.LabelField(" To X", GUILayout.Width(40));
            rule.toX = EditorGUILayout.IntField(rule.toX);
            EditorGUILayout.LabelField("Y", GUILayout.Width(20));
            rule.toY = EditorGUILayout.IntField(rule.toY);

            EditorGUILayout.LabelField(" Resolution", GUILayout.Width(80));
            rule.textureResolution = EditorGUILayout.IntField(rule.textureResolution);

            if (GUILayout.Button("Up", GUILayout.ExpandWidth(false))) moveUp = i;
            if (GUILayout.Button("Down", GUILayout.ExpandWidth(false))) moveDown = i;
            if (GUILayout.Button("X", GUILayout.ExpandWidth(false)))
            {
                rules.RemoveAt(i);
                rulesCount--;
            }

            EditorGUILayout.EndHorizontal();
        }

        EditorGUILayout.EndScrollView();

        if (moveUp > 0)
        {
            Rule t = rules[moveUp - 1];
            rules[moveUp - 1] = rules[moveUp];
            rules[moveUp] = t;
        }

        if (moveDown != -1 && moveDown < rulesCount - 1)
        {
            Rule t = rules[moveDown + 1];
            rules[moveDown + 1] = rules[moveDown];
            rules[moveDown] = t;
        }

        if (GUILayout.Button("Add")) rules.Add(new Rule());
        if (GUILayout.Button("Execute")) Execute();
    }

    private void OnWaitGUI()
    {
        if (finished) ExecuteNextTerrain();

        Rect rect = GUILayoutUtility.GetRect(GUIContent.none, GUI.skin.box, GUILayout.Height(20), GUILayout.ExpandWidth(true));
        float progress = (float)executeIndex / (container.terrainCount - 1);
        EditorGUI.ProgressBar(rect, progress, Mathf.FloorToInt(progress * 100) + " %");

        if (GUILayout.Button("Cancel"))
        {
            status = 2;
            RealWorldTerrainWindow.CancelCapture();
        }
    }

    [MenuItem("RWT/Automator")]
    private static void OpenWindow()
    {
        GetWindow<AutomatorExample>();
    }

    private void UnsubscribeFromEvents()
    {
        RealWorldTerrainWindow.OnCaptureCompleted -= OnCaptureCompleted;
        RealWorldTerrainWindow.OnCaptureCanceled -= OnCaptureCanceled;
    }

    internal class Rule
    {
        public int fromX;
        public int fromY;
        public int toX;
        public int toY;
        public int textureResolution = 256;

        public bool Contains(RealWorldTerrainItem item)
        {
            return fromX <= item.x && toX >= item.x && fromY <= item.y && toY >= item.y;
        }
    }
}
Kind Regards,
Infinity Code Team.

Do not know the best way to thank the developer? Rate the asset in Asset Store!