• Stars
    star
    275
  • Rank 149,796 (Top 3 %)
  • Language
    C#
  • License
    MIT License
  • Created almost 2 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Unity C# attribute for serializing component and interface references within the scene or prefab during OnValidate.

Scene Reference Attribute

openupm

Unity C# attribute for serializing component and interface references within the scene or prefab during OnValidate, rather than using GetComponent* functions in Awake/Start/OnEnable at runtime.

This project aims to provide:

  • a simple set of tags for declaring dependency locations
  • resolution, validation and serialisation of references (including interface types!)
  • determinate results so you never have to worry about Unity losing your references, they'll always be safely regenerated

Installation

Basic

You can simply clone (or download this repo as a zip and unzip) into your Assets/ directory.

UPM

Install with UPM on the command-line like so:

openupm add com.kylewbanks.scenerefattribute

Why?

Mainly to avoid framerate hiccups when additively loading scenes in Farewell North, but I also find this to be a much cleaner way to declare references.

For more details on how this project came about, check out this Farewell North devlog on YouTube.

How?

Instead of declaring your references, finding them in Awake or assigning them in the editor, and then validating them in OnValidate like so:

// BEFORE

[SerializeField] private Player _player; 
[SerializeField] private Collider _collider;
[SerializeField] private Renderer _renderer;
[SerializeField] private Rigidbody _rigidbody;
[SerializeField] private ParticleSystem[] _particles;
[SerializeField] private Button _button;

private void Awake()
{
    this._player = Object.FindObjectByType<Player>();
    this._collider = this.GetComponent<Collider>();
    this._renderer = this.GetComponentInChildren<Renderer>();
    this._rigidbody = this.GetComponentInParent<Rigidbody>();
    this._particles = this.GetComponentsInChildren<ParticleSystem>();
}

private void OnValidate()
{
    Debug.Assert(this._button != null, "Button must be assigned in the editor");
}

You can declare their location inline using the Self, Child, Parent, Scene and Anywhere attributes:

// AFTER

[SerializeField, Scene] private Player _player; 
[SerializeField, Self] private Collider _collider;
[SerializeField, Child] private Renderer _renderer;
[SerializeField, Parent] private Rigidbody _rigidbody;
[SerializeField, Child] private ParticleSystem[] _particles;
[SerializeField, Anywhere] private Button _button;

private void OnValidate()
{
    this.ValidateRefs();
}

The ValidateRefs function is made available as a MonoBehaviour extension for ease of use on any MonoBehaviour subclass, and handles finding, validating and serialisating the references in the editor so they're always available at runtime. Alternatively you can extend ValidatedMonoBehaviour instead and ValidateRefs will be invoked automatically.

Serialising Interfaces

By default Unity doesn't allow you to serialise interfaces, but this project allows it by wrapping them with the InterfaceRef type, like so:

// Single interface
[SerializeField, Self] private InterfaceRef<IDoorOpener> _doorOpener; 

// Array of interfaces
[SerializeField, Self] private InterfaceRef<IDoorOpener>[] _doorOpeners; 

From here they'll be serialised like any other component reference, with the interface available using .Value:

IDoorOpener doorOpener = this._doorOpener.Value;
doorOpener.OpenDoor();

Attributes

  • Self looks for the reference on the same game object as the attributed component using GetComponent(s)()
  • Parent looks for the reference on the parent hierarchy of the attributed components game object using GetComponent(s)InParent()
  • Child looks for the reference on the child hierarchy of the attributed components game object using GetComponent(s)InChildren()
  • Scene looks for the reference anywhere in the scene using FindAnyObjectByType and FindObjectsOfType
  • Anywhere will only validate the reference isn't null, but relies on you to assign the reference yourself.

Flags

The attributes all allow for optional flags to customise their behaviour:

[SerializeField, Self(Flag.Optional)]    
private Collider _collider;

[SerializeField, Parent(Flag.IncludeInactive)]
private Rigidbody _rigidbody;

You can also specify multiple flags:

[SerializeField, Child(Flag.Optional | Flag.IncludeInactive)] 
private ParticleSystem[] _particles;
  • Optional won't fail validation for empty (or null in the case of non-array types) results.
  • IncludeInactive only affects Parent, Child and Scene, and determines whether inactive components are included in the results. By default, only active components will be found, same as GetComponent(s)InChildren, GetComponent(s)InParent and FindObjectsOfType.
  • Editable only affects Parent, Child and Scene, and allows you to edit the resulting reference. This is useful, for example, if you have two children who would satisfy a reference but you want to manually select which reference is used.

Features

  • Supports all MonoBehaviour and Component types (basically anything you can use with GetComponent), including interfaces
  • Determinate results, so there's no worry of Unity forgetting all your serialised references (which has happened to me a few times on upgrading editor versions). All references will be reassigned automatically.
  • Fast, this tool won't slow down your editor or generate excessive garbage.
  • Fully serialised at edit time, so all references are already available at runtime
  • The ValidateRefs() function is made available as a MonoBehaviour extension for ease of use. You can also invoke it outside of a MonoBehaviour like so, if preferred:
