unity-atoms / unity-atoms Goto Github PK
View Code? Open in Web Editor NEW⚛️ Tiny modular pieces utilizing the power of Scriptable Objects
License: MIT License
⚛️ Tiny modular pieces utilizing the power of Scriptable Objects
License: MIT License
I got a new small idea to add, I can make a pull request when two earlier issues will be resolved.
What do you think about adding two properties to GameEventListener and one mechanic:
We could trigger some UnityEvents/GameActions every few raised Event, not every once (like it's now). "triggerFirst" means if we set "every=5", will something be done on the first occurrence or not). Every raised event a counter will be increased to check how many times it triggered. It would add more flexibility to Listeners and it's a small change.
Not sure if this is related to Unity Atoms or if a solution to this problem should be part of Unity Atoms. Anyway, here we go..
It is really annoying that when you rename a MonoBehaviour / ScriptableObject (when using Unity Atoms for example a Game Function or a Game Action) class the reference gets lost and you might need to rewire everything in the editor that used that class. From my understanding Unity is using fileID + a generated guid to reference something hooked up in the editor (or in an asset file). I have also heard that the guid is based on the class name + namespace. So if it is possible to get the generated guid (or if there is an API where you pass class name + namespace), then it would be possible to create a rename script that renames the class + change all the guids in all meta / scene / asset files. The script might be added to the Unity editor or it might be a IDE extension (for example VS Code). Many assumptions here, but if it is possible it would be a great feature.
So, not sure about the best way to approach this, but I just added Unity-Atoms as a submodule in a different project I have and moved to the Canary branch. This made me unable to build the game because of a dependency on UniRx in one of the example folders. For now I basically deleted it, but if I ever make changes to the branch and want to submit a PR, it might prove itself a bit more annoying.
I think that when we use the project as a submodul (or just getting it from git directly) it should try to avoid external dependencies as much as it can (or could use other open source dependencies as submodules?)
This is more of a suggestion and trying to figure the best way to keep the examples in the package (since in that case it's easier to have external dependencies)
We could have the examples be in a different branch and do some continuous deployment to make sure the "package branch" has all the examples in it?
Why AtomReference does not use AtomBaseVariable as Constant?
e. g. IntReference has a int and a IntVariable, but could be a IntConstant and a IntVariable.
It would be really nice to have a generator that creates new atoms classes for you, to reduce the amount of boilerplate code to be written. It should be possible to choose what to generate (Variable, EventListener, Constant, etc), what to name it and what types to use.
Not sure what techniques to use. Have worked with Yeoman / EJS before, but not sure if it's a good fit for Unity / C# (is it possible to run from the inspector if it's a node module for example?). Maybe do some custom templating?
Create an editor script to make it possible to trigger GameEvents from the Unity Inspector. Probably best to create a generic class that gets extended for each GameEvent type.
Is your feature request related to a problem? Please describe.
Make it possible to generate Atoms of different type for:
Eg. generate a BoolIntEvent. This should be done in the Generator already available in Unity Atoms.
Describe the solution you'd like
This is not part of the regular Atoms generation currently implemented in Unity Atoms. I propose to create a new "page" in the Generator to generate "Multi Atoms" (I'm open for better naming here). The user will first pick what Atom to generate (selection box): Action, Listener, Function or Event. Then options to add types will appear.
Describe alternatives you've considered
Another consideration is to create a new Generator for this kind of generation.
I would be really appreciate someone making a PR on this. Make sure to read the guidelines before starting + assign yourself (or ask me) to the issue. Also don't hesitate to ask any further questions below before developing.
I just saw the atomittacs issue/feature and it has imho many of the problems unity has with its own tags:
https://github.com/AdamRamberg/unity-atoms/blob/v1.0.0/Assets/UnityAtoms/AtomicTags/AtomicTags.cs
checking if a tag is in the list: O(n) in a hashset O(1). now, hashsets are not serializable but: ISerializationCallbackReceiver to the rescue.
also, tagged objects could add/remove themselfs (OnEnable / OnDisable) from a static Dictionary<StringReference, List<GameObject>>
with the addition of public static GameObject[] FindByAtmicTag(...)
unity has for its own tags a list of all tagged objects and iterates through all of them, IIRC.
also make AtomicTags a ListComponent or something similar... maybe: static Dictionary<GameObject, AtomicTags>
this could help further down below on HasTag
for the extension methods
they all scream inefficient. GetTags calls GetComponentTwice -> could cache it
(same for HasTag)
HasTag could become:
var tags = AtomicTags.GetForGameObject(go); // uses the static Dictionary<GameObject, AtomicTags>
return tags != null ? tags.Contains(str) : false;
note: also overload hashCode from StringConstant to be equal to its Value
member. maybe do it for all in the base class ScriptableVariable base, can't think of any drawback for now.
Equivalently GetTag could become:
var tags = AtomicTags.GetForGameObject(go);
return tags != null ? tags.GetTags() : new List<StringConstant>(0);
Hey there,
I downloaded the 0.1 unitypackage in an empty project and got three errors after import:
Assets/UnityAtoms/Variables/ColorVariable.cs(6,34): error CS0315: The type UnityEngine.Color' cannot be used as type parameter
T' in the generic type or method UnityAtoms.EquatableScriptableObjectVariable<T,E1,E2>'. There is no boxing conversion from
UnityEngine.Color' to `System.IEquatable<UnityEngine.Color>'
Assets/UnityAtoms/Variables/Vector2Variable.cs(6,36): error CS0315: The type UnityEngine.Vector2' cannot be used as type parameter
T' in the generic type or method UnityAtoms.EquatableScriptableObjectVariable<T,E1,E2>'. There is no boxing conversion from
UnityEngine.Vector2' to `System.IEquatable<UnityEngine.Vector2>'
Assets/UnityAtoms/Variables/Vector3Variable.cs(6,36): error CS0315: The type UnityEngine.Vector3' cannot be used as type parameter
T' in the generic type or method UnityAtoms.EquatableScriptableObjectVariable<T,E1,E2>'. There is no boxing conversion from
UnityEngine.Vector3' to `System.IEquatable<UnityEngine.Vector3>'
Running on Windows 7, Unity version: 2017.4.15f1
Create a default atoms property drawer that enables the user to create and assign an atom to an empty atom property.
Is there any special reason why ScriptableObjectList doesnt implement any Enumerable interfaces?
ICollection can be implemented basically for free
Just going through the files and folders, here are my thoughts:
Source/Base/CreateOnAwake
Sources/GameFunctions
Source/Logger
AtomsLogger.cs
should be in Utils. there is no need for an own folder for that simple wrapper class.Source/Utils
Vector2Utils.cs
is never usedSource/Extensions
GameObjectExtension
are unusedSource/AtomicUI
UIContainers.cs
Source/SceneManagement
hey, i highly refactored the project in my fork: https://github.com/soraphis/unity-atoms/tree/stable
i made this to have the source files in the root directory, so i could add a package.json.
i updated the readme and added how to install it with the package-manager in unity 2018.3+
(more information about that can be found here and here )
i don't know if this is a way you wanna go with your tool / repository, thats why i have not created a pull request for this changes
Describe the bug
If you create multiplie game objects with a common event listener type, selecting all of them makes the event they are listening to be the same as the last selected object (overriding each objects events)
To Reproduce
Expected behavior
Selecting multiple objects should not cause any modifications at all in the game objects
Environment
Wouldn't this library be soooo much better with gizmos? :D
Investigate if it is possible to just use one image / icon and use it for all script icons in the inspector and all unity atom assets created (like the Post Processing Stack is doing - https://github.com/Unity-Technologies/PostProcessing)
Wouldn't it be quite convenient if it had default variables that reset each time on OnEnable
or somewhere else ? Or am I missing some design philosophy here ? :)
this week i was working on small project and we used the variables of unity-atoms pretty extensively.
And one of the more annoying this is, that scriptable objects keep playmode changes in the editor.
So you have to write scripts that setup your variables to start values.
I propose to make the Variable classes Implement ISerializationCallbackReceiver like shown here: https://unity3d.com/de/how-to/architect-with-scriptable-objects (the 3rd image)
See this:
https://allcontributors.org/docs/en/bot/overview
Also add instructions in the CONTRIBUTING.md
Making it easier for users to find and add the appropriate component or create the appropriate ScriptableObject
derived unity-atom asset can make this library much easier for new users. There is some consistency with the context menu creation for SO assets, but I think some reorganization could help there as well. There is a bit more cleanup to do in order to get these AddComponent menus more organized.
As of the latest on canary, these seem to be mostly organized around the type they revolve around versus the type of thing they are. This can lead to making these menus less navigable for a user if there is growth of atoms revolving around a particular type.
For example, everything dealing with an GameObject
value is organized for the context menu into a single scope including actions, events, variables, lists, etc... Right now as far as I can see there is only a single GameObject
action of type GetUnusedGameObject
, but presumably this list could grow to be very large as the number of actions/events revolving around GameObject
(s) is subject to a lot of growth.
For both SO asset creation and AddComponent menus, I believe a more helpful structure would be to organize these into the type of thing they are versus what they revolve around or use. Instead of a structure looking like this:
you would have something that looked like this:
This is also more in-line with the UX for other popular game development tools like Bolt or PlayMaker and can lead to a more consistent development experience and quicker onboarding for new users.
Making these changes would not result in any breaking API changes for end-users as these affect the Unity Editor UX only and would be a general UX improvement with little downsides.
Add a MonoBehaviour called AtomicTags that takes a list of StringConstants. Also add some extension methods to GameObject so that we can check if a GameObject has an AtomicTag.
GameObjectExtensions API:
Hey there,
so I copy&paste the dependency as told in the readme into my manifest file like this
{
"dependencies": {
"com.unity.ads": "2.0.8",
"com.unity.analytics": "3.2.2",
"com.unity.collab-proxy": "1.2.15",
"com.unity.package-manager-ui": "2.0.3",
"com.unity.purchasing": "2.0.3",
"com.unity.textmeshpro": "1.3.0",
"com.unity.modules.ai": "1.0.0",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.cloth": "1.0.0",
"com.unity.modules.director": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0",
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.physics2d": "1.0.0",
"com.unity.modules.screencapture": "1.0.0",
"com.unity.modules.terrain": "1.0.0",
"com.unity.modules.terrainphysics": "1.0.0",
"com.unity.modules.tilemap": "1.0.0",
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.uielements": "1.0.0",
"com.unity.modules.umbra": "1.0.0",
"com.unity.modules.unityanalytics": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.unitywebrequesttexture": "1.0.0",
"com.unity.modules.unitywebrequestwww": "1.0.0",
"com.unity.modules.vehicles": "1.0.0",
"com.mambojambostudios.unity-atoms": "https://github.com/AdamRamberg/unity-atoms.git",
"com.unity.modules.video": "1.0.0",
"com.unity.modules.vr": "1.0.0",
"com.unity.modules.wind": "1.0.0",
"com.unity.modules.xr": "1.0.0"
}
}
Then Unity throws an error:
An error occurred while resolving packages:
Project has invalid dependencies:
com.mambojambostudios.unity-atoms: No 'git' executable was found. Please install Git on your system and restart UnityA re-import of the project may be required to fix the issue or a manual modification of E:/Behind The Stone/Game Development/Games/Experimenting/AtomsTesting/Packages/manifest.json file.
Don't know exactly what the problem is. Git is installed on my machine.
Any ideas?
It's a bit annoying to have to create events all the time to be able to use the event listeners, so sometimes it would be nice to be able to set either a Variable or an Event to the listener (making the event be used in case it exists, or created on load in case it's not).
In order to subscribe to changes without carrying about the value of the GameEvent.
Add an GameObject extension method like this:
public static List<string> AtomicTags.GetAtomicTags(GameObject go)
Something that would be useful for developers would be an Atom revolving around a SceneAsset
. Ideally it does not keep a reference to a SceneAsset
itself since it is an editor-only type, but instead serializes its full path and name only so that at runtime a user could load a scene using that serialized name or path value.
This would have a custom inspector/property drawer so that a user can assign a SceneAsset
directly to the Atom or ping the currently referenced instance in the Project view, but would only assign its name and path to serialized fields.
The benefit of this versus a StringConstant
or StringVariable
is that this would offer a better UX and stronger validation of the values. There is a lack of validation that a general-purpose type offers that this more specific type could address. For example, the Atom itself could leverage OnValidate
to assert that the name/path values should not be blank, custom methods to indicate that the name/path resolves to a valid scene in the build settings, and the custom inspector could also warn the user if the referenced SceneAsset
was not in the build settings or asset bundle.
Like stated above, would you like us to create a Slack, Spectrum or Discord (or something else) channel to be able to communicate more effectively? Please add a thumbs up (👍) to the option that you prefer below 👇
If you want something other then Slack, Spectrum or Discord create a new comment with that option.
Rename Game Listener components in the Inspector based on the specified event for which it is listening. Currently, if you have several Game Listener components on a scene object / prefab, you may have several listeners with the same generic name (e.g. Game Object Listener) and it makes it harder to find which listener you need in the Inspector.
Description
If I have multiple unassignes Variables in a list (of serializable classes), when I click to create a new variable, the "Name of new item" text box shows up fot all unassigned variables in the list
Note: When you finally press create, this bug does not create a variable for all the objects, just the one you initially selected for creation, so the impact is very minor
To Reproduce
Steps to reproduce the behavior:
[Serializable]
public class ClassWithVariable
{
// [...]
FloatVariable var;
// [...]
}
public class MonoBehaviourWithListOfClass : MonoBehaviour
{
// [...]
public List<ClassWithVariable> objectsWithVariables;
// [...]
}
Expected behavior
The text box should show up only for the variable being created
Note that all the variables has "asdfa" with the checkbox and the x opened beside it
Environment
State your question below
In the demo scene. HealthListener is missing HealthBar.HealthChanged
However, when I "fix" it, I am now required to give a static value. And the health bar no longer works.
How is it setup to feed the HealthBar.HealthChanged a dynamic variable?
Add any additional information / background
Screen shot of the missing state https://snipboard.io/LWk0KG.jpg
Also the health bar needs to be assigned an source image, as its also missing
Hi, I got a problem with the build in Unity 2019.1.5f1 (platform doesn't matter; I tried both on Android build and Windows build).
More information in the screenshot. Is it possible to get a fix?
BTW: This is my first project with UnityAtoms and until now, it works really nice. It takes some time to get used to, some things could be better, but I really appreciate your repo. A great extension to Unity workflow. Thank you
Do you consider to enhance this repo with new features? Or show it on Unity forum (I haven't found anything related to that repo)?
I'm using 2019.3.0a4 version
When I add atoms on package manager this i what I see on my console, any Idea of what could be happening?
[CompilerError] The type or namespace name 'UI' does not exist in the namespace 'UnityEngine' (are you missing an assembly reference?)
Compiler Error at Library\PackageCache\com.mambojambostudios.unity-atoms@163a216\Source\MonoHooks\OnButtonClickHook.cs:2 column 19
1: using UnityEngine;
-->2: using UnityEngine.UI;
4: namespace UnityAtoms
[CompilerError] The type or namespace name 'EventSystems' does not exist in the namespace 'UnityEngine' (are you missing an assembly reference?)
Compiler Error at Library\PackageCache\com.mambojambostudios.unity-atoms@163a216\Source\MonoHooks\OnPointerDownHook.cs:2 column 19
1: using UnityEngine;
-->2: using UnityEngine.EventSystems;
4: namespace UnityAtoms
[CompilerError] The type or namespace name 'IPointerDownHandler' could not be found (are you missing a using directive or an assembly reference?)
Compiler Error at Library\PackageCache\com.mambojambostudios.unity-atoms@163a216\Source\MonoHooks\OnPointerDownHook.cs:7 column 55
5: {
6: [AddComponentMenu("Unity Atoms/Hooks/On Pointer Down")]
-->7: public sealed class OnPointerDownHook : VoidHook, IPointerDownHandler
8: {
9: public void OnPointerDown(PointerEventData eventData)
[CompilerError] The type or namespace name 'PointerEventData' could not be found (are you missing a using directive or an assembly reference?)
Compiler Error at Library\PackageCache\com.mambojambostudios.unity-atoms@163a216\Source\MonoHooks\OnPointerDownHook.cs:9 column 35
7: public sealed class OnPointerDownHook : VoidHook, IPointerDownHandler
8: {
-->9: public void OnPointerDown(PointerEventData eventData)
10: {
11: OnHook(new Void());
[CompilerError] The type or namespace name 'Button' could not be found (are you missing a using directive or an assembly reference?)
Compiler Error at Library\PackageCache\com.mambojambostudios.unity-atoms@163a216\Source\MonoHooks\OnButtonClickHook.cs:7 column 30
5: {
6: [AddComponentMenu("Unity Atoms/Hooks/On Button Click")]
-->7: [RequireComponent(typeof(Button))]
8: public sealed class OnButtonClickHook : VoidHook
9: {
The extension methods for AtomicTags are making calls twice to GetComponent. Cache the result from the first call.
Also go through other extension methods and make the same change.
Is would be really nice to have an automatically set up name for the event when creating a new event for a variable (could be fancy and try to understand what naming convention is being used or just force some naming convention such as appending " changed" or "_changed", or some middle ground such as a setting regex for it?)
This makes the process of creating new events for variables less repetitive (especially in the case mentioned in #66 )
Was just trying to subscribe to an int int event in the editor but that listener doesnt seem to exist, is there a reason why I shouldnt have an int int listener? or is it just an oversight
Is your feature request related to a problem? Please describe.
This is an issue that tries to increase the developer experience using Unity Atoms. It would be really nice if there were templates / CreateAssetMenu
items for some Atoms, eg:
Create IntFunction
or Create BoolIntFunction
Create IntAction
Create FloatBoolListener
Create IntBoolEvent
My thinking is that these should be generated based on the Atom types that are defined. This should probably also be part of the Generator as well as further additions to the generation (see issue #60).
Describe the solution you'd like
The best DX would be to add templates (like the ones in the generator) and then generate .cs
files from the templates calling a method via a CreateAssetMenu
attribute. When clicking the CreateAssetMenu
we probably also need some solution to enter the name of the newly generated Atom.
Describe alternatives you've considered
The straight forward solution would be to generate these templates in the Generator following this: https://support.unity3d.com/hc/en-us/articles/210223733-How-to-customize-Unity-script-templates
This doesn't sounds like a great solution since it is not possible (to my knowledge) to add templates on a project basis (only global).
In this case there will be an option to "Generate Unity Atoms scripting templates", but also "Remove generated Unity Atoms scripting templates".
Additional context
Consider finishing #60 before starting this issue.
I testing the library and using a Changed event on a FloatVariable, listening to it with a FloatListener in another GameObject and in the FloatListener calling a response to a function in the destination object/script that accepts a float. What I get in the inspector though is a field appearing under the script name and that value is the value passed through to my script, not the incoming value from the event.
Any idea what I'm doing wrong? I seems as though I've set everything up just like the Medium post and in the Medium post the listener response to HealthChanged doesn't have a field under it.
Cheers
Aaron
Hi Adam,
Every now and then my event listeners are breaking and I'm unable to setup using dynamic values. Previous dynamic listeners continue to work but the inspector shows the following:
The missing Actor.TargetAllAbilities
is still present on the game object. Like I say it continues to work too but that might just be because it's not doing a clean build.
Any ideas? I've raised it as a question rather than a bug due to the fact I'm pretty new to Atoms and relatively new to Unity as a whole - so it might just be me being stupid!
Thanks.
While attempting to register a function of a custom script as an event response for a VoidEvent I am not able to select a function. The function itself takes no variables, is public, and returns void.
Here is what I see when I try to register the custom script.
Two things to note.
https://github.com/AdamRamberg/unity-atoms/blob/v1.0.0/Source/Base/IGameEvent.cs
should the multiple parameter version have the register and unregister? or they are supposed to be derived from each other?
Thanks
I encountered a problem that I can't pass dynamic value in the callback.
Fortunately, I found a cause and a solution.
To fix the issue require to modify GameEventListener file.
change this
[SerializeField] private UER UnityEventResponse = null;
to this
public UER UnityEventResponse = null;
Need to do this in both classes.
I think those two classes need to be refactored to extract a common code.
For Variables, set a ShouldUpdate "hook" that you query before you update the value. Eg:
public bool SetValue(T value) { if (!AreEqual(this.value, value) && (ShouldUpdate == null || (ShouldUpdate != null && ShouldUpdate(T newValue, T currentValue, T oldValue)))) { // Set value } }
This makes it possible to add your custom logic to your variables, for example "clamp value" - to clamp the value between a min and a max. In this feature it is also included to create the "clamp value" hook.
Is there any special reason behind the events having to implement an interface? Doesnt this even makes it weirder if you want to listen for 2 events of the same type in a single class?
I cloned out the repository and ran the example scene with Unity 2019.2.4f1. The HealthBar is missing an int event listener and the Sprite assignment for the bar is missing.
What is the license for this project?
http://www.roboryantron.com/2017/10/unite-2017-game-architecture-with.html?showComment=1518505684655#c499355616768136746
What do you think about that? Do we need that? It's based on Unite 2017 talk.
Is it possible to achieve something like:
I got FloatVariable called "MovementSpeed", where Initial value is "4.4", Value is changing during a game, but Initial is constant, I restart a level and want to reset MovementSpeed to its Initial value 4,4.
In other words:
I want to reset Variable (Float/Int etc.) to its initial value when a scene is loaded/level started. I can use a pattern like in demos&examples with GameObject "OnLevelStart", hook, and SetVariable in Listener for every Variable, but...
In SetVariable we have to set what the value is, like "100", "5" (a number) or could use another Variable, but we don't have any mechanism to Reset a Variable to its initial value. I can't imagine, that I make MovementSpeed with Initial value 4.4, and SetVariable to reset to 4,4, because when in some moment designer will think that InitialValue for Variable would be 5, I have to also remember that I need to change SetVariable to 5 in OnLevelStart. It would be messy.
I got 2 ideas to solve this problem:
Are there any other better options to solve that problem? Maybe something is already implemented but I miss that?
Serialized fields do not show up in the inspector for some reason. At the moment, the only way to inspect and assign values is to activate debug mode.
Not really an issue but...
I am pretty sure the Serializable attribute is not needed on ScriptableObjects?
Thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.