Runtime Level Design

I wasn’t very clear: when I talked about selection I only meant that the user should be able to use selection and multiselection in play mode, it was not a thing I wanted to keep when switching back to the editor :wink:

About creation and deletion, I was thinking/suggesting about a more naive approach:

Each object that gets manipulated in realtime creates a struct/class like this on the object, or on a generic list of PlayTimeInfo:

PlayTimeInfo{
GameObject manipulatedObject; //null if this object has been created during playTime, otherwise this holds the reference to the actual object which has been manipulated
Vector3 localPosition;
Quaternion/Vector3 localRotation;
Vector3 localScale;
bool pendingDelete=false; // Should we delete this object when returning to the Editor?
GameObject pendingCreationObject=null; //If null, just apply the changes. If not null, first instantiate this GameObject and then apply the above settings on that
}

supposing we are able to keep this data about every manipulated object when going back to the editor, we apply all changes to objects that have the manipulatedObject == null or the pendingCreationObject != null.
if pendingCreationObject is not null, we instantiate in editor an object with pendingCreationObject as “Prefab”
we then apply all transforms.
finally, if pendingDelete == true we delete the manipulatedObject object (or, we may be entirely skipping its creation/tweaking)

During playtime:
Deleting an object = setting an appropriate PlayTimeInfo with a reference to the object about to be deleted, and pendingDelete = true

Duplicating:
if pendingCreationObject != null, then it’s a duplicated/new object

Duplicating an existing object = setting an appropriate PlayTimeInfo with a reference to the object about to be instantiated in pendingCreationObject

Duplicating a duplicate = duplicate the PlayTimeInfo, also copying the pendingCreationObject since they’re both created with the same blueprint.

Of course the new objects are not really the same (different instanceID) when going back to the editor, but since we’re probably just decorating, it shouldn’t matter.

The only important thing is to handle creations before deletions.

This is just how I’d try to implement it, there are probably more stylish ways to do it :slight_smile:
No need to know about any serialization technique :wink:

Sorry for the late reply.
Ok :slight_smile: I will give this a try and let you know how it worked.

1 Like

Hi @NeatWolf ,

Unfortunately I haven’t managed to start working on the solution yet. :slight_smile: I am working on an update for another package and I thought it would be finished by now, but it seems to take more time. Is the needed functionality urgent? Although I wish to finish with the other one, I can make a switch if needed.

Thanks for undestanding.

1 Like

Hi,

thanks for caring but no, it’s not urgent, it would be a welcome feature to have, tho :slight_smile:

Please keep us posted about it! :slight_smile:

Cheers,
Alessandro Salvati

Hey there,

I can’t seem to find it anywhere - what’s the licensing on this? Per seat? Per Title?

Hi,

I am sorry, but to be honest, I can not give you a direct answer to that since it’s not really my area of expertise :smile:
The best I can do is to point you to this page: Legal Terms. I believe Appendix 2 contains the info you requested. In any case, you should be able to get a much clearer answer from a Unity representative.

Thanks for taking an interest in my package.

No worries, lad. Just trying to determine if I need to pay per user or if it’s a one-time purchase.

The legal terms link pretty much answers my questions. Thanks for the heads up!

Ok. Glad to hear you cleared the matter up! :slight_smile:

Hi there @NeatWolf

I just wanted to let you know that I haven’t forgotten about you :slight_smile:
I have released a new update for RTTGizmos recently and I’ve just finished implementing another one. Need to submit it on the store and I think I can start working on the functionality that you requested tomorrow.

Thanks for your patience :slight_smile:

1 Like

Since in the description of the asset is not reported is a one-time

Great to know! I also haven’t forgotten about you as well, since I came here several hours ago to check up the current state of the asset (notifications aren’t working properly) and finally decided to purchase it with or without my feature requests :slight_smile:
Looking forward to the next update then! :slight_smile:

Cheers,
Alessandro Salvati

@NeatWolf
Ok. Great! If you would like me to send you the package before it gets approved, send me an e-mail or PM.

EDIT: This package won’t contain the features you requested. That will be in the next one :smile:

1 Like

HI everyone,

I would like to let you know that version 1.2 is available on the store. Here are the new changes:

