GithubHelp home page GithubHelp logo

intothedev / multitag-system-for-unity Goto Github PK

View Code? Open in Web Editor NEW
144.0 7.0 11.0 242 KB

This package allows you to Tag Game Objects with ScriptableObjects

License: MIT License

C# 100.00%
unity unity3d unity2d unity-scripts scriptableobjects inspector

multitag-system-for-unity's Introduction

MultiTag System for Unity

This package allows you to Tag Game Objects with ScriptableObjects.

TODO

  • Editor support with custom inspector
  • Add tag code generator to quickly access tags without referencing them in the inspector
  • Add API to get entity's runtime added tags

Features

  • Allows you to put as many Tags on your GameObject as you want
  • Add and remove tags via code and inspector
  • Work with ScriptableObjects instead of strings
  • Faster than Unity's tag system. Keep in mind that such methods as AddTag, AddTags, RemoveTag and RemoveTags are way slower in Editor than in Build because of the Taggable component's updates and Custom Inspector
  • Editor support

How to Install

Git Installation (Best way to get latest version)

If you have Git on your computer, you can open Package Manager indside Unity, select "Add package from Git url...", and paste link https://github.com/IntoTheDev/MultiTag-System-for-Unity.git

or

Open the manifest.json file of your Unity project. Add "com.intothedev.multitags": "https://github.com/IntoTheDev/MultiTag-System-for-Unity.git"

Manual Installation (Version can be outdated)

Download latest package from the Release section. Import MultiTags.unitypackage to your Unity Project

Usage

How to create a new Tag/CompositeTag

Assets/Create/ToolBox/Tags

Change Tags in Editor

If you want to change tags only in Runtime via code then Taggable component is unnecessary.

Runtime Operations (HasTag, HasTags, AddTag, RemoveTag, GetInstances, etc)

Code

using ToolBox.Tags;
	
public class Test : MonoBehaviour
{
	[SerializeField] private GameObject _enemy = null;
	[SerializeField] private Tag _zombieTag = null;
	[SerializeField] private CompositeTag _allEnemiesTags = null;
 
	private void Awake()
	{
		// Check for Tag
		if (_enemy.HasTag(_zombieTag))
		{
		
		}
		
		// Check for Multiple Tags
		// You can also pass in simple array of tags
		if (_enemy.HasTags(_allEnemiesTags, allRequired: false))
		{
		
		}
		
		// Add Tag
		// Be careful, if you create a copy of an existing object with added/removed tags via API (AddTag, RemoveTag, etc). 
		// These tags will not be copied to the new object. 
		// But I'll implement a way to copy tags in the future.
		_enemy.AddTag(_zombieTag);
		
		// Remove Tag
		_enemy.RemoveTag(_zombieTag);
		
		
		// Get all objects with tag
		var zombies = _zombieTag.GetInstances();
		
		foreach (var zombie in zombies)
		{
			// Do something
		}
	
		// Instead of gameObject you can use any class that inherits from Component (transform, collider, etc)
		// Example:
		_enemy.transform.AddTag(_zombieTag);
	}
}

CompositeTag Usage

CompositeTag allows you to combine tags into single asset and use API with that asset (AddTags, RemoveTags, HasTags)

Example:

Performance Test

Code

using Sirenix.OdinInspector;
using System.Diagnostics;
using ToolBox.Tags;
using UnityEngine;

namespace ToolBox.Test
{
	[DefaultExecutionOrder(-100)]
	public class Tester : MonoBehaviour
	{
		[SerializeField] private Tag _myTag = null;
		[SerializeField] private string _unityTag = null;
		[SerializeField] private GameObject _object = null;

		private const int ITERATIONS = 100000;

		[Button]
		private void MyTagTest()
		{
			Stopwatch stopwatch = new Stopwatch();
			stopwatch.Start();

			for (int j = 0; j < ITERATIONS; j++)
			{
				_object.HasTag(_myTag);
			}

			stopwatch.Stop();
			UnityEngine.Debug.Log($"Scriptable Object Tag Comparer: {stopwatch.ElapsedMilliseconds} milliseconds");
		}

		[Button]
		private void UnityTagTest()
		{
			Stopwatch stopwatch = new Stopwatch();
			stopwatch.Start();

			for (int j = 0; j < ITERATIONS; j++)
			{
				_object.CompareTag(_unityTag);
			}

			stopwatch.Stop();
			UnityEngine.Debug.Log($"Unity Tag Comparer: {stopwatch.ElapsedMilliseconds} milliseconds");
		}
	}
}

Test Result

Result

multitag-system-for-unity's People

Contributors

intothedev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

multitag-system-for-unity's Issues

Standalone build warning

Hello !
This var is only used in editor code and generate a warning when building. Shouldn't it be declared inside a #if UNITY_EDITOR ... #endif as well ?

public sealed class Taggable : MonoBehaviour
{
        ...
        private static Tag[] _all = null;
        ...
}

Capture

