I recently encountered an issue using Unity3d where I was unable to create a build of a client's project because of a crash that occurred in the Unity Editor during build publishing. Unfortunately I don't have an image of the crash message dialog, but essentially it said:
"Fatal error! GetManagerFromContext: pointer to object manager 'RenderSettings' is NULL"
which wasn't the most helpful message in the world. I spent some time trying to track down any obvious issue in the code with no luck, so start looking on the Unity forum and found This forum post which described a very similar issue I was seeing.
Luckily it seems this was a known issue, apparently caused by assigning ProceduralMaterials to Material properties inside scripts. There have been a couple of fixes for this particular problem recently, the Unity 4.5.4 release notes and Unity 4.5.4p2 release notes both mention fixes related to this issue.
Updating to the vanilla Unity 4.5.4 release from 4.5.3 fixed my particular crash.
TL;DR
If you're seeing a crash similar to what I posted above, and you use procedural materials in the project, try to update to Unity 4.5.4 or one of the patch releases and see if that fixes the issue
Random Thoughts of a Game Developer
I'm the co-founder and programmer of Nakai Entertainment (www.NakaiEntertainment.com), a small mobile games company in Raleigh, NC. I talk a lot about programming, game development and design, and games engines like Unity3d and Unreal.
Monday, September 29, 2014
Tuesday, February 25, 2014
Unity 4.3.x doesn't support Google Native Client
While spending some time tonight working with Unity's platform preprocessor defines I noticed I wasn't getting proper results when checking if the UNITY_NACL symbol was defined. Oddly enough when I set Unity to make a Native Client build, it defined the UNITY_WEBPLAYER symbol instead. After asking on Twitter and making some Google searches, I finally found an semi-buried explanation here and this nugget in the Unity3d 4.3 release notes
. Hopefully this helps anyone who stumbles into this when trying to use the UNITY_NACL define
This change isn't readily apparent when looking at the build window, as you can see in this picture, there isn't any information to indicate the Native Client build isn't supported. I suspect this is the first step to phasing out NACL support entirely, similar to the removal of Flash build exports
- Google Native Client support is not functional in Unity 4.3. If you need to publish to Native Client you can still use Unity 4.2.2.
. Hopefully this helps anyone who stumbles into this when trying to use the UNITY_NACL define
Labels:
4.3,
Google,
Native Client,
unity,
UNITY_NACL,
unity3d
Thursday, February 20, 2014
Releasing games for multiple platforms
Today is a big day, I finally released my company's 3D puzzle game, Shatter Crash, for Android on the Google Play Store. I'm pretty happy about this release, it's something I've wanted to do awhile now, especially considering Shatter Crash originally came out for iPad in July of 2012.
Took long enough....
Actually there is a story as to why it took so long for the Shatter Crash Android version to come out, but that's something for another blog post. It wasn't a technical reason though.
Since this is all fresh in my mind, I wanted to share a couple tips on stuff to think about when you do a multi-platform game. This is more oriented for iOS and Android stuff, but will work for any other platforms as well
Took long enough....
Actually there is a story as to why it took so long for the Shatter Crash Android version to come out, but that's something for another blog post. It wasn't a technical reason though.
Since this is all fresh in my mind, I wanted to share a couple tips on stuff to think about when you do a multi-platform game. This is more oriented for iOS and Android stuff, but will work for any other platforms as well
- Port your game to the new platform. This is pretty obvious. I use Unity3D which handles 99% of the stuff for all the different platforms.
- You should look at the new platform and learn if there are a particular nuances of the platform you should try to handle. One example, on Android hitting the back button on the main menu generally pops up a quit dialogue giving the user an ability to cleaning quit the app, not just put it into the background
- Handling product/app store links for the new platform. For Shatter Crash I added a 'Rate' button so users can rate the app. On iOS this takes the user to the iOS ttore list, for Android it takes the user to the Google Play listing. Ideally you can take advantage of a mechanism so the app uses the proper links automatically depending on the platform.
- Handling UI layouts for different platforms. The iOS devices are pretty nice because you only have a handful of UI resolutions and aspect ratios. All iPads are 4:3 aspect ratio, and iPhones/iPods are either 3:2 or 16:9. Android obviously has a lot of different aspect ratios. Ideally your UI can automatically handle scaling and moving widgets to take advantage of the screen for particular device it's running on, rather then you manually placing the widgets for every possible screen size
- Way to direct users to the different store pages - When you go from 1 platform to many, you need to make it as easy as possible for people to find the version of the game relevant to them. One idea here is make a page on you website with links to the different stores you game is on; then make sure to SEO the hell out of said page so it's highly placed on search engines.
- Achievement/Leaderboard/etc. - Competitive features like leaderboards and challenges, plus achievements for the collector-mentality players, are definitely nice to have in your game. Different platforms generally have different implementations of these, which can be annoying to manage. I created an internal API which my games use for handling leaderboards/achievements/challenges updates and unlocks. That API in turn works with a binding layer responsible for interacting with the platform-specific system. In this way I can build in support for all those features, then the platform binding layer handles how the nuances of converting that to the platform game system format
Those are the ones off the top of my head, would love to hear more on this anyone had more suggestions.
And if you're looking for a fun 3D puzzle game, please do check out Shatter Crash on Google Play or iOS App Store!
And if you're looking for a fun 3D puzzle game, please do check out Shatter Crash on Google Play or iOS App Store!
Labels:
Android,
App Store,
Google Play,
iOS,
mobile,
programming,
Shatter Crash,
unity3d
Friday, February 7, 2014
Method to get the name of a calling method in C#
When doing quick testing with debug logging it's usually helpful to include the name of the method where a log call originates. It's pretty easy to include, but it can be a hassle if it's a large method you have to scroll through to find the name, or God forbid if the method name changes in the future. What would be handy is a quick and easy way to get the name of a calling method at runtime so it's guaranteed to be the correct name.
This is one thing I've wanted for quite some time, and for one reason or another I never spent the time to investigate how to access this until now. It was surprisingly easy to setup and works very nicely by taking advantage of the System.Diagnostics.StackFrame class to determine the calling method.
Here's what I came up with. You're welcome to copy and use this code in your own projects.
I'm not sure what the performance penalty is for using this at a high frequency, so if anyone has insight into that I would love to hear it!
This is one thing I've wanted for quite some time, and for one reason or another I never spent the time to investigate how to access this until now. It was surprisingly easy to setup and works very nicely by taking advantage of the System.Diagnostics.StackFrame class to determine the calling method.
Here's what I came up with. You're welcome to copy and use this code in your own projects.
1: // Use a stack frame to get the name of the method which called this method
2: public static string GetCallingMethodName ( bool includeClassName = true )
3: {
4: System.Diagnostics.StackFrame lastFrame = new System.Diagnostics.StackFrame(1);
5:
6: // return ClassName.MethodName
7: if ( includeClassName == true )
8: return lastFrame.GetMethod().DeclaringType.Name + "." + lastFrame.GetMethod().Name;
9:
10: // return just MethodName
11: return lastFrame.GetMethod().Name;
12: }
I'm not sure what the performance penalty is for using this at a high frequency, so if anyone has insight into that I would love to hear it!
Wednesday, December 4, 2013
Busy year doing contracting work and using OpenCV
So 2013 has been a pretty busy year. Contracting has been going incredibly well and I've had a chance to work on some really cool stuff. Jumping back into C++ after 2 years away from it was quite fun, although it reminded me how tedious and annoying C++ can be, especially when trying to do small things. Unfortunately being so busy also meant I neglected this blog for most of the year.
My most recent contracting project is pretty interesting and gave me a chance to learn some new things. One of my more recent tasks was creating a high-speed image processing tool, which lead me to learn about using the OpenCV library for image processing tasks. There are some pros and cons to using it, however the pros definitely outweigh the downsides. OpenCV has a huge amount of functionality built-in for image processing, and the API to use it is quite easy to use. One of the simplest, yet most powerful, methods I found in the library was imread() which handles reading an image file and loading the pixel data into an object.
There are some gotchas when using OpenCV, one that tripped me up initially was how it stores pixel data. All game engines I've worked with handle color data as RGB channels, OpenCV uses BGR channels (the Red and Blue channels are switched). This ended up biting me for a little while during the first round of testing when the tool flagged red images as blue ones.
I should also mention OpenCV assumes you have some level of knowledge of image processing techniques, and is mainly there to provide implementations of those techniques. Coming into it with little knowledge of the subject like I did will be difficult, expect to do a lot of research to play catch-up for what they talk about.
On a final note, if you're new to OpenCV, I highly recommend checking out these excellent lessons http://opencv-srf.blogspot.com/p/opencv-c-tutorials.html. They provide a great starting point for navigating the OpenCV library and some terrific examples of image filtering operations.
My most recent contracting project is pretty interesting and gave me a chance to learn some new things. One of my more recent tasks was creating a high-speed image processing tool, which lead me to learn about using the OpenCV library for image processing tasks. There are some pros and cons to using it, however the pros definitely outweigh the downsides. OpenCV has a huge amount of functionality built-in for image processing, and the API to use it is quite easy to use. One of the simplest, yet most powerful, methods I found in the library was imread() which handles reading an image file and loading the pixel data into an object.
There are some gotchas when using OpenCV, one that tripped me up initially was how it stores pixel data. All game engines I've worked with handle color data as RGB channels, OpenCV uses BGR channels (the Red and Blue channels are switched). This ended up biting me for a little while during the first round of testing when the tool flagged red images as blue ones.
I should also mention OpenCV assumes you have some level of knowledge of image processing techniques, and is mainly there to provide implementations of those techniques. Coming into it with little knowledge of the subject like I did will be difficult, expect to do a lot of research to play catch-up for what they talk about.
On a final note, if you're new to OpenCV, I highly recommend checking out these excellent lessons http://opencv-srf.blogspot.com/p/opencv-c-tutorials.html. They provide a great starting point for navigating the OpenCV library and some terrific examples of image filtering operations.
Labels:
BGR,
C++,
coding,
contracting,
image processing,
imread,
OpenCV,
programming,
RGB
Tuesday, February 5, 2013
Handling OpenSSL's SSL_ERROR_WANT_WRITE to avoid socket error:1409F07F
I spent a good part of last week working with OpenSSL C++ networking code. One of the issues I ran into was the network SSL socket no longer sending data for some reason.
There are a fair number of error codes OpenSSL will return for certain situations when calling into the API. Based on the error code returned from an I/O operation you may be required to take certain actions. In particular, if you write to a SSL socket and get the SSL_ERROR_WANT_WRITE error code, you really need to jump through some hoops. If you receive SSL_ERROR_WANT_WRITE during a write operation, the OpenSSL documentation states you must call the write method again at a later time, with the same parameters. Please note I emphasized the last part about the parameters, because there is a huge caveat there.
What the OpenSSL documentation doesn't properly convey is when you retry the OpenSSL write operation at a later point after receiving a SSL_ERROR_WANT_WRITE error, the parameters must literally be the same, DOWN TO THE ADDRESS OF THE BUFFER YOU WISH TO WRITE. My initial assumption was the buffer contents just needed to be the same, which may be the case, but I found the actual buffer address needed to be the same as well.
It seems OpenSSL internally remembers the address of the buffer passed in when SSL write returns the want write error, and if a different address is used on the next write operation, the socket enters an error state. In this error state the SSL write call returns SSL_ERROR_SSL, and checking the SSL error queue returns this error:
"error:1409F07F:SSL routines:SSL3_WRITE_PENDING: bad write retry"
I'm not sure if this error state is recoverable. It may be possible to recover by calling the write with the proper parameters. However if the original buffer was lost, because you memcpy'ed the data into a new buffer and freed it, then your socket is probably hosed.
In my case, we were trying to send data through the socket first, then queuing a copy of the data if the write failed. Unfortunately the copy operation memcpy'ed the data we wished to send, so the next time we called SSL write we were sending a pointer to a different data location than the original call. Our solution was to simply copy and queue the data first, then trying to write to the socket. If the write succeeded then we just removed it from the queue, and if it failed then we were guaranteed to still have the same data buffer address when we tried to write again.
There are a fair number of error codes OpenSSL will return for certain situations when calling into the API. Based on the error code returned from an I/O operation you may be required to take certain actions. In particular, if you write to a SSL socket and get the SSL_ERROR_WANT_WRITE error code, you really need to jump through some hoops. If you receive SSL_ERROR_WANT_WRITE during a write operation, the OpenSSL documentation states you must call the write method again at a later time, with the same parameters. Please note I emphasized the last part about the parameters, because there is a huge caveat there.
What the OpenSSL documentation doesn't properly convey is when you retry the OpenSSL write operation at a later point after receiving a SSL_ERROR_WANT_WRITE error, the parameters must literally be the same, DOWN TO THE ADDRESS OF THE BUFFER YOU WISH TO WRITE. My initial assumption was the buffer contents just needed to be the same, which may be the case, but I found the actual buffer address needed to be the same as well.
It seems OpenSSL internally remembers the address of the buffer passed in when SSL write returns the want write error, and if a different address is used on the next write operation, the socket enters an error state. In this error state the SSL write call returns SSL_ERROR_SSL, and checking the SSL error queue returns this error:
"error:1409F07F:SSL routines:SSL3_WRITE_PENDING: bad write retry"
I'm not sure if this error state is recoverable. It may be possible to recover by calling the write with the proper parameters. However if the original buffer was lost, because you memcpy'ed the data into a new buffer and freed it, then your socket is probably hosed.
In my case, we were trying to send data through the socket first, then queuing a copy of the data if the write failed. Unfortunately the copy operation memcpy'ed the data we wished to send, so the next time we called SSL write we were sending a pointer to a different data location than the original call. Our solution was to simply copy and queue the data first, then trying to write to the socket. If the write succeeded then we just removed it from the queue, and if it failed then we were guaranteed to still have the same data buffer address when we tried to write again.
Thursday, December 13, 2012
Removing OpenFeint from Ninja Hamster Rescue
* This is a follow up to a post I previously made here about GREE shutting down the OpenFeint servers with about 1 month of lead time for developers to remove it from their games.
The last month has been incredibly hectic for me. I've spent the large majority of my time working on a contract job, and the rest of my time spent getting Match and Flip ready for release on iOS before Christmas. Luckily both of those jobs are winding down a bit, so I was finally able to turn my attention to Ninja Hamster Rescue and purging OpenFeint functionality from the Android and iPad version. As a quick recap, OpenFeint is social system that provided some nice services like leaderboards and achievements, and was very easy to add to your game.
I'm a little upset about having to remove OpenFeint from NHR, one of the biggest reasons being I don't know of any alternative services offering achievement and leaderboard tracking for Android. Unfortunately I don't have a choice though, especially since their servers are suppose to stop responding to requests sometime tomorrow (Dec 14, 2012), and I don't want the user experience to suffer from timed out web queries or what have you. So what does that mean for people who played NHR? For players using the iPad HD version not much will change, except OpenFeint will disappear and your achievements and leaderboards *should* continue to exist in GameCenter. For Android players, the game itself will still perform exactly as it did before, the biggest changes being achievements won't unlock and you won't be able to compare your scores to other's on leaderboards.
Ninja Hamster Rescue on Google Play will be updated shortly, and even is getting a Holiday update to add a new level.
Ninja Hamster Rescue HD for iPad will probably take longer to update, as it will need to go through the App Store review process first.
The last month has been incredibly hectic for me. I've spent the large majority of my time working on a contract job, and the rest of my time spent getting Match and Flip ready for release on iOS before Christmas. Luckily both of those jobs are winding down a bit, so I was finally able to turn my attention to Ninja Hamster Rescue and purging OpenFeint functionality from the Android and iPad version. As a quick recap, OpenFeint is social system that provided some nice services like leaderboards and achievements, and was very easy to add to your game.
I'm a little upset about having to remove OpenFeint from NHR, one of the biggest reasons being I don't know of any alternative services offering achievement and leaderboard tracking for Android. Unfortunately I don't have a choice though, especially since their servers are suppose to stop responding to requests sometime tomorrow (Dec 14, 2012), and I don't want the user experience to suffer from timed out web queries or what have you. So what does that mean for people who played NHR? For players using the iPad HD version not much will change, except OpenFeint will disappear and your achievements and leaderboards *should* continue to exist in GameCenter. For Android players, the game itself will still perform exactly as it did before, the biggest changes being achievements won't unlock and you won't be able to compare your scores to other's on leaderboards.
Ninja Hamster Rescue on Google Play will be updated shortly, and even is getting a Holiday update to add a new level.
Ninja Hamster Rescue HD for iPad will probably take longer to update, as it will need to go through the App Store review process first.
Subscribe to:
Posts (Atom)