Tag: Solution

Multiple C# Projects In Your Unity 3D Solution

Unity

Problem: Visual Studio and Unity Aren’t Playing Nice!

Disclaimer: I develop on Windows, so I have no idea if any of this even applies to other operating systems. I assume not. Sorry.

I just started poking around in Unity 4.6 and I’ve been having a blast. I’ve made it to the point where I want to actually start hammering out some code, but I came across a bit of a problem: I want to start leveraging other projects I’ve written in my Unity solution while I’m in Visual Studio, and things are blowing up. So, what gives?

Okay, so let me start by explaining why I want to do this. I understand that if I’m making a simple game, I should have no problem breaking out my unity scripts into sub folders and organizing them to be nice and pretty. The problem I’m encountering is that I have existing projects under source control and I don’t want to copy and paste all of the code as scripts into my Unity folder. I also want to be able to create re-usable code for my future games, so I’d like to start breaking things out into libraries as I see fit.

So, if you’ve been playing around in Unity for a bit, you might say “Oh, well you’re a dummy! Unity can totally leverage your C# DLLs once you drop them into your asset folder”! And you’d be 100% correct. But that’s not the workflow I want.

The underlying problem here is this: Unity will re-write your solution and project file when you flip between Unity and Visual Studio. But I’m sure they have it that way for a reason.

The Goal: Visual Studio and Unity Should… Play Nice!

My ideal state would be something like this:

  • Work in visual studio as much as I’d like to new projects to my solution, and reference them accordingly
  • Flip back and forth from Unity and Visual Studio without having to reset things to compile/run again
  • Build from visual studio and have things end up in the right spot… NOT copy DLLs
  • Not copy+paste my entire project(s) already under source control elsewhere

Is this something that can be achieved though? I was pretty determined that I should be able to do *something* to have this working. Could I get it perfect? I wasn’t sure… But I knew I could make it better.

The Solution: Give and Take with Unity

My *almost* perfect sution, which I’ll walk you through, is this: Leveraging Visual Studio tools for Unity, modify the Unity solution as you see fit and use directory junctions (symlinks) to the build output directories of other projects.

  1. Let’s get Visual Studio tools for Unity installed. Visit that link and download the version that you need for the version of Visual Studio that you use. After installing, I opened up my project within Unity and I had to import the Visual Studio Tools package.Import Package
    After selecting this menu item, I was presented with a dialog for picking the items to import. I left it as is.Import Package2After importing these items, I could see that Unity had successfully added these entries under my Assets folder. Okay, now we’re getting somewhere. Next up, I wanted to configure Unity to not modify my solution every time I go back and forth from Unity to Visual Studio. This is the part that kills whether or not I’ve added projects to my solution. For me, it’s critical to have code I’m working on immediately accessible so that I can jump back and forth between projects. Lucky for us, this part is pretty easy. Go to the menu to access your new Visual Studio Tools menu item:

    VS Tools Configure
    Selecting “Configuration” opens up a really simple dialog. Let’s make sure “Generate solution file” is unchecked! It’s that easy.

    VS Tools Configure2
    Once we have all of this setup, we should be able to go into Visual Studio and add other projects to our solution.

  2. The one thing that I *could not* get this solution to do is have Unity leave my main game project alone in Visual Studio. As a result, the rest of this walk through is allowing us to play by Unity’s rules. Unity is good at magically referencing all of the managed DLLs that you include within your assets folder. If you drop DLLs somewhere within “Assets” and switch to Visual Studio, Unity will likely have modified your main project to reference this DLL.My next step was creating a spot where I wanted to drop the build outputs of my extra projects I wanted to reference. In my Visual Studio solution, I have my original game project and some newly added projects I want to build from source. In Unity, I wanted these to end up in “Assets/Dependencies/bin”. No problem. Let’s make that folder structure (or your equivalent if you don’t like my naming):Bin Dependencies
    The next part is probably the “trickiest” part because it’s… well… unusual. You could technically stop here and manually copy DLLs back and forth, but I’m not about that life. I want things to happen automatically. For this, we’re going to use junction points. Browse to your newly created folder in an administrator command prompt. I say administrator because only certain users have permissions to create junction points. Your non-admin user might, but this is my “safe” way of instructing you. On the command prompt, we’re going to use “mklink” to create a junction. The command is “mlkink /D /J <NAME_OF_YOUR_PROJECT> <RELATIVE_PATH_TO_YOUR_PROJECT>”. For example, if you had a C# project you wanted to reference that was “MyCoolLibrary.csproj” and was located in the directory above your Unity project, you might use the command “mlkink /D /J MyCoolLibrary “……..MyCoolLibrarybindebug””. Note that I used two dots to go back up a directory several times (since we’re inside of AssetsDependenciesbin and want to get outside of our Unity project). you should get a success message when your junction is created.

    Repeat this step for as many extra projects as you want to include. You can always come back and add more projects this way too, or remove the junctions if you don’t want to include a project anymore.

    At this point, you’re technically done. If you build from Visual Studio, you should have your other projects’ DLLs end up in your Unity folder, and your main game project will be updated by Unity to reference these now!

  3. But… You’re not done if you use source control for your Unity project and have separate source control on your other projects. The scary thing here is that usually we don’t want our build outputs to be stored in source control… But if we do nothing else, your source control system will likely want to include the newly created “AssetsDependenciesbin” folder and any of the contents you’re building into there. I just modified my git ignore file (I’m sure there’s an equivalent for SVN or other source control) to exclude the contents of “AssetsDependenciesbin”.The reason I didn’t excluded dependencies all together is because I can add other folders and DLL references here that I don’t want to build (like… the normal way). This gives me the flexibility of building the projects I want to control and still be able to just reference other pre-built DLLs!

