#archived-code-general
1 messages · Page 102 of 1
beautiful
mah I'll just store the average vector instead of the collision
there is no way that running a loop of max 3 iterations every now and then can be worse than the extra workload given to the garbage collector
@cobalt wave Idk I would still store a different type than Collision, and keep reuseCollisionCallbacks true
I'm off to do that rn
thanks
in hindsight
I should not use Vectors for that
quirky float math and stuff + comparing = insomnia
Tbh I dont know why vectors would be the identifier here
Cant you use the collider or something?
i am having trouble understanding what you're doing :p
this here explains it quite well
Tbh I'm not 100% sure about the use case here
But I happened to catch the reuseCollisionCallbacks thing
but i'm unclear on what the objective is
I have a base prefab for enemies, a bunch of enemies prefabs that are variants of that base prefab.
Also I have a base prefab for player character, a bunch of player characters prefabs that are variants of that base prefab.
Now I want to create empty base entity prefab, I need enemyBase and playerBase to be variants of my new entityBase prefab.
Is it possible?
i don't think you can sneak that in after creating the original prefabs, unfortunately
i had a similar situation recently
So the only option is to remake it all manually?
why is the objective tied to the problem?
anyways, the objective is getting a good understanding of what the player is standing on, eliminating issues like standing on something spiky but still think it's not grounded (even though it's obviously colliding with something that is stopping it from falling)
also cases like standing on the edge
being able to go up steps without jitter (using a rigidbody)
that's for the ground collection at least
the wall collection will allow the player to get stuck "controllably" (and other things in the future aswell)
as of right now, the player gets stuck on the wall unless they are moving completely to the right or to the left of it
that has to do with the physical properties of the player, but just making a new physics material is not a solution, since it's a rigidbody movement setup (meaning if I just set the friction to 0 the player will decide to move around as it wishes if on even the slightest slope)
because people often XY-problem themselves
Asking about your attempted solution rather than your actual problem
I'm well aware of that
I would generally use Physics queries instead of OnCollision messages for ground/slope detection etc.
Or both 🤷♂️ But I don't find collision messages too reliable
And you also don't get any leeway, you have to be in contact with the ground
why? Collision messages are sort of free
I don't think they are. They look free, but they aren't
Probably more performant than a couple of SphereCasts but if it doesn't work well then whats the point
that's sort of the exact reason why I don't want to use queries
i still don't understand why you're doing any of this
you're making a list of collisions you've experienced with the ground?
if that's the case yes
if I'm standing on two objects then yes
if i'm standing on one object it's the same as one
let's just say I need the average normal angle of all the collisions for the walls
and for the ground, I just need to know if I'm allowed to be grounded
i do not think there will be any difference whatsoever if you just use a physics query
your code will also be dramatically simpler
By the way. You are looping over a HashSet, checking equality manually, then removing it.
You could just remove all that and use if(groundCollisions.Remove(collision)) { ... }
there will be
- casting a capsule downwards (or anything) will require me to disable it checking against itself
- I will need to cast a capsule (or a ray) in all directions somehow
- That casting has to be good enough for me to get the normals that are relative to the player's collider itself (something Collision already stores)
- There is leeway, meaning I don't really have to be touching the ground to be considered me grounded (unless I cast the capsule exactly where the player's collider is, which is already done by the collider itself and I can get that information from OnCollisionEnter and Exit)
:/
hmm, fair enough.
I mean, if there is something I actually do not know, I'll be glad to hear about it, because I'm pretty sure I know way less than I don't (if that makes sense)
I'm trying to set up disabling the player for my UI-only scenes. I want it to check to see if the currently loaded scene is a UI scene and if so the player should be disabled. I tried using an Awake() method but that did not work. I was trying to use OnRuntimeMethodLoad but because it has to be static I'm not sure how to set the player as inactive. Are you able to help?
[RuntimeInitializeOnLoadMethod]
static void OnRuntimeMethodLoad()
{
Scene scene = SceneManager.GetActiveScene();
Debug.Log(scene.name);
if (scene.name == "Menu" | scene.name == "QuizGame")
{
gameObject.SetActive(false);
}
}```
So did you find some way to automate it at least partially?
nothing should be in the runtime initialize other than what I gave you
any code like disabling player, just put an object in the scene you dont want him in
then the code should just "find player" and disable
Ok, will do
Hya. I wrote a script to manipulate a quadratic bezier curve visually in the Inspector, but I'm getting some choppy results
Im doing everything in OnInspectorGUI, could this be the problem?
Within OnINspectorGUI i'm using Events like MouseDown and MouseDrag
Is FixedUpdate guaranteed to run every 0.02s by default?
I'm making a game with a generative soundtrack, where I need to time things by the millisecond and it looks like FixedUpdate goes off tempo at times.
it runs as often or as infrequently as it needs to keep an average rate of 0.02 seconds. It represents 0.02 seconds of game simulation time
no fixedupdate is not going to work for audio syncing
Ok I did that and I made a separate script for enabling the player. When I change scenes I get this error. It seems like the scripts I made are not able to find the player. (the FindPlayer.cs is a script to set the player on the follow camera)
it has no guarantees like that
I tried using a while loop with yield, but that also went off sync
You will want to base things off the audio system's timer
was about to type the same
also yield return new WaitForSeconds is not a good way in general to make an accurate timer if that's what you did
Ah I see
How would I use dspTIme then?
Just in my FixedUpdate method?
Well it really depends what you're trying to do
And use that instead of fixedDeltaTime?
I just need to create a clock that runs some code every so often
To play a sound effect on beat of the background song
right so you're making a rhythm game
I mean I guess?
using dspTime or the sample count will be your best bet
Right yeah but in what context do I use dspTime?
If not Update() and FixedUpdate() I mean
someting like:
float expectedEffectTime = whatever;
bool effectPlayed = false;
void Update() {
if (myAudioSource.time >= expectedEffectTime) {
// play sound effect here
effectPlayed = true;
}
}```
Depending on framerate this is going to always have some error though
Damn what then
Hello!
I have a main character controller. There is a separate input script that generates UnityEvents that the controller should respond to.
I don't like that I have to write many functions that need to be subscribed to these events. In theory, I can distribute these functions across subclasses (a movement handler class, a shooting handler class), but these classes will be fields of the controller and their methods cannot be subscribed directly through the editor inspector.
What is commonly done in this situation? I can subscribe to events through scripts, but I want to do it nicely, in the editor inspector.
no one can help you troubleshoot without seeing code 😄
I'm not really an audio expert maybe the people over in #🔊┃audio will have a better idea. Perhaps FMOD has a way to do this better or something. But in general playing sound from an audio source is likely to be limited to frame boundaries.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnablePlayer : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
GameObject.FindWithTag("Player").gameObject.SetActive(true);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DisablePlayer : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
GameObject.FindWithTag("Player").gameObject.SetActive(false);
}
}
this will never work given FindWithTag can't find inactive objects
also the .gameObject is unecessary / redundant
using Cinemachine;
using UnityEngine;
public class FindPlayer : MonoBehaviour
{
private void Awake()
{
var vcam = GetComponent<CinemachineVirtualCamera>();
vcam.Follow = GameObject.FindWithTag("Player").GetComponent<Transform>();
}
}
^this one is for the followcam
I have another question in regards to UI elements. What would be a way to implement a custom UI element to multiple scripts. For example the Bezier Curve Editor I've written. It's in a custom editor script. I'm sure there is a better way to use / implement that custom editor into other scripts, rather then having to copy past every time, right?
I am completely new at custom editors, Barely used it before
Hope someone can help as it's for a uni assignment haha
if you get good fps it wont be an issue 😄
yeah but the groupmate of mine who's doing the music doesn't have really good FPS on the game
so when showing his progress it won't work
Disabling the player seems to work, but enabling it is still causing the same errors. Here is what I changed the code to:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnablePlayer : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
GameObject.Find("Player").SetActive(true);
}
}
Would it cause issues if my Player is a child of Systems?
not sure if find works if its disabled also 😄
Whenever I need to get player I just call
Gamemanager.instance.player
cause my gamemanager has player serialized in it
and will never be disabled
Is there a way to enable and disable the player directly within the player script and have it trigger when changing scenes? Remember I have some scenes I want the player and some where I don't
I don't think I have a gamemanager
Only if that script isnt part of the gameobject thats being disabled.
I'm confused, I thought you could disable and enable with an attached script? And you also can't with external scripts on a different gameobject?
Or at least enable, I guess you can disable
a component can enable the gameobject it is attached to provided you are not doing so in Update or a Coroutine neither of which would run on a disabled gameobject/component. but another object with a direct reference to said component can call methods on the component which can then enable/disable itself or the gameobject
OHHH ok I think I know what to do then
I made a method in my player class for enabling it. Is it possible to call this method using EnablePlayer? Is there a way to get the player and call that method?
get a reference to the player object. here are several ways you can get a reference that don't require any of the Find methods (since most of them cannot find disabled objects anyway): https://www.youtube.com/watch?v=Ba7ybBDhrY4
anyone any idea how I would re-use a custom inspector script? Let's say I have coded a fancy button, and I want to use that fancy button in multiple monobehaviours, surely there's a better way then having to create a custom inspector for each monobehaviour and copy pasting the Fancy Button code, right?
sounds like you want an attribute similar to naughtyattribute's Button
Will any of these methods work if the object isn't being instantiated in the scene until the scene is loaded? I noticed a lot of them use serialization and I'm not sure that will work
make an object that is also dontdestroyonload
yes, there's literally an entire section of the video dedicated to that
serialize player there
Ohhh that should work
then just "find" that object and grab the serialized player and disable the player
aka...what a gamemanager does 😄
something in the scene will have a reference to the prefab and instantiates it, use that to pass references around
a DDOL object wouldn't just implicitly have a reference to an object that is spawned at runtime though. unless of course the DDOL object is the object that spawns it
Thanks, looking on their github now
his player is also DDOL
he wants an object in scene to grab the player and disable sometimes
or enable other times
Okay I feel like I'm very close. I serialized a field to pass in the player and this script is added to DDOL. In order for this to run when the scene changes, what should I use instead of Start()?
using UnityEngine;
public class EnablePlayer : MonoBehaviour
{
public GameObject player;
// Start is called before the first frame update
void Start()
{
player.SetActive(true);
}
}
listen to the scene change
SceneLoaded event
How would I call that? I'm pretty unfamiliar with events in Unity
there is literally an example code
I wouldn't have the start at all
I would have it just hold the reference
and have an object in scene grab the player reference and enable/disable when you want
You might need to use this, not sure if it affects the scene only or inspector too
https://docs.unity3d.com/ScriptReference/Editor.RequiresConstantRepaint.html
Also might wanna ask in #↕️┃editor-extensions if that doesn't help
@hexed pecan thanks i'll read that.. also asked in Editor Extensions, it's a little slower in there 🙂
Though if your code is just simply slow, then you just need to optimize the code. I doubt the code makes it chug like that though
Unless youre doing some really heavy stuff
Yeah its slower, but from what ive seen, most people get help for their problems there eventually
me wondering why my code was bad and realizing I had thousands of the same Coroutine running on accident 😄
so im trying to measure 1% lows in my game atm, with my methodology being to record the delta of each frame (for 15s or up to x frames) then calculating by taking the 1% of all lowest deltas and averaging it to get the value, is there a faster way that i can do this?
or a better way to calculate it
heys quick question, when pressing down a button and while still pressing i move the cursor out of the button, the button still detects that is being pressed how can i change that
You can use the IDragHandler to set a flag afaik
so if you hold down the mouse button and move outside of the ui button it's still pressed and you want to change it?
yes
you can make custom button with
public void OnPointerClick(PointerEventData eventData)
{
}
and use the eventdata to detect if he with the mouse hover the button?
this function is called once you click on the ui element with this script, then you can use if(eventData.button == PointerEventData.InputButton.Left) to check that it was a left mouse button
it doesn't have this "hold down to keep pressed" thing, just being called once
Might be worth mentioning that it needs the IPointerClickHandler interface to work
true
but I don't remember, can it work without new input system?
yes
"new", yeah
cool then
yeah, but that's not the problem, the problem is not executing the code multiple times, is just because that button that i have has a script that drags the button ui when pressing it, but he needs to be pressing the button for 1 second to activate, and if in the 1 second he moves the cursor out of the button while still pressing, the drag position of the button becomes bugged.
So do you need a button that works only when you hold it for 1 second?
And if your cursor leaves the button, it will be canceled?
It's draggable too?
the part that works of one second i already done, i just need to when moving the cursor out of the button, it stops but i could try using onmouseenter()
You can detect the cursor leaving the button with this one
https://docs.unity3d.com/2018.3/Documentation/ScriptReference/EventSystems.IPointerExitHandler.html
Is there a way I can get a point a specific distance across a navmesh path?
Maybe there's a more elegant way, but you can loop the path positions until the total distance reaches your specified distance
Say you had a page like this...how would you break up scripts?
One for holding button references? 1 for doing item stuff, one for hero stuff?
realized I've got almost 1000 lines of code for this UI screen in 1 file so trying to figure out what I should be breaking it up next time lol
What is the best way to store a reference to a GameObject in a json file? I have already placed enemies in a scene and want to save an array of enemies that are dead, this way after loading the game, I'll iterate through the array and kill each enemy in it.
You can’t store references in json. Best you can do is store an ID which you can look up during deserialization
welcome to the hard part of serialization :B
you'll need to find a way to uniquely identify these enemies
I know, but there must be a workaround
Nope, all you can do is lookup an ID to an existing object or generate the object from serialized data
does unity have a built-in id for each object in a scene?
no; if you're thinking of InstanceID, that is an unstable value
Nope, just asset IDs
technically each object in the scene will have an instance ID, but you cannot rely on it
Hmm, I think I can store the ID in the name of an enemy
Don’t do that. Make a serialized field with the id
i wonder what the best way to automate that is
you could have it generate a random ID in OnValidate
Can’t automate it. It breaks in a bunch of edge cases. Unity lacks some callbacks during object creation to automate it fully
I mean, it'd be much harder to find enemy by their id in loading
find every object of the relevant type, read all of their IDs, and pick a fresh one
O(n^2) 
Yes, but that is very slow
it might be sufficiently fast for reasonable numbers of enemies
oh right, but you'd have to do that every single time OnValidate is called, which happens a lot
since we, indeed, lack callbacks for things like "just got duplicated"
Can the order of adding objects with FindObjectsOfType<>() change between sessions?
100%
If something doesn’t explicitly expose a stable ordering property you cannot rely on it at all. Even if all your experiments would indicate stability.
btw, why shouldn't I use name as a field for an id?
I don't rely on names anywhere in my code
It’s brittle and will therefore break
You should never rely on a name for maintaining a reference, always use IDs without any meaning
what about creating a class with 2 variables: string id and GameObject object. Then I use x, y and z position of an object as it's id and populate array of these classes?
And the name of objects in unity is too easy to change by accident to be a good keeper of an id even it has no meaning
Use a guid/uuid
For my items i have a database that automatically looks at all prefabs with the item script and adds them to a dictionary, coild use something like that here
isn't guid only for files in the project?
GUIDs are 128-bit values, so you can pretty comfortably just generate random ones
Not sure if we are talking prefabs or scene objects tho
collisions will not happen for any non-insane number of entities
assets are identified with a GUID
but there's no reason you can't use 'em too
the only problem is that System.GUID is not serializable
Even for insane numbers they won’t 😲
I use a struct that pretty much just reproduces the behavior of System.GUID
yeah, but I need a reference to an object of a scene, not to an asset
yes, so you identify them via GUID
you do not store references at all
you just store a list of GUIDs
When I launch my Doodle Jump the game does not display the platforms (which were created with a random script). The only platform displayed is the one I added as a base. The orders in the layers are 1 for the platforms, 0 for the player and -10 for the background. An idea ? I put my random script below just in case
grab all of the enemies and make a Dictionary<GUID, Enemy>
I've often wondered why we don't see PRNGs which can absolutely guarantee no duplicates or collisions used for ID generation instead of things which are unlikely to collide 🤔
do GUIDs change from machine to machine?
no, they're just numbers
they're just long ints
there are several ways to generate a GUID
so it isn't connected with path to the game or smth
A rng is stateful, guid generator is stateless
What would you use as a seed?
it's not that hard to make an RNG that doesn't produce duplicates
an LFSR will walk through every possible value
the annoying part is remembering that state, forever
you'd have to store the seed and the number of values you've sampled
I suppose that's compelling - I'll have to think on that a little more. I was just assuming a hard-coded seed, but that may not work for every application
ah yeah - and sample count 🤔
Fair enough - I appreciate the insights 😁
Random does have a serializable get/set state property
That’s not the point
Just saying that you wouldn't need to store a sample count
If by that they meant like how many numbers have been sampled so it can be reproduced
bump question... @hexed pecan you seem to know things, how might you break up programming a big UI like this?
but I will still have to iterate through the list of my enemies in order to find an enemy with matching guid, right?
figure 1 script and 1000 lines probably is a bad idea lol
you would make a dictionary
dictionaries are good at this
Not my expertise, but maybe start with splitting each menu into a script
so I can't get the object through its guid
it's not far off how GUID's are generated to begin with
You can with a Dict
get all of the enemies
make a dictionary out of them
done
yeah
good idea, hadn't thought of that
do that once at startup and then delete all of the killed enemies
do you think splitting each button into a different script is overkill?
that sounds a bit much
Yes
each kind of button, sure!
I have a script for a button that makes a scene load
and a script for a button that just summons a submenu
gotcha
More or less, yeah. I wrote a little linear congruential generator once, and it had a fairly sizable state given it's purpose.
I think I'll have to play with the stateful Random for ID generation a little bit to fully appreciate the limitations/complications discussed
btw, what's wrong with using x, y and z positions in a string format as a guid and getting it in Awake if all enemies start the scene always in the same place?
well, that wouldn't be a guid
it'd just be a location
it sounds fine if you are sure that nothing is going to move...although you'd probably want to use something less prone to floating point pain
Hmm yeah not sure how GUID generation works internally but it doesn't seem too far off from a PRNG
An answer I found says that C# GUIDs are generated with Mac address + Timestamp + extra bits + some identifier
https://stackoverflow.com/questions/1888254/how-does-c-sharp-generate-guids
ok, no, it gives different results in different runs
The method creates a Version 4 Universally Unique Identifier (UUID) as described in RFC 4122, Sec. 4.4.
Sounds like you need something with a state
Version 4 is random.
extremely
it's basically just asking for four random ints
the entire point is that it's random
it's fast but it does create garbage so be careful where you're doing it.
Ah that's kind of awesome - I reckon that's what @mental rover was getting at. I think I've just been naïve in assuming that all GUIDs were randomly plucked out of the space
how on earth did they make that produce garbage
look at you, using the ï
Hopefully it's garbage-free
i love writing naïve with the umlaut
nvm lol
¨¨¨¨¨
it must be random but the same in different runs of a programm, right?
i don't know what you're trying to do with it
you only need to generate it once
at editor-time
the only tricky thing here is making sure that duplicating an enemy doesn't result in two enemies with the same GUID
oh, I get it now, I think
Yeah it would probably have to check the dictionary in OnValidate or something
now introduce undo and redo 😵💫
I'd think an acceptable approach would be to write an editor script that you can run once when you're ready to build your game - the editor script gets all objects in the scene and generates an id for each/resolves missing or duplicates, etc
eh, it's fine if you redo and it winds up thinking it needs a new guid
Can somebody recap the usecase here for me real quick?
unfortunately there's not really a way do this in a watertight way, on some level you're going to have to manually acknowledge how the ids are being used/assigned to not break it
A bunch of enemies are spawned. Some may be killed by the player. The save is supposed to contain the IDs of the dead enemies, to kill/skip spawning them on load
Ah so when the game is opened the next time, it would first load the whole scene and then remove killed enemies etc?
I would personally not have any enemies in the scene but store them by identifier to begin with, and them spawn them from that ID list
But that just depends on your workflow and game
That was my understanding 👍
an alternative to turn the problem on its head a bit, instead of having manually placed enemies in a scene have a flag for whether it's the first time the player has played it - from there, load from a default "first time" set of enemies and spawn them in, or use the players saved list instead
then you can just save all data of what to spawn, rather than what not to spawn
this would require a rewrite and rethink of how you're creating and serialising scenes though
quite not like this. Enemies already exist in the scene, if an enemy dies, I can add it to an array of killed enemies and then save it, so after loading, Kill() function would be called for every enemy in the array;
Yeah that's my thinking here as well
Additive spawning > Subtractive spawning
down the line it's a much more robust way to avoid headaches when you change things
That sounds like the same thing 🤔
Ah well the difference is spawned vs. already existing in the scene
the difference is that I cannot spawn them, a lot of them have unique parameters and making each of them a prefab would be a hell
Ideally those are the parameters you'd serialize
those parameters can contain scriptableobjects and other GameObjects so yeah
Hello, can someone please help me with a Toggle? It doesn't register touch and I can't figure out why
Check nothing is rendering ontop of it. blocking the touch functionality. debug.log
I can't Debug.Log because there's no script attached to it yet. Nothing's rendering on top of it.
prove to me theres nothing rendering ontop of it
The buttons nearby work just fine
thats not proving anything
Find the EventSystem in your scene and look at its inspector while playing
You will see what object the mouse raycast is hitting
I don't think I'm seeing anything change even though I'm pressing a button in the screenshot
Look at the very bottom of the inspector, theres another tab that you can drag up
See EventSystem here
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "ItemRarityStats")]
public class ItemRarityStats : ScriptableObject
{
public Dictionary<MyItemTypes,Dictionary<MyItemRarity,HpAtk>> ItemRarity;
}
[Serializable]
public struct HpAtk
{
public int hp;
public int atk;
}
MyItemTypes and MyItemRarity are both enums....why can't I fill this in in the inspector?
Wait why are there no cameras rendering in your game view?
I'm not sure what you mean by this. It's a Main Menu
I discovered that the toggle does, indeed, toggle on and off. The problem now is that the graphic isn't changing
Unity can not serialize a Dictionary
was hoping naughty attributes would make it possible 😄
You can use this for example
https://assetstore.unity.com/packages/tools/integration/serializabledictionary-90477
Hey. I'm not really used to editor scripts, I created a button to save guids and referenced to a GameHandler's dictionary but it resets upon running the game, how can I fix this?
Which graphic should it be changing to?
Do you want to toggle the text?
To this little red square, but it only appears while I'm holding the toggle
And yes, I want to change the color of the text too
I'm not too experienced in the UI, so there may well be a better way. But you can drag a Game Object from the hierarchy which will be transitioned to to this field in the Toggle's inspector - so you might create a child object with your desired image (and perhaps your colorized text) and set it as the "Graphic"
Edit: I misspoke - it looks like it does have to be some sort of rendered graphic - so you could set it to an Image of the red square there, but I think you might need to change the text color via script.
Is safe to pass a ref managedArray[n] into a a method which has the attribute [BurstCompile]?
Thank you, that worked! I'll be changing the color of text via script then. But it is very satisfying to finally have a working toggle. Thank you so much!
Ok, I just decided to add them to a list through a button and then populate the dictionary from this list after running the game, thanks everyone for helping, now I have a dictionary of GameObjects with their guids. 
Does anyone know how to use player's voice to do actions in unity? A form, wiki or a site to figure it out would be greatly appreciated.
how can I do this without the empty task?
Task saveKeyHashTask = Task.Run(delegate { }).ContinueWithOnMainThread( _ => {/*Code to run on the main thread*/});```
so, I want to run a task, that will run on the main thread, from a task that isnt running on the main thread
I was playing with built-in voice recognition some time ago and remember it being janky and slow
Use UniTask and use these examples
// Multithreading, run on ThreadPool under this code
await UniTask.SwitchToThreadPool();
/* work on ThreadPool */
// return to MainThread(same as `ObserveOnMainThread` in UniRx)
await UniTask.SwitchToMainThread();```
any way without using an entire library?
Man I should really try UniTask it looks dope
Well you're already using a library to get ContinueWithOnMainThread (Firebase)
So that task does nothing right, you could try a Task.CompletedTask.Continue...()
the thing is, I am already using firebase, but I dont really want to download UniTask, for just a few async cases I have
that's a bit better looking I guess
another option would be capturing SynchronizationContext.Current from the main thread, then calling mainThreadSyncContext.Post
but that solution seems even uglier
I was going to use this for a vr game where player say the name of the spell and it gets activated
atm I am just using directional abilities like the way the player folds there hands and such
but I thought it would be cool if you could yell out "fireball" and it would shoot one
what was the main issue that you ran into to cause it to be slow?
Just a delay between input and doing something, maybe it's fixed now
Sounds interesting, like Rumble VR + In verbis virtus
Is there another way to fix GUIText is obsolete?
If I replace it all with "UI.Text" the code doesn't hook right, and nothing updates.
That is the way to fix it: replacing it with text mesh pro components and code.
Ah. So don't correct it in VS, instead use Text Mesh Pro?
why can't I modify scriptable object at runtime? is it not possible now?
You can, but the changes won't be saved in a built game
you can modify it, sure.
That's an issue.
Yeah they aren't for saving data
Oh different person 😆
Both. You need to use text mesh pro components and set up proper UI, then modify the code to use it.
I already have the latest version of TextMesPro.
thats weird because it doesnt work for me
int value = newResource.resourceQuantity + resource.resourceQuantity;
resource.resourceQuantity += value;
resource is SO, and its value doesnt change after value add
You need to actually use it
Built game or in editor?
I have never used this thing. lol
editor
Well, that code does change its value. Are you sure the code is running?
Also I see double addition here. Youre basically doing assetValue = assetValue + assetValue + newValue
Honestly, this game is light, so I can do with some shitty coding. Is there a way to just keep using GUIText? lol
Debug.Log the resource.resourceQuantity before and after doing the addition
And are you sure you want += and not = ?
In any case, modifying a ScriptableObject asset is not going to work in a built game. Or it will work but it wont persist
Yeah. The issue is I got an asset as a starting point. The code is fucking old.
So just changing GUIText makes it so the code doesn't hook, and nothing on screen updates.
it return valid value but when i check it in editor it still shows old value which is now super weird
Maybe another script/object is also modifying its resourceQuantity value
Another reason to not modify shared assets from code
modifying assets at runtime is scaaaary
i dont think so, its instance of SO and its prety fresh project so im sure nothing else modify it
Oh so it's an instance. Are you looking at the editor/inspector of that instance too?
Or maybe youre looking at the asset?
im looking at the instance specificly
Can't speculate further without seeing the rest of the code
I’m making a top down 3d game and the first boss has a shockwave attack that starts at his position and grows across the ground. The player should be able to jump over it to avoid being hit. I’m having a mind blank on how to implement the collision detection though. It can’t be a trigger sphere because I only want it to be at ground level and I don’t want the player to collide if they jumped and landed “inside” the sphere. My current thought was have two concentric sphere colliders, the outer one to detect a “hit” at the edge and the inner one to verify that they’re not “inside” already (i.e they jumped over and landed in the safe area) but this seems iffy. I feel like I’m over thinking this and there’s probably a much simpler way.. any help much appreciated
i'd do a trigger sphere whose logic checks if you're on the ground
(or near the gruond)
it'll need to use OnTriggerStay in case you hit the ground after hitting the trigger
it'll also need to check if you're close enough to the edge of the shockwave, of course
Ok yep this makes sense. So inside OnTriggerStay I check that the character is within some threshold distance to the ground (in line with the shockwave visuals height) and also check the players distance from the shockwave centre and the current radius of the shockwave to determine if they’re “at the edge”. This makes sense. Thanks @heady iris
and then set a flag once they get hit, so that they don't get hit over and over :p
I'm not sure if you could do anything to prevent the repeated checks.
Hah yep, my character has an invulnerability state after being hit which should take care of that but you’re right the trigger itself should flag that it’s already dealt damage to the player.
I have a char controller with a rigidbody, I have a section under an if statement isSwimming. The player goes in the water, you can swim, tread water and get out just fine. I cannot for the life of me get the damn guy to dive down. He stays on one constant level. Anybody wanna help?
what have u tried?
also for the char controller with a rigidbody, you mean a custom character controller and not the built in one right?
man, that's a deep question, no pun intended. I have tried some code snips to use x y and z axis and that failed big time on my part. I have buoyancy script working to keep him treading water with head above. I feel like its gonna be movement on y axis,
yes, custom
im using the new input system, and would like the dive to be on the shoulder buttons or q and e on the keyboard. I just cant figure out how to get that movement. its been a couple days of many tries.
well, how are you keeping the player from going underwater?
the type of input shouldnt really affect it, whats wrong with adding force downwards while an animation plays?
i turned off gravity when a collider attached to his head hits the water. he stayed a constant level, so I added a buoyancy script to get his head above water. im thinking as i type that maybe if i manipulate those values in code it might do what i need.
reduce the buoyancy or apply downward force
the latter would be more physically accurate
since buoyancy should be a constant (once you're submerged, at least)
also it depends on what your game is supposed to do, like is it supposed to push you above water while you're far down and not inputting anything
ill try the down force on the method i have set up for the animations and such. They way the game is going, you will have to dive to obtain certain items and get back up before you run out of air.
i dont want the player to have to button mash to stay afloat.
is anyone here familiar with using the passthrough over link beta feature on oculus desktop?
I have two gameobjects, one red and one green with the same script. This script has an oncollision method which detects the color of the object collided with, and sets the current color to that collision color. When the objects collide, will they swap to green and red, or will one update first, and cause both to be the same color? example of the latter case is that the oncollision of the red object runs first, and the object turns green, then the other objects oncollision runs, sees that the original object (which was red) is now green, and stays green
From a guestimate, I'd say 99% of the time they'd end up the same colour
ok, i have it working, but you have to tap the shoulder buttons to dive and ascend. I added a interaction for Hold in the new input system but its not working. any tricks to get that to work.
too many variables involved with the former
how would i go about making them swap then? I can't think of an easy way besides setting a manual delay between reading the color and writing the color
I am using an integer as a binary mask, I don't know the length of this mask, how can I check if evvery bit is a 1?
elaborate on this, i'm working in passthrough on the quest pro
at the moment, im pretty consistently able to get pasthrough to work once over oculus link through my unity project, but if i stop and re-run then it's just a black screen. i have to reboot unity every time for passthrough over link to work again. similar story?
oh hm, i'm not using passthrough oveer link, i'm just building the app to my quest directly
ya thats much cleaner
i tried using passthrough over link but was having similar issues so decided to just do things manually
unfortunately i need the desktop connection at the moment to test some local networking stuff to the unity app
which networking platform are you using, netcode or photon?
its some local tcp stuff coming in through a python client
ahh i dont have any experience with that sorry D:
all g all g. im considering switching to webxr. since i dont need very unity-heavy stuff for this at the moment.
increase by 1 and repeatedly divide by 2, if you get remainder 1 at any point, one of the bits is not a 1
ty tho
so there is no better way than loop it all?
Add 1, remove the first bit
If it’s 0 then all bits are set
This removes the looping
how can I remove the first bit?
where n is the mask I guess
Ya
111 & 1000 = 0
Doesn’t work for any other n because not all bits will shift
Unless n has all bits set
Bump on this :3
omg I'm sorry
Ya it’s been a while so I’ve forgotten all my bit manipulation
ok thanks it worked
Just double check that the mask isn’t 0 as well
Since 0 & 1 is 0 too
Annoying edge ase
yeah I already do that
i guess 0 is a number with all zero bits set :B
@grave cranefor (int i = 0; i < 32; i++) {
Debug.Log((myMask >> i) & 1);
}
For future reference, you can do something like this to analyze all of the bits
I need to generate a 3rd model from the glb file. how do I display a 3d model from a glb that comes from a blob via api in react?
This is the Unity discord, not React
Hi, from what I understand, in unity ML agents, CollectObservations is called every fixedUpdate, correct?
Then does something like this make any sense, if I want the observations made every 5 updates?
public override void CollectObservations(VectorSensor sensor)
{
if (_fUpdateToObservation > 0)
{
_fUpdateToObservation--;
return;
}
else
{
_fUpdateToObservation = _observationInterval;
sensor.AddObservation(_currentPoint.rightHandPositions);
sensor.AddObservation(_currentPoint.leftHandPositions);
sensor.AddObservation(_currentPoint.rightHandRotations);
sensor.AddObservation(_currentPoint.leftHandRotations);
sensor.AddObservation(_currentPoint.handState);
}
}
HI everyone! I am trying to figure out which code returns the native resolution of the Desktop/Monitor, and NOT the resolution of the program in unity. There is a thread on it in the Unity Forums and it appears there is some conflicting information in the unity docs, as people are getting different results.
Here is the unity thread: https://forum.unity.com/threads/get-screen-resolution-not-window-resolution.319511/#post-8708817
So which is the code I should be using to detect the monitor/OS desktop resolution?
Screen.currentResolution.width
Screen.currentResolution.height
or
Display.main.systemWidth
Display.main.systemHeight?
There are claims that Display.main.systemWidth/systemHeight are broken. The unity documentation claims Screen.currentResolution only returns the windowed resolution of the unity program, but people seem to think that it returns the desktop resolution instead.
sure, but the else scope is unnecessary . . .
oh yea I forgot I put return in there
well, as long as it works
Just make one Quad manually and rotate it as needed
ok I will try ^_^ ty
That appears to only grab the display of the game window, not the desktop
AH HA, that thread is right, the Unity docs ARE wrong: Screen.currentResolution.width actually gets my desktop resolution, despite the fact it says the opposite in the docs.
Question. I am using the attribute AddComponentMenu. I have "MyFolder/MyScript", I need to have MyFolder on the top of all the folders. The second order arguement only orders MyScript
I'm making a 2D top down game, and the tutorial I watched used rigidbody, but in the fixed updated function he used rb.MovePosition as the main mechanism of moving (based on if a raycast says it's all good to move, and also based on a movement speed value).
What's the benefit/difference between this and using rb velocity? Is there a preferred approach?
I have this prefab that I want to instatiate at everysingle point on a trail renderer, How should I do this?
https://docs.unity3d.com/ScriptReference/TrailRenderer.GetPositions.html
is it just the position u want of every vertex?
mhm
GetPositions should be what u need then
also that was like a 10 second google search..
https://assetstore.unity.com/packages/tools/game-toolkits/third-person-controller-basic-locomotion-free-82048
Hey I have been using this Asset Package for an Assignment to demonstrate my animations and I want to include one more animation to include a Death Button (Triggered by F) I have attempted to edit the original script but they don't trigger the animation to change
I have the Animator set up properly so what I am experiencing is a scripting problem. I have also attempted to create a 2nd Script as a work around to my code editing issues to trigger my death animation upon pressing F but that doesn't seem to be working either
Would appreciate some help and advice on how to quickly add my Death Animation to my character.
Hay I'm making a meteos clone and trying to check if there are 3 or more "packets" in a row if the same type its working horizontally but not vertically these are the 2 methods involved in it: https://gdl.space/dirixaremo.php
Oh wait no I figured out the issue, I never added the starting block to the lists I'm returning
Hello everyone !
A few weeks ago, I have been advised to use
Collider2D[] collArray = Physics2D.OverlapCircleAll(Centerposition, collRadius);
to check out collisions inside a circle.
Re-reading old code, I found out I used
int resultNumber = coll.OverlapCollider(noFilter, results);
a few months ago to do basically the same thing (with the script attached to a prefab with a CircleCollider).
What could be the point in using on of these over the other ?
The OverlapCollider will miss static Rigibodies when on a static rigidbody (because the standard onTrigger would too) ?
well for OverlapCircleAll u can call that on a position without having an existing collider
according to the docs too, OverlapCircleAll will allocate memory unless u use the NonAlloc version, while OverlapCollider wont resize your results array if it isnt big enough (not allocating memory)
if these arent a concern for u and u just need something that works, either should be fine
OK, thanks !
I think I'll mostly use overlap collider now, since that means the script running it doesn't need to know what the collider looks like
OverlapCollider does make sense if u already have a collider in the correct position
yeah, I was using it to check for static-RB on static-RB collisions, since these do not trigger the OnEnter methods
and since the OverlapCollider has a version with a List of result in the signature, this dot not limit the number of results
OverlapCircleAll creates a new array each time whilst OverlapCollider uses one you defined beforehand, allowing you to avoid extra allocation, garbage and therefore save performance.
You should wonder if it's necessary to save performance on this. I would say you use the bottom one if you call this part often.
How to make an if statement that only runs if either THIS || THIS not on THIS && THIS
usually or statements even work if THIS && THIS is the case and I dont want that
sound like xor
I came up with a solution but dont know if its good enough
if ( isWallking && !isInAir)
// first function
else if (!isWalking && isInAir)
//second function
what is that?
exclusive or
Ok I will check it out
It means either condition of the or are true butnot both
Thank you, thats what I was looking for, I remember XOR but never knew its use
// If walking but not in the air OR if not walking and in air
if ((isWalking && !isInAir) || (!isWalking && isInAir))
{
// do this
}
XOR is a bitwise operator, and I don't think you need that
You can just do the simple boolean check
If you really want to, this might work, but I haven't tested it
if (isWalking ^ isInAir)
{
// Your logic goes here
}
@formal slate
xor works on bools, should be fine. U dont need it but it simplifes the expression otherwise
Yeah, I would just suggest the basic boolean check done above it, since this is confusing to a lot of people
if (isWalking != isInAir) // Do Stuff
You're a fucking genius
Welp listen to the boring lectures kids or you'll never learn the good stuff
Is it possible to use the job system to call ParticleSystemRenderer.BakeMesh?
Doesn't look like it. Can I ask what you need BakeMesh for? Maybe there's a different approach.
I am using the UIParticle from mob-sakai. And i am just wondering if i can modify its function to call the bake mesh in jobs
It doesn't look like it. Unity is pretty clear about what APIs are thread safe and it doesn't look like ParticleSystemRenderer.BakeMesh is one of them.
Yea was kinda cool to see that Physics.BakeMesh can be jobbed, but not the ParticleSystemRenderer one.
But okay thanks for giving it a sanity check as well 🙂
XOR is equivalent to !=.
@frosty lark If you in depth detail, you could refer to http://calccheck.mcmaster.ca/. It is a whole world.
http://calccheck.mcmaster.ca/CalcCheckDoc/2DM3-2019_LongTheoremList.html#Propositional Logic
I tested it and it wasnt working with booleans
A better answer was already given
That actually is a great idea
you probably need a state machine here.
Just as additional information on XOR, the only reason I ever found to use it is for a toggle in a bitmask.
Anyone here good with blender python stuff?
I want to check if an object is the original or alt d duplicate. I have not found a way to read this out so far and I really really need to do this. If I can't do this I'll have to redo all the levels I make in blender inside of unity. If I can find how to differentiate the objects I can just name them .orig and .linked and then write a script in unity to replace the .linked with an instance of the original.
to put it in words and not code you want this ?
if this & not this then do this
elseif this & not this do this
end if
thats pretty easy to do in C#
??? whats the ^ for i never seen that
can you explain
yeah like this
XOR is a OR exclusive. See how in the following it respect the OR but exclude if there are the same. This is the same of !=.
A B Result
True | True | False
True | False | True
False | False | False
False | True | True
is that a newer feature of .net or has this existed for longer and im just now seeing this
This is older than computer science itself I think.
this is exactly what i need constantly, has it any drawbacks ? Like performance or other stuff
so isWalking && !isInAir
Bitwise operator that you most likely never use
I didn't even know it existed since it pretty much does the same thing as !=
i always did this
which essentially would be isWalking != isInAir
forgot that != exists for a moment there
even tho im using it in my code
Please, do not do if(a != true)...
infinite loop go brrrrrr
oh yeah you could still set a to true
int? connectingSocketID = manager.GetConnection(socket.ID);
if(connectingSocketID != null)
{
Socket connectingSocket = manager.GetSocketFromID(connectingSocketID);
}``` how does one convert a nullable int to an int?
idk where my brain is today sorry Simforce
.Value
Thank you 🙂
now that i think about it, why would you, you just do if(!a)
Probably but the thing is the above code was just an example of what I am trying to achieve, in actuallity my game is match 3 and I was trying to make something work out similar to this
I tried that but I found a better way now tbh
can I invoke or cancel a player input action via script instead of the keybinding?
As far as I know, there isn't a way to do so
There isn't even a way of changing input setting at runtime
What's the best way to think about items in a 2D game? Like the floating sprite items that can be picked up and dropped. They essentially all have the same behaviour, so it seems a bit overkill to make a script for each. But also I feel like it'd be overkill to have prefabs for them all too, I guess you could have it dynamically fetch the displayed sprite based on the item id?
yep - one prefab, one script, and perhaps a reference to a SO that identifies the object or just an enum or an id of some kind
what's a SO?
ScriptableObject
Also previously I was going down this rabbit hole, but realized it's way overkill
although I do want there to be 1 differentiator between items, those that enable actions (sword) vs those who don't (skull)
Make them child clases of item
That, however, wont allow you to use ScriptableObjects
Just a bool field on your SO
That too
well so it'd need to reference an action class type
this is WAAAAAAY overkill
make your game data driven, not code driven
it's working for me right now, there's a bit of context I haven't given
Is swinging an axe really that different from swinging a sword?
those are all things that can be described in data
for sure
this is my first major refactor, I'm down to refactor it to data driven later
just wanted to clean it up from the hacky state it was in before
although
how would I represent this as data?
using Pathfinding;
using UnityEngine;
public class MoveTo : Action
{
// A* pathfinding
public Vector2 target;
protected float nextWaypointDistance = .2f;
protected Path path;
protected int currentWaypoint = 0;
public Seeker seeker;
public MoveTo(string id, string name, string description) : base(id, name, description)
{
}
public MoveTo(Vector2 target) : base(System.Guid.NewGuid().ToString(), "MoveTo", "Move to a target location")
{
this.target = target;
}
public override bool CanExecute(Character character)
{
// TODO: Check if the target is reachable
return true;
}
public override void Execute(Character character)
{
seeker = character.GetComponent<Seeker>();
seeker.StartPath(character.transform.position, target, OnPathComplete);
}
public override void Update(Character character)
{
return;
}
public override void FixedUpdate(Character character)
{
if (currentWaypoint >= path.vectorPath.Count)
{
character.FinishAction();
return;
}
// Direction to the next waypoint
Vector2 direction = ((Vector2)path.vectorPath[currentWaypoint] - character.rb.position).normalized;
if (direction != Vector2.zero)
{
// Flip the sprite if necessary
character.Flip(direction.x);
// Play the walking animation
character.PlayAnimation("walking");
}
// Move the character
character.rb.MovePosition(character.rb.position + direction * character.Speed * Time.fixedDeltaTime);
// Distance to the next waypoint
float distance = Vector2.Distance(character.rb.position, path.vectorPath[currentWaypoint]);
if (distance < nextWaypointDistance)
{
currentWaypoint++;
}
}
public void OnPathComplete(Path p)
{
if (!p.error)
{
path = p;
}
}
public override void Cleanup(Character character)
{
return;
}
}```
since it has complex pathfinding logic in it, and it's nicely contained such that any character can use it
Hello, how can I rebind key on the Input Manager, because I search a tuto but I don't find anythings about the Input Manager ?
I don't understand what "data driven" means, but I think it means to tidy up data to store later on
There is nothing to store on a pathfinding algorithm
i guess that's my question, how do you make a SwingSword action data driven when there's custom logic associated with it "if sword hitbox hits type of entity, deal damage", "if axe hitbox hits type of tree, chop it"?
like you could abstract it to "if tool hits type of desired target, do logic", but u still gotta store that logic somewhere, right?
https://www.youtube.com/watch?v=2BfoxlF3OGY Havent fully seen it, but there is nothing much to know about the Input Manager
Welcome back! Today we'll be talking about the Input Manager in Unity, with this you can condense code and setup whatever control scheme you would like!
I also post updates on everything on Facebook and Twitter.
Facebook Page: http://www.facebook.com/pages/Frosty-Gaming/522714524447707
Twitter Feed: https://twitter.com/FrostyGamingLP
It doesn't tell me how I can change the keys.
Sure, but it may be useful to have the class of the axe include what kinds of trees it can chop, instead of having that data on a monobehaviour on the prefab you'll instantiate
look into input system and input actions, it lets you rebind keys to actions in the input actions object
I want to change Alt Negative/positive button by scirpt
Whats on swingaxe/sword etc then?
I think you can't access the input manager at runtime
Wondering if I could have help with a coding problem. This script should work with any TMPro.TextMeshProUI.text field, it just produces a string as a block of line entries that are timestamped internally and timeout:
using System.Collections.Generic;
using UnityEngine;
public class DebugConsole : MonoBehaviour
{
public static DebugConsole log = null;
public const int timeOut = 8;
private static SortedList<string, float> texts = new SortedList<string, float>();
private string textBlock;
void Awake()
{
if (log == null)
{
log = this;
}
}
private void Start()
{
textBlock = GetComponent<TMPro.TextMeshProUGUI>().text;
}
private void Update()
{
RemovePairIfTimedOut();
}
private void RemovePairIfTimedOut()
{
KeyValuePair<string, float> pairToRemove;
foreach (KeyValuePair<string, float> pairSearch in texts)
{
if (pairSearch.Value + timeOut < Time.time)
{
pairToRemove = pairSearch;
texts.Remove(pairToRemove.Key);
UpdateText();
return;
}
}
}
public void Text(string newText)
{
RemovePairIfDuplicate(newText);
float virtualTimeStamp = Time.time;
texts.Add(newText, virtualTimeStamp);
UpdateText();
}
private void UpdateText()
{
string fullText = "";
foreach (KeyValuePair<string, float> textLine in texts)
{
fullText += textLine.Key.ToString() + "\n";
}
textBlock = fullText;
}
private void RemovePairIfDuplicate(string newText)
{
KeyValuePair<string, float> pairToRemove;
if (texts.ContainsKey(newText))
{
foreach (KeyValuePair<string, float> pairSearch in texts)
{
string textFromPairSearch = pairSearch.Key.ToString();
if (newText == textFromPairSearch)
{
pairToRemove = pairSearch;
texts.Remove(pairToRemove.Key);
return;
}
}
}
}
}```
This code used to work, which is why I'm asking if anyone can run the code for me ❤️
You just use csharp DebugConsole.log.Text(string); to add a line
oh the error is I get no update to the UI text
"Data-Driven" or "Data-Oriented Programming" is actually an anti-pattern in most case as it create what we call an anemic domain. "Data-Driven" approach should only be taken when performance is crucial. Favorizing "Data-Oriented Programming" in all part could result in a hard to maintain game.
https://en.wikipedia.org/wiki/Anemic_domain_model
https://en.wikipedia.org/wiki/Data-oriented_design
IT WORKS. Guess what, it was a Unity error
The code works better than before, I've refined it many times hoping Unity would "catch on"
I had to delete the Component TMPro.TextMeshProUI it had became buggy
and reinstate it
What's the fast way of encrypting a string(for json saving)? I've tried this but it's extremely slow(99.918% time of saving was spent on encryption)
string EncryptDectrypt(string data)
{
string result = "";
for (int i = 0; i < data.Length; i++)
{
result += (char)(data[i] ^ key[i % key.Length]);
}
return (result);
}
string concatenation is going to be extremely slow and wasteful here
use StringBuilder or a character array
every time you do += an entirely new string is allocated and the old one thrown away
and the entire contents copied over
thank you, I used StringBuilder, now the saving takes only a few milliseconds and it used to be like 30 seconds
C# for you.
It's because C# strings are immutable
fullText += textLine.Key.ToString() + "\n";
that was in my code, I didn't think anything of it
the Vigenere cipher is not a very good choice for encryption..
but yes, you got hit by the Shlemiel the Painter problem
Shlemiel gets a job as a street painter, painting the dotted lines down the middle of the road. On the first day he takes a can of paint out to the road and finishes 300 yards of the road. “That’s pretty good!” says his boss, “you’re a fast worker!” and pays him a kopeck.
The next day Shlemiel only gets 150 yards done. “Well, that’s not nearly as good as yesterday, but you’re still a fast worker. 150 yards is respectable,” and pays him a kopeck.
The next day Shlemiel paints 30 yards of the road. “Only 30!” shouts his boss. “That’s unacceptable! On the first day you did ten times that much work! What’s going on?”
“I can’t help it,” says Shlemiel. “Every day I get farther and farther away from the paint can!”
Never heard that one, good analogy
O(n^2) in action
anyway I can instantly destroy this cipher by setting my character's name to "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
the Vigenere cipher, which is what you've implemented here, just gives you the key if you know the plaintext
I don't want to prevent players from changing save files, I just want a system that would scare away people who don't know anything about programming and who can change something without any knowledge and break their save file.
fair
my game is singleplayer so I don't care if anyone hacks in it
@wide pecan just save it in a different format so that they can't even open it
too much work, if a person knows how to decrypt it, then they probably know how to revert damage they can deal and know what they can change and what they mustn't change in the file
saving in a different format is the easiest thing you can do though
if they manually open it in text editor after that then they deserve whatever damage they did to themselves
We did just talk about it in Code-Beginner
main thing I realized was that you can subclass SOs and that SOs can reference other classes
A guy used the same video you did
hey everyone, I don't know if this channel is the right place to ask this, but i've been having issues with the pixel perfect dll and the artifacts folder in library. It's set to read only and even if I try to change it to writeable, it changes back. I've tried deleting the bee and library folder, but nothing works, and it's driving me crazy because I can't work on my project. I added a screenshot in case anyone knows what to do :')
how can I attach mono scripts to scriptable objects?
You mean put the script on it as if it were a GameObject?
no, i have logic that I'm trying to associate with Items
so for example I have a scriptable object representing a sword, and I want to attach the sword action to it
So you want to reference an instance of a MonoBehaviour
it's not a mono behaviour
using UnityEngine;
[CreateAssetMenu(fileName = "New Action Item", menuName = "Item/ActionItem")]
public class ActionItem : Item
{
public Action action;
}```
```csharp
public abstract class Action
{
public string Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public Action(string id, string name, string description)
{
Id = id;
Name = name;
Description = description;
}
public override string ToString()
{
return $"{Name} ({Id})";
}
public override bool Equals(object obj)
{
if (obj is Action)
{
Action action = (Action)obj;
return Id == action.Id;
}
return false;
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
public abstract bool CanExecute(Character character);
// Start the action
public abstract void Execute(Character character);
// Update loop for the character
public abstract void Update(Character character);
// Fixed update loop for the character - for physics, etc
public abstract void FixedUpdate(Character character);
public abstract void Cleanup(Character character);
}```
sorry, what I meant is neither are mono behaviours
(the functions that look like they are mono behaviors are being called when the character executes an action, the character is a mono behavior but the action isn't)
seems like you are reimplementing monobehaviors to me but ignoring that, you probably want:
MB in world which references an SO to represent your 'item' which references a list of other SOs, each representing actions that item affords
that's not quite what I'm doing. My character is a mono behavior, and my character class can do many different actions. The actions have functions where they essentially "take over" the character's functions in order to carry out the action, so let's say a PathfindTo action would take over fixed update to move the charcter to that location
In this case I'm trying to associate Actions to items, such that when a character picks up an Item, they can then implement the Action referenced by it
i realize it's a bit out of the ordinary, but I think it makes sense (?)
that's why i said 'ignoring that' 😛
It makes sense to me, I did something similiar recently
but instead you ignored my solution! so good on ya
Actions that can take over/override certain parts of the player
sorry i've been awake for 30 hours at this point 😰
Like Vault, Reload, Incapacitated, are all actions
With their own bodypart masks that determine if another action can be stacked or if the bodypart is already occupied by the action
Cant vault because incapacitated occupies your feet and arms
yeah, this is what my character's update/fixed update looks like
protected void Update()
{
Controller.ProcessInput();
if (CurrentAction == null)
{
if (ActionQueue.Count > 0)
{
ExecuteAction(ActionQueue.Dequeue());
}
else if (!IsRequestingAction)
{
StartCoroutine(GetActionQueueCoroutine());
}
}
if (CurrentAction != null)
{
CurrentAction.Update(this);
}
}
protected void FixedUpdate()
{
if (CurrentAction != null)
{
CurrentAction.FixedUpdate(this);
}
else
{
PlayAnimation("idle");
}
}```
but I mainly just don't understand what you mean by having a secondary list of SOs
ideally I just want
using UnityEngine;
[CreateAssetMenu(fileName = "New Action Item", menuName = "Item/ActionItem")]
public class ActionItem : Item
{
[SerializeField]
public Action action;
}```
so I can associate actions (mono scripts) with items easily
😮
wait
I can just put
public UnityEditor.MonoScript actionScript;```
?
you can reference the asset but i'm not sure how that helps you
you are thinking backwards
maybe
correct, my actions are not MBS
what you want to do is configure your items as SOs and your actions as SOs
then your item SO can reference the list of relevant action SOs
give them an Execute method and put logic in it
can I put all these functions in a SO?
your MBs should call out to your SOs to perform logic (well maybe they actually shouldn't because doing things this way can be not great, but you do you)
certainly
oh interesting
but you won't have a constructor
oh hmm
instead each instance would be an asset
your SOs are the instances that you can reference
i need to be able to edit it during runtime
you can do that with SOs, it just won't persist any changes magically
interesting
it's a pretty common pattern (though i always end up enumerating my actions anyway for various reasons)
right now my Actions are pure C# classes that my MBS Character script reaches into, so to do it properly I'd convert my Actions to SOs?
In this Unity tutorial we will look at how you can improve your workflow in Unity, avoid spaghetti code and tight coupling by using ScriptableObjects.
I've created a Scriptable Cookbook playlist that I will add all the videos I mentioned above to, along with any new videos I create in this series.
Here are the links to the resources mention...
which can then be referenced by my item SOs
you would define each action type as a subclass of your parent abstract SO action class
my only thing is I need to be able to alter parameters in them (like destination for a MoveTo action)
which is what I'm currently doing with my constructor
and then make an instance of that action as an SO asset and reference it
if your actions all have unique input it doesn't work as well
many of them have unique input
iirc you'd basically need to make an instance for each set of inputs
eh i guess not, you could have one instance and reuse it or something
i would interrogate what value you'd actually be getting from a system like this
it sounds really cool to be able to customize all your logic in the editor but in practice having your game be made up of poorly organized little assets composed together in ways that you forget is somewhat fraught
life is simple when you have an enum which maps to a function call or whatever
my actions aren't really a single function though, they hook onto the mono behavior of the player affecting the core lifecycle functions
yeah, i don't think it's a very good idea
you are tightly coupling all of your logic together into one blob
I don't see how that's the case?
I view this as a strategy pattern
where the Character can swap out strategies at run time depending on the action that they're doing
sure, it's just at such a high level of abstraction that it doesn't sound very useful to me
if you have a connection or something that you might make in a few ways, that is a constrained problem that you can implement a few strategies for and select from at runtime
if you have a video game where anything can do anything, your strategies cannot be reasonably constrained (which is why you implemented all of the MB methods again) and you end up with two layers doing the same thing
I'm not sure I see your point, I'm not going to include all the logic for all the actions in the character class?
that's ok, you may as well figure out what works for you instead of listening to me
If there are 30 something actions that seems like a lot of code in a single class
and a very messy update/fixed update function
i'm not sure how you got that from what i said
but that's ok, i'm not really helping so we can move on
alright I need help as I'm struggling a ton and all my solutions have failed. I have tried rounding my camera, I've tried offsetting by remainders(modulus), all my objects are snapped to the nearest "pixel"(based on PPU) but I believe it has more to do with my projection. Basically, I'm trying to do a "prerendered" background with a 3d scene, but I can't get my overlays and such to render on the same pixel coordinate as my backdrop. It's hard to see but you can see it in this gif, where for a single frame the background shifts a pixel off from the buildings:
as osmal said, you can certainly do what you're trying to but i would recommend at least thinking of your SOs as dependencies of your MBs and not the other way around
and my scene layout
ortho projection? are you using the built-in pixel perfect camera or doing that part yourself?
yes, ortho. All pixel cameras I have found are for 2d only
my actual scene is visually pixel perfect, I'm using this to determine the ortho size:
float size = ((Screen.height)/ (screenScale * PPU)) * 0.5f; and I'm using a shader to fix the projection of the sprites. But there is obviously some floating point issues with the backdrops when they unalign
luckily I think I can solve all the issues by adding one word. I went ahead and made my action class a subclass of ScriptableObject and I think that fixes it?
I can now attach the Action SOs to ItemSOs which get used by the Character MBS
that is one of the steps i suggested, which is making each action a subclass of your parent action type
now you can have an instance for each 'action'
luckily they already are 🙂
This would not be available at runtime.
good to know, thank you! went ahead and went a different way
and making that type extend from SO
yup
oh wait, but now I need to also create instances of all those SOs in the project structure

also need to figure out how to pass them starting params
I am not sure I follow everything, but making your action a scriptable object seem to be a huge pain in the ass due to the sheer amount of unique data.
that's why you would do a subclass for each type of action and then you can put the parameters on the action itself (but it sounds like you don't actually want to do that, since you want all your parameters to be injected at runtime)
well so that's the thing there are no two same actions, like the swinging axe action has different logic than the swinging sword because one needs to be able to interact with trees
and the Move and MoveTo actions will always have different values for their target
Which means, that scriptable object is NOT a good idea.
well I need to be able to assign actions to items which are SOs
i mean, it could be if 'interact with trees' is always the same
SOs would work ok as a list of affordances
it's just then you are basically using them as enums and need to map back to your actual logic (but that is fine and probably preferable)
that need is easy to meet in a bunch of ways though
my actions are a group of functions though, not a single function i can make to
map*
map to a class
like if you just imagine SOs don't exist, what would you do? you'd make an enum entry for each action and a class for each action and then in your SO you just make a list of enum values and at runtime you build your action classes based on the enum and whatever data you want to pass in
an item is just a list of ActionType (0,1,3,5) under the hood
you could even bitmask it if you wanted to get fancy
ok this is gonna take a second for my sleep deprived brain to process

whats nice about my character class right now is that it doesn't need to have any knowledge of the different type of actions available.
As long as it's a subclass of Action it can mount it, and run it
If you really want to use ScriptableObject, you can procedurally create your node and then add them under the same asset using UnityEditor.AssetDatabase.AddObjectToAsset. This is what we are doing with our solution. Ideally, we would switch to use [SerializeReference]. The reason we are doing this is because polymorphism was not possible before.
by introducing an enum to items, wouldn't that mean I would then need character to be aware of all actions to map from enum -> action?
oh i forgot about serializereference! you don't actually need odin then and can just do subclasses with unique data
but keep in mind that only works if at least the config data can be populated in-editor
not really, all you need is something somewhere which can convert an action type into an action instance
it wouldn't really make sense for that to live on the player imo
so some class that takes enum and returns back an instance of an action
i could see that
yep, and it might need references to the world so it can pull data into those actions, or maybe you pass the world in, or maybe each action has its own build method and you pattern match it, whatever you're into
at that point it can be a static function somewhere and life is simple
that's the last part I'm trying to figure out
although I'm wondering if I'm forcing a requirement I don't actually have
right now I can't think of any item based action that would have different variables in the same way Move or MoveTo would
it sounds like you are mostly concerned with your character right now
but eventually you will have a world where things affect each other
it's useful to be able to check stuff like 'is it nighttime?' so that you can have your Boots of the Nightwalker give +2 speed at night
in that way, you will eventually wish your actions had full context for everything
which is why a lot of these systems evolve (devolve?) into single function actions which are just
DoThing(Game game)
but how do they handle multi-part actions
where it's like "for every fixedupdate on character do X"
there is no such thing as a multipart action
just individual actions which are sequenced or executed sequentially
sure, but take pathfinding for example
it's a nice abstraction where right now I can do MoveTo(1, -2) and my character will move there no problem
because the move to action takes over the character fixed update function until the action is complete or something interrupts it
yeah, i would posit there is only no problem because your game is not complex enough for a 'set and forget' move command to cause problems
but it depends on the game for sure
this feels very bad to me
the reason I set it up like this is because a core part of this game is that NPCs and players share the same action set
and NPCs have a list of actions that are generated at runtime
your goals are all admirable
i just don't agree with your methods
but that doesn't mean they are wrong!
always down to improve it, this refactor was mainly meant to add some structure where it was all hardcoded before
another benefit of this system is that I can inhabit any character either by an AI or by a character because I abstract away the control loop
sometimes you just have a system that's designed to run at a fixed rate. Other times you need state magement, which can be done in a number of different ways: state machines/behavior trees/co-routines are just some examples of patterns that are designed to manage states
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
public class PlayerCharacterController : ICharacterController
{
public Vector2 direction;
public void ProcessInput()
{
float moveHorizontal = Input.GetAxisRaw("Horizontal");
float moveVertical = Input.GetAxisRaw("Vertical");
direction = new Vector2(moveHorizontal, moveVertical).normalized;
}
public Task<Queue<Action>> GetActionQueueAsync()
{
if (direction != Vector2.zero)
{
Queue<Action> actionQueue = new Queue<Action>();
actionQueue.Enqueue(new Move(direction));
return Task.FromResult(actionQueue);
}
return Task.FromResult(new Queue<Action>());
}
}```
this seems like the important part to me
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
public class AgentCharacterController : ICharacterController
{
public void ProcessInput()
{
// TODO: Get surrounding environment
}
public Task<Queue<Action>> GetActionQueueAsync()
{
Queue<Action> actionQueue = new Queue<Action>();
// Generate random MoveTO action for testing
actionQueue.Enqueue(new MoveTo(new Vector2(Random.Range(-10, 10), Random.Range(-10, 10))));
actionQueue.Enqueue(new SwingSword());
actionQueue.Enqueue(new MoveTo(new Vector2(Random.Range(-10, 10), Random.Range(-10, 10))));
actionQueue.Enqueue(new SwingPickaxe());
actionQueue.Enqueue(new MoveTo(new Vector2(Random.Range(-10, 10), Random.Range(-10, 10))));
actionQueue.Enqueue(new SwingHammer());
return Task.FromResult(actionQueue);
}
}```
and so by just checking a boolean on a character I can switch them from player control or AI npc
and that part works
you're basically re-inventing co-routines there
i thought co-routines run alongside in a parallel thread
they can, but usually they don't
coroutines, like everything (except the job system and explicit threading) in unity, run on the main thread
They never run on another thread, they're sequential and pause at every yield
oh TIL
When you start a coroutine, all code in it up to the first yield runs immediately. Then execution continues from the StartCoroutine() call, up until Unity decides it's time to continue running the coroutine up to the next yield, again an again until the end of the method
how can i add the string function in the void Awake class? So if i press 0 on my controller then he should tap the button on my ui
with a if function? if yes then how?
this is probably dumb, but right now I'm kind of thinking I keep items ("sword", "carrot", "log) as scriptable objects and they have an enum of an action.
Then when a character uses says item, it takes that enum and goes to an ActionFactory, to create an instance of said action, with the specific params that are appropriate
this then allows me to add the Action instance to my ActionQueue on the character for it to then carry out
sounds very reasonable
the only missing piece would be how to get any params from the item to the ActionFactory, so for example if I have a generic "Consume" action, I would need to be able to pass the health value that it would restore
so a carrot would only provide 5 health, a cake 10 or something
i just might advise you to build the action as late as possible so that eventually when you want it to have data from now instead of whenever you built those actions, you won't be sad
right, you don't really want to build the action until right before you execute it
why?
because that's when you can pass in the values it needs
i guess you could do it either way
i prefer the action to be something useful, but it could just be a handle which you call Execute() on and pass in the parameters
that's the part i'm still a little confused on
the action instance is supposed to have the data self contained
since character doesn't know what data to pass in
protected void Update()
{
Controller.ProcessInput();
if (CurrentAction == null)
{
if (ActionQueue.Count > 0)
{
ExecuteAction(ActionQueue.Dequeue());
}
else if (!IsRequestingAction)
{
StartCoroutine(GetActionQueueCoroutine());
}
}
if (CurrentAction != null)
{
CurrentAction.Update(this);
}
}```
it just calls execute
{
CurrentAction = action;
action.Execute(this);
}```
and passes itself
yeah i think you want your actions to be like this:
public class DoDamage {
public int Damage { get; }
public DoDamage(int damage) {
Damage = damage;
}
public void Execute(World worldInput) {
// do the damage
}
}
but then I wouldn't be able to represent animation actions for example
you don't actually need to pass anything to execute, depending on how your state is managed
no, that's where you're trying to reinvent coroutines
where I not only need to start the sword swing, but then handle the animation event that applies damage, and then the animation event that resets state
yeah, because unity wants you couple all those things together but it's a pain in the ass
your action should be 'start attack' and some other system should handle the attack/animation logic
that seems messy though?
using UnityEngine;
public class SwingSword : AnimationAction
{
public SwingSword() : base(System.Guid.NewGuid().ToString(), "SwingSword", "Swing sword")
{
}
public SwingSword(string id, string name, string description) : base(id, name, description)
{
}
public override bool CanExecute(Character character)
{
return true;
}
public override void Execute(Character character)
{
// Play animation
character.PlayAnimation("attack");
}
public override void Update(Character character)
{
return;
}
public override void FixedUpdate(Character character)
{
return;
}
public override void TriggerEffect(Character character)
{
// Create hitbox in front of character on certain frame
Debug.Log("Sword damage would apply now");
// Check if hitbox collides with enemy
// If so deal damage
}
public override void Cleanup(Character character)
{
character.PlayAnimation("idle");
}
}```
here I can just have it all in one class
is 'having it all in one class' the goal?
all the logic for an action being in one class seems to make sense to me
it's all messy because unity's way of doing things, with update methods and all your logic living within each object being executed every frame, is silly
you are not subverting that, so you are ending up with all the same silliness plus whatever else you're doing
what you really want to do is get out from under unity...stop thinking in terms of update and fixedupdate at all
well maybe? if you think it's easier to manage then that's cool
Is there a way to instantiate temporary prefabs in the editor, so they are not saved in the build?
Give them the EditorOnly tag
the goal is to have a visual indicator of the prefabs for the other members of the team, but they will only be loaded at runtime
public void Fire(int dmg, string shooterTag)
{
this.dmg = dmg;
this.shooterTag = shooterTag;
rb.velocity = transform.right * speed;
}
Is there a way to add like 1 line here to make the rb rotate by 15 at a time on the Z axis?
Hey, I have a component called "IsHittable" which I want to use to control what happens when a certain object is hit. I want the hittable component to reference a function to be called with a parameter when the object is hit, and to be able to set that function in the editor.
or do I need to add in a fixedUpdate function that does that?
honestly this whole system would work for me if I could just bridge the gap between items and actions because everything else "works"
Is that something I can do? UnityEvents are pretty close but I'm struggling with the parameter part
You can use a generic UnityEvent for that. UnityEvent<T>
Do note that not all parameter types are supported with this. Simple ones like numbers, strings, GameObjects, components are OK
oh sorry, i thought it does work, right? just not in your cases where you need sequencing and per-frame execution?
actions work yes
oh nice, SPR2 and praetor are on...if its possible to do in 1 line outside of update/fixedupdate Im sure one of the 2 know 😄
even the sequencing and per frame stuff works
horay we did it
i didn't change anything 
Change its .angularVelocity
It'll slow down over time if you have angular drag
but I'm trying to flesh out the inventory and Item system, and so that a player can pick up an item and then when they right click on it, it carries out the associated action, either swing sword, dig hole, eat food, etc
awesome thanks
wasn't sure if angular velocity would make it just constantly rotate or not 😄
Just like linear velocity
What if I want for example my own struct of data?
I don't think it'll be able to serialize that.
Well I mostly want to be able to invoke it from code
but I want to be able to pick the function from editor
try it and see -- if you mark it serializable and it is, maybe it'll work
So for example a human character would have the "IsHittable" component connected to their "TakeDamage" function
Try it
In my case using UnityEvent<int> also does not show it in editor, for some reason, so
hard to try with a struct
Maybe it'll expose it as a "dynamic parameter", you won't be able to edit it from the Inspector but you'll be able to invoke it from the code and pass it there
well the inspector doesn't serialize generics
IIRC you need to derive a concrete subclass
public class IntEvent : UnityEvent<int> {
}
then use that
or the same with your struct
public void Fire(int dmg, string shooterTag)
{
this.dmg = dmg;
this.shooterTag = shooterTag;
rb.velocity = transform.right * speed;
rb.angularVelocity = 10;
}
the Z rotation value is staying constant at -1 (am wanting it to slow increase or decrease) am I doing something wrong here?
I have this
[System.Serializable]
public class ObjectHitEvent : UnityEvent<int> { }
in the IsHittable file
That... doesn't compile?
It's a vector
you could also flip this around and have whatever is your TakeDamage component search itself for a sibling IsHittable component and if it finds one, set its Damage method as the event handler for that Hittable component
And then I would like it to connect to void TargetHit(int test)
in a different file
This is true I could do this
doesn't seem to want a vector
Hm oh, you need AddTorque() then
that would make more sense if you always want something with both components to be damagable and don't want to have to remember to set it in the inspector
😄
It works like AddForce
we're all dumb but some of us read error messages and that makes up for it 😛
2d rigidbody takes a float for addtorque
was gunna be my next Q thanks lol
Because it only rotates around z axis
It's probably better anyway, maybe I want the object to turn its hittable on or off
Ah that's 2D, couldn't see that from screenshots
So setting .angularVelocity works fine then
Degrees per second is the unit, I think
@simple egret it doesn't continually change though?
it gets stuck at -1
Yeah that applies it once
If you need it to slow down over time, then add angular drag to the RB
I mean
I want it to continually spin...aka 1 to start, then say, 100 in a second
etc
Continuous spin is "as long as it spins", so to me setting the angular velocity produces a continuous spin
If you want it to accelerate that's another issue
just want it to constantly spin
atm it doesn't spin at all
it changes the Z rotation to the -1...and then it never changes
thus...not continuous spin
show your code.
@heady iris
fire is executed once when object spawns
The RB might be rotation-locked on Z, also
okay, that should be rotating at 10 degrees per second
that would do it thanks
ah, yes
audioSource.time is changed when I move volumeSlider with my mouse
volumeSlider.onValueChanged.AddListener(_ =>
{
audioSource.volume = volumeSlider.value / 100f;
ChangeVolumeInputText();
});
well, what does ChangeVolumeInputText do?
void ChangeVolumeInputText() => volumeInput.text = volumeSlider.value.ToString();
yes
is this a question, an observation, what?
that's my issue should be fixed I guess ??
should I send the whole code then?