New features:

  • added event for active gizmo type change (e.g. EditorGizmoSystem.Instance.ActiveGizmoTypeChanged += EventHandler);
  • added IRTEditorEventListener interface which can be implemented by monobehaviours to listen to different types of events;
  • it is now possible to specify the corner where the scene gizmo will sit. Possible values are: TopLeft, TopRight, BottomRight, BottomLeft;
  • key mappings for gizmos, object selection and camera;
  • it is now possible to specify if Unity colliders must be used for object interaction. This is especially useful when you are working with scenes that contain large amounts of objects or when the meshes that you are working with are very high res. If you experience low frame rates, checking the ‘Use Unity Colliders’ options in the RuntimeEditorApplication Inspector should fix this issue. NOTE: Using Unity colliders is not possible when working with 2D sprites. In that case, the custom system must be used (i.e. uncheck Use Unity Colliders).

Bug fixes:

  • fixed terrain and mesh surface placement for move gizmo bug which was happening when the controlled object was part of a hierarchy. The objects would snap in an awkward manner because the mouse cursor was hovering one of the objects in the hierarchy;
  • fixed gizmo position not updated correctly after gizmos were toggled off;
  • fixed rotation gizmo angle snap not working correctly when activating snapping in the middle of a normal rotation session. The gizmo was applying the snap rotation relative to the existing rotation instead of the default pose (zero rotation).

Removed:

  • the scene view gizmo representation for the transform gizmos is no longer shown. This was done purely for having a cleaner and smaller codebase as far as the gizmo classes are concerned. Besides, the scene view representation was rather rough around the edges and it is much more useful to check the look and feel of the gizmos at runtime, in the environment where they will actually be used;
  • SetEnabled method from the EditorObjectSelection mono. Enabling or disabling the object selection mechanism can be done by simply enabling or disabling the EditorObjectSelection component;
  • ObjectSelectionModeChangedAction is no longer available. The reason that this action existed was to ensure proper undo/redo of this mode change. However, this is useless and error prone. The ObjectSelectionModeChangedMessage has also been removed;
  • AssignObjectsToSelectionMaskAction is no longer available;
  • RemoveObjectsFromSelectionMaskAction is no longer available;
  • removed custom object selection click/multi select handlers. In consequence the ‘Custom’ object selection mode has also been removed;
  • removed gizmo change, transform pivot change, transform space change and turn off gizmos actions. These were necessary to allow Undo/Redo for these types of proprty changes. However, Undo/Redo is no longer supported for these as it can prove to be rather unintuitive;
  • the ‘TakeZoomFactorIntoAccount’ property of the editor camera has been removed. This should always be the default behaviour;
  • removed ‘ObjectsAddedToSelectionMaskMessage’ message class;
  • removed ‘ObjectsRemovedFromSelectionMaskMessage’ message class;
  • removed ‘TransformSpaceChangedMessage’ message class;
  • removed ‘GizmosTurnedOffMessage’ message class;
  • removed ‘TransformPivotPointChangedMessage’ message class;
  • removed ‘ActiveGizmoTypeChangedMessage’ message class;
  • removed redundant gizmo color properties which could easily be deduced from the specified gizmo axes colors.

As you can see, there’s quite a number of things which have been removed :), so please be aware that if you have been using these entities (classes or functions) in your project, you might get compile errors when importing this new version. However, I consider that this was a necessary cleanup so it had to be done.

I would like to suggest that you take a look at the entire chapter 6 inside the documentation as there are some new things that you can now do with the API which weren’t previously available.

Please don’t hesitate to contact me for any inquiries you might have.

Enjoy!

Best Regards,
Andrew

1 Like

Hi @NeatWolf ,

I just wanted to let you know that as of this moment I can start working on the functionality you requested. I will keep you posted :slight_smile:

1 Like

Hi @NeatWolf ,

I wanted to let you know that the requested functionality is finished.
You can preserve object position, rotation and scale, and object duplication. However, you can not record object deletion. The reason for this is that the system currently does not support a feature which deletes objects. Although it may seem simple, it is made a bit complicated by the fact that it also has to work with Undo/Redo.

