DEV Community

Khoa Pham
Khoa Pham

Posted on • Edited on

Making Unity games in pure C#

As an iOS engineers, I ditched Storyboard to avoid all possible hassles and write UI components in pure Swift code. I did XAML in Visual Studio for Windows Phone apps and XML in Android Studio for Android apps some time ago, and I had good experience. However since I’m used to writing things in code, I like to do the same for Unity games, although the Unity editor and simulator are pretty good. Besides being comfortable declaring things in code, I find that code is easy to diff and organise. I also learn more how components work, because in Unity editor, most of important the components and properties are already wired and set up for us, so there’s some very obvious things that we don’t know.

All the things we can do in the editor, we can express in code. Things like setting up components, transform anchor, animation, sound, … are all feasible in code and you only need to using the correct namespace. There’s lots of info at Welcome to the Unity Scripting Reference. Unity 2018 has Visual Studio Community so that’s pretty comfortable to write code.

Javascript and C

I would be extremely happy if Unity supports Kotlin or Swift, but for now only Javascript and C# are supported. I’m also a huge fan of pure Javascript, but I choose C# because of type safety, and also because C# was the language I studied at university for XNA and ASP.NET projects.

Indentation

If you like 2 spaces indentation like me, you can go to Preferences in Visual Studio to change the editor settings

GameObject and Canvas

In the Unity editor, try dragging an arbitrary UI element onto the screen, you can see that a Canvas and EventSystem are also created. These are GameObject that has a bunch of predefined Component .

If we were to write this in code, we just need to follow the what is on the screen. In the beginning, we must use the editor to learn objects and properties, but later if we are familiar with Unity and its many GameObject , we can just code. Bear with me, it can be a hassle with code at first, but you surely learn a lot.

I usually organise reusable code into files, let’s create a C# file and name it Sugar . For EventSystemand UI we need UnityEngine.EventSystems and using UnityEngine.UI namespaces.

Here’s how to create EventSystem

public class Sugar {
    public GameObject makeEventSystem() {
        GameObject systemEventObject = new GameObject("EventSystem");

        EventSystem system = systemEventObject.AddComponent<EventSystem>();
        system.sendNavigationEvents = true;

        StandaloneInputModule module = systemEventObject.AddComponent<StandaloneInputModule>();
        module.horizontalAxis = "Horizontal";
        module.verticalAxis = "Vertical";
        module.submitButton = "Submit";
        module.cancelButton = "Cancel";
        module.inputActionsPerSecond = 10;
        module.repeatDelay = 0.5f;
        module.forceModuleActive = false;

        return systemEventObject;
    }
}
Enter fullscreen mode Exit fullscreen mode

and Canvas

public GameObject makeCanvas() {
    GameObject canvasObject= new GameObject("Canvas");

    Canvas canvas = canvasObject.AddComponent<Canvas>();
    canvas.renderMode = RenderMode.WorldSpace;

    CanvasScaler scaler = canvasObject.AddComponent<CanvasScaler>();
    scaler.scaleFactor = 10.0f;
    scaler.dynamicPixelsPerUnit = 10.0f;

    GraphicRaycaster graphic = canvasObject.AddComponent<GraphicRaycaster>();

    canvasObject.GetComponent<RectTransform>().SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, 3.0f);
    canvasObject.GetComponent<RectTransform>().SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, 3.0f);

    return canvasObject;

}
Enter fullscreen mode Exit fullscreen mode

and how to make some common UI elements

public GameObject makeBackground(GameObject canvasObject) {
    GameObject backgroundObject = new GameObject("Background");
    backgroundObject.AddComponent<CanvasRenderer>();

    Image image = backgroundObject.AddComponent<Image>();
    image.color = Color.green;

    backgroundObject.transform.SetParent(canvasObject.transform, false);

    return backgroundObject;
}

public GameObject makeLogo(GameObject parentObject) {
    GameObject logoObject = new GameObject("Logo");
    logoObject.AddComponent<CanvasRenderer>();

    Image image = logoObject.AddComponent<Image>();
    image.color = Color.red;

    logoObject.transform.SetParent(parentObject.transform, false);

    return logoObject;
}

public GameObject makeButton(String title, GameObject parentObject) {
    GameObject buttonObject = new GameObject(title + " Button");
    buttonObject.AddComponent<CanvasRenderer>();

    GameObject textObject = new GameObject("Text");
    textObject.AddComponent<CanvasRenderer>();

    Text text = textObject.AddComponent<Text>();
    text.text = title;

    textObject.transform.SetParent(buttonObject.transform, false);
    buttonObject.transform.SetParent(parentObject.transform, false);

    return buttonObject;
}
Enter fullscreen mode Exit fullscreen mode

Now create an empty GameObject in your Scene and add a Script component to this GameObject . You can reference code in your Sugar.cs without any problem

Where to go from here

❤️ Support my apps ❤️

❤️❤️😇😍🤘❤️❤️

Top comments (2)

Collapse
 
eriksk profile image
Erik Skoglund

I went from 6 years of XNA to Unity and I saw a lot of this in my own stuff as well.
Pretty much going against the philosophy of Unity and doing more things in code than in the editor.
As the years went by I started doing more and more in the editor and while scripting UI definitely has its' place, I think that embracing the Unity editor can be really powerful.

Today I tend to do most things in editor and write scripts in a more generic way to work with UI.

Make a script to fit a container to parent, check, now I can use that for a lot of different things. Add some margin & padding and we're good to go.

But I think the biggest benefit of using the editor for this kind of stuff is how fast it actually is to build the UIs. Mainly I now use scripting for wiring things up and some smaller generic scripts to make it nicer to work with.

One of the things that really helped was making a themeable component that you can drop a theme created by a ScriptableObject to each UI game object.

Changing colors, fonts and those kind of things is extremely tedious from the get go in unity. I actually also used the hierarchy to swap primary/secondary colors when objects are nested so if you have text under a background object for example, the colors will always be right.

But I guess it's a trade-off generally speaking. And definitely a matter of taste. No way is wrong, so if this fits your way of developing then go for it!

Also now that we have nested prefabs, UI becomes a looot easier :D

Collapse
 
onmyway133 profile image
Khoa Pham

You 've just convinced me to use editor again ❤️