Skip to main content Link Search Menu Expand Document (external link)

Day 2: Using DLLs and Defining a Crafting Container

The crew continued work on the Crafting System. Today, we explored how to link an external DLL within a Unity project, began the CaptainCoder.Core library, defined the API for the [CraftingContainer] class, and began writing a unit tests for [CraftingContainer].

Table of contents
  1. Adding a DLL to Unity
    1. The Position struct
    2. Referencing CaptainCoder.dll in the Unity Project
    3. Off Stream
  2. Crafting Container

Today’s goals were:

  1. Figure out how to use DLL in Unity
  2. Define CraftingContainer Class
  3. Implement a RecipeDatabase Class
  4. Implement CraftingContainer

Adding a DLL to Unity

As we began to implement the [CraftingContainer] class, it became very apparent that it would be useful to have a [Position] struct to represent a (Row, Column) within the CraftingContainer. Having implemented this struct in the past, it seemed like a good time to stop and consider how to write an external library and add it into the Unity project.

To do this, we created a new .NET Class Library project. To ensure compatibility with Unity, it was important to specify that it should target the .NET Standard 2.1 framework. Because we are now writing code outside of unity, it was also possible to specify that we would like to use C# 11 as our language version. After a short hiccup, the crew found a solution and the .csproj file looks like this:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.1</TargetFramework>
    <Nullable>enable</Nullable>
    <LangVersion>11</LangVersion>
  </PropertyGroup>
</Project>

The Position struct

Because we are using C# 11, we are able to define Position as a record struct:

namespace CaptainCoder.Core;

public record struct Position(int Row, int Col);

Isn’t that beautiful? Next, we build the project which produces a dll that can be placed within Unity. Because we likely will continue to build upon the CaptainCoder.Core library, I wrote a small script which copies the dll into the Unity project’s Assets/Libs folder each time the project needs to be built. The name of this folder should probably be considered.

Referencing CaptainCoder.dll in the Unity Project

All that was left was to reference CaptainCoder.dll in the Unity Project assemblies. To do this, we discovered that you must tick the check box Override References in the Inspector for the Assembly. Then, you can select CaptainCoder.dll from the Assembly Reference drop down.

Override References

Once this was done, I did need to reload Visual Studio Code but was able to access the CaptainCoder.Core namespace. Awesome!

LEARNING GOAL #2 ACHIEVED

Learning Goal #2: Learn how to use external DLLs in Unity

Off Stream

Because I expect I will be using this library in future projects, I created a repository specifically for CaptainCoder.Core and put it HERE. Then, I created a submodule reference to it within the project. This will not appear in the tagged version of the project until tomorrow.

Crafting Container

A Crafting Container is defined as a 2D grid of positions where items can be placed. For this initial version, all items will take up exactly 1 position (though it might be cool to implement a version that has items with a variety of sizes). We first began by discussing HOW the user will ultimately interact with a crafting container:

Crafting Container Interactions

For those who cannot read chicken scratch, let me translate:

  1. Add an item at an unoccupied Position.
  2. Handle attempting to add an item at an invalid Position
  3. Handle attempting to add an item to a Position that is occupied
  4. Handle moving an item within the CraftingContainer
  5. Handle removing items

This ultimately led to the following API (which we may still change):

public class CraftingContainer<T> where T : IItem
{
    public CraftingContainer(int rows, int columns, IEnumerable<CraftingCategory> categories, IEnumerable<Position> invalidPositions = null);
    public int Rows { get; }
    public int Columns { get; }
    public HashSet<CraftingCategory> Categories { get; }
    public HashSet<Position> InvalidPositions { get; }
    public IEnumerable<(Position, T)> Positions { get; }

    /// <summary>
    /// Attempts to add the specified <paramref name="item"/> into this <see cref="CraftingContainer"/>
    /// at the specified <paramref name="position"/>. 
    /// Returns true, if the item was added and false otherwise.
    /// </summary>
    public bool TryAddItem(Position position, T item);
    public bool Move(Position from, Position to);
    public bool TryRemove(Position position, out T removed);
    public bool TryItemAt(Position position, out T result);
    public T ItemAt(Position position);
    public bool HasItemAt(Position position) => _grid.ContainsKey(position);

}
  • The full code from day 2 is available here: LINK
  • Additionally, we began writing a test for the CraftingContainer class which is available here: LINK

The tests are far from complete but we are off to a great start managing to finish two of the days goals. Tomorrow we shall continue our quest! Do we have enough time? Will the Captain go insane? Find out next time!

Join the Discussion

Before commenting, you will need to authorize giscus. Alternatively, you can add a comment directly on the GitHub Discussion Board.