Also, please keep in mind that all the changes (position, rotation, scale, object duplication) must be performed via the RTTGizmos interface (no Unity actions). This is necessary because the system needs to be informed when such events occur.

Let me know if you would like me to send you the package (PM or e-mail).

Hi everyone,

Version 1.2.1 is now available on the store. Here’s the change list:

New features:

  • added ‘Can Click-Select’ property in object selection Inspector. If unchecked, the user can no longer select/deselect objects by clicking;

  • implemented new scale gizmo type called ‘VolumeScaleGizmo’. This allows you to perform object scaling in almost the same way that you can modify box colliders using collider widgets;

Improvements:

  • added possibility to toggle the Undo/Redo system on/off (‘Enable Undo/Redo’ toggle inside the Runtime Editor Application Inspector);

  • added possibility to specify if a custom camera must be used for scene navigation. When a custom camera is used, default camera functionality is disabled;

Bug fixes:

  • fixed bug which was causing the active gizmo type to change when manipulating the camera (happened because of hotkey clash);

  • fixed scene gizmo was not taking the editor camera viewport into account.

You can see the volume scale gizmo in action in the following video:

Enjoy!

Finding a number of bugs in 1.2.1

First one, in MonoSingletonBase.cs:
public static T Instance
{
get
{
// Is the instance availanle?
if (_instance == null)
{
// Apply lock on our sync object
lock (_singletonLock)
{
// Retrieve the instance from the scene.
// Note: We will retrieve an array of instances and make sure that only one intance exists.
T[ ] singletonInstances = FindObjectsOfType(typeof(T)) as T[ ];

// More than one singleton?
if (singletonInstances.Length > 1)
{
// Log warning message if running in editor mode and then return null
if (Application.isEditor) Debug.LogWarning(“MonoSingleton.Instance: Only 1 singleton instance can exist in the scene. Null will be returned.”);
return null;
}
_instance = singletonInstances[0]; // Only one instance was found, so we can store it
}
}

// Return the singleton instance
return _instance;
}

First pass through, on line _instance = singletonInstances[0]; will throw a system exception that you are going out of bounds on the array, since the array isn’t created.

Starting with V1.2.1 the singleton class assumes that the instances already exist. They are created when you click on the Initialize menu item. In previous versions, they were created by actually calling the Instance property which would detect that no instances exist and it would create one.

So FindObjectsOfType will always return an instance except for the case in which we are dealing with the UndoRedoSystem which can now indeed be missing from the scene in case it was disabled in the RuntimeEditorApplication Inspector. However, even in this case, this is treated elsewhere so currently there is no danger here.

But this is indeed something that needs to be adjusted. The length of the array needs to be checked against 0 and if it is 0, return null.

I will fix this in the upcoming version.

Yeah, I’m using it a bit differently - invoking and building the runtime components through code, not through the Editor initialization script - would rather build it at runtime rather than storing gameobjects into the editor.

I’ve also noticed that there are an number of additions of #if UNITY_EDITOR that are defined in source files in the Scripts folder, rather than isolating them inside the Editor folder. Personally, I prefer that separation.

Well, I built the singleton class and classes that derive from it with the assumption that they will always exist in the Editor after Initialize was clicked on :).

Regarding, #if UNITY_EDITOR that all depends on someone’s style I guess. In this case I do not remember where these are used, but I usually like to have only GUI related code in the Editor folder. If other types of functionality require to run only inside the Editor, I will use the macro wherever I need to. For example, in the GameObjectExtensions file (if I am not mistaken) I used this macro to include the UnityEditor namespace and to define a function which checks if an object is a scene object or a prefab. This file resides somewhere in the scripts folder.

Also sometimes (but I believe it’s not the case in RTTGizmos), I might have a Settings class for a specific entity and I would define a method called RenderView() to render the GUI controls inside the Inspector or Editor window that allow the settings properties to change. In this case, I would have to use the macro and only compile the RenderView method when inside the editor. Puting the Settings class inside the Editor folder won’t work because then I would not be able to access it from the Scripts folder.

Well… :slight_smile: I guess there is no right or wrong here. If you need any help with the scripts, let me know.

Would it be hard to modify your runtime gizmos to work with VR, raycast from the tracker to select gizmos and move them?