MyScript script = ...;
SceneRefAttributeValidator.Validate(script);
  • One-click to regenerate all references for every script under Tools > Validate All Refs.
  • Regenerate references for any component by right-clicking the component and selecting Validate Refs. image

Limitations

  • Supports arrays but not Lists. Feel free to submit a PR if you'd like to see this:
    • Valid: [Child] Renderer[] _renderers;
    • Invalid: [Child] List<Renderer> _renderers;

License

This project is made available under the MIT License, so you're free to use it for any purpose.

More Repositories

1

depth

Visualize Go Dependency Trees
Go
909
star
2

goggles

🔭 Goggles is a cross-platform GUI for your $GOPATH!
Go
671
star
3

XOREncryption

XOR encryption implementations for several languages.
Visual Basic .NET
348
star
4

IconEditText

Reusable view for displaying an ImageView with an EditText for Android 4.0 +
Java
265
star
5

conways-gol

Conway's Game of Life implemented with Go and OpenGL.
Go
110
star
6

ReactCalculator

A React Native tutorial where you'll write a calculator app for Android and iOS.
JavaScript
77
star
7

goodreads

Goodreads API client written in Go.
Go
68
star
8

go-kit

A collection of Go utility packages intended to be independent and reusable.
Go
60
star
9

AnimatedListView

An Android ListView implementation that animates views into place, similar to the Google Plus app on Android
Java
49
star
10

shader-pong

HLSL
46
star
11

dockerstats

Monitor Docker container statistics, including memory and CPU usage, from Go!
Go
42
star
12

kylewbanks.com-AndroidApp

An Android app that loads and displays posts from kylewbanks.com
Java
34
star
13

iOS-Enterprise-Distribution-Plist-Generator

Shell
22
star
14

GSONAndroidSample

A simple application that uses the GSON to fetch and parse JSON into Java models for Android
Java
22
star
15

commuter

Commute times on the command line!
Go
20
star
16

AsyncImageDownloader

Very simple asynchronous image downloader for iOS and Mac OS
Objective-C
15
star
17

tensorflow-checkpoints

This repository demonstrates how you could use a simple convolutional neural network classifier to determine game save checkpoints from a video game screenshot.
Python
14
star
18

conways-gol-cnn

A convolutional neural network that plays Conway's Game of Life.
Jupyter Notebook
11
star
19

tensorflow-docker-retrain

Retraining of InceptionV3 or MobileNet using TensorFlow and Docker.
Dockerfile
11
star
20

modoc

modoc is the Master Of Document Organization and Compilation
Go
11
star
21

s3fs

S3 File Explorer written in Go
Go
10
star
22

animated-line-graph-view

📈 An animated line graph view for Android.
Java
9
star
23

unimation

Animation toolbox for Unity 2D and 3D games.
C#
6
star
24

DeployAutoScalingGroup

Shell
6
star
25

awsprof

Manage AWS Access and Secret Key Environment Variables using Profile Names
Go
6
star
26

sql-jekyll-migration

Go
5
star
27

banks-residence

Various home automation related projects.
Go
5
star
28

overlap-shader

5
star
29

react-native-tutorial-reactusers

React Native Tutorial for AnDevCon.com
JavaScript
5
star
30

lambda-uploader

A Node.js module for uploading a source directory to AWS Lambda
JavaScript
4
star
31

Rdio-Controller-for-Leap-Motion

A simple Rdio controller built for the Leap Motion
Objective-C
4
star
32

unity-git-sample

Sample project with Unity
4
star
33

RESTCache

An In-Memory Cache with an HTTP(s) Interface
JavaScript
4
star
34

1rm

A very small command-line tool to calculate your One-Rep Max (1RM).
Go
3
star
35

dockerton

Dockerton wraps the core functionality of Docker into an easy-to-use Node.js library.
JavaScript
3
star
36

thanos

Go
3
star
37

metroid

A fully managed system for tracking and fetching metrics (Metroids) from AWS DynamoDB.
JavaScript
3
star
38

wilks

A Golang implementation of the Wilks Formula for comparing powerlifters across gender and weight class.
Go
3
star
39

whatsthecodeforthat.com

💻Reference snippets for common tasks in various programming languages.
HTML
3
star
40

hows-the-market

📈 Checking in on the market from your command line.
Go
3
star
41

readme

A command-line tool to fetch and display a projects README.
Go
2
star
42

unity-shader-graph-sprite-effects

C#
2
star
43

DartCalculator

A basic calculator built using Dart
Dart
2
star
44

go-yf

A small wrapper around the Yahoo Finance v8 API written in Go.
Go
2
star
45

GSONVolleyTutorial

Java
2
star
46

btn

Objective-C
1
star
47

unity2d-custom-gravity

Custom Global Gravity in Unity
C#
1
star
48

udacity-ml-engineer-nanodegree

Jupyter Notebook
1
star
49

linguist

A command-line tool to practise translating sentences
Go
1
star
50

kurz

Go
1
star
51

make

Various Makefile Templates
Makefile
1
star