Runtime Editor

I dont have RTEditor, maybe because i have the lite version?

Assets/Battlehub/RTCommon/Scripts/ClampAngles.cs(3,17): error CS0234: The type or namespace name RTEditor' does not exist in the namespace Battlehub’. Are you missing an assembly reference?

And with the camera when i try to change from camera1 to camera2 the gizmos are with problems

3096298--233705--CameraPreblem.gif

https://forum.unity3d.com/threads/runtime-handles.428094/#post-3096726

I am wondering how to reduce the decimal number of transform components such as Position, Rotation and scale? I want to have them just showing integers without decimals point
Thanks

Hi, please import attached package
I have added following field to
Vector3 editor

public bool RoundToInt;

and modified TransformEditor like this

public class TransformEditor : ComponentEditor
    {
        protected override void InitEditor(PropertyEditor editor, PropertyDescriptor descriptor)
        {
            base.InitEditor(editor, descriptor);
            if(RuntimeTools.LockAxes == null)
            {
                return;
            }
            if(descriptor.ComponentMemberInfo == Strong.MemberInfo((Transform x) => x.position))
            {
                Vector3Editor vector3Editor = (Vector3Editor)editor;
                vector3Editor.RoundToInt = true;

Regards,
Vadim

3104632–234502–TransformIntEditor.unitypackage (2.09 KB)

1 Like

Thanks but, I got 2 errors:

  1. Assets/Battlehub/RTEditor/Scripts/Editors/TransformEditor.cs(1,17): error CS0234: The type or namespace name RTCommon' does not exist in the namespace Battlehub’. Are you missing an assembly reference?
  2. Assets/Battlehub/RTEditor/Scripts/Editors/PropertyEditors/Vector3Editor.cs(7,34): error CS0246: The type or namespace name PropertyEditor1’ could not be found. Are you missing a using directive or an assembly reference?

Are you using latest version of RTEditor from asset store?
Have you imported attached package over RTEditor package?
(Import RuntimeEditor package from asset store, then import TransformIntEditor package from previous post. Does problem still exists after this?)

Unfortunately I updated to the latest version but the style of the old UI is more convenient with my current project. Actually the old version is more user friendly for me. Could you please give me the code compatible with the old version?
Thanks and appreciated

There are several previous versions 1.0, 1.1, 1.2. Which is yours? It should be on first page of Battlehub/RTEditor/RuntimeEditorBasics.pdf included in your package.

Ver.1.1 03.10.2016
Thanks and appreciated

Replace RTEditor/Scripts/TransformComponent.cs with this code

using UnityEngine;
using UnityEngine.UI;
using System.Linq;
using System.Collections.Generic;
using Battlehub.RTHandles;

namespace Battlehub.RTEditor
{
    public class TransformComponent : MonoBehaviour
    {
        public bool RoundToInt = true;

        public Toggle EnableDisableToggle;
        public GameObject TransformComponentUI;
        public InputField PositionX;
        public InputField PositionY;
        public InputField PositionZ;
        public InputField RotationX;
        public InputField RotationY;
        public InputField RotationZ;
        public InputField ScaleX;
        public InputField ScaleY;
        public InputField ScaleZ;
        public Button Reset;

        private Transform[] m_transforms;
        private HashSet<GameObject> m_selectedGameObjects = new HashSet<GameObject>();

        private bool m_isPositionEditing;
        private bool m_isRotationEditing;
        private bool m_isScaleEditing;

        private DragField[] m_dragFields;

        private void Awake()
        {
            RuntimeSelection.SelectionChanged += OnRuntimeSelectionChanged;
            RuntimeUndo.BeforeUndo += OnBeforeUndo;
        }

        private void OnDestroy()
        {
            RuntimeSelection.SelectionChanged -= OnRuntimeSelectionChanged;
            RuntimeUndo.BeforeUndo -= OnBeforeUndo;
        }

        private void OnEnable()
        {
            ExposeToEditor.TransformChanged += OnTransformChanged;

            PositionX.onValueChanged.AddListener(OnPositionXChanged);
            PositionY.onValueChanged.AddListener(OnPositionYChanged);
            PositionZ.onValueChanged.AddListener(OnPositionZChanged);
            RotationX.onValueChanged.AddListener(OnRotationXChanged);
            RotationY.onValueChanged.AddListener(OnRotationYChanged);
            RotationZ.onValueChanged.AddListener(OnRotationZChanged);
            ScaleX.onValueChanged.AddListener(OnScaleXChanged);
            ScaleY.onValueChanged.AddListener(OnScaleYChanged);
            ScaleZ.onValueChanged.AddListener(OnScaleZChanged);

            PositionX.onEndEdit.AddListener(OnEndEdit);
            PositionY.onEndEdit.AddListener(OnEndEdit);
            PositionZ.onEndEdit.AddListener(OnEndEdit);
            RotationX.onEndEdit.AddListener(OnEndEdit);
            RotationY.onEndEdit.AddListener(OnEndEdit);
            RotationZ.onEndEdit.AddListener(OnEndEdit);
            ScaleX.onEndEdit.AddListener(OnEndEdit);
            ScaleY.onEndEdit.AddListener(OnEndEdit);
            ScaleZ.onEndEdit.AddListener(OnEndEdit);

            Reset.onClick.AddListener(OnResetClick);
            EnableDisableToggle.onValueChanged.AddListener(OnEnableDisableValueChanged);

            m_dragFields = GetComponentsInChildren<DragField>();
            for(int i = 0; i < m_dragFields.Length; ++i)
            {
                m_dragFields[i].EndDrag.AddListener(OnDragFieldEndDrag);
                if(RoundToInt)
                {
                    m_dragFields[i].IncrementFactor = 1.0f;
                }
            }

            OnRuntimeSelectionChanged(null);
        }

        private void OnApplicationQuit()
        {
            Unsubscribe();
        }

        private void OnDisable()
        {
            Unsubscribe();
        }

        private void Unsubscribe()
        {
            ExposeToEditor.TransformChanged -= OnTransformChanged;

            PositionX.onValueChanged.RemoveListener(OnPositionXChanged);
            PositionY.onValueChanged.RemoveListener(OnPositionYChanged);
            PositionZ.onValueChanged.RemoveListener(OnPositionZChanged);
            RotationX.onValueChanged.RemoveListener(OnRotationXChanged);
            RotationY.onValueChanged.RemoveListener(OnRotationYChanged);
            RotationZ.onValueChanged.RemoveListener(OnRotationZChanged);
            ScaleX.onValueChanged.RemoveListener(OnScaleXChanged);
            ScaleY.onValueChanged.RemoveListener(OnScaleYChanged);
            ScaleZ.onValueChanged.RemoveListener(OnScaleZChanged);

            PositionX.onEndEdit.RemoveListener(OnEndEdit);
            PositionY.onEndEdit.RemoveListener(OnEndEdit);
            PositionZ.onEndEdit.RemoveListener(OnEndEdit);
            RotationX.onEndEdit.RemoveListener(OnEndEdit);
            RotationY.onEndEdit.RemoveListener(OnEndEdit);
            RotationZ.onEndEdit.RemoveListener(OnEndEdit);
            ScaleX.onEndEdit.RemoveListener(OnEndEdit);
            ScaleY.onEndEdit.RemoveListener(OnEndEdit);
            ScaleZ.onEndEdit.RemoveListener(OnEndEdit);

            Reset.onClick.RemoveListener(OnResetClick);

            EnableDisableToggle.onValueChanged.RemoveListener(OnEnableDisableValueChanged);

            if (m_dragFields != null)
            {
                for (int i = 0; i < m_dragFields.Length; ++i)
                {
                    if (m_dragFields[i])
                    {
                        m_dragFields[i].EndDrag.RemoveListener(OnDragFieldEndDrag);
                    }
                }
            }
        }

        private bool m_handleTransformChange = true;
        private void HandlePositionChanged()
        {
            if(!m_handleTransformChange)
            {
                return;
            }


            if (m_transforms == null || m_transforms.Length == 0)
            {
                return;
            }
            float xVal;
            if (!float.TryParse(PositionX.text, out xVal))
            {
                return;
            }
            float yVal;
            if (!float.TryParse(PositionY.text, out yVal))
            {
                return;
            }
            float zVal;
            if (!float.TryParse(PositionZ.text, out zVal))
            {
                return;
            }

            if (!m_isPositionEditing)
            {
                m_isPositionEditing = true;
                RecordTransforms();
            }

            if (RoundToInt)
            {
                xVal = Mathf.RoundToInt(xVal);
                yVal = Mathf.RoundToInt(yVal);
                zVal = Mathf.RoundToInt(zVal);
            }
            for (int i = 0; i < m_transforms.Length; ++i)
            {
                m_transforms[i].position = new Vector3(xVal, yVal, zVal);
            }
        }

        private void HandleRotationChanged()
        {
            if (!m_handleTransformChange)
            {
                return;
            }
            if (m_transforms == null || m_transforms.Length == 0)
            {
                return;
            }
            float xVal;
            if (!float.TryParse(RotationX.text, out xVal))
            {
                return;
            }
            float yVal;
            if (!float.TryParse(RotationY.text, out yVal))
            {
                return;
            }
            float zVal;
            if (!float.TryParse(RotationZ.text, out zVal))
            {
                return;
            }

            if (!m_isRotationEditing)
            {
                m_isRotationEditing = true;
                RecordTransforms();
            }

            if (RoundToInt)
            {
                xVal = Mathf.RoundToInt(xVal);
                yVal = Mathf.RoundToInt(yVal);
                zVal = Mathf.RoundToInt(zVal);
            }

            for (int i = 0; i < m_transforms.Length; ++i)
            {
                m_transforms[i].rotation = Quaternion.Euler(xVal, yVal, zVal);
            }
        }

        private void HandleScaleChanged()
        {
            if (!m_handleTransformChange)
            {
                return;
            }
            if (m_transforms == null || m_transforms.Length == 0)
            {
                return;
            }
            float xVal;
            if (!float.TryParse(ScaleX.text, out xVal))
            {
                return;
            }
            float yVal;
            if (!float.TryParse(ScaleY.text, out yVal))
            {
                return;
            }
            float zVal;
            if (!float.TryParse(ScaleZ.text, out zVal))
            {
                return;
            }

            if (!m_isScaleEditing)
            {
                m_isScaleEditing = true;
                RecordTransforms();
            }

            if (RoundToInt)
            {
                xVal = Mathf.RoundToInt(xVal);
                yVal = Mathf.RoundToInt(yVal);
                zVal = Mathf.RoundToInt(zVal);
            }

            for (int i = 0; i < m_transforms.Length; ++i)
            {
                m_transforms[i].localScale = new Vector3(xVal, yVal, zVal);
            }
        }

        private void EndEditField(InputField field)
        {
            float val;
            if (!float.TryParse(field.text, out val))
            {
                field.text = "0";
            }
            else
            {
                if(RoundToInt)
                {
                    field.text = Mathf.RoundToInt(val).ToString();
                }
             
            }
         
        }

        private void OnEndEdit(string value)
        {
            EndEditField(PositionX);
            EndEditField(PositionY);
            EndEditField(PositionZ);
            EndEditField(RotationX);
            EndEditField(RotationY);
            EndEditField(RotationZ);
            EndEditField(ScaleX);
            EndEditField(ScaleY);
            EndEditField(ScaleZ);

            if(m_isPositionEditing || m_isRotationEditing || m_isScaleEditing)
            {
                RecordTransforms();

                m_isPositionEditing = false;
                m_isRotationEditing = false;
                m_isScaleEditing = false;
            }
        }

        private void OnDragFieldEndDrag()
        {
            if (m_isPositionEditing || m_isRotationEditing || m_isScaleEditing)
            {
                RecordTransforms();

                m_isPositionEditing = false;
                m_isRotationEditing = false;
                m_isScaleEditing = false;
            }
        }

        private void OnBeforeUndo()
        {
            if (m_isPositionEditing || m_isRotationEditing || m_isScaleEditing)
            {
                RecordTransforms();

                m_isPositionEditing = false;
                m_isRotationEditing = false;
                m_isScaleEditing = false;
            }
        }

        private void RecordTransforms()
        {
            RuntimeUndo.BeginRecord();
            for (int i = 0; i < m_transforms.Length; ++i)
            {
                if(m_transforms[i] != null)
                {
                    RuntimeUndo.RecordObject(m_transforms[i]);
                }
            }
            RuntimeUndo.EndRecord();
        }

 
        private void OnPositionXChanged(string value)
        {
            HandlePositionChanged();
        }

        private void OnPositionYChanged(string value)
        {
            HandlePositionChanged();
        }

        private void OnPositionZChanged(string value)
        {
            HandlePositionChanged();
        }

        private void OnRotationXChanged(string value)
        {
            HandleRotationChanged();
        }

        private void OnRotationYChanged(string value)
        {
            HandleRotationChanged();
        }

        private void OnRotationZChanged(string value)
        {
            HandleRotationChanged();
        }

        private void OnScaleXChanged(string value)
        {
            HandleScaleChanged();
        }

        private void OnScaleYChanged(string value)
        {
            HandleScaleChanged();
        }

        private void OnScaleZChanged(string value)
        {
            HandleScaleChanged();
        }

        private void OnTransformChanged(ExposeToEditor obj)
        {
         
            if (!m_selectedGameObjects.Contains(obj.gameObject))
            {
                return;
            }

            m_handleTransformChange = false;
            UpdateAllFields();
            m_handleTransformChange = true;
        }

        private void OnRuntimeSelectionChanged(Object[] unselected)
        {
         
            GameObject[] gameObjects = RuntimeSelection.gameObjects;
            if(gameObjects == null)
            {
                m_selectedGameObjects.Clear();

                EnableDisableToggle.gameObject.SetActive(false);
                TransformComponentUI.gameObject.SetActive(false);
                m_transforms = null;
            }
            else
            {
                m_selectedGameObjects.Clear();
                m_transforms = gameObjects.Where(g => g != null && g.GetComponent<ExposeToEditor>()).Select(g => g.GetComponent<Transform>()).Where(t => t.GetType() == typeof(Transform)).ToArray();
                for(int i = 0; i < m_transforms.Length; ++i)
                {
                    m_selectedGameObjects.Add(m_transforms[i].gameObject);
                }

                if (m_transforms.Length > 0)
                {
                    EnableDisableToggle.gameObject.SetActive(true);
                    TransformComponentUI.gameObject.SetActive(true);
                    m_handleTransformChange = false;
                    UpdateAllFields();
                    m_handleTransformChange = true;
                }
                else
                {
                    EnableDisableToggle.gameObject.SetActive(false);
                    TransformComponentUI.gameObject.SetActive(false);
                }
            }
        }

        private void UpdateAllFields()
        {
            var positionX = m_transforms.Where(t => t != null).Select(t => t.position.x);
            var positionY = m_transforms.Where(t => t != null).Select(t => t.position.y);
            var positionZ = m_transforms.Where(t => t != null).Select(t => t.position.z);
            var rotationX = m_transforms.Where(t => t != null).Select(t => t.rotation.eulerAngles.x);
            var rotationY = m_transforms.Where(t => t != null).Select(t => t.rotation.eulerAngles.y);
            var rotationZ = m_transforms.Where(t => t != null).Select(t => t.rotation.eulerAngles.z);
            var scaleX = m_transforms.Where(t => t != null).Select(t => t.localScale.x);
            var scaleY = m_transforms.Where(t => t != null).Select(t => t.localScale.y);
            var scaleZ = m_transforms.Where(t => t != null).Select(t => t.localScale.z);
            SetFieldValue(PositionX, positionX);
            SetFieldValue(PositionY, positionY);
            SetFieldValue(PositionZ, positionZ);
            SetFieldValue(RotationX, rotationX);
            SetFieldValue(RotationY, rotationY);
            SetFieldValue(RotationZ, rotationZ);
            SetFieldValue(ScaleX, scaleX);
            SetFieldValue(ScaleY, scaleY);
            SetFieldValue(ScaleZ, scaleZ);
            EnableDisableToggle.isOn = m_transforms.Where(t => t != null).All(t => t.gameObject.activeSelf);
        }

        private void SetFieldValue(InputField field, IEnumerable<float> values)
        {
            if (values.Any(p => p != values.First()))
            {
                field.text = string.Empty;
            }
            else
            {
                if(RoundToInt)
                {
                    field.text = Mathf.RoundToInt(values.First()).ToString();
                }
                else
                {
                    field.text = values.First().ToString();
                }
             
            }
        }

        private void OnResetClick()
        {
            float zero = 0;
            float one = 1;
            PositionX.text = zero.ToString();
            PositionY.text = zero.ToString();
            PositionZ.text = zero.ToString();
            RotationX.text = zero.ToString();
            RotationY.text = zero.ToString();
            RotationZ.text = zero.ToString();
            ScaleX.text = one.ToString();
            ScaleY.text = one.ToString();
            ScaleZ.text = one.ToString();
        }

        private void OnEnableDisableValueChanged(bool value)
        {
            if (!m_handleTransformChange)
            {
                return;
            }
            for (int i = 0; i < m_transforms.Length; ++i)
            {
                m_transforms[i].gameObject.SetActive(value);
            }
        }
    }
}

3108838–234936–TransformIntEditor_for_RTE11.unitypackage (2.87 KB)

:wink: Fantastic Job dude. Thanks

Is there any way to import an Asset Bundle at runtime and have the resources within exposed to the editor? Even if I have to do something specific to package a resource map along with the asset bundle.

To create asset bundle with resource map do following:

  1. assign asset bundle to object and all of it’s dependencies
  2. click Tools->RTSaveLoad->Build Resource Map or (Build All) menu item
    3116178--235661--upload_2017-6-21_14-36-57.png

Asset Bundle will be moved to StreamingAssets folder
3116178--235662--upload_2017-6-21_14-38-0.png

See AddResourcesTest script for details on how to import assets from asset bundle at runtime
(To add all assets form bundle use Keypad 6 key)
3116178--235663--upload_2017-6-21_14-39-47.png

Here is code:

  if (InputController.GetKeyDown(AddAssetBundleKey2))
            {
                ProjectItem rootFolder = m_projectManager.Project;
                m_projectManager.AddBundledResources(rootFolder, "bundledemo",
                    (obj, assetName) =>
                    {
                        return true;
                    },
                    addedItems =>
                    {
                        for (int i = 0; i < addedItems.Length; ++i)
                        {
                            Debug.Log(addedItems[i].ToString() + " added");
                        }
                    });
            }

Regards,
Vadim

1 Like

Thanks Vadim, that’s exactly what I needed!
I’m having a small issue, though. I’ve added a prefab to an asset bundle and loaded it as you describe which puts the object in the project window correctly, and I can drag it into the editor, but the object is then not selectable in the editor. I can click on it in the Heirarchy window, but I can’t select it in the editor, and I can’t drop materials on it.
I assume I’m missing something really basic, but I can’t figure out what it is.

Difficult to say. Could you add collider of appropriate size to your object?

I’ve added mesh colliders to the meshes and now I can drag materials on to the meshes, but I still can’t select them. This is good enough for my purposes for now, as I can still select them in the hierarchy window.
Through playing around with things, I think it might be related to the fact that the mesh I’m using has submeshes (it split itself automatically on import due to having too many vertices). The submeshes are not visible in the heirarchy and I’m not sure why that is.

Hi Vadim,
Are there any ways to load the scene from the runtime editor? since the player won’t just use the runtime editor build.

thanks

Not sure if I understand question correctly. Could you clarify a little bit which scene runtime editor should load? Unity scene? or what?

Send your mesh to Vadim.Andriyanov@outlook.com and I could test it.

  1. the scene is created by players, for example, if player create a new scene and put some objects into it, then save the scene to a *.rtsc file, next time when the play opens the editor is there a way to load the scene, or upload the scene to a server and players can load the scene ?

2.When I use this editor, I found this bug few times when close and open scene continuously [editor version is the lastest], see the attachment.

3.If I wanna implement this kind of feature, Is it possible with this editor, the editor provides some default prefabs to the player in the 1st version, later we can publish more asset bundles, so the player can download these bundles to make more scene since the editor need to build the resource map. I do not quite understand why you have this kind of resource mapping system.

What I think the way will be like this,
we put some prefabs or asset bundles in a specific folder when the editor read that info, the player can use those bundles to make their scenes when saving the scene, we just need to save the asset bundle type and the serialized instance value. please let me know what do you think about this?

BTW, this editor is so good, you did a fantasic job, save me lots of time.