#archived-code-general
1 messages · Page 396 of 1
Hey does anyone have a good resource to change geometry in unity gui?
AddComponent will cause Awake to run immediately.
yes, addcomponent will call awake
why not just have a backing field and set that directly
or just use awake
(why are they serialized anyways if you're gonna assign them)
Note that there is nothing stopping you from giving your objects a constructor. It's just that this can result in unexpected behavior
For example, Unity applies serialized properties after the constructor runs, so it'll stomp on any values you store in your serialized fields
your conscience
I wouldnt worry about that attribute, I'm only using the inspector to let me get a look at the various properties
we already had a very long discussion about this, yes
I still dont see the inspector as being useful for much more than doing some basic debugging
The inspector is primarily used for configuring objects. It isn't a particularly good debugging tool.
not for me at least, I understand the purpose and utility of the inspector
the entire point of the inspector is to configure objects
any configuration I'm doing, largely is going to be done via code
You can do whatever you'd like, just pointing out what the inspector is intended for, and what it does best.
For example: my Entity class references a list of "perspectives", which are ways you can view the entity when possessing or observing it
(entity index is debug information 🤫 )
My code does not expect a specific set of perspectives. That would be very silly.
I create as many as I need and then put them in the list.
My HumanoidLocomotion class has fields for things like the footstep audio sources and the foot transforms. It would not make any sense to try to populate these fields via code: this is configured per-entity.
What does this mean?
And what do you mean with Unity gui
maybe once the garden tool is fleshed out, I'll do more with the inspector
Unity UI system?
change geometry in what way
i want to achieve something like this
Unity has a few ui systems, i assume you mean the component based system?
timer
sorry i didnt see that channel before
this channel is for code. And wdym, you asked there first
no i asked here first
well it's a UI question.
Anyone know why this for loop isn't working? It works when I do it once, but once I stick it in a for loop to do 5 times, it doesn't instantiate anything...
for (int i = 0; i < 5; i++)
{
currentSpread = Mathf.Lerp(0.0f, GameManager.instance.levelManager.currWaterPistol.attributes.maxSpreadAngle,
GameManager.instance.levelManager.currWaterPistol.attributes.accuracy /
GameManager.instance.levelManager.currWaterPistol.attributes.timeToMaxSpread);
fireRoation = Quaternion.RotateTowards(fireRoation, Random.rotation, Random.Range(0.0f, currentSpread));
GameObject tempProjectiles = Instantiate(GameManager.instance.levelManager.projectile, GameManager.instance.levelManager.projectileSpawn.transform.position,
fireRoation);
tempProjectiles.GetComponent<StraightProjectile>().hitPoint = hit.point;
}
How do you know it's not working? I see no debugging in your code
Debug.Log
check your console
My guess - it's doing exactly what you told it to do and the projectiles are probably colliding with each other and destroying themselves immediately
but - start learning to debug your code.
I have been debugging... I deleted lines so I didn't post too much in Discord.
If the code is too long, then use a paste site
if you debugged you should explain what debugging steps you took and the result of those steps
It should be trivial to confirm your loop is indeed running 5 times as well as Instantiate
Don't show us something different from what you were actually running
This can conceal problems, notably..
Is levelManager.projectile a prefab?
Is there a way in Unity to create a script that prevents specific tilemaps from being editable in the Tile Palette window? For example, I want to make sure that TerrainDisplay can only be updated via a script based on TerrainData, and avoid accidentally editing it manually.
Perhaps you can instantiate the display at runtime so that it doesn't even exist in the scene?
That might be inconvenient.
I've thought about similar things (notably, making it so that i can only select certain tile palettes for each tilemap)
Alterantively, you could nuke the tilemap's contents during startup
so that even if you put some garbage in it, the tilemap is cleaned up
Thanks for the answer. Ideally, I’d like the display tilemap to remain in the scene even when the game is paused, so I can see my changes in real time as I update TerrainData.
I’ve managed to write a script that prevents me from editing the tilemap, but it only works if the tilemap is selected in the hierarchy.
That said, I think the best approach might be to set it up so that hitting play (or perhaps using a custom editor script with a button) triggers the display tilemap to update by reading from the data tilemap. I was hoping there is another way but yeah.
i a getting arhument exception erro?
what is wrong?
I assigned everything properly in inspector
what is the actual error and on what line
ArgumentException: GetComponent requires that the requested component 'Image' derives from MonoBehaviour or Component or is an interface.
line where i getcomponent image
can we not getcomponent Image
So you have a non Unity class called Image
I want To assign sprite of an Image in my canvas , randomly from an array of srptes
how do i do that
this method doesnt work
you first need to fix the problem of the Image class
no it is not, hover over the word Image in your code and see what it says
what does it say exactly
not a unity component
does it not show you a namespace for the class?
remove the UIElements namespace, that is the incorrect one. you want UnityEngine.UI.Image
so you are using UIElements.Image and you need UI.Image
It really helps when you read the full messages
my joystick in my game is not working. im using almost all joystick packages and when using the joystick it works perfectly fine in editor (and in simulation) but on my real phone it doesnt work
What do you mean by "I'm using almost all joystick packages"?
What kind of joystick are we talking about here? Where's the code?
Hey,
I have a school project where I want to create a school platform for schools in VR. I want to create a kind of meta menu where the school loads their website as a home menu via unity webview. I am trying something with chatgpt and google but it aint working out. I saw this video: https://www.youtube.com/watch?v=q3swlSP1mRg&t=4s but i can not find the sample or something. Would someone like to help?
this joystick works in all of my other projects
and my other projects were unity 6 aswell
so im not sure why touch isnt being registered
Not sure, I would recommend using the Input System's built in on screen controls instead probably.
If this asset isn't working you should ask the publisher for help
hm alr alr
but also i just checked the example scene in the project, the joystick works fine there for some reason so it might be something in my scene blocking the joystick or idk
and i've tried making it as close to the original as possible
It certainly can be something in your scene and probably is
Maybe another UI element or canvas
doesn't seem to be???
except for the note
but the joystick should be overlayed on top
i do
im using old input system btw
is there a prefab or demo in there where the joystick positions itself at the first touch.. and will reposition after a release and second touch?
dynamic joystick? idk the terminology for it
yeah i think its that
sorry i didnt message before but i figured it out: i had two joysticks in the scene
and for some reason i cant use two at the same time 😔
probably b/c its a bit more logic.. have to take into account if theres already one going.. and then another one for the (2nd touch)..
multitouch joysticks
wonder how i can do multi touch
the asset i showed in the video is actually this asset ^ i believe
it doesn't say it specifically in the details tho.. (just tagged).. and i cant remmeber all the demo's they had
Hi, I'm running into a deltaTime-based issue with a function that pulls the characters downwards with increasing velocity when falling.
I'm calling AddGravity in Update. It reads the player's velocity (rb.velocity is saved to CurrentVelocity) and I add an additional gravity force to it. Here's the relevant code snippets.
https://paste.ofcode.org/iXKKHGLQWHUJqsCCSSdBnp
I realised that this extra gravity performed differently with different frame rates. The video shows the same jump performed on two different refresh rates (around 120 and 200+) and one character clearly lands quicker than another. Printing out CurrentVelocity over time confirmed that the 160 refresh rate character had a slightly higher velocity by the time they landed on the ground.
I'm fairly confident the issue I'm encountering is explained in this video https://youtu.be/yGhfUcPjXuE?t=502. A linear increase in velocity over frames. And the solution is to calculate the new speed by multiplying by deltaTime and then use deltaTime again when changing transform.position.
This issue is, I'm working directly with velocities here, not positions. So I'm not quite sure how I would carry over this principle to my code. Anyone have any ideas?
Well i dont think it works or there isnt a clear explanation to turn it on
gonna have to home-brew it
You would do half of your accelerate before setting the rigidbody's velocity and half after setting the velocity
But the difference you're seeing is huge
Or maybe I skipped ahead too far
I went ahead to the part where they add half of the acceleration before moving and half of it after
at around 11:56
The difference here is huge. I wouldn't expect to see that much of a change
When do you actually call AddGravity?
my characters run on an FSM. in the air state, I have this line in my update method
if ((_character.isJumping && jumpInputCancel) || (_Movement.CurrentVelocity.y < _characterData.gravityKickInVel))//character.Movement?
{
_character.AddGravity();
}
Are you falling slower at higher framerates?
faster
adding forces to a rigidbodies should be done in FixedUpdate()
this is directly setting the velocity, not applying forces
movementvector is just a vector2 that stores the velocity from MoveX and MoveY
ah, I'd never seen the Set method before
I don't see anything here that'd make you fall much faster
you think there's something other than the frame rate at work?
Does anything else modify the MovementVector?
ooh shit oopsie. the video i posted isn't a regular jump. its a movement ability with both an X and Y component. completely my fault for misreading the clip i posted.
the core idea is the same though.
I call this function to launch the player in a specific direction, and then the gravity stuff kicks in as i described
{
MovementVector.Set(angle.x * facingDirection, angle.y);
SetFinalVelocity();
}```
the added movement in the x direction here could account for why the discrepancy between the two frame rates is so drastic but i think the underlying cause (the AddGravity method) is the same
here's a video of both of us doing the same ability but without that gravity line. you can see it lines up pretty much exactly
okey. sorry if its a little messy/unreadable. haven't got around to making it look good yet hehe
is there a preferred method for pasting entire scripts here
!code
📃 Large Code Blocks
Use links to services like:
https://gdl.space/, https://paste.ofcode.org/, https://hatebin.com/, https://paste.myst.rs/, https://hastebin.com/
📃 Inline Code
Surround code with three backquotes. Not quotation marks.
To format as C#, add cs to the first line:
```cs
// Your code here
```
Add a comment with a line number if there is an error message.
❤️
Character GO script (contains the AddGravity method) - https://paste.ofcode.org/6r2xueYXeMPMp2AxXdaXPT
Slingshot State script (the ability in the video) - https://paste.ofcode.org/cJHLTwWZQUQZwpEbcHGbgC
Movement script (contains MoveX, MoveY, MoveXY) - https://paste.ofcode.org/m78ctzibtqQ7MS3zznzag9
i can post anything else you need but that should give a good overview of whats happening
Hi! If i understand correctly if i need a class to call a method from another class its better to use a service locator, while if many class need to fire the same method of another class is better to use events? Can anyone enlight me on this? (avoid Dependency injection in this case)
No - this distinction has nothing to do with the numbers in the relationship (n-n, 1-n, n-1)
Events reverse the dependency
If A has a reference to B and wants to call a function on B, we could reverse that dependency such that:
B has a reference to A, so B listens to an event on A in order to invoke the function on B
This means A doesn't need a reference to B
Instead B has a reference to A
That's the only thing events do really
so can you explain me better the difference between the service locator and an event bus? they could act in the same exact way no?
so if i have an event bus, its not bad to use it just to call a method (one subscriber)
i mean its not bad to use it in this way
A service locator helps you find the service to call a function on.
The event pattern would reverse the dependency.
Let's use an example of a player with HP and a health bar UI element.
The player object could use a service locator to find the health ui handling object and call UpdateHealthBar() when the health changes to change the UI.
Alternatively, the player object could publish a "MyHealthChanged" event into an event bus.
The health UI can listen to that event and update itself. This way it's the health UI depending on the event it's listening to rather than the player object depending on the health ui existing.
it's fine to have one subscriber, zero subscribers, or many
The beauty of an event based system is that the publisher of the event doesn't know and doesn't care how many listeners there are
it's fire and forget
all clear! thank you so much even tho i have one more question
Is there any way to return multiple items in a function (I'm trying to return a boolean and a list)?
ive made my own static event bus system which will fire any events given the event type. only problem is that the methods that describe events can't return anything (so void methods).. is it good to have callback that do so?
the structure is this
struct MyEvent : IEvent {
public int value;
public Action callback;
}
then i can subscribe doing
public class MyClass : MonoBehaviour {
private void Awake {
EventBus<MyEvent>.Subscribe(MyEventMethod);
}
private void MyEventMethod(MyEvent evt){
//do something
evt.callback?.Invoke();
}
}
You can eeither:
- use
outparameters to return extra things - return a class or a struct containing multiple items
- return a tuple
For example Physics.Raycast returns a bool indicating if there was a hit or not, and returns a RaycastHit struct as an out parameter
im not using the unity events but i implemented my own thats why
sweet, I'll look into these. May I ask what a tuple would be as I never used one
oh nevermind, I just found the documentation for it
This seems backwards to me? Or weird? Maybe I'm missing something? I would expect basically:
struct MyEvent {
int some;
bool random;
float data;
}
public class Publisher {
void PublishEvent() {
MyEvent e = new MyEvent();
e.data = 4;
EventBus.PublishEvent(e);
}
}
public class Listener {
void Awake() {
EventBus.Subscribe<MyEvent>(MyEventHandler);
}
void MyEventHandler(MyEvent eventData) {
print("Received event with data!: " + eventData.data;
}
}```
It's weirtd to me that the listener function would receive the delegate and then.. be able to invoke it... again?
Maybe I misunderstood your example
oh i forgot one piece!
ill copy your to be faster. So the problem is when i want to do something like
if(intValue > GetIntValueFromAnotherClass())
what im doing is this in the publisher
struct MyEvent {
int intValue;
Action callback;
}
public class Publisher {
void PublishEvent() {
MyEvent e = new MyEvent();
e.intValue = 4;
e.callback = DoSomething();
EventBus.PublishEvent(e);
}
void DoSomething(){
}
}
public class Listener {
int listenerIntValue = 0;
void Awake() {
EventBus.Subscribe<MyEvent>(MyEventHandler);
}
void MyEventHandler(MyEvent eventData) {
if(eventData.intValue > listenerIntValue){
eventData.callback?.Invoke();
} else {
Debug.Log("Its not greater!")
}
}
}```
Is it more clear?
not really - i'm not sure what the callback is for
why would the publisher provide a callback for the listener
And why not just ahve the publisher do this:
EventBus.PublishEvent(e);
DoSomething();```
if(intValue > GetIntValueFromAnotherClass())
how can i handle that case
Ok I guess you're now talking about having the publisher retrieve a value from a listener
yes yes
which is usually not something you do in event-based architecture
usually events are "fire and forget"
That's sort of against the event pattern
and we don't care who is listening
mostly because then what happens if you have multiple listeners?
Which one would we retrieve the return value from?
or zero listeners
yeah so im lost T_T thats why ive put a callback in there
i have instantiated object that need to check for example onclick if i have enough "stamina" to click. Since i dont wanna make a singleton for everything and the stamina is stored in its own manager i was calling an event to do so
I would have the stamina button listen to an event from the player object or stamina manager that fires whenever stamina changes
if thats true than this instantiated object has to do something
and have itself turn on and off in response
so the object has a int value that tells how much stamina it would consume. I need to give this value to the manager check if i have enough stamina and then tell to the object "ok you can proceed"
class SprintButton : MonoBehaviour {
EventBus.Subscribe<StaminaChangedEvent>(StaminaChangedHandler);
}
void StaminaChangedHandler(StaminaChangedEvent evt) {
myButton.interactable = evt.newStaminaValue > 5;
}```
but when the event is fired i have already clicked on the object
Why would it be
why not just make the button unclickable before hand, based on when the stamina changes
Also I guess you're just really trying to avoid the button having a reference to the stamina manager?
Why can't we just do if (StaminaManager.Instance.CurrentStamina > 5)?
or if (StaminaManager.Instance.TryConsumeStamina(5))
because its not only one button, lets say its a stamina system for those idle games. there are many of these objects and everyone has its own stamina consuming value. Since you get stamina every x minutes i should enable buttons every time?
yeah i was trying to avoid singleton patterns. i have already few and im refactoring all my code for more readability
the buttons listen for the stamina change events and enable/disable themselves when there is enough stamina or not, sure
Isn't the event bus itself a singleton?
its a static class
But if you really don't want to do StaminaManager.instance you can keep local copies of the stamina level in each of these things
you can subscribe unsubscribe and raise from everywhere
then i need to update them anyway when you gain stamina
so the disable enable is the best thing
class SprintButton : MonoBehaviour {
int energy;
void OnEnable() {
EventBus.Subscribe<EnergyChangeEvent>(EnergyChangedHandler);
}
void EnergyChangedHandler(EnergyChangeEvent evt) {
energy = evt.newEner;
// Check whether to enable or disable whatever button(s)
}
void OnButtonClick() {
if (energy > 5) Consume();
}
im sorry lets not call it stamina, but energy or idk clicks. Stamina can give different ideas
sure it doesn't make much difference
anyway yes i should do this in the object class, and every time energy gets changed in the manager i raise the event
it was really this simple
tysm
one last question! would be bad performance-wise to call an event in the update function every frame, or in a coroutine or whatever?
generally fine
im still stubborn about one thing. I have another use case for this example.
Lets say i have my grid inventory. I have an itemobject that store its quantities and the item can be 1x1 1x2 or whatever. every time i click it i need to check if the inventory is full. if its not i decrease the quantity of the item.
You might say "have the item listen to the inventory to know when its full" but if the item has different sizes what do i do
or maybe i let the inventorymanager to store all the items (and their quantity) and just raise the event to check and decrease?
it make sense, why the item should know its quantity. The manager does that! (no?)
How can I make my regular animations override animation rigging animations
As in override the constraints?
I think you probably just need to write a function that checks each cell and sees if it’s a valid space or not
i have but i dont have the reference to the inventory manager if the item is instantiated at runtime (a prefab)
This sounds like logic that should be handled by the inventory manager entirely. The UI could invoke an event ItemClicked(Item), that the inventory listens to(potentially via a proxy, like inventory ui). The inventory then checks the inventory contents and whether it can add the item or not. If it can, it adds, otherwise it doesn't do anything.
If you need to play some kind of effect depending on whether the item was added or not, the inventory ui could be having an actual reference to the inventory instance and call an actual method that returns true/false. Then it could play the desired effect, or call some method on other ui/invoke a method.
Also, it's very easy to get a reference at runtime. There are many ways to do it.
yes i wanted to avoid that since i instantiate not many but not few objects at runtime and everyone should have a reference
There are very cheap(virtually free) ways to get a reference. But yeah, design wise it wouldn't be great. The other suggestions I gave still stand though.
so do you think the inventorymanager should update the itemdata? so holding all the reference of all the items
thats what you suggest?
Inventory instance. Inventory manager sounds like something that would manage all the inventories in the game.
Though, if you only have one, it might be fine.
yes the inventorymanager for now holds one inventoryinstance
Then yes. Inventory manages the items in it. It logically makes sense.
So I can't just subscribe for InputAction being performed in Awake:
void Awake() {
Action1.action.performed += _ => SwitchToNextCharacter();
}
And let C# unsubscribe on when the my PlayerInput component and Action1 objects are destroyed?
After I restart the scene with Application.LoadLevel(0);, I get null object reference errors in the console when I perform actions. And so I solved it by creating a function and subscribing on Awake and then unsubscribing on OnDestroy:
void Awake() {
Action1.action.performed += Action1_performed;
}
void Action1_performed(InputAction.CallbackContext obj) {
SwitchToNextCharacter();
}
void OnDestroy() {
Action1.action.performed -= Action1_performed;
}
It works but now I'm forced to use named functions, because I can't do Action1.action.performed = null on destroy to make all handlers unsubscribe. Is there a way to simplify this: use lambdas instead of having to create named functions and maybe reinitialize the InputAction or InputActionReference, so I don' have to manually unsubscribe each even handler myself?
is there a dedicated channel for in app purchase?
right now i have this weird problem where Unity
UnityPurchasing.Initialize(this, builder);
gives me no callback
like failure/success nothing
im trying to do it for an unreleased android game
i've already added the RSA public key in the unity dashboard and it shows up in my editor
You can't use lambdas because a lambda in your unsubscribe function does not use the same reference as the one you subscribed to
Whatever the case, you will have to store your lambda somewhere. Either a named method or a delegate will do.
And regardless it should be done anyway because it's more readable.
Weeeeeeeell, RAII is better, because it works even when exception is thrown
And less code, too
hi lets say i have a class lobber which inherits from base Bullet
if i call -> this.destroy in Bullet class , will the lobber also be deleted?
The problem is also that we need to unsubscribe each event handler separately instead of just doing Action1.action.performed = null but we can't do it, that property doesn't have set defined.
And there's a callback array as a backing property. Would be better if we could just reset the InputAction instead of manually unsubscribing and if it did it itself when the object is destroyed.
Would it be possible to define a list of delegates which are subscribed and then unsubscribed?
Yes. In inheritance it's the same thing. There is no 2 objects.
ok thanks
i'd rather have it like that to be honest, it's better that you can only remove events you know you subscribed rather than it being possible for the whole array to be cleared from anywhere in the code
it's a little more inconvenient if you're only using it in one place, but it's worth it for cases where you might have multiple listeners being added and removed in various places
any idea about the in app bug :P?
You mean something like this:
List<Action<InputAction.CallbackContext>> Action1Listeners = new();
void Awake() {
Subscribe(Action1, Action1_performed, Action1Listeners);
}
void OnDestroy() {
Unsubscribe(Action1, Action1Listeners);
}
void Subscribe(InputActionReference InputActionReference, Action<InputAction.CallbackContext> ActionListener, List<Action<InputAction.CallbackContext>> ActionListeners) {
ActionListeners.Add(ActionListener);
InputActionReference.action.performed += ActionListener;
}
void Unsubscribe(InputActionReference InputActionReference, List<Action<InputAction.CallbackContext>> ActionListeners) {
foreach(var Listener in ActionListeners) {
Action1.action.performed -= Listener;
}
}
It works but
I already wrote my own Action and Axis abstractions, so that I can accept inputs in a character from different sources: PlayerInput or AI
Because the default InputAction only allows to accept inputs from physical devices
At this point it my PlayerInput component start to look a lot like what InputAction does
But not tied to physical devices and ability to take inputs from anything
For the "auto unsubscribing on destroy" there are approaches, but imo they are only worth it if you go all in for your entire project.
That usually is a bit too much of a commitment (but it works really when if you really do commit to it), so in generally I suggest to just use a method and remember to unsubscribe manually.
LGTM
I'd look into just manually making delegates then if I were you
You won't need to make whole methods and instead use the delegates. Just make sure to put them on class scope so you can use them properly
There's probably an automated way using weak references but at a certain point you should wonder if adding functionality like this is really going to improve anything
Weak references wouldn't work for automatic unsubscription.
A weak reference that triggers unsubscription on allocation is perfectly possible and there are .NET classes that use this system as a handle to finalize classes that were not disposed
But like I said, at some point you should wonder if adding a system like this would really benefit an application considering the code involved
Especially since this is not a case of possible forgetting to dispose and more a case of convenience
It wouldn't work for automatic unsubscription, a weak reference only guarantees that the referenced object can still be GC collected, but GC is not deterministic.
When a GO/component gets destroyed, GC doesn't immediately collect it so the weak reference will possibly linger for much longer depending on the mood of GC, and until it gets collected the weak reference is still valid and the action will still get called.
Weak reference data structures are memory optimization techniques.
Yeah. Definitely. I just want to have a nice system for gathering player input and then passing it to the controlled objects.
At first, I thought I can put those InputActionReference and InputAction objects directly on my Character component, so that it could be controlled by the physical devices and then by AI and network controllers. But, apparently, I can't, InpuAction can only take inputs from physical devices.
So I created my own abstractions for Action and Axis and I take that on the Character and I pass it to the Character from my PlayerInput component.
It feels like I'm working around and against Unity's framework and not with it.
I'm not sure how well the add/remove operators on event properties work, but perhaps you can somehow fiddle with that and get a unique reference to lambda's that way. Unity also has an event system that (I believe) uses listeners and a way to remove all listeners at once, so maybe you can also use that
Addlistener/RemoveAllListeners
Lambda is reference type, you just need to hold onto a reference to it to unsubscribe.
Notice how in the case of UnityEvent, it basically tries to do the same thing I explain, where it basically provides its own system https://github.com/Unity-Technologies/UnityCsReference/blob/master/Runtime/Export/UnityEvent/UnityEvent.cs
And when removing the listeners, it can simply clear the list
Also, note you can make a delegate variable yourself and attach multiple methods on it. You don't necessarily need to use events and it might be a lot cleaner if you attach multiple methods on a delegate when working internally
I do not see how this works, this does not prevent the case of observer is "destroyed" but it is not yet GC collected, and the subscribed handler is still being called. Remember that WeakReference.Target is alive for as long until GC collects the referenced object.
does anyone know how getcomponent works internally ?
like i had a doubt if a game object has a script with class A which extends from B
will I will be able to use Getcomponent< base class> , even though its not directly atttached to the object
so due to mysterious reasons, my layout element cant work, like it doesnt do ANYTHING at all, so i might need to make my own script that simulates what it gonna do
so i gonna start with : how do u get the line count of a text
I dont think anybody knows the functionality of GetComponent because it goes into an internal Unity call (c++ code) quite quickly.
But GetComponent should work fine with base classes
With generic types, at least.
Another question guys, how to setup 2 player input systems using the same physical device? Specifically, keyboard.
Am I going to have to define Player1 and Player1 InputActionReferences?
So I'll have to have double the actions for each action: for player1 and player2?
oh damn
ok
Example: left player uses WASD for movement and YGHJ for actions. Player 2 uses arrow keys and numpad keys.
How do I set this up using this input system?
What have you tried so far?
Nothing, I can only see doing it by duplicating actions in the input actions list. That's why I'm asking: maybe there is a better way of doing it by reusing the current input actions asset and input actions.
That's what I'm going to do if there is no other way, I just thought somebody would know a better way.
Yes you will be OK as long as class B (the base class) derives from Monobehaviour
This is what Resharper decompiles it to:
[SecuritySafeCritical]
public unsafe T GetComponent<T>()
{
CastHelper<T> castHelper = new CastHelper<T>();
this.GetComponentFastPath(typeof (T), new IntPtr((void*) &castHelper.onePointerFurtherThanT));
return castHelper.t;
}
When I jumped to the definition, Resharper downloaded the .pdb and then decompiled the class.
Ah that old issue - I think it is a weakness in C# that delegates lead to classes not being garbage collected - you do indeed need to remember to manually unhook. Would like to see an automatic system - which is why MS invented weak references for .Net I guess
Are those weak references usable in Unity?
No that's not really what weak references is meant for. Weak references allow you to hook into GC, but an object being GC collected =/= it being "destroyed" because fundamentally the latter is a user defined concept.
That would require management that has performance overhead which is not a cost most people want to pay. If you want this kind of management you can use unity events.
As for Unity, I think there are some issues with weak references when you build with IL2Cpp, not sure about Mono.
But either way, weak reference is not a solution for automatic unsubscription.
Can the One shot audio gameObjects that are created by AudioSource.PlayClipAtPosition() be pooled? I've trouble to get them into an object pool
Is there a way to increase the padding of FindIntersectingWord?
It works fine on PC, but on mobile you often tap just next to the word, which is very frustrating
but there is also WeakDelegate Class
dunno what Microsoft.SPOT namespace is!
Yes there are quite a lot of weak data structures, it's not that they don't exist or do what they claim to do, but it's simply that what they do is not what automatic unsubcription needs.
what does it need from your point of view?
Well bad wording, what they do does not solve automatic unsubscription.
The use case and what the original question asks for, is for a way to automatically unsubscribe when a MB is destroyed, and "destroyed" is defined as "when OnDestroy Unity message is called."
What weak reference allows you to do, is to keep a reference to the object without preventing GC from collecting it, so when GC does collect it the object is automatically gone.
Do you see the problem now? "When OnDestory is called" is not the same as "when GC collects it."
yes well it is true MBs are not very helpful - for me personally I use a lot of straight C# classes in Unity so it might solve some cases. But yes OnDestroy is a pain
No, since that method won't pull the gameobject from your pool or return it.
Yeah, weak data structures offer a way for you to hook into specifically GC, so they are suitable for use cases that has something to do with GC. For example the WeakReference docs shows an example of using it as a cache, which has the advantage of allowing to cache as much as possible until GC feels the pressure to collect, comparing to something like LRU cache.
For automatic unsubscription, the point where unsubscription needs to occur rarely has anything to do with GC.
Yes this is my conclusion too - thus no automatic system used!
Doing multiple players on one device is surprising involved. Check out https://discussions.unity.com/t/2-players-on-same-input-device/762490. But don't expect it to work with rebinding or players joining/leaving. I recommend checking out. https://u3d.as/3pzb
the method creates an audio source and automatically disposes of it. if you want to use an audio source for an object pool, just create a prefab GameObject with an AudioSource and pool that. when you Get or Spawn the pooled audio source, give the method the same parameters as PlayClipAtPoint so it sets the clip, the position, and optionally, the volume . . .
Still applicable, just make sure the object is destroyed
Equality comparison allows you to do that
If you'd truly make a system that applies weak references to classes, then you could build that in to save the trouble. But again, probably not something you want to add to your application to begin with
Also, it was just a general thought to give an idea of the possibilities. It's going to have edge cases, that wasn't the point of the message
Yeah I did that, it works as needed, tyty!!
sure, how did you handle returning the audio source (pooled object) back to the pool? did you use a coroutine/timer?
So if you are going to have to explicitly check if a MB has been destroyed before calling, then you wouldn't need weak reference at all because you are doing the check no matter what.
I'm using a coroutine that deactivates the pooled object after the clip has been fully played (I'm using UnityEngine.ObjectPool)
nice, just wanted to ensure . . .
In the second post they're suggesting to do this:
// Instantiate two players using a split-keyboard setup.
var p1 = PlayerInput.Instantiate(playerPrefab,
controlScheme: "KeyboardLeft",
device: Keyboard.current);
var p2 = PlayerInput.Instantiate(playerPrefab,
controlScheme: "KeyboardRight",
device: Keyboard.current);
But I don't see how to create different key bindings per control scheme. When I change the key bindings for an action in one control scheme, once I switch to a different one, the key bindings stay.
This looks like it will create different instances of PlayerInput components with different control schemes, but since the button bindings are the same for both control schemes, I don't see how that helps to create separate controllers for player1 and player2 on the same device.
They're always the same
You need to assign the individual bindings to a control scheme
notice how (GLOBAL) is appended to every binding here
if a binding is not assigned to at least one control scheme, then it'll be used by every scheme
e.g.
Hey, i have a question. This is my first time doing a 3rd person project and im curious as to why my camera is shaking in build mode but not in the editor.
public class CameraFollow : MonoBehaviour
{
public Transform CameraHolderPosition;
public GameObject InputGameObject;
[SerializeField] float Speed;
[SerializeField] PlayerInput input;
[SerializeField] Transform playerBody;
Vector2 lookInput;
[SerializeField] float lookY, sens, lookX;
private void Start()
{
input = InputGameObject.GetComponent<PlayerInput>();
}
void Update()
{
lookInput = input.actions["Look"].ReadValue<Vector2>();
Debug.Log(input.actions["Look"].ReadValue<Vector2>());
Vector3 CameraHolder = CameraHolderPosition.position;
transform.position = Vector3.MoveTowards(transform.position, CameraHolder, Speed);
CameraSens();
}
void CameraSens()
{
lookX += lookInput.x * sens;
playerBody.Rotate(Vector3.up * lookInput.x * sens);
//lookX = Mathf.Clamp(lookX, -90, 90f);
lookY -= lookInput.y * sens;
lookY = Mathf.Clamp(lookY, -90f, 90f);
transform.localRotation = Quaternion.Euler(lookY, lookX, 0f);
}
}
Hello, i'm not sure ill do a great job explaining but i will try.
I am currently working on a system that takes a CSV file with ability data, serializes it and uploads it to scriptable objects that contain the ability itself.
when i save the actual data through a custom editor script it uploads the data to all the scriptable objects and works perfectly, but after restarting the editor/building, the data is gone.
is there a special interaction/property i have to give a scriptable object field in order for it to save after being updated through script?
i would like to specify i am not updating the scriptable object during run time, but only through a unity editor button that links to a script.
make sure you mark the SO as Dirty and save it to the AssetDatabase
is this necessary even if they are not created at run time?
absolutely
i see, do i have to "resave" them to the same locations with assetdatabase?
not necessary, you just pass the SO object, I suggest you go read the documentation
i have read, i just didn't realize it fits my issue aswell i apologize.
i thought since i wasn't doing it at runtime it wasn't the same
thank you will update if this helps ❤️
you cannot, as standard, save an SO at runtime anyway except in the Editor
foreach(ScriptableAbility ability in Abilities.Values){
ability.abilityUpgradeData = new List<AbilityUpgradeData>();
}
upgrades = CsvReader.ReadCsv<AbilityUpgradeData>(filePath);
foreach(AbilityUpgradeData upgrade in upgrades){
if(upgrade != null && upgrade.AbilityName != null){
#if UNITY_EDITOR
EditorUtility.SetDirty(Abilities[upgrade.UID]);
#endif
Abilities[upgrade.UID].abilityUpgradeData.Add(upgrade);
Abilities[upgrade.UID].abilityUpgradeData = new List<AbilityUpgradeData>(Abilities[upgrade.UID].abilityUpgradeData); // Reassign to trigger change detection
}
}
#if UNITY_EDITOR
AssetDatabase.SaveAssets();
#endif
}
Even after setting all the objects to dirty before/after changes and saving the assets it doesn't quite save them after resetting
experienced dev, not all that sharp at C#, probably failing some basic OOP knowledge here:
I have a Piece class that holds data about a game piece
I have a ILoc interface, the Piece class has a reference to an ILoc
I have HexLoc and ReserveLoc as struct implementations of ILoc
At runtime a Piece's loc could point at a HexLoc or a ReserveLoc (or other ILocs as needed)
But during runtime I need to find out if a Piece is at a HexLoc, and I'm getting weird results
(At this point, there's no actual fields specified in the ILoc, its just there to let a piece exist in one and only one ILoc)
Is this the right C# approach for solving this? Or is there more Csharpey way to do it?
also seeing unexpected editor behavior, things i thought would be visible in editor are not. Piece is a serializable struct and it shows up, but the List<Card> and ILoc are not?
Interfaces are not generally serializable
and Card would have to be a serializable type in order for List<Card> to be serializable
The rules for what is and is not serializable are here https://docs.unity3d.com/6000.0/Documentation/Manual/script-serialization-rules.html
[Serializable]
public class Card { }
But during runtime I need to find out if a Piece is at a HexLoc, and I'm getting weird results
(At this point, there's no actual fields specified in the ILoc, its just there to let a piece exist in one and only one ILoc)
Is this the right C# approach for solving this? Or is there more Csharpey way to do it?
What do you mean by "weird results" exactly?
does it actually need to like... have something to serialize
Oh the other thing is that cards is a property
Unity doesn't serialize properties
only fields
oh snap ok
in fact it's a property that just returns a brand new list each time it seems
IDE telling me that structs cant initialize with cards = new List<Card>; that works if i switch the struct back to a class
im never quite sure when i should be deciding to use structs instead of classes
ok i switched my loc items back to:
public class Loc { }
[Serializable]
public class HexLoc : Loc
{
public TerrainTypeCode terrainCode;
public int altitude;
public Vector2Int coord;
}
[Serializable]
public class ReserveLoc : Loc { }
Structs cannot have field initializers (at least, not in this version of C#)
yea
I have a script for a custom MenuItem that spawns an empty gameobject. How would I make these automatically the children of the scene's current Default Parent? As of right now, they just go straight to the bottom of the hierarchy.
if i understand your q correctly, Instantiate has a second optional argument of a transform, if you pass a transform the prefab will instantiate as the child of the transform's gameobject
the scene's current Default Parent
What is the scene's default parent? That's not a concept I'm familiar with
That's probably an editor-only thing
you can mark an object to be the default parent for new objects you add
Are you trying to write editor-only code, or is this meant to work in the built game?
(I've never ever used this, but it'd be nice for building levels, now that I think about it..)
actually yes I should definitely be using this
Editor only code
For spawning certain tools I've made like spawn points
hmm, i don't see a way to get the current default parent
you can set it and clear it
is it possible to determine the default parent gameobject
what's the proper way to check if a gameobject has been destroyed in a unit test?
doing a null check doesn't work for some reason:
Expected: null But was <null>
[UnityTest]
public IEnumerator HoverOverOccupiedTile()
{
CommonInstall();
_boardItem.DestroyItem();
yield return null;
Assert.That(tileManager.tiles.ContainsKey(new Vector2(2, 2)));
Assert.Null(_boardItem); //Expected: null But was: < null >
//Assert.IsNull(_boardItem); //same result
yield break;
}
Thank you.
Ok, I got this part.
Now, what's the prefab object
Since I'm doing it in code, what do I pass it?
I can't exactly pass it a path to the prefab.
you need to get a reference to that prefab. is that code from a MonoBehaviour-derived class?
I don't know, it's code from this thread:
https://discussions.unity.com/t/2-players-on-same-input-device/762490
well, yeah, you need to get a reference
that's nothing new, though
this is just like any other situation where you need to instantiate a prefab
You got Unity's "destroyed but not null yet" null. You can implicitly cast it to a boolean and assert that this boolean is false for your test: Assert.False(_boardItem) - if such an assertion method exists on your library
works perfectly, thanks!
public class RichochetBullet : Bullet
{
public override void Start()
{
base.Start();
MoveForward();
}
public override void Update()
{
base.Update();
}
private void MoveForward()
{
rb.velocity = transform.right * bulletSpeed;
}
private void OnCollisionEnter2D(Collision2D collision)
{
Vector2 normal = collision.GetContact(0).normal;
Vector2 direction = Vector2.Reflect(rb.velocity, normal);
rb.velocity = direction.normalized * bulletSpeed;
// Slightly move the bullet away from the collision point
transform.position += (Vector3)(normal * 0.01f);
}````
guys idk why my bullet gets stuck after collisions
doesnt reflect
When OnCollisionEnter is called, the collision has already happened, so rb.velocity has already been reflected off the other collider by the physics engine.
You then reflect it again back into the collided object
You can keep track of your velocity by storing it in a member variable each frame
Then you'd use that instead of rb.velocity here
🫡 damn , thanks
it worked but tbh i dont understand
So this line is supposed to reflect the velocity away from the collision, right?
Vector2.Reflect(rb.velocity, normal);
The physics system has already processed the collision. The bullet was already reflected
I think you could also skip the whole "store the last frame's velocity" and just do rb.velocity = rb.velocity.normalized * bulletSpeed
If you just want to keep the speed but let the physics engine do the reflecting
so update stores last frames velocity ,not current frame?
You want to store the current velocity
Preferably do it in FixedUpdate tho
The point is that you need to know what your velocity was before the collision happened.
What algorithms can I use to build a navmesh on a closed surface (for example: sphere) ? Tetraedalization is not very suitable due to extra edges, BPA is not entirely accurate...
Is there a pattern for when a value is managed by different contexts?
For example, player movement being restricted when a UI menu is open, but then it shouldn't allow it if it wasn't allowed before. Not sure if you get what I mean.
another example would be altering the game's time scale
how do i snap a capsule collider to the ground?
you can use a Physics.CapsuleCast to see where the capsule would hit the ground.
https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Physics.CapsuleCast.html
I've been prototyping a platformer game lately, in which I want to have certain surfaces (the blue ones) be like normal solid surfaces, but some others (the purple ones), be bouncy, and while I managed to make a bouncy material that works very well when bouncing off the ground and ceilings, it doesn't really work against walls, and I'm not sure why or how to fix it
does anyone know how to fix it? feel free to ping me with responses or further questions about other factors at any time
Ive been thinking to make a check similar to a ground check but for wall collisions and a bounce tag, but I'm not sure if a simpler, more elegant solution exists
I've been buried in the docs but can't find anything, is there a built in method to get the distance between knots on a spline? I know there's a method to get the length of the whole spline?
The keybindings stay because of the version of the action being instantiated. Like I mentioned, you can't switch action references if you want to follow that forum post. If you want to switch at run-time to a specific control scheme it's a ton of work... or using the $15 asset store tool i mentioned.
If you don't need it at run-time, you're getting kind of close with the screen shots you posted. Double your button bindings so the action contains both WASD and arrow keys. Then click on a binding to change what controlScheme that button set belongs to using the properties on the right side.
Its possible your movement logic could be overriding horizontal physics and gravity, you could try testing with a rigidbody that has no logic or try rotating the walls "forward" - I think a raycast approach from your player is fine too, though I personally wouldnt use a tag, I would use a inherited class (or interface) instead or something dynamic and descriptive about the object like a material, that way you could swap the script or material to get different effects for different surfaces, in case you may want more than just a bounce later
Vector3.Distance
ok I meant distance along the curve
I'm using this to calculate the resolution for mesh generation along the curve and in some cases I want that between two knots on the spline
Probably nothing like that. You'll need to calculate it manually.
You can convert between units in the spline package
yeah I've found this function GetCurveLength(int) which can get the length from one knot to the next so I can sum the lengths between knots
So you can convert from knot index to actual distance
note that both this method and the one I suggested would be in the spline's own space -- you would need to adjust this number to account for the transform of the object the SplineContainer is on
(if you care about that)
Non-uniform scale would be...interesting
nah I'm leaving the spline container at the origin so no need for transformation
In that case, use Spline.ConvertIndexUnit to go from PathIndexUnit.Knot to PathIndexUnit.Distance
ok I'll check it out thanks
Just for some added context since you seem to know splines well, this is the method I already have and am now refactoring to allow distance between knots
public float GetSplineLength(int splineIndex)
{
return SplineContainer.Splines[splineIndex].GetLength();
}
public float GetLengthBetweenKnots(int splineIndex, int startIndex, int endIndex)
{
Spline spline = SplineContainer.Splines[splineIndex];
// check if knot indexes are valid
// Use GetCurveLength to get the length of each curve
return spline.GetLength();
}
public int SampleSplineResolution(int index, float width)
{
float splineLength = GetSplineLength(index);
int splineResolution = (int)(splineLength / width) - 1;
return splineResolution;
}```
any advice here?
yeah, you can collapse this down to
var spline = SplineContainer.Splines[splineIndex];
float start = spline.ConvertIndexUnit(startIndex, PathIndexUnit.Knot, PathIndexUnit.Distance);
float end = spline.ConvertIndexUnit(endIndex, PathIndexUnit.Knot, PathIndexUnit.Distance);
return end - start;
I guess I'd allow start to be higher than end (by taking the absolute value of the result)
This will also allow for fractional indices
0.5 being 50% of the way between knot 0 and knot 1, for example
thanks
I have a problem where the raycast isnt hitting the object that I want it to hit. In the Editor I have an empty game object (supposed to be a machine) that has a couple of shapes as children to visualize it and each child has a box collider, one of the children objects is a console thats supposed to activate the machine. This empty game object has the script for the machine and has a rigidbody on it. I want the player to be able to interact with only the console and not the entire machine to get it working.
CraftingMachine:
public Transform console;
Player:
private void Update()
{
if (Physics.Raycast(playerCameraTransform.position, playerCameraTransform.forward, out RaycastHit raycastHit, interactDistance, interactLayerMask))
{
if (raycastHit.transform.TryGetComponent(out CraftingMachine craftingMachine))
{
if (raycastHit.transform == craftingMachine.console)
{
Debug.Log("Console");
if (Input.GetKeyDown(KeyCode.E) && !craftingMachine.isJammed && !craftingMachine.isCrafting)
{
craftingMachine.NextBlueprint();
}
} ```
Add more debugs to see what's going on. Or step through the code with the debugger
well I added another debug log before the second raycast hit check and it only logs the name of the parent object itself when I am looking at the console on the machine. That's because the console is the only child object that is on the "Interact" layer mask.
im guessing raycasts do not treat child objects independently?
Share the updated code and the logs. As well as a screenshot of the hierarchy.
Raycasts don't have anything to do with child/parent objects. They hit what they hit.
They return info on the physical object that they hit. Note that having an rb somewhere in the parent, would make the parent the actual physical object, even if a collider exists somewhere in the children.
if (raycastHit.transform.TryGetComponent(out CraftingMachine craftingMachine))
{
Debug.Log("looking at " + raycastHit.transform.name);
if (raycastHit.transform == craftingMachine.console)
{
Debug.Log("Looking at " + raycastHit.transform.name);
if (Input.GetKeyDown(KeyCode.E) && !craftingMachine.isJammed && !craftingMachine.isCrafting)
{
craftingMachine.NextBlueprint();
}
}
I do have a rigidbody on the parent as i've mentioned
Then the hit transform would belong to the parent. If you want to access the collider object, do it via the collider component. hit.collider.transform
Great, now its working. It does log the name of the parent object but in terms of behaviour its doing what I need it to do.
Thanks I appreciate it.
The same goes with name. If you need the collider object name, access it via the collider.
Either Unity's API for ECS is beyond garbage or I'm dumb. How am I supposed to query for reference type managed components in systems? Or should I open a topic in #1062393052863414313 which seems overkill.
You can also use the general discussion thread #1064581837055348857
Oh thank you didn't notice that
Hi. I have a class that on startup calls a method of all the interfaces of a type present in the scene (a load system)
something like
GameData gameData;
List<ISaveable> objects = new ();
foreach(var obj in objects){
obj.Load(gameData)
}
and then when i quit the game, in the same way i call obj.Save(ref gameData), giving a ref so that i change the object passed.
Im wondering if its overkill to pass as ref in the Load method so that every change made at runtime are already in the class.
I ve come up with this problem because i have a skill system that holds info of only the levels of the skill. the level is multiplied by a constant to determine its power.
For example i have energy in the game starting at 100. Every levels i put in the "Energy skill" must increase the energy by 20 (and display it in the UI).
or maybe every class that have the Load method will have their copies of the gamedata (or datas into it) so that when the game is playing everything is updated within the game and only saved at the end. In this way i can just access these copies (which are updated and will be saved)
That's a lot of text, but I'm still not sure what the actual question is?
i think i replied myself while writing. But for clarification i need a way to update the values that will be saved (with autosave and or on quit).
so just holding a copy of the savedata (using the same classes) and calling some events when a value is updated is my go to
something like
GameData
PlayerData
SkillsData
then the playermanager manages the playerdata info, and listen to an event in skillsdata for when one of the skill is updated
Yeah, I'd have separate data structures for save data and actual data used at runtime. And only create the save data structure during saving/loading.
Terrible practice.
Player Prefs are actually registry entry.
Always better to completely separate the saving structure and the runtime structure. Both data serve different purpose.
https://docs.unity3d.com/6000.0/Documentation/ScriptReference/PlayerPrefs.html
- Windows: HKCU\Software\ExampleCompanyName\ExampleProductName
Kinda obvious isnt ?
File, like all other games that has been created since the dawn of time.
Whatever format you want, wherever you want.
I prefer json in Application.persistentDataPath
But, depending on the console, Switch, Ps or Xbox I use other means.
so the managers update the copies of the save data and fire the events/edit the other part of the code not the save data itself
I mean, you kinda have to use other means.
It does not "copy" it translates the data from the save to its internal states.
Whenever you want to save, you generate a XSaveData.
Whenever you want to load, you read from the save as a XSaveData and then interpret the data/load.
Obviously, the save data and the state of the object you want to save will have a lot in common. There is a lot of library that enables you to configure the state to automatically handle the "translation" part (meaning that you only needs the actual runtime representation).
However, it usually harder to make it works correctly.
so the managers update the copies of the save data and fire the events/edit the other part of the code not the save data itself
Yes, it does. But not because you have a lot of data but because you use PlayerPrefs + you are not serializing anything.
Also, is there a reason why everything has the "_player" prefix ?
Exactly, the save data should only be treated as a DTO. https://en.wikipedia.org/wiki/Data_transfer_object
In the field of programming a data transfer object (DTO) is an object that carries data between processes. The motivation for its use is that communication between processes is usually done resorting to remote interfaces (e.g., web services), where each call is an expensive operation. Because the majority of the cost of each call is related to t...
DTOs are simple objects that should not contain any business logic but may contain serialization and deserialization mechanisms
There is many things that are wrong in your code...
I do not even know what to say
Obviously not lol.
Like why is it static ?
Why are you not using [SerializedField]
Why do you have your default into the constructor
Why is there any business logic there if it is suppose to be the save
Why the event are static
Why the experience table is directly associate to the player ?
Take all of and directly shoot them in your character:
[SerializeField] private string _playerName;
[Header("Statistics")]
[SerializeField] private int _playerLevel;
[SerializeField] private int _playerHealth;
[SerializeField] private int _playerMaxHealth;
[SerializeField] private int _playerMana;
[SerializeField] private int _playerMaxMana;
[SerializeField] private int _playerExperience;
[SerializeField] private int _playerMinAttack;
[SerializeField] private int _playerMaxAttack;
[SerializeField] private float _playerHealthRegen;
[SerializeField] private float _playerCritRate;
[SerializeField] private float _playerCritDamage;
[SerializeField] private int _playerStatPts;
[SerializeField] private int _playerSkillPts;
[SerializeField] private int _playerStrength;
[SerializeField] private int _playerAgility;
[SerializeField] private int _playerIntelligence;
[SerializeField] private int _playerConstitution;
[SerializeField] private int _playerAccuracy;
After, take time to search on how to save data.
Yeah, which means that you can only have 1 character ?
Yeah, and that is an issue.
Which you would almost definitely need to solve down the line.
Yeah, that makes your code garbage.
Hey, you are the one that asked.
Have you tried debug logs/break points (if using VS) to see which one gets called when your RB goes flying?
I have
and it just calls the hit detect one and does nothing
Currently they try to mimic the body but also don't a sec
they were workigna dn sticking to the body before but when I added these extra rigid bodies they flew away
So which segment of your code is responsible for the issue?
None?
And explain your set up a bit more
Ok so I just have rigid bodies on the same elemt that has the collision detectors
Then why did you send all that code? Implying it was related to the issue
Not a code related statement.
now its suddenly working with out rgid bodies let me test
ANd now its detecting collision
I decided to reset the untiy enginge I guess that fixed it?
Not sure, did it?
Yeah I have no idea
it just works
I have been making all sorts of magic occur
If you could help maybe stream line something I have pllaned for the next step after this i would apprecaite it
If you would care
Sure? Ask away
So with my current config It is unrealistic to toggle my model into a ragdool
due to it have collision detects that would get overwirtten during ther agdool creation process
I have made a spare ragdoll and my goal is to have that ragdooll spawn in the same state as the enemy as the enemy is destroyed when it dies
I mainly wonder if there is an easy way to transferbone data from the live enemy to tha ragdoll model
So it spawns in the same position where the enemy dies in? If i’m understanding that right.
Or it’s data/status?
Rig psoition and position on the map
I rather it not die and tpose is spawned in
No other purpose that I know of. Main reason is simply for convenience for private members to avoid naming conflicts within other scripts of the same namespace
velocity and position are not hard due to just transferring just the velcocity vector3 from one rig body to the other and transferring tranformation data
So in your death logic for the enemy (assuming where Destroy() is called) you would capture the position of the enemy and simultaneously apply it to the instantiated ragdoll
yup
Pretty sure that guy got banned due to his insolence lol
mianly how do i copy over the rig data effieciently?
You would just take the transform.position that was captured at death and apply it to your ragdoll script. You’d likely want to reference the class where you instantiate the object
All dynamically of course
I dont have a rig body and it working? I am incredibly confsued if I add rig body it breaks the hit detection
BuT more improtnatly it t-poses on death
Pretty sure you’d want to declare a variable of type vector3 globally then assign that variable to the object you want to destroy followed by .transform.position
how would I transfer the velocity?
Cause I do not have a rig body on it
The nav mesh agent handles the moving fine I guess
I think you would find your object of type Rigidbody and similarly to position logic, but store the .velocity?
I dont have a rigid body on this thing
Well how will you transfer velocity then?
If I add it my collision detection breaks
Which I do not understand
You can’t really work with physics without a rigidbody then
I think its the navagent handling it?
Then my point still applies. You’d find the object of type NavMeshAgent and store it’s .velocity
quick question with rigidbody
Would I be able to just give a vleocity and a direction or is it more complicated than that?
It’s pretty straightforward
Unless you’re looking for more complex forces such as certain trajectories
Nav agent gives a vector3 we are good
Last thing to deal with is the rig data
SO the ragdoll doesnt just tpose and face plant
Good luck!
[Serializable]
public class Test {
[SerializeField] private int myInt = 0;
[SerializeField] private Dictionary<MyEnum, Dictionary<string,string>> myDict1;
public Dictionary<MyEnum, Dictionary<string, string>> myDict2;
//constructor
}
why myInt and myDict2 are saved into a json while myDict1 is not?
enums must be set to serializable too?
If you're using json utility, dictionaries are not serialized/serializable by default.
MyDict2 shouldn't be saving either. You must be confusing something
Okay. Then I'm not sure.
I don't know if it requires the SerializeField attribute or not, but maybe that's the issue?
Ah, myDict1 is a dictionary of dictionaries. I'm not sure even newtonsoft is able to serialize that.
also mydict2 is
That too.
and gets serialize thats why im confused
Hmm... Indeed. If it's actually serialized, then I guess it's possible.
but i also have another class that has private [serializefield] but simple integers and gets serialized
i guess he doesnt like private dictionaries? XD
removing the serializefield doesnt work either if its private
yeah insane, he just doesnt like private dictionaries (idk about other data structure). Making it public save it properly
Private serialized field should be serialized the same way as public.
well i dont know why it doesnt
Debug
Can't say much about newtonsoft serializer. Maybe check the documentation.
Random refactoring to reduce unnecessary getchild calls and limit iteration if one has fewer children than the other: ```cs
public void CopyRig(Transform spinin, Transform ragger)
{
int spiCap = spinin.childCount;
int ragCap = ragger.childCount;
int cap = spiCap < ragCap ? spiCap : ragCap;
for (int i = 0; i < cap; ++i)
{
Transform child = ragger.GetChild(i);
if (child.CompareTag("ragdoll")
{
Transform other = spinin.GetChild(i);
child.position = other.position;
child.rotation = other.rotation;
CopyRig(child, other);
}
}
}```
thanks
!collab
:loudspeaker: Collaborating and Job Posting
We do not accept job or collab posts on Discord.
Please, use Discussions to promote yourself as job-seeking, advertise commercial job offers, or look for non-commercial projects to participate in:
• Collaboration & Jobs
Hey guys, I've been struggling with this for a while, and I don't know where to ask. So i've made a chatgpt wrapper using unity and tried to export it to WebGl, but I keep getting a webassembly error. I'm pretty sure I can find another way to do the wrapper. I'm just wondering what went wrong and why it's broken, anyways it works fine and is able to be build in Windows.
Hey Fish, try asking in #🌐┃web
You'll find more WebGL pros over there
oh alrighty
Code Review - Settings Script
It still doesn't work. Only first PlayerInput is working.
My PlayerInputActions are setup like this:
Then I have a PlayerInputLogger prefab with a PlayerInput component using my PlayerInputActions asset and my PlayerInputLogger component:
Here's the code for PlayerInputLogger component:
public class PlayerInputsLogger : MonoBehaviour {
public InputActionReference Action1;
void Start() {
Action1.action.performed += _ => Debug.Log("Action 1 performed");
}
}
Then, I have PlayerInputsSpawner object and the component in the test scene. Here's the code for PlayerInputsSpawner component:
public class PlayerInputsSpawner : MonoBehaviour {
public GameObject PlayerInputLogger;
void Start() {
PlayerInput Player1 = PlayerInput.Instantiate(PlayerInputLogger, controlScheme: "KeyboardP1", pairWithDevice: Keyboard.current);
PlayerInput Player2 = PlayerInput.Instantiate(PlayerInputLogger, controlScheme: "KeyboardP2", pairWithDevice: Keyboard.current);
}
}
When I start the game, here's how the scene looks like:
It logs only when I press on the G key and not Numpad1 key
When I switch the control schemes on the spawned objects, it logs when I press numpad1 key but not the G key
Only the first instantiated object is working.
Hi lads, I have a question,
Suppose my game is capped at 60 and only 60 fps and by capped I mean it always set the fps to 60
What happens if a machine that runs my game can only run it at flawless 5 fps?
Then you get 5 fps
Words, but I have a line that will cause the application to set the fps at only 60 every frame update
Then its still at 5?
Capping is maximum
The closest you get is fixed update which can run multiple time on single frame
Even then you can’t get 60, obviously when your machine cannot keep it up
Has anyone worked with ML-Agents in Unity?
It depends on how the game is coded. Some might run slower and other might run at the same speed.
Heck, you can code it so it runs faster at lower FPS
That has nothing to do with NavMesh Baking. It's the Vector3 you are using to place the gameobject with the NavMeshAgent
ok how do i fix
Please ask your actual question and make sure it is actually related to coding and not better suited for channels involving machine learning.
Nobody will respond to your current message: https://dontasktoask.com/
I would like to inquire whether the ONNX file in the unity ML agent contains all types of learning or if it only retains the best results, Additionally, how can we filter it out if needed?
Hi all. I’m trying to make an avatar customisation window. Ive made a scriptable object for clothing items where their type (head,chest,legs,feet) are set as well as a name and sprite. Several clothing items exist as assets now.
Im trying to find out the best way to make my customisation window show them all once. The idea is that by clicking on them in the window, the avatar will equip them. That i can code fine though. Im trying to find out how to show them all.
Best I can find is ScriptableObject.CreateInstance<T> but this seems more usable for dynamically generating new clothing items to exist in the game, rather than load existing assets in. Any advice?
Either load them all via Resouces.LoadAll(), load them all via addressables or have a serialized array/list of them all.
This might be better suited for a channel lik #1202574086115557446 or #🤖┃ai-navigation. Alternatively you can check #🔎┃find-a-channel
I'd probably make some API surface in your SO like public static List<Sprite> GetAllItems(int itemType) (or instead of a Sprite, an Image or whatever data structure you have), then have the UI render them all in a dialog box or whatever.
This is not, strictly Unity related, ML_Agents are trained via Python code and so I suggest you learn how Neural Networks work which may answer your question
I thought of using a dynamic box to display them yeah. Im unsure how to get the SO assets to become actual c# objects that i can use to render though. However i wasnt aware of Resources.LoadAll() as rob mentioned
Just write static getters on your SO script, or "normal" looking API surfaces (lemme write one up)
the scriptable object can contain the information required, a name as a string, sprite, gameobject prefab reference... Should be no problem loading them and using the data to render a UI and perform actions
They already contain them yeah. But when the game starts, no c# objects of them exist in memory. Though again i didnt know about loadall. Im curious what @modern creek will do though
public class InventoryItem : MonoBehaviour
{
[SerializeField] private Image ItemIcon;
.. methods, fields, properties, whatever ...
}
public class InventoryItemDatabase : ScriptableObject
{
[SerializeField] private InventoryItem SomeItem;
... x 1000 ...
public InventoryItem GetItem(int itemId) => .. lookup table or whatever to return the right item ...
}```
then, say you have something that needs access to the item database..
So you’d say make a component with a serialized InvdntoryItem array and manually drag all the assets in?
that works just fine
public class ItemDialogBox : MonoBehaviour
{
[SerializeField] private InventoryItemDatabase ItemDatabase;
public void OnOpenInventoryClicked()
{
int theItemId = ...;
DisplayedItem.sprite = ItemDatabase.GetItem(theItemId).ItemIcon.sprite;
DisplayedItemDetailsText.text = ItemDatabase.GetItem(theItemId).DetailsText; // or whatever
}
}
Wherever you'd have a script that needs access to c# items (and unity items - like image/sound assets) - you can hold those in a scriptable object "database" and then just link the database to the script that needs it
you could even make SOs of SOs - which i might suggest for your situation
like an "item database'" SO that holds all the individual items as their own SOs
its a good approach, id do something like make a Dictionary of them on Awake() to make look up quicker.
I have my "crew database" which has references to all the (65!) crew in our game, and each crew SO has the artwork for all of the various poses and whatnot.. for inventory you could have weapon stats, weight, whatever
then i just link the crew database in whatever script needs access to deets about the crew (including "parent level" stuff like various art for each of the kinds of crew - like header images, ribbons, banners, etc)
hope that helps
oh god why are there 65 seperate fields 😐
I was also thinking of using a dictionary that used the item names as keys. But then how do i get them in there? Is there a way to do so without serializing an array and dragging the SO assets in?
Or can dictionaries be serialized with a customisabke key field?
I actusllt dont know
because we have 65 separate crew 🙂
(our poor artist had to draw 9-15 poses for each of those crew btw)
and our poor animator had to do 5-10 spine animations for them :p
The easy way would be to load them all via say Resources.LoadAll(), then create the dictionary using the asset name as the key (or a field).
var myAssets = Resources.LoadAll("items", typeof(InventoryItem));
Dictionary<string, InventoryItem> allItems = new(myAssets.Length);
foreach(var asset in myAssets)
{
allItems.Add(asset.name, asset):
}
may be correct i just wrote it from memory
So just bear in mind that resources and the resources directory will have some ramifications you may not be aware of
its not a very flexible solution to have a specific field for each one but if its working for you atm then i guess no need to change
(in general I advise all new people to unity to avoid it because unless you're doing something advanced, it's probably not the solution you're wanting)
Yea i work with Addressables only now but where i work we have a json -> protobuf config where we configure things and we configure addresses in there.
Yep, that'd be a usecase- although I thought protobuf had a cpp option (like MessagePack)
I appreciate the help, let me see what I can work out. I needed this nudge in the right direction, thanks!
but config files and other runtime stuff might still be better accessed in the application directory api - not the resources directory
it is usable in many languages, we mostly use it for a shared serde system for server and client for games that need that.
I mean, not really sure what you want me to say. There's 65 distinct crew, there needs to be a lookup table of some sort somewhere 😛
this is defined once, and there's enums for the crew so everywhere in the app, anything that needs access to any sort of crew asset just have to have access to the main crew database SO
you index them with their unique identifier and retrieve them this way. a big switch statement that manually links an enum to a field is not a good solution as it requires lots of manual effort to maintain.
if each scriptable object has its unique id configured on it then there is no problem. And when i say "index" i dont specifically mean array/list index
Oh, I see what you mean, like a list of them, then each SO has an enum with their ID, and I iterate the entire list (or build a dict lookup at startup) when I want to find one
sure, that's an idea, too, although we'd have to do some data validation on load (ie, make sure there's no dupes, that there's one for every enum expected, etc) but that's NBD
That's true but you can always use OnValidate() to catch this in edit mode.
yep, I like the idea, although ultimately we'd still have to define the value of each crew's identifier in the SO
so whether or not the "database" has 65 fields that have to be linked, or each of 65 separate crew SOs have an enum that's set one by one in the inspector is sort of irrelevant
I'll put it this way.. either way, it's a butt ton of linking textures/sfx/data in the inspector
I still haven't found a nice way to automate it
i would not overengineer it out of some weird notion that 65 similar looking fields is somehow bad.
Oh, I haven't.. I haven't touched that database code in a while, I rather like it the way it is (I also have messagepack and json serialization concerns)
your design has 65 well defined entities, its fine do handle that exactly like you did
you aren't making a library
reminds me of this meme
for (int i = 1, i < 4, i++) {
printf("This is item {0}", i);
}
// vs
printf("This is item 1");
printf("This is item 2");
printf("This is item 3");
Damn, that is horrible
Someone has never heard of Arrays or how to use them, lol
like i always say, if you do it once, do it once. if you do it twice, do it twice. if you do it 66 times, THEN you generalize
It's satire
like I always say, if your modus operandi is copy/paste/change - copy/paste/change. You are not programming you are writing a word document
one should not loose sight of what purpose programming serves in the end
more to the point, one should never lose sight of WHO it serves
one should never lose sight of who he serves
Being able to produce 10 bugs a second?
One should never lose sight.
(coming from a dude who is starting to get as old as @knotty sun and has to wear glasses)
❤️ steve
and guess what, 50 years of staring at screens and I still don't need spectacles
oh we go way back, although get as old as steve and i and "way back" can mean different things
but you use the word "spectacles", your argument is invalid
/me says, squinting at the screen through spectacles
so fault me for my enhanced vocabulary, thanks
Just teasing. 🙂 Bed for me! gn
whilst we are on a related subject, wouldn't it be nice if people actually used the spelling checker that I know they have access to?
I saw that
You're not fooling anybody
thay would not care
but I, for one, saw it AND corrected it
which, unfortunately, you obviously cannot
its interesting how you manage to remind me within 2 messages why i don't talk to you.
your loss, do you really expect me not to take a cheap shot when you set it up so nicely?
Why is x86 a checkbox, but x64 a dropdown?
Not sure. Cosmetic reasons perhaps - take it up with the ux designers
because X86 only runs on very specific processors but x64 runs on different ones
x64 is an architecture implemented by different hardware manufacturers
If anything, the drop down box prohibits you from selecting the other two if one was selected whereas the checkbox option allows you to select multiple.
Where they're implying that you're not allowed to select x64, ARM64 and Any CPU (all together) at any one given time.
but in terms of build settings, there's only Intel32, Intel64, and Arm64 for windows, right? So a bit confused how this correlates
IE. if I only have x86 checked, but CPU None checked, will it still be built if I build to Intel32?
well x86 (32 bit) works in x64 just fine but its a bit weird why the plugin settings is like that
Because Intel 64 and Arm 64 do not use the exact same instruction set at cpu level
I guess I don't plan to build for 32 bit systems anyways, steam hardware survey doesn't even have any 32 bit OSes
It is very unlikely that anyone will run your game on a 32 bit machine
I'll just delete the x86 dll and let it be
if its x86 (32 bit) its gonna work if you will only target x86_64 (probably)
may be that it has to match so ignore me
I assume for that I'd have to mark it as both x86 and CPU set to 64, given both are in the name
whatever, I'll just pretend 32bit doesn't exist 🙈 🙉 🙊
x86 is the instruction set, x86_64 is the 64 bit extensions added by amd making it support 64 bit os's
for some reason, don't ask me why, a lot of people are still running 32 bit Windows 7, you would need x86 compilation to enable them to run the game
steam doesn't support win 7 any more officially but that is true. Its up to the dev I guess and the platforms where the game is served to decide what to cater for.
Hmn, there's no scripting define symbols for ARM64 vs Intel64
why would you need them? You're not writing assembler code here
I suppose you could be trying to use intrinsics
I've thought about using POPCNT once or twice
Well, there's two different DLLs depending on platform, so I'd need to be able to DLLImport the right one
But I think I can assume whichever dll is the correct one is in root for builds
It's not really well-documented
then you should be able to set the correct dll to be used for the build platform chosen
Yeah, it's more editor I'm unsure how it should be set up for
you already know which platform your editor is running on so why is that a problem?
I cannot find any examples of how to make DLLImport work when the script isn't in the same folder as the script. And it'd be really ugly to have the editor dll in the same folder as the script, and the arm dll in a subfolder
both should be in a Plugins folder. If they have the same name then I use subfolders of that
Yeah, was the full asset path
so just right clicking the correct dll and choosing copy path worked
is there some way to move all the preferences from visual studio, over to visual studio code? VS works really well for me, lots of really good hotkeys and I have the editor settings how I like, and I dont know how to get VScode feeling good to work in
Just don't do it, why would you move from a full featured IDE to a jumped up text editor?
because you're tired of int being auto corrected to internalSiliconTransistorFactory
so do what I do, turn off all the unnecessary intellisense, autocomplete bullshit or, and I realize this is difficult, pay attention to what you are doing
why would this happen?
its interesting how many people think its impossible to code without intellisense
and I find it impossible to code with it
lol I've been paying attention to what I do and had some ridiculous auto completes before
just a joke
then you were obviously not paying enough attention. Autocomplete does not happen without your consent
only time ive had weirdness is when I give my class a name that already exists in the UnityEngine namespace
but its easy to fix by just specifying "using foo as mything.foo" or whatever it is you do
ok chief
I think there are keymap "extensions" (a lot of things in VS Code are distributed as "extensions") that presets everything to what VS is, if those are what you want to change.
Other than that, not sure what other VS preferences that you are referring to.
Okay to be fair, what it will do is I'll type cs public void Start and hit tab, expecting the intellisense suggestion (of parentheses and brackets), and then I'll get the copilot suggestion instead. In that way I end up hitting tab as part of my keystroke and it does actually autocomplete without my consent.
turn the crap off, problem solved
intellisense or the AI assistant that helps me refactor code super quickly and thus has made my code cleaner than its ever been? I don't want to turn off either they're really useful to me. Ctrl+z is a super familiar keystroke
if you cannot remember or refactor your code without assistance I would question why you are programing in the first place
it was a lighthearted joke I thought anyone who has used VS before would understand, you can chill with the condescending attitude
I didn't say I can't refactor it without assistance, but you can't tell me you never avoid refactoring because "I don't have time for that right NOW, but that's the ideal design"
I have time now, I do the ideal design, that's pretty cool.
Pretty sure the copilot suggestion for that is usually just "finish writing the function".
I've never had it actually put anything in the function until I start typing myself. Like, if I set a private variable to a Get component, it'll suggest doing that for other private variables, but never just off of the names
Hm, maybe it hasn't done it for Start and the default unity functions, but I've definitely wanted a very short/specific intellisense suggestion I was expecting and gotten a whole function that did something very unrelated to what I wanted :p just undid it and typed it myself tho
That said, there was probably some other context that made it seem like I wanted that code there
If your function has a name like "GetHeight" and you have a variable named "Height" I've seen it populate those, but Start has too many variations for it to predict what you want from the name alone
I design my code structures with pen and paper before I start coding so , yes, I almost never refactor, it's called being a professional
@steady bobcat @modern creek
Hi again, I'm back with an issue regarding the clothing UI we discussed (using Scriptable Objects). The first script correctly loads the objects from the resources folder, but then when the second script tries to render them in a prefab to add to a scrollview, it results in a NullReference? I'm very confused why
[CreateAssetMenu(fileName = "clothingSerializedDB", menuName = "Serialization Source")]
public class ClothingSerializedDB : ScriptableObject
{
private const string RESOURCE_PATH = "Clothing/Items";
[SerializeField] private ClothingItem[] items;
private IDictionary<string, ClothingItem> clothing;
void Init()
{
ICollection<ClothingItem> resources = Resources.LoadAll<ClothingItem>(RESOURCE_PATH);
clothing = new Dictionary<string, ClothingItem>(resources.Count);
Debug.Log($"Returned {resources.Count} items");
foreach (ClothingItem item in resources)
{
clothing.Add(item.ItemName, item);
}
//foreach (var item in items)
//{
// clothing.Add(item.ItemName, item);
//}
}
public ClothingItem this[string key] => clothing[key];
public ICollection<ClothingItem> GetAll()
{
if(clothing == null)
{
Init();
}
return clothing.Values.ToArray();
}
public ICollection<ClothingItem> GetAll(ClothingType type)
{
if(clothing == null)
{
Init();
}
return clothing.Values.Where(item => item.Type == type).ToArray();
}
}
public class DisplayClothingHandler : MonoBehaviour
{
[SerializeField] private ClothingSerializedDB _clothingSerializedDB;
[SerializeField] private GameObject clothingContainer;
[SerializeField] private Transform content;
public ClothingSerializedDB ClothingSerializedDB => _clothingSerializedDB;
// Start is called before the first frame update
void Start()
{
ClothingUI.NewClothingSelected += HandleNewClothing;
Populate(_clothingSerializedDB.GetAll());
}
private void OnDestroy()
{
ClothingUI.NewClothingSelected -= HandleNewClothing;
}
void Populate(IEnumerable<ClothingItem> clothingItems)
{
foreach(ClothingItem item in clothingItems)
{
GameObject newItemClothingBox = Instantiate(clothingContainer, content);
ClothingBoxRenderer renderer = newItemClothingBox.GetComponent<ClothingBoxRenderer>();
renderer.SetItem(item);
}
}
void HandleNewClothing(ClothingItem item)
{
}
}
it's called having a massive ego
for me intellisense is about 3 things really:
- when I type "object." I see all its functions, fields, properties, and events
- F2 to rename a symbol all over the project
- Right clicking a class and having it shove it in its own named file
the issue is the renderer.SetItem() line
doing it right the first time is always nice, though (:
this server is not beating the allegations if this is how regulars talk to people
Okay, unnecessary
strange how you are the one being insulting
professionals refactor regularly and design code in a way it can easily be
hey can y'all both chill someone needs help
right and you saying things like "I'm questioning why you're programming" and "I only code on pen & paper cause I'm a professional" is not insulting
do you even hear yourself
@short osprey reading now
thx :)
this means that renderer is null. are you sure that a ClothingBoxRenderer actually exists on the prefab?
Notably, your prefab is referenced as a GameObject. You could have assigned any object into that field.
👆
and, importantly, nothing in this first script has anything to do with the ClothingBoxRenderer
it has the correcrt value
so it working correctly doesn't guarantee much of anything
does that gameobject have the ClothingBoxRenderer component though?
DIRECTLY on it?
(not on a child object)
If this is UI don't you want an Image or Graphic component?
No, he's just really old.
the box im trying to add several of (one for each item) has image and text
lemme confirm
I presume ClothingBoxRenderer is a component that handles displaying an item
(This is a good idea)
yes its 1 box for 1 item
At that point, you should just reference the prefab as a ClothingBoxRenderer 😉
public class ClothingBoxRenderer : MonoBehaviour
{
[Header("UI")]
[SerializeField] private Image icon;
[SerializeField] private TextMeshProUGUI text;
public ClothingItem Content { get; private set; }
public void SetItem(ClothingItem item)
{
icon.sprite = item.InventoryIcon;
text.text = item.ItemName;
Content = item;
}
}
being old doesn't excuse talking to people like that. Nobody cares about your expertise if you're going to be an insufferable human being
Can you show us the gameobject in the engine though
Just explaining, not advocating
#archived-code-general message this prefab we'd like to see, if you could double click on the ClothingBox object to open it up
I see the issue
Haha well easy fix
That's why you should reference prefabs by a specific type!
yeah - my bad
It'll prevent this from happening in the first place
I almost never reference prefabs as a GameObject
Yep best choice if the component is on the root
probably a good idea
okay but question, is there a better way to do that than Instantiate(object.gameObject).GetComponent<type> ?
[SerializeField] ClothingBoxRenderer prefab;
I swear at some point unity would just instantiate it regardless but lately it doesn't like instantiating non gameobject types directly
thats what i was going for actually
There is nothing wrong with doing that
Then what's your excuse for being insufferable because I've seen nothing but that from you since you joined the server
You can instantiate any Unity object type, including any kind of Component
There's a version of Instantiate with a generic type parameter that returns you the component
yes -- so this works:
[SerializeField] Foo prefab;
void Start() {
Foo instance = Instantiate(prefab);
}
Bro y'all need to take it to dms cmon on now this is just personal and there is actual dev conversation going on here, I understand everyone is heated
That hasn't been working for me! Not in 2022 at least!
at some point there was a change, if it's back in unity 6 that's great
You'll need to show an example
It has worked this way more-or-less forever
hey man that's your opinion. But I'm being told this is a great place to participate and get answers and half the people in this text channel have some superiority complex talking down to people for asking questions and generally being unpleasant. Nobody cares that you send HTTP requests through carrier pigeon, find a way to have some empathy for your fellow programmer.
I don't have one but here's what I can say is that I always did it exactly how you're showing. Then I worked on a game and one of the other devs was like "Well you can't just instantiate from the component type" and I was like "what? I absolutely can that's how I always do it". Then we tried it and he was damn sure right, Unity wanted me to instantiate the gameobject then grab the component
Addressables does force you to use Game object only annoyingly.
Also wtf is this dumb other convo
That means that you were instantiating a game object.
[SerializeField] GameObject prefab;
void Start() {
Foo instance = Instantiate(prefab); // compile error; types don't match
}
What do you mean? It was a serialized SomeOtherClass prefab being instantiated without .gameObject or .GetComponent is what I'm saying
okay so it renders now, but.. what?
yep, ill try to solve it and otherwise go there. thx for the help so far
[SerializeField] GameObject prefab;
void Start() {
GameObject instance = Instantiate(prefab);
}```
^Obviously this works, we all know that
```cs
[SerializeField] SomeOtherMonobehaviour prefab;
void Start() {
SomeOtherMonobehaviour instance = Instantiate(prefab);
}```
^ This would not work for me at a certain point, and very much to my surprise, I was eventually forced to do:
```cs
[SerializeField] SomeOtherMonobehaviour prefab;
void Start() {
SomeOtherMonobehaviour instance = Instantiate(prefab.gameObject).GetComponent<SomeOtherMonobehaviour>();
}```
the first example there does not compile; that was an example of what would cause the behavior you saw
The second one simply does not make any sense. That isn't how Unity's API has worked since at least vesrion 5.2 (the furthest back I could dig on the documentation site)
oh sorry copied the wrong one (based that off your pasted example obviously)
SomeOtherMonobehaviour is not actually a MonoBehaviour. There is no other explanation.
But even then, that wouldn't make any sense, because then GetComponent wouldn't work
alterantively, you had two very similarly named types and got them mixed up
(and neither would the .gameObject property)
hmmm but then my getcomp would be null
it wouldn't fail but it wouldn't have been there
Perhaps only the generic argument version can do this or was that just a quick example
the code worked
The generic type is inferred from the argument
DW I'm aware
which again is something I considered XD this discord convo is like my exact pattern of conversation with myself AS this happened, that's why I can confirm like, this went down like I'm saying, this is all ringing bells I went through all of this like "I have always spawned these this way what on earth"
Who knows 🤔
Go test now if you care but seems like a waste to wonder any more
like trust me I would not do Instantiate(prefab.gameObject).GetComponent<MyType>() if I didn't have to, it's ugly haha
There must some other missing context.
yeah I think that's likely
Interface? Its inconsistent where you can use one as a generic type arg for components
An interface would not be serialized by Unity in the first place.
It would otherwise have been consistent with what you saw, though
so quick to retort
I've explored this a few times :p
just a general idea. I often use Component ref and onvalidate to enforce interface implementation to do such references.
Instantiate would refuse to accept any interface type, since it wants UnityEngine.Object. But you could write an interface with a gameObject property, and GetComponent can be used to retrieve a component that implements an interface
oo that's not a terrible idea, I do that just to fill out my same-go-comps sometimes as it is so I could just use interfaces if I did that. I guess unity is still able to serialize it just doesn't have a property drawer or whatever for the inspector?
If you had some other way of populating that field other than Unity serialization, this would've been possible
It can draw a property just fine -- you're serializing a Component (or even just an Object)
You can add a fancy property drawer to help you select the right type https://github.com/Thundernerd/Unity3D-SerializableInterface
public static void ValidateInterfaceComponent<I>(ref Component component)
{
if (component != null && component is not I)
{
component = component.GetComponent(typeof(I));
if (component is not I)
{
component = null;
}
}
}
no no sorry I'm talking about what @steady bobcat said about as a general idea using OnValidate to kind of have serialized interface
I was talking about rob's idea, yes
fancy
i use this with OnValidate() to at least enforce interface implementation in edit mode
with support for throwing in a GameObject (which'll give you its Transform) and getting the right component out, too
nice
unless it's new in unity 6 you can't serialize interfaces to the inspector directly though unless I've lost my marbles
as you can see, the non generic version works with an interface so that is useful.
Again, no interface typed field is being serialized
rob is serializing a Component
oh! Okay good lord I understand the flow of the messages now haha yeah I'm with you
👍
Does anybody know what I can use instead of PrefabUtility.UnpackPrefabInstance() since that function doesn't do anything anymore?
I have a prefab running in editor that creates children generatively in OnValidate and I don't need them flagged as prefab changes.
yyaa, pookies, How can i acheive this Squash, stretch effect via code,Also, that sweet lil tilt while falling in either direction?
Thanks in advancee!!
Perhaps you're not using it correctly? I see no reason for that method to not work
You could make an AnimationCurve an sample that to modify your scale
no like the functions summary literally says it doesn't function since 2018 and it's deprecated
Doing this in OnValidate sounds very suspicious
I do not see this.
^Maybe in combination with a coroutine or a tween
i can see that working, but what about the tilt, when its falling?
I generally just avoid onvalidate alltogether
Note: You should not use this callback to do other tasks such as create objects or call other non-thread-safe Unity API. You should only use it to validate the data that changed. This restriction is because OnValidate can be called often when the user interacts with an inspector in the Editor, and because OnValidate can be called from threads other than Unity's main thread, such as the loading thread.
It runs very often
Yeah, that's your problem for sure
Also on assets
you are right i meant to type PrefabUtility.DisconnectPrefabInstance() hahaha my bad i pasted the wrong one
yo guys, am stuck on slope mechanics for unity 3d cant get it to work as i want it to, can someone help?
It's a tricky subject but you can show your code and character setup and tell us what is going wrong
Can I ask zenject-related questions here?
No
where do I go then?
to the dev of whatever it is?
I'd prefer to ask on a discord, as I feel like it's a silly question
i mean, this seems like a unity-adjacent programming problem
they don't have a discord
The average person here is just much less likely to know about it
look through the issues on their github, may already be answered
issues are for bugs though, aren't they?
I just want to ask how a simple thing is done
I do not use it, but I might have a clue anyway
the issues page on github isn't just for bugs no. Go see if your question has been answered there anyway
I want to inject stuff into a non-monobehaviour class, when I make one, and I'm not sure how
Why do people use zenject with unity, i'm genuinely ignorant about DI frameworks
it's actually amazing, I recommend learning about it
it helped me a lot in my previous project and got me my current job
Can you give me an example use case?
Many of the examples are for non-MonoBehaviour classes https://github.com/modesttree/Zenject?tab=readme-ov-file#injection
it's like singletons but better and cleaner and easier, and can inject scriptableObjects as well etc etc
that's the briefest description I could come up with
it magically provides the correct object
alright, the problem is when i move on slopes, it slides down, i want it to stop but it just slides to infinity if i let it, and when i try to jump on slopes it doesnt
singletons are an obvious example of DI where there is exactly one correct object
that doesn't work for me, though
i'm describing DI :p
I know how DI works in general, I'm ripping out our current homemade DI solution and replacing it with zenject
i also tried this @hexed pecan
@sudden inlet See !code how to post code properly
📃 Large Code Blocks
Use links to services like:
https://gdl.space/, https://paste.ofcode.org/, https://hatebin.com/, https://paste.myst.rs/, https://hastebin.com/
📃 Inline Code
Surround code with three backquotes. Not quotation marks.
To format as C#, add cs to the first line:
```cs
// Your code here
```
Add a comment with a line number if there is an error message.
As opposed to.. DI frameworks where there are multiple objects to choose from? Or what
Maybe I should just go read on them
Right.
I would like to point out the existence of https://github.com/hadashiA/VContainer for DI
unlike zenject it's being updated regularly
It's an extremely broad concept
I would argue that this is DI:
public float Add(float x, float y) => x + y;
It has dependencies (some numbers) and you give it the dependencies
I will eventually stop being a stick in the mud and try out VContainer or something
private void MyInput()
{
horizontalInput = Input.GetAxisRaw("Horizontal");
verticalInput = Input.GetAxisRaw("Vertical");
if (Input.GetKey(jumpKey) && readyToJump && grounded)
{
readyToJump = true;
Jump();
Invoke(nameof(ResetJump), jumpCooldown);
}
if (Input.GetKey(jumpKey) && readyToJump && OnSlope())
{
readyToJump = false;
Jump();
Invoke(nameof(ResetJump), jumpCooldown);
}
}
@hexed pecan
Instead of using Invoke() method, have you look into coroutine?
you can't easily create a singleton for a ScriptableObject, can you?
That's what confuses me, everything related to passing values around seems to to be DI
i dont know how to work with coroutines
also, yeah, you CAN have multiple objects if you'd like
At some point, you didn't know how to use Invoke() either
So anything that is not absolutely pointing up is considered a slope here.
You should instead check the angle or dot product of the ground surface.
Like float slope = Vector3.Dot(slopeHit.normal, Vector3.up)
That would give you 1 on a perfectly level surface, and 0 on a 90 degree surface (and -1 on a ceiling)
meanwhile for me adding any scriptableObject as a singleton is declaring a variable, binding it in one line, and dragging it through the inspector
cleaner, I think
but yes, you can technically achieve many of the same things through singletons
private bool OnSlope()
{
readyToJump = true;
if (Physics.Raycast(transform.position, Vector3.down, out slopeHit, playerHeight / 3.5f + 0.3f))
{
if (slopeHit.normal != Vector3.up /*&& slopeHit.normal != Vector3.zero*/)
{
return true;
}
else
{
return false;
}
}
return false;
}
this also doesnt work
well, doesn't matter