So as I was working on a project that has a bunch of UI panels I kept forgetting to disable certain panels before running the game or before committing it and my client would see the panels with the loading screen. Sure I could add a line to the controllers I have set up to set the default state, but there's a bunch of controllers, not all of them have the panel assigned to them at start, not all of them are disabled (some are alpha 0, some are scale 0), and it's really best when an object maintains its own default state. So I said to myself, "I really need a universal script to do this. Wouldn't it be great to have some sort of drag-drop interface to do this?" I didn't really want to write a custom inspector for it since that would take 2 scripts. Then it occurred to me: BUTTONS they have on-click events. That's what I want. And boy was it easy!
So all you have to do is create a MonoBehaviour derived class. Declare using UnityEngine.Events, declare a public UnityAction variable. Then in your Start() method just Invoke() that event. Super simple. Here's the code:
Way too easy. Of course, you could extend this to also do Awake, OnEnable, OnLevelWasLoaded, OnApplicationPause, OnBecameVisible/Invisible, OnApplicationQuit, and OnDisable (I'd highly recommend avoiding using any of the main loop events). A very neat and clean way to do a simple delegate that's assignable from the inspector and can set the value on pretty much any component.
I hope you all find this as handy as I have. Feel free to post a more extended version here if you like sharing with others.
As always, thanks for reading!
On a personal note, my wife just published her first book! If you like kick-ass female protagonists, spies, and a bit of sci-fi then please check out her book on Amazon.
2016/09/16
2016/08/27
Unity 3D Tutorial - Custom Transform Inspector
Hi everyone!
One of the awesome things about Unity is you can customize the editor to add all sorts of cool functionality. This article will show you how to override Unity's transform inspector with a more useful customized version. The Custom Transform Component includes:
Here's what the final product will look like:
Some extra explanation beyond the comments as to what's going on here. First, we set up a class level Transform (aptly named _transform) to hold the transform of the target (the selected object) so that we can refer to it throughout the class. We override OnInspectorGUI() and immediately cast target (a property of the Editor class) to a Transform type and set _transform.. Then we call our new method, StandardTransformInspector().
In the StandardTransformInspector() method we have a few things going on. First, we set up some bools to flag when a value is changed in the inspector and we store the initial position, rotation, and scale of our transform so that we can make a comparison later. Then you'll see three spots where we check for changes with EditorGUI.BeginChangeCheck() and flag our bools if a change has occurred by checking EditorGUI.EndChangeCheck(). Once that has finished and when know what if something has changed we now use Undo.RecordObject() to record the state of the object before any change has been made (this allows use to Undo the operation). Then we simply apply only the changes that have occurred.
Next, we have some adjustments to make to get our inspector to work like Unity's default inspector. Since we're using BeginChangeCheck() and EndChangeCheck() our changes will only be applied to the last selected object. So this basically breaks multi-selection editing which is what we're fixing next.To help us out I created another method, ApplyChangesOnly(), which will only apply a change to the x, y, or z value of the vector if it was changed in the selected transform. So if you change the x position it only changes the x position of all selected objects. Similarly I set up an undo state if anything will be changed, then iterate through all of the selected transforms (retrieved with Selection.transforms) and apply changes when it is appropriate.
That'll cover all the changes we need for recreating the default inspector for transforms. The only actual change I made over the default is I named the "Rotation" fields to "Euler Rotation". This is just so that we can see how to do this, and we'll be showing the Quaternion rotation in the inspector next.
The new QuaternionInspector() method uses familiar components as the StandardTransformInspector() method, but also uses EditorGUILayout.Foldout() to tell us whether the foldout should be open or not. A special note here: I used a static bool to store the state of the foldout. This means that when you open the foldout for any game object they will all be open since they're using a global static value. This decision was made because I didn't like opening it on one object, then making a multiselection and having to open it again. There's also a couple utility methods for converting the quaternion to and from a Vector4 since Unity doesn't offer a GUI item for quaternions and quaternions at their base are Vector4s, Those utility methods are pretty basic so hopefully you'll understand without extra explanation. Here's the new chunk of code we add to get it all working:
Now we have a custom inspector for transform components that shows us (and allows us to edit) the quaternion rotation. Pretty cool, but not overly useful. Next up we're going to add some utilities to our inspector to get the most out of it.
To accomplish safe destruction of component via another component we'll need a custom inspector that waits for the proper time to destroy the component. Otherwise, we'll get some nasty errors in Unity. The below script does just that. We don't care about any special display, but since we used HideInInspector and Range in ShowLocalAxis, we'll use base.DrawDefaultInspector() to show the default view instead of base.OnInspectorGUI() that I mentioned before. So what happens is our custom transform component will set the destroyWhenSafe bool to true, then when the editor's state is Repaint we can safely destroy the ShowLocalAxis component.
Now we have our component all set up, let's integrate it with our custom transform component. For this we'll make a new method called ShowLocalAxisComponentToggle() and change our CustomTranformComponent's OnInspectorGUI() to so it calls the method like this:
In Next up is the ShowLocalAxisComponentToggle() method, For this we'll need a private bool, showLocalAxisToggle, that will be used to toggle on/off the ShowLocalAxis component. And we'll need a First, we start off by adding some padding above the rest of the GUI elements with two calls to Unity's EditorGUILayout.Space() method. Next we attempt to see if there is a ShowLocalAxis component attached to the game object. If there is then we set our showLocalAxisToggle to true and display it in the inspector. This time we're going to use a horizontal layout (which starts a horizontal section where the GUI elements will be placed) by calling EditorGUILayout.BeginHorizontal(). Then we use a EditorGUILayout.LabelField(), start to monitor changes, and display a EditorGUILayout.ToggleLeft() with a corresponding label of "on" or "off" based on the existence of the ShowLocalAxis component. If the toggle changes value then we add the component and move it up to the second position so that it is right under the transform component. If we're toggling the ShowLocalAxis to off then we flag it with destroyWhenSafe and allow the ShowLocalAxis component to destroy itself when it is safe to do so. The full method looks like this:
That takes care of showing the local axis. Now we've learned how to create custom inspectors, do some layout, show axis line gizmos, and safely add/remove a component from another component. In the next section I will show you how to add even more functionality to the transform component. We'll set up methods for aligning selected game objects to each other, randomly rotating them, randomly scaling them, and randomly positioning them. Each of which can be very helpful in speeding up level design.
One of the awesome things about Unity is you can customize the editor to add all sorts of cool functionality. This article will show you how to override Unity's transform inspector with a more useful customized version. The Custom Transform Component includes:
- The ability to view and edit the quaternion rotation (nice for experimenting and learning how quaternions work).
- The ability to show the local axes in the Scene view even when the object is not selected.
- Some special operations for aligning to other objects, random rotation, random scale, and random position.
Here's what the final product will look like:
Part I: Extending the Default Transform Inspector
Overriding the Defaults
First, thing's first. We'll need to recreate Unity's transform inspector (not completely necessary). To make any custom editor scripts you'll first need a folded called "Editor" in your Assets folder. This is a special folder that Unity looks in to for scripts that can only run in the Editor i.e. any script using UnityEditor;. You're not limited to one Editor folder per project so you can organize your editor scripts right alongside your MonoBehaviour scripts if you like. More info on on Unity's special folders can be found here. The UnityEditor namespace This gives us access to a whole bunch of awesome tools for writing editor windows, inspectors, importing assets, and pretty much anything that you need in the Editor.
The first part of our script is a bit boring and doesn't really add any functionality to the Transform component. Some other notes before proceeding:
- Custom inspector scripts need to inherit from Unity's Editor class.
- To indicate what component (in our case the Transform component) the custom editor is for we will use the CustomEditor attribute.
- Very commonly, you'll want to be able to select multiple items simultaneously and edit them. For this you'll need to add the CanEditMultpleObjects attribute. There are some caveats to this and you may need to write your own methods to apply changes to all selected objects as in the example below.
The first part of our class will basically recreate Unity's transform component. Unity draws the inspector in the method OnInspectorGUI() we will override this to make our custom inspector. Now, you don't need to recreate the default inspector (the part that shows position, rotation, and scale). I'm doing it here to give you insight on how custom editors work, If you just want to use Unity's default then you can call base.OnInspectorGUI() from your override of OnInspetorGUI(). As you may see from the extents of the code below, that may be your preferred option.
Some extra explanation beyond the comments as to what's going on here. First, we set up a class level Transform (aptly named _transform) to hold the transform of the target (the selected object) so that we can refer to it throughout the class. We override OnInspectorGUI() and immediately cast target (a property of the Editor class) to a Transform type and set _transform.. Then we call our new method, StandardTransformInspector().
In the StandardTransformInspector() method we have a few things going on. First, we set up some bools to flag when a value is changed in the inspector and we store the initial position, rotation, and scale of our transform so that we can make a comparison later. Then you'll see three spots where we check for changes with EditorGUI.BeginChangeCheck() and flag our bools if a change has occurred by checking EditorGUI.EndChangeCheck(). Once that has finished and when know what if something has changed we now use Undo.RecordObject() to record the state of the object before any change has been made (this allows use to Undo the operation). Then we simply apply only the changes that have occurred.
Next, we have some adjustments to make to get our inspector to work like Unity's default inspector. Since we're using BeginChangeCheck() and EndChangeCheck() our changes will only be applied to the last selected object. So this basically breaks multi-selection editing which is what we're fixing next.To help us out I created another method, ApplyChangesOnly(), which will only apply a change to the x, y, or z value of the vector if it was changed in the selected transform. So if you change the x position it only changes the x position of all selected objects. Similarly I set up an undo state if anything will be changed, then iterate through all of the selected transforms (retrieved with Selection.transforms) and apply changes when it is appropriate.
That'll cover all the changes we need for recreating the default inspector for transforms. The only actual change I made over the default is I named the "Rotation" fields to "Euler Rotation". This is just so that we can see how to do this, and we'll be showing the Quaternion rotation in the inspector next.
Showing the Quaternion Rotation
Quaternions are what Unity (and many other 3D applications) use to store rotational information. They're a bit complex and not as intuitive as euler angles (degrees for x, y, and z). However, they are a necessity in 3D applications because euler angles don't fully describe rotation and the suffer from Gimbal lock. Check out the links to learn more on these. A discussion on Quaternions go well beyond the aim of this post and, honestly, I'd probably do a bad job explaining them. A quaternions are often a mystery to many and I decided to expose them in the inspector so that we can view and optionally edit them to get a better understanding of their behavior.
This section of the inspector will use a foldout (the little arrow head that shows more info when clicked). To maintain the state of the foldout we use a bool (is it open or closed?) and we'll use a new method, QuaterionInspector(), to display the quaternion's values.We'll also need to add a call to the method in OnInspetorGUI() as can be seen below:
The new QuaternionInspector() method uses familiar components as the StandardTransformInspector() method, but also uses EditorGUILayout.Foldout() to tell us whether the foldout should be open or not. A special note here: I used a static bool to store the state of the foldout. This means that when you open the foldout for any game object they will all be open since they're using a global static value. This decision was made because I didn't like opening it on one object, then making a multiselection and having to open it again. There's also a couple utility methods for converting the quaternion to and from a Vector4 since Unity doesn't offer a GUI item for quaternions and quaternions at their base are Vector4s, Those utility methods are pretty basic so hopefully you'll understand without extra explanation. Here's the new chunk of code we add to get it all working:
Now we have a custom inspector for transform components that shows us (and allows us to edit) the quaternion rotation. Pretty cool, but not overly useful. Next up we're going to add some utilities to our inspector to get the most out of it.
Showing the Local Axis
Oftentimes I've found that I'll really need to see the direction an object is pointing when I don't have it selected. It can be a pain to try to align rotations when you can't see the rotation of the object you're trying to align to! So I created a simple MonoBehaviour class that does just that. Now, you don't need the custom transform component for this, but the goal here is to show you how to integrate another component with your custom inspector. We could control all of the values of the ShowLocalAxis component via our custom transform component, but for such a simple component it is pretty pointless. Besides Unity already exposes the only variable we have in the component: handleLength. The goal here is to show you how to properly add and remove a component from another component via the inspector.
Here's the ShowLocalAxis class. It's pretty short and makes use of OnDrawgizmos() to show some lines that represent the axes of the object it is attached to. It allows for variable length of the lines (handleLength) which have been limited using the Range attribute. The Range attribute sets up a nice slider in the inspector for us. We are also using the HideInInspector attribute to prevent Unity from showing a public bool, destroyWhenSafe, whose purpose I will explain in a bit. Otherwise, the class should be pretty straight forward. It is just drawing a line on the local x, y, and z axes. To set the Gizmo's space to the object's local space we set Gizmos.matrix to transform.localToWorldMatrix.
To accomplish safe destruction of component via another component we'll need a custom inspector that waits for the proper time to destroy the component. Otherwise, we'll get some nasty errors in Unity. The below script does just that. We don't care about any special display, but since we used HideInInspector and Range in ShowLocalAxis, we'll use base.DrawDefaultInspector() to show the default view instead of base.OnInspectorGUI() that I mentioned before. So what happens is our custom transform component will set the destroyWhenSafe bool to true, then when the editor's state is Repaint we can safely destroy the ShowLocalAxis component.
Now we have our component all set up, let's integrate it with our custom transform component. For this we'll make a new method called ShowLocalAxisComponentToggle() and change our CustomTranformComponent's OnInspectorGUI() to so it calls the method like this:
In Next up is the ShowLocalAxisComponentToggle() method, For this we'll need a private bool, showLocalAxisToggle, that will be used to toggle on/off the ShowLocalAxis component. And we'll need a First, we start off by adding some padding above the rest of the GUI elements with two calls to Unity's EditorGUILayout.Space() method. Next we attempt to see if there is a ShowLocalAxis component attached to the game object. If there is then we set our showLocalAxisToggle to true and display it in the inspector. This time we're going to use a horizontal layout (which starts a horizontal section where the GUI elements will be placed) by calling EditorGUILayout.BeginHorizontal(). Then we use a EditorGUILayout.LabelField(), start to monitor changes, and display a EditorGUILayout.ToggleLeft() with a corresponding label of "on" or "off" based on the existence of the ShowLocalAxis component. If the toggle changes value then we add the component and move it up to the second position so that it is right under the transform component. If we're toggling the ShowLocalAxis to off then we flag it with destroyWhenSafe and allow the ShowLocalAxis component to destroy itself when it is safe to do so. The full method looks like this:
That takes care of showing the local axis. Now we've learned how to create custom inspectors, do some layout, show axis line gizmos, and safely add/remove a component from another component. In the next section I will show you how to add even more functionality to the transform component. We'll set up methods for aligning selected game objects to each other, randomly rotating them, randomly scaling them, and randomly positioning them. Each of which can be very helpful in speeding up level design.
Part II: Special Operations
This section is split into subsections for each of the Special Operations. First, I'm going to show the full code for handling an animated foldout for showing/hiding the special operations. First, we need to have a class-level AnimBool object to maintain the state of the foldout, and a static bool to set the foldout states on all custom transform components globally. We set assign the AnimBool in OnEnable() which fires when a game object is selected in the editor. The states will then be properly set and we'll need to add a call to the SpecialOperations() method in our OnInspectorGUI() method like we've done before. For now, you won't have the AlignmentInspector(), RandomRotationInspector(), or RandomPositionInspector() methods, so you can just create stubs for them now if you like. But we'll cover them in the following sections.
Custom Button
Before we dig in, each of these inspectors will have buttons associated with them. Unity's default for an inspector button is to stretch its width to fit the inspector window. I don't really like that so I went ahead and created my own button. First I define a GUILayoutOption to set the width of all the buttons to 200 (I found this number after I made all my buttons and could see their width). Then in the Button() method I wrap everything in a horizontal layout, add flexible spaces to the left and right of the button (this centers it), I then get the bool value from Unity's GUILayout.Button() so I can return it from the new method.Alignment Inspector
The Alignment special operation will allow us to select multiple objects and line them up on their X, Y, or Z axis (or any combination of). This can be quite handy when doing level design. Definitely much better than having to figure out your snap interval or manually inputting position values. First thing we're going to need is a couple of enums. AlignToType is just either the last selected GameObject or the first selected GameObject. AxisFlag is a bit flag enum that allows us to make any combination of X, Y, and/or Z (the values you see are bits - i.e. 2 to the power of 0, 1, and 2 respectively). Then we set some default values up for these in alignTo and alignmentAxis. Like so:
Next up is our method to actually perform the alignment operation, this is called AlignTo(). First it gets an array of all of the selected transformas then it determines the index in that array (targetIndex) of the transform (or GameObject) we'll be aligning to. This is index 0 for the first selected and the last index of the array to align to the last selected transform. Then we iterate through all of the selected transforms and set their positions that should be aligned to the position of the selected transform. While doing this for loop, we ensure we skip over the selected transfor, because it makes no sense to move it to itself. Finally, we use Undo.RecordObject() so that we can reverse these operations.Some of you may be familiar with bitwise operations and may see the & in the conditions. Others of you are probably wonder what statements like
if ((axis & AxisFlag.X) == AxisFlag.X)
actually mean. The single & is a binary AND operator. What this does is it copies the bit to the results IF the bit exists in both operands (axis and AxisFlag.X). So if axis contains the bit for AxisFlax.X the result will be AxisFlag.X. This is why we're using powers of 2 for our AxisFlag enum's values. Basics on bitwise operators in C# can be found here at tutorialspoint.com. The full AlignTo() method is as follows:
if ((axis & AxisFlag.X) == AxisFlag.X)
actually mean. The single & is a binary AND operator. What this does is it copies the bit to the results IF the bit exists in both operands (axis and AxisFlag.X). So if axis contains the bit for AxisFlax.X the result will be AxisFlag.X. This is why we're using powers of 2 for our AxisFlag enum's values. Basics on bitwise operators in C# can be found here at tutorialspoint.com. The full AlignTo() method is as follows:
Finally, we get to our AlignmentInspector() method which will display this special operation in our inspector. We're now making use of some enums, so there's two new methods for that - EditorGUILayout.EnumPopup() and EditorGUILayout.EnumMaskField(), The EnumPopup will allow us to select from a single enum value (our align to first/last selected) while the EnumMaskField will allow us to pick from any combination of enum elements (as long as they're powers of 2). It's also important to note here that these two methods return a generic enum so we must cast them back to our enum type to ensure they're correct. The we set up a string to hold our button label if only one game object is selected. We check to see if multiple game objects are selected. If they are we label the button more appropriately and enable the button. Finally we check to see when the button is pressed and if it is we execute AlignTo(). The following code illustrates this in its entirety:
Random Rotation Inspector
The Random Rotation inspector doesn't really cover anything new. In brief we're doing many things similar to the Alignment inspector. We set the axis flag(s) for what axis to rotate on, change the button label to indicate if 1 or more transforms are selected, then apply a random rotation (in euler angles) to the appropriate axis. See, things are getting easier!
Random Scale Inspector and Random Position Inspector
Last, but not least, are the Random Scale and the Random Position inspectors. These are also pretty easy now that we've gotten through all the drudgery. No new concepts appear here other than using a min and max value for the random value. The reason for this is that we need some bounds for our random value. With rotation, that's simple (0-360), but with position and scale... it could be anything to +/- infinity. So we ask the user to set those values in the inspector (of face the consequences!). The code below completes our custom inspector:
Final Thoughts (and some homework)
Ha! Didn't think you were going to be given homework, did ya?
All of this was done to provide you with a practical example of customizing Unity's inspectors. You can apply these to your own classes, or override inspectors that you don't like (or think need more functionality). This is one of the many features that makes Unity powerful, it's extendible. Not only can you make these custom inspectors to help you with tasks, but you can also make custom context menus, custom menus, and editor windows. My rule is: if I'm going to be doing something a lot, then why not have a script do it for me. One example is: I ran into a project with about 60 scenes (yeah...) each scene had its own camera, like usual. Well, my client wanted to change settings on those cameras. I don't want to think how long it would have taken me to go through all of those scenes. And what happens when the client wants to make another adjustment to all the cameras (they did a few times)? Or if I miss something because I was trying to do it fast. Unity editor scripting to the rescue! I spent maybe an hour writing a custom script that would go through every scene and change the main camera to the settings I wanted. Changes now take about 1 minute instead of a couple hours. I sure was glad they were using Unity.
On to the homework!
The Custom Transform Inspector isn't quite complete. It needs at least one more thing: an even distribution component. Wouldn't it be amazing to select a few objects, align them on an axis and then make them nicely distributed? Yes, it would! Your task is to add on to the custom transform inspector and make this happen! The first person to do this will get a free copy of my Mobile Screenshot Helper asset from the Unity Asset Store. Just make the code neat and clean and keep to the same naming conventions Im using in the script.
Here are the full scripts for you to play with:
As always, thanks for reading!
.
2016/07/29
Unity 3D to IBM DB2 Connection Tutorial
I recently had the challenge of connecting to an IBM DB2 database via Unity. After some struggles with setting up DB2 and getting the user access all correct, it ended up being fairly easy. This quick tutorial will show you how to do it and point out some of the pitfalls you might encounter along the way.
Step 1 - Set up IBM DB2
To try this out you'll need to be able to connect to a DB2 database. I didn't have access to any so I set one up on my Windows 10 PC. Any of the DB2 installations should work fine for this, but for my task, I went with IBM DB2 Express-C. That's their free community edition. It's probably missing some more advanced features, but I really just needed a simple database set up to test the connection to.
The installation isn't difficult, but the installer UI looks like something out of the 90s for Windows 3.1. Basically, just follow the prompts for the typical installation. You'll be asked to create a user and password. This actually creates a new user on the Windows OS. It wasn't clear that would happen at the time of installation and I probably could have gone with my standard Windows user credentials. This is an important factor to note. After setup this account that you choose is the one with default rights to create the database.
So after lots of digging around, I found out this was a problem I had and was slowing me down. Eventually, I found out that the Windows user you're logged in as has to belong to a user group that DB2 set up. It sets up two user groups: DB2ADMNS and DB2USERS. I made it so that my main Windows account belonged to both groups. This can be done via lusrmgr.msc. Right click on the Start Menu, select Run and type in lusrmgr.msc and you'll get the Local Users and Groups Manager window. In here you can select your username, right click to get to properties, then in the Member Of tab you can add the user to the user group. I think that only DB2ADMNS group is required, but I did both.
Once you get that all corrected you may also have to make some adjustments to DB2's configuration. This is done via the newly installed DB2 Command Window. I always run the Administrator version so that I'm sure I have all the access I need. Once you launch this you can run the command db2 get dbm cfg. This will print out the config details in the terminal window. If this doesn't work right away then try db2start, which starts the DB2 service. Now you'll want to change a few of these settings. specifically: SYSADM_GROUP, SYSCTRL_GROUP, SYS_MAINT_GROUP, and SYSMON_GROUP. You'll want all of these to be set to DB2ADMNS which is the user group in Windows that has full access to modify the database. Use the following command to set these:
db2 update dbm cfg using SYSADM_GROUP DB2ADMNS
Do this for each setting.
Now things should be pretty happy. You can try creating a new database with:
db2 create database YOURDATABASENAME AUTOMATIC STORAGE YES
If all is set up correctly then you should get a success message.
Other useful DB2 commands.
I don't overly enjoy working via the command line terminal so I went and downloaded IBM Data Studio. It was a pretty simple setup and I just went with the defaults. From there you can create your databases, tables, import data and run queries. One major annoyance I found with this is that when you type a lowercase name for a table or column name this program will surround it with double quotes. Which means that if you create a table named mytable then to query it you'll need to use "mytable" in your queries. Not cool, IBM, not cool. I eventually just named everything with caps, but Data Studio prepares SQL statements for you that you can edit and remove the unnecessary quotes when creating your tables. I still can't get Data Studio to create a database, so I do that by command line. Not sure what the problem is, I've even tried by running it as Administrator and even in the user account that it set up. No go. Command line, no problem. Go figure...
Also when you set up DB2 you have the option to create a sample database. My installation said this had failed, but after going in to Data Studio the database was present.
Last caveat: You'll need to make sure that your user has access privileges to the database. Do that in Data Studio via the database's properties.
So after lots of digging around, I found out this was a problem I had and was slowing me down. Eventually, I found out that the Windows user you're logged in as has to belong to a user group that DB2 set up. It sets up two user groups: DB2ADMNS and DB2USERS. I made it so that my main Windows account belonged to both groups. This can be done via lusrmgr.msc. Right click on the Start Menu, select Run and type in lusrmgr.msc and you'll get the Local Users and Groups Manager window. In here you can select your username, right click to get to properties, then in the Member Of tab you can add the user to the user group. I think that only DB2ADMNS group is required, but I did both.
Once you get that all corrected you may also have to make some adjustments to DB2's configuration. This is done via the newly installed DB2 Command Window. I always run the Administrator version so that I'm sure I have all the access I need. Once you launch this you can run the command db2 get dbm cfg. This will print out the config details in the terminal window. If this doesn't work right away then try db2start, which starts the DB2 service. Now you'll want to change a few of these settings. specifically: SYSADM_GROUP, SYSCTRL_GROUP, SYS_MAINT_GROUP, and SYSMON_GROUP. You'll want all of these to be set to DB2ADMNS which is the user group in Windows that has full access to modify the database. Use the following command to set these:
db2 update dbm cfg using SYSADM_GROUP DB2ADMNS
Do this for each setting.
Now things should be pretty happy. You can try creating a new database with:
db2 create database YOURDATABASENAME AUTOMATIC STORAGE YES
If all is set up correctly then you should get a success message.
Other useful DB2 commands.
I don't overly enjoy working via the command line terminal so I went and downloaded IBM Data Studio. It was a pretty simple setup and I just went with the defaults. From there you can create your databases, tables, import data and run queries. One major annoyance I found with this is that when you type a lowercase name for a table or column name this program will surround it with double quotes. Which means that if you create a table named mytable then to query it you'll need to use "mytable" in your queries. Not cool, IBM, not cool. I eventually just named everything with caps, but Data Studio prepares SQL statements for you that you can edit and remove the unnecessary quotes when creating your tables. I still can't get Data Studio to create a database, so I do that by command line. Not sure what the problem is, I've even tried by running it as Administrator and even in the user account that it set up. No go. Command line, no problem. Go figure...
Also when you set up DB2 you have the option to create a sample database. My installation said this had failed, but after going in to Data Studio the database was present.
Last caveat: You'll need to make sure that your user has access privileges to the database. Do that in Data Studio via the database's properties.
Step 2 - Connect from Unity
Now that you have your DB2 installation all working fine (this took me what felt like forever) we can hop on over to Unity and set up access to the database. This part is pretty simple.
I created a fresh Unity project and added a Plugins folder to the project. We'll need to add two DLL files to this folder:
System.Data.dll
System.EnterpriseServices.dll
Unity-friendly versions of these can be found in your Unity installation folder like this:
E:\Unity_5.3.4p5\Editor\Data\Mono\lib\mono\2.0
Of course, your directory will be different from mine, but the subdirectories should be the same. Just locate those two DLLs and drag and drop them into your project's plugin folder. I just left the settings on the marked for "Any Platform", but I've only tested on Windows so I'm not sure if these libraries will work on Mac or Linux. I highly doubt they will work on WebGL, maybe on Android, probably not on iOS (because what does? right?).
Now that's all done we can finally get to my favorite part: code!
For a test I simply created a new MonoBehaviour class and attached it to an empty GameObject in my scene. The code below provides an example of making a simple query and reading the results as strings. For a real integration of this you'll want to convert the results to useable object types. A good example of this can be found here. For my purposes it was just good enough to prove a connection worked. And here's the code:
That's it. Hopefully the code is self-explanatory with all of the comments. I've set up a repository of this you can grab from GitHub that has a simple UI so you can do a full build and test it out on various machines or modify it to your own purposes. Check it out here.
I hope this saves someone from the many headaches I encountered over the past few days of trying to get this to work. There are a lot of outdated examples on the internet and none specific to Unity. Next up I have to test this with some other database management systems (DBMS) such as MySQL, SQLLite, Oracle, and SQL Server. Should be a fun time setting those up!
I was testing this for an additional feature of an app I'm working on called vuzop. It is a data visualization tool that allows you to view your data in 3D or with a VR headset. Check out more information on vuzop here.
As always,
Thanks for reading!
I hope this saves someone from the many headaches I encountered over the past few days of trying to get this to work. There are a lot of outdated examples on the internet and none specific to Unity. Next up I have to test this with some other database management systems (DBMS) such as MySQL, SQLLite, Oracle, and SQL Server. Should be a fun time setting those up!
I was testing this for an additional feature of an app I'm working on called vuzop. It is a data visualization tool that allows you to view your data in 3D or with a VR headset. Check out more information on vuzop here.
As always,
Thanks for reading!
2016/07/22
Long Time, No See
Hi, everyone!
I noticed a blog post is way overdue. Please forgive me, I've been super busy.
"What have you been up to?" you ask.
Well, unfortunately, no new games from Napland Games itself (though I have many in the works), but I've been involved with a bunch of cool projects that have kept me quite busy.
My main project right now is called vuzop. It is a virtual reality data visualization tool. It can read in data from a database and create interactive visualizations where you can fly around to explore the data as it moves in real-time, sped up, or slowed down. It's target toward enterprise, but could be used in a variety of fields to explore data in a new and exciting way. You can see a demo video and more info at vuzop.com.
Another fun project I've been working on is Eddie The Yeti. A cute endless runner with beautiful Hannah-Barbera style characters. It's been released on Google Play, but we still have plans for more levels and features. Play it here.
I've also been spending all of my free time learning JavaScript and have completely revamped our website and merged in my portfolio page to a new, more modern and interactive site. It has videos, slideshows, crossfade slideshows, responsive navigation, and even a cool sound effect. I hope you dig it as much as I do! It's now easier to find some of my interactive portfolio pieces that you can play with right from your desktop browser. Check them out at naplandgames.com/services-game-dev.php, I think my favorite is the Model Exploder... or maybe Oh My Marbles (I swear I'll finish development someday!).
Beyond that, I've started focusing on tutoring Unity 3D a few months ago. I've had quite a few students making a variety of interesting projects. It's very cool to have a chance to see the ideas of fresh new developers. And it keeps me challenged and on my toes. Every session there seems to be a new challenge that I need to find a quick solution to. I'm really enjoying it. Soon I hope to offer group classes. The syllabus for the first 12-hour class is done, but there's still a bit of work to do!
In the meantime, I'm re-dedicating myself to writing blog posts on a more regular basis. It's easy to fall behind! I was writing for Clean Source Code, but unfortunately, the site owner could not continue to pay his dues and I did not have a chance to salvage my posts. And regrettably, the Way Back Machine didn't catch the site and archive it. So I've been a bit discouraged by that. Enough of my excuses. Expect more posts soon!
As always,
Thanks for reading!
I noticed a blog post is way overdue. Please forgive me, I've been super busy.
"What have you been up to?" you ask.
Well, unfortunately, no new games from Napland Games itself (though I have many in the works), but I've been involved with a bunch of cool projects that have kept me quite busy.
My main project right now is called vuzop. It is a virtual reality data visualization tool. It can read in data from a database and create interactive visualizations where you can fly around to explore the data as it moves in real-time, sped up, or slowed down. It's target toward enterprise, but could be used in a variety of fields to explore data in a new and exciting way. You can see a demo video and more info at vuzop.com.
Another fun project I've been working on is Eddie The Yeti. A cute endless runner with beautiful Hannah-Barbera style characters. It's been released on Google Play, but we still have plans for more levels and features. Play it here.
I've also been spending all of my free time learning JavaScript and have completely revamped our website and merged in my portfolio page to a new, more modern and interactive site. It has videos, slideshows, crossfade slideshows, responsive navigation, and even a cool sound effect. I hope you dig it as much as I do! It's now easier to find some of my interactive portfolio pieces that you can play with right from your desktop browser. Check them out at naplandgames.com/services-game-dev.php, I think my favorite is the Model Exploder... or maybe Oh My Marbles (I swear I'll finish development someday!).
Beyond that, I've started focusing on tutoring Unity 3D a few months ago. I've had quite a few students making a variety of interesting projects. It's very cool to have a chance to see the ideas of fresh new developers. And it keeps me challenged and on my toes. Every session there seems to be a new challenge that I need to find a quick solution to. I'm really enjoying it. Soon I hope to offer group classes. The syllabus for the first 12-hour class is done, but there's still a bit of work to do!
In the meantime, I'm re-dedicating myself to writing blog posts on a more regular basis. It's easy to fall behind! I was writing for Clean Source Code, but unfortunately, the site owner could not continue to pay his dues and I did not have a chance to salvage my posts. And regrettably, the Way Back Machine didn't catch the site and archive it. So I've been a bit discouraged by that. Enough of my excuses. Expect more posts soon!
As always,
Thanks for reading!
Subscribe to:
Posts (Atom)