Summary

In three easy steps, you should be able to use Unity, Visual Studio, and multiple projects in one solution in a what-feels-like-normal way. Because there’s still some dynamic stuff going on with Unity updating your main project, you might find the odd time you need to build twice to fix up compilation problems. I’ve seen this happen maybe once or twice so far, but otherwise it feels like normal. It’s also  important to note that you can’t escape the Unity project updating… don’t add references to your main project manually. That’s what that “AssetsDependencies” folder is for that we made.

Here are a few shots of what my setup looks like (proof that it works):

Solution Explorer

Unity Dependencies

And of course… it’s not the perfect solution. There’s still these things:

  • Unity gets mad at you for using junctions within your project. It actually tells you not to do this because you can mess things up. It’s working awesome for me right now though… So I’m going to just ignore this warning.
  • Remember step 3 where we ignored the AssetsDependenciesbin location in git? This actually ignored your junction points you created too. As a result, anyone else who clones your code will need to create junctions too. I’m working solo, so I’m not too worried about this step… But it’s definitely something that should be fixed up (again, I’m sure it’s doable, but I’m in no rush).

Hope that helps you feel more at home in Unity and Visual Studio! It certainly made it nicer for me.

 


The Problem With “There’s a Problem”

"There's a Problem! (Image from http://www.sxc.hu/)

Problem?

If you’ve ever had a job, as I’m sure anyone reading this has, you’ve probably been on the one side of this situation before. You tell your supervisor/leader/manager/someone-responsible-for-the-thing-with-the-problem that simply, “There’s a problem”. If you’re in or have been in one of those positions I just listed, I’m sure you’ve been on the receiving end of it. But as I said, you probably did the same thing at one point so don’t go holding it against anyone just yet.

What’s the big deal with telling someone there’s a problem? I mean, don’t you think someone should know if something is going wrong? Especially if they’re the one in charge of it! We can’t continue operation with this problem. We can’t release the product to the customer with this thing missing or broken. We can’t sell our product or service with this part of the process being dysfunctional or unreliable. Someone needs to know.

The problem is not sharing the fact that something is wrong. The underlying issue is simply stopping at “there’s a problem”.

Leader’s Perspective: Keep Focus

You’re in a leadership or management position. Without getting into a big leadership vs management debate, one of your primary functions is delegating tasks out to team members. You’re ultimately going to be responsible for project if it fails, so hearing about issues isn’t necessarily a bad thing. So what’s the concern?