public sealed class Taggable : MonoBehaviour
{
...
#if UNITY_EDITOR
        private static Tag[] _all = null;
#endif
...
}

Thank you for this package !

Doesn't work in IOS

Hey, HasTag check doesn't work in IOS Iphone,but works in editor. It doesn't work only when gameobjects are instantiated via addressables. Maybe Taggable component acts differently when loaded with addressables? What might be the reason

[Feature Request] Equivalent of Unity FindWithTag/FindGameObjectsWithTag

I see you store a reference to the GameObject hash, this feature would be trivial if you store a reference to the object as well? It seems to me that this would be blazingly fast compared to Unity's FindWithTag, which is part of the reason why I'm interested in seeing that happen. Are there any concerns with storing the GameObject references themselves in the Tag?

Current release has an Odin Inspector attribute

Hello!

First of all thanks a lot for this, it looks a really good made tool and I will hopefully use it in a major project of mind :D
I got the unity package on the release from 2 days ago but upon importing I saw this in Tag.cs:

[Button]
private void Clear()
{
    _entities.Clear();
}

The button attribute is part of Odin inspector and it seems you forgot to comment it out with a compiler directive. I wanted to do a PR but I was confused not to find the function in the repo, maybe the repo is outdated?

Anyway just wanted to point this out, and thanks again :)

P.S. The Test Results section of the readme doesnt seem to have actual test results, just a screenshot of the inspector.

Some Suggestions

Selecting Tags through the list will be difficult when there are many Tags. Can you consider using the form of drop-down menu and grouping Tags at the same time, so as to facilitate rapid selection and positioning

In addition, can we consider implementing more Tags selection methods (similar to UE4โ€˜s Tags)

[feature request] Add GameObject.GetTags() extension

Hello !
Thank you for this package.
I think it would be a good addition to be able to get a list of Tags from a GameObject based on a TagContainer.

public static class TagExtensions
{
        ...
        public static Tag[] GetTags(this GameObject entity, TagsContainer tags)
        {
            Tag[] tagTable = new Tag[tags._tags.Length];
            int index = 0;

            for (int i = 0; i < tags._tags.Length; ++i)
            {
                if (entity.HasTag(tags._tags[i]))
                {
                    tagTable[index] = tags._tags[i];
                    index++;
                }
            }

            System.Array.Resize(ref tagTable, index);

            return tagTable;
        }
        ...
}

but it require the TagContainer tag array to be public.

public sealed class TagsContainer : ScriptableObject
{
	[SerializeField] public Tag[] _tags = null;
	...
}

use example :

using System.Collections.Generic;
using UnityEngine;
using ToolBox.Tags;

public class Example : MonoBehaviour
{
    public List<GameObject> myGameObjects = new List<GameObject>();
    public TagsContainer relevantTags;

    public List<GameObject> GetMatchingGameObjects(GameObject reference)
    {
        List<GameObject> matchingGameObjects = new List<GameObject>();

        Tag[] referenceTags = reference.GetTags(relevantTags);

        foreach(GameObject g in myGameObjects)
        {
            if (g.HasTags(referenceTags, true))
                matchingGameObjects.Add(g);
        }

        return matchingGameObjects;
    }
}

[Question] A few questions about usage and typical setup

-- Edit: It feels like something is missing from this package to tie it all together. Did you perhaps forget to upload something? I have been checking your other repos that you have, and I see one of them has a TagCreator, a TagType, and an interface called IBranch (in which I can't find the actual implementation anyhere) that this repo doesn't have. I cannot figure out how I am supposed to reference the actual tags in code to check, add, remove them, etc aside from manually placing them into the container or onto a GameObject that has the taggable class.

Hey there,
I came across this and thought it sounded like really good idea, especially for my use case of checking tags on hundreds of waypoints in the editor to draw different things for my waypoint tools. I am trying to piece together exactly how to use it, though. I would venture a guess that I need to modify it slightly, probably adding [ExecuteInEditMode] for some of it to work in the editor.

I took the included "New Tag" and called it "Waypoint", added it in the TagContainer, added the "Taggable" script to a waypoint and then added the Waypoint tag object to it. I had a few questions from here, though.

My first one is, I see that there is the ability to make multiple tag containers, and there is a HasTags method that takes in a container, which looks like it checks the container for an entity. What is an example scenario in which you might use multiple containers? Do you reuse the already created tags within multiple containers? If so, it sort of sounds like ECS's Archetypes.

My second question is, do you have a quick example of the proper use to check/add tags? My first instinct was to do waypointList[i].GetComponent() as I was looping through my waypoints but I feel like that sort of defeats the purpose and I could just check for my Waypoint class that is already there, so I would imagine there is a different/better way to do this that I am just not aware of? I tried to do

TagExtensions.HasTag(waypointList[i].gameObject, ?? );

I am not sure exactly where I am supposed to get the reference to a specific tag from, in order to pass it in?

I definitely appreciate your work on this, I am excited to see if it might help out a bit on performance instead of checking all of the normal built-in tags.
Thanks for your time,
-MH

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.