Giter Site home page Giter Site logo

display-list's Introduction

Display List

This package acts as a framework for building and managing data-driven lists in your Unity projects. Simply define the data model for what you want do display, create a MonoBehaviour script and prefab for the elements in the list, and then give display-list the list of data elements you want to display.

For simple cases display-list handles all the work of managing a list of objects. Even in more complex cases, display-list provides tools to make it as easy as possible for you to write clean, correct view logic.

// MyData.cs
//
// Define the data you want to diplay in your game.
public struct MyData
{
    public string Name;
    public int Value;
}

// MyElement.cs
//
// Create a script for the view elements for your data.
public class MyElement : MonoBehaviour, IDisplayElement<MyData>
{
    [SerializeField]
    private TextMeshPro _nameText;

    [SerializeField]
    private TextMeshPro _valueText;

    public void Populate(MyData data)
    {
        // Do whatever you need to display your data.
        _nameText.text = data.Name;
        _valueText.text = data.Value.ToString();
    }
}

// MyDisplayList.cs
//
// Create a specialized subclass of DisplayList for your data type.
public class MyDisplayList : DisplayList<MyElement, MyData> { }

// MyGameLogic.cs
//
// Use your specialized display list to display data in your game.
public class MyGameLogic : MonoBehaviour
{
    [SerializeField]
    private MyDisplayList _displayList;

    public void Start()
    {
        // Get the data that you want to display.
        var dataToDisplay = new List<MyData>()
        {
            new MyData { Name = "Foo", Value = 12 },
            new MyData { Name = "Bar", Value = 7 },
            new MyData { Name = "Baz", Value = 123 },
        };

        // Populate the display list with your data.
        _displayList.Populate(dataToDisplay);
    }
}

Setup

To include display-list as a Unity package, you'll need to be on Unity 2018.3 or later. display-list is hosted on OpenUPM. Follow the OpenUPM getting started guide if you're not already using it, then run the following command from within your Unity project:

openupm add com.synapse-games.display-list

Alternate Setup (Git)

If you'd prefer to add display-list to your project directly through GitHub, open Packages/manifest.json in your project and add "com.synapse-games.display-list" to the dependencies object:

{
  "dependencies": {
    "com.synapse-games.display-list": "https://github.com/randomPoison/display-list.git"
  }
}

NOTE: You'll need to have Git installed on your development machine for Unity to be able to download the dependency. See https://git-scm.com/ for more information.

Custom Assemblies

If you're using assembly definitions for your project, you'll need to reference the Unity.DisplayList.Runtime assembly in order to access display-list.

Usage

There are two primary ways to use display-list:

  • Simple case: You have a single type of data element and a single type of view element.
  • Complex case: You have multiple types of data element, multiple types of view elements, or both.

Simple Case

TODO: Flesh this out. Use the example at the top of the README as a quick reference.

Complex Case

Create a subclass of DynamicDisplayList and implement the InstantiateElement() method. You'll have to manually implement any logic for deciding which view elements to instantiate from your data elements, but DynamicDisplayList will take care of everything else.

As an example, let's take a look at how we might display rewards from an in-game quest in a hero collector game. In practice, quests might be able to award a number of different types of items, but for our purposes let's say there are three reward types:

  • An item, represented by ItemRewardData.
  • A specific hero, represented by HeroRewardData.
  • A random hero, represented by RandomHeroReward.

In this case we have two display elements: A display element for item rewards, and a display element for hero rewards (which knows how to display both specific heroes and random heroes).

When representing the raw list of rewards data, we use a List<object> (or some other list of untyped data) in order to allow us to store the multiple different reward types in our list. When creating the display list for our rewards, we have to manually check the type of each element and instantiate the appropriate display element for that type of reward.

using System;
using System.Collections.Generic;
using UnityEngine;

public class QuestRewardDisplayList : DynamicDisplayList<object>
{
    [SerializeField]
    private ItemRewardDisplay ItemRewardPrefab;

    [SerializeField]
    private HeroRewardDisplay HeroRewardPrefab;

    // Quests can reward both items and new heroes, so the InstantiateElement()
    // method takes an untyped item and uses different display elements based
    // on the type of the reward.
    public void InstantiateElement(object reward)
    {
        switch (reward)
        {
            case ItemRewardData itemReward:
                CreateChild(ItemRewardPrefab).Populate(itemReward);
                break;

            case HeroRewardData heroReward:
                CreateChild(HeroRewardPrefab).Populate(heroReward);
                break;

            case RandomHeroRewardData randomHeroReward:
                CreateChild(HeroRewardPrefab).Populate(randomHeroReward);
                break;

            default:
                throw new ArgumentException(
                    $"Unknown reward data type {reward.GetType().Name}");
        }
    }
}

While this is less convenient than the simple case, it still provides a number of advantages over manually managing the list of elements:

  • Down-casting is centralized in the InstantiateElement() method of your display list, so the display elements can still work with strongly-typed data.
  • DynamicDisplayList handles the bulk of the work of manging the view elements at runtime, including pooling and recycling elements.
  • Boilerplate is minimal, and creating a new display list type is easy.
  • You still have complete control over the logic for instantiating your view elements, and can perform any custom logic necessary.

Custom Display Lists

If DynamicDisplayList is still too constraining for your purposes, you can create a direct subclass of BaseDisplayList. This provides only minimal functionality for managing a list of view elements, but gives you the most flexibility and control.

TODO: Provide more documentation on what functionality BaseDisplayList provides and how to use it correctly.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.