Problem?

When someone comes up to you to let you know that there’s an issue, the next logical step is finding out what needs to be done. Now, if you only know that there’s an issue and there’s no additional information or plan of attack provided, it’s all on you to find out how to approach it. Realistically, that’s not so bad. After all, you’re likely in your current position because you’re good at this kind of stuff. However, there are two things to be concerned about:

  • Do you pull yourself off from whatever you’re doing and try to address the problem?
  • Do you need to go find someone to delegate this issue to?

I mentioned delegation is one of your primary functions, so the reason these two things are a concern is because they conflict. They both take up your time. When you’re told that something goes wrong, your brain likely spins up and starts thinking about the how and the why. Then you start thinking about how to fix it. You know the project, the system, or the process inside and out. You could probably find a way to fix it if you put your nose to the grindstone for a bit. But is it the most effective use of time?

Maybe it is. Maybe it isn’t. If it’s not, now you need to start thinking of your team’s status. You know John and Jane are both on something else that’s mission critical for the project to be delivered on time, and they’re your number one and two options for the skill sets required to tackle this. Do you pull one of them off? Do you maybe ask Tim who has some experience with this and is working on something that’s a low priority? Hold on… How can you even know who’s best suited for the problem if you don’t actually even know anything more than the fact that there’s an issue!

Someone–either you or a team member–is going to have to investigate this problem. Why wasn’t any of this done already?

Team Member’s Perspective: Bad Habits

You’re the member of a team and you play a critical role (as do your teammates). Everyone’s time is valuable, so you and everyone else should be keeping this in mind. You’ve stumbled upon an issue and it’s looking like it’s pretty nasty.

Being on the development team, you remember from your standup meeting that John had recently fixed a bug in a similar area. You should go talk to him because he likely has some insight as to what’s going on. On the sales team, you know that Tim had to try and work with a customer from the same country last week, so maybe he can offer some assistance with some of the legalities. Regardless of what team you’re on or what your core role is, having knowledge of what people are doing around you can certainly benefit in this kind of scenario.

But what should you do even before that? Here’s a little list:

  • Is the problem reproducible? Was it just off-chance that it happened? Did you try again?
  • What other things do you think are affected by this? Have you investigated?
  • Do you know what’s wrong? Do you know what’s completely expected, or do you just know that something isn’t completely right?
  • Have you come up with a potential solution? What about a secondary solution?
  • Did you try searching the Internet, a knowledge base, or any other easily-accessible resource as a first step?

What’s great about the items in this list? These are all things you can do or consider on your own before involving anyone else. As soon as you drag someone else into it, now it’s the time of multiple people. Acquire the information that you can and analyze the situation before going to other people. It’s a bad habit to get into where you see a warning sign, toss your hands up in despair, and go tell someone else so they can deal with it.

It may not be in your job title, but taking this kind of responsibility when approaching problems makes it so much easier on everyone that gets involved. It increases the efficiency of the team when you can provide information and context when looking for a solution.

Summary

Things go wrong. It sucks, but nothing is perfect. It affects the staff responsible for projects, processes, and teams. It can teach you to avoid analyzing problems if you simply notify someone without digging a bit deeper.

Consider being on the receiving end of just being told of a problem. What are the first things you’re going to ask to get more information? Try answering these questions yourself before escalating the issue.

Finally, as a leader, it’s your responsibility to identify this type of behaviour. Don’t get mad at your teammates for doing it. They might not even realize that they’re doing it! Have the conversation with them where you tell them that in the future, things will go much more smoothly if they can provide a bit more context to you. Of course, don’t just tell them that there’s a problem.


  • Nick Cosentino

    Nick Cosentino

    I work as a team lead of software engineering at Magnet Forensics (http://www.magnetforensics.com). I'm into powerlifting, bodybuilding, and blogging about leadership/development topics over at http://www.devleader.ca.

    Verified Services

    View Full Profile →

  • Copyright © 1996-2010 Dev Leader. All rights reserved.
    Jarrah theme by Templates Next | Powered by WordPress