#archived-code-general
1 messages · Page 408 of 1
okay but they do that already no? because its in DDOL scene as singleton
your error isnt related to settings though, its because you need a way to assign pauseMenu
they do, if I in the Main menu first click on options so the settingsCanvas has been activated once
then everything works as I intended it to
ok
where does that happen exaclty? i dont see it in these scripts
Sounds like you just drag dropped it to your script in inspector and the gameobject holding the UI is not a child of the scripts gameobject. In that case, switching scene will destroy the canvas and your reference in inspector will turn null. You can check that, if its exposed in your inspector of the script.
A solution would be, to keep your UI a static thing over all scenes by making it a child of your scripts gameobject.
can someone explain to me why you aren't allowed to have a prefab reference itself correctly? the easiest workaround is to just have two of the exact same prefab but with the reference pointing to each other, but (1) that's stupid, and (2) I'm now spawning alternating objects using the reference and any changes I make to one prefab I have to remember to bring to the other.
its mega annoying and has been a pain to debug for forever all to find out its forcing the reference to be something i didn't put in it in the first place
it broke so many features that i was trying to work around
what are you trying to do exactly ? prefabs are mainly an editor thing not ingame
you don't use prefabs in runtime?
prefabs are just "templates" to gameobject
yeah the one spawned is a gameobject
so what do you mean prefab referencing itself
you want the spawned object ?
oh i see the confusion
the spawned object needs a reference to its original prefab because the spawned object can spawn another copy of itself (its a lot more complicated then that but to shorten the whole process down thats sufficient lol)
and object spawning itself sound like a recursion nightmare lol
its not a recursion nightmare
It sounds like you are trying to force your system into it instead of taking a step back and for example using a static manager that can be fetched from instead of let the object do runtime stuff on its own
if you want more details-
its a magazine for a gun. its a vr game so there is an ammo pouch, the game checks what items you have picked up last, and associates a prefab from them. picking up a magazine or the gun it goes in associates that magazine prefab with the ammo pouch.
Ah, I see the problem, when you spawn from a prefab all of the references are updated from editor instances to runtime instances. So a prefab referencing itself the prefab reference would also be updated to the new gameobject instance
you might wanna look into addressables and use references instead of prefabs
yes, but i dont think this should be forced - the workaround is to just have an identical second prefab that alternates between itself and the other
what do you mean use references instead of prefabs? it uses a reference to a prefab to spawn the new one
no, best way is to use dependency injection and inject the original prefab reference into the new game object
When you reference a prefab, it will get loaded into memory. If you use addresables, you just have a "pointer" to it and can spawn it from any script as a raw object instead of a reference of a reference
thx for the tips
still though, why is this a forced feature?
You can still pass in the prefab you are instantiating to the new instantiated object by script with a simple Init() method
because the instantiation routine does not know the difference
Has anyone ever worked with easy save 3 and webgl? I cant seem to make Easy save work on webgl games
Contact Easy Save, we do not provide support for 3rd party assets
Alrite
Hi there, i have some trouble trying to get working my game smoothly, its first time i do it, so im searching in documentation and some threads in unity forum and this is what i got, it works but in unity editor works smooth with moouse or gamepad, but not in real device with my gamepad , there is my input manager and my cam controller
Your !ide does not look properly configured. Is this correct?
If your IDE is not autocompleting code
or underlining errors, please configure it.
Select one:
•
Visual Studio (Installed via Unity Hub)
•
Visual Studio (Installed manually)
•
VS Code
•
JetBrains Rider
• :question: Other/None
Namely the fact methods like LateUpdate are unknown, and in general syntax highlighting is very off
Please configure it first, then we can help you
is visualcode, ok let me see what i have wrong
you mean visual studio code?
i got installed visual code with the common but still looking like this
im using macos yes
If you use Visual Studio Code, I suggest you use Visual Studio or Jetbrains Rider instead. I believe support has generally improved for Unity, but the other two editors have very good support
visual studio for mac is dead, visual studio code is the recommended replacement (idk about rider)
In that case I suggest you check out Jetbrains Rider. It recently got a license that allows it to be free
that is
That it, depending on a few prerequisites obviously
but also visual studio code does work fine in my experience
for me works fine, then only i have found is lateupdate and other methods from unity are grey
if you're familiar with it and can set it up properly then you should just use the one that's more comfortable 🤷
im comfortable with that
Yes, so I think you're still missing some configuration steps. I suggest you follow each step once more to verify
this is not legible?
These methods should be known Unity methods, but they are not
Right now they are listed as being unknown methods which is not correct
If you lack the intellisense here, you likely have to manually write each method, do you?
just disable-enable the extension
That looks even worse 😄
Now ALL the intellisense and highlighting is gone
If you want/can change then you can also try Jetbrains Rider. It has a single plugin you need to install I believe
ok uninstalled extension and installed again
Weird. You have auto completion but it doesn't know LateUpdate is a reserved method name
i will check later jetbrains, but i want to try to improve this code 🙂
Generally I would expect it to work properly but maybe this is just VSC being weird as always
I would definitely consider it, yeah. An actual IDE for C# is always better than a text editor with plugins 😛
Regardless, I suppose this is how it works then
LateUpdate and other messages are recognized as proper messages in my ide
ok im just installed for now jetrider
im earing about that long time ago so maybe is a good moment for testing
Jetbrains is skyrocketing when it comes to supporting different c# frameworks
Which is both surprising and generally weird considering you'd expect applications like VSC and VS to get the same treatment since they are not from a 3rd party company
ok, about the code to manage my gamepad, any suggestion? i have to deal also with the bad support on macos with gamepad, my ps4 gamepad works, but some times when it comes to standby i have to re-plug again
are you using the old input or the new input system?
new input system
this is how i manage the input from gamepad
And your issue is your gamepad movement is not smooth in runtime but in editor?
yes
Did you ever test another gamepad?
I mean, it works in editor, so either macos is trying to do something in "game mode", maybe disable that, or your gamepad is trying to do something ingame mode or is broken entirely, if its having connection issues. macos on latest updates?
yes, but i use unity editor in macos but real device is android, with an steelseries stratus
well... that is some minor information you should put in your introduction of the question 😄
How is it connected, BT, wired?
bluetooth
Hi, gyus. I am trying to bake a light. After baking has been completed, the light on the wall seem to be correct, but after importing a lightmap, everything becomes too bright. Just moved to unity 6 and have never had this problem before. Also, it does not seem that baked light maps are so bright..
The problem was that, for some reason, unity marks all lightmaps as default in the scene folder. I changed it to lightmap, dir lightmap and shadowmask accordingly and it fixed the problem. But looks like unity set it as default every time..
Why unity marks lightmaps as default? it takes some time to correct it...
you add the scene as additive?
Could you explain what you mean by importing after baking? Are you talking about just a few seconds after it has finished baking it automatically starts reimporting the textures?
im testing the game pad in stumble guys (i dont know another game) and my gamepad works smoothly, so the problem should be my code
And its connected to BT to your editor as well?
yes
Ah, good to know. But there is a lot going on from editor to android. So not sure, its the code itself, as it works in editor.
yes
private void Update()
{
_speed += (_moveDirection != Vector2.zero ? 1 : -1) * _speedRate * Time.deltaTime;
_speed = Mathf.Clamp(_speed, 0f, _maxSpeed);
}
private void FixedUpdate()
{
Vector2 move = _moveDirection * _speed * Time.deltaTime;
_rb.AddForce(move, ForceMode2D.Force);
}```Does this seem like a decent way to implement a simple vehicle controller? It's a little stiff which is mostly because the code hasnt been fine tuned yet
deltaTime shouldn't be factored into the force
(the one in FixedUpdate)
Also all of it should really go in FixedUpdate
Hey :)
When you're working in the FixedUpdate block, you want to use Time.fixedDeltaTime as opposed to Time.deltaTime. That probably helps smooth out some of the jitter you're seeing.
Time.deltaTime is set to Time.fixedDeltaTime within FixedUpdate
It would still be incorrect to factor in the length of the frame or the length of the physics update when using AddForce, either way
private void FixedUpdate()
{
_speed += (_moveDirection != Vector2.zero ? 1 : -1) * _speedRate * Time.fixedDeltaTime;
_speed = Mathf.Clamp(_speed, 0f, _maxSpeed);
Vector2 move = _moveDirection * _speed;
_rb.AddForce(move, ForceMode2D.Force);
}```This definitely feels much smoother
That looks correct.
plus move doesnt end up being really small
You accelerate towards a target velocity, moving by Time.fixedDeltaTime * _speedRate each physics update
Well, it's not really a speed, but close enough
you accelerate towards a target force value
you'll wind up getting a sort of "double-smoothing" effect from this -- you accelerate towards a force value, and that force value causes you to accelerate!
You might compare this to just doing _rb.velocity = move; and seeing how that feels
Yeah, the _speed property is mostly so I can control the initial acceleration. But it does seem counter-intuitive considering the rigidbody does the same thing
make sure interpolation is enabled on your Rigidbody too
Is there a many-to-many dictionary?
because I can only have 1 instance of a key
actually no, I'll just use a list as the value
dict to set/list of value
Hello guys. Im having a bit of a gigantic trouble with loading some data from Json.
My current project has a single entry point for Data, which is the Profile class. We load a Json file containing an object of type Profile at startup and then save it on application quit.
Profile has a list of characters, characters have an inventory, inventory has inventory entries and inventory entries have and item.
Item is polymorphic so it can be an Equipment.
Equipments have two lists, one for PrimaryAttributeModifiers and a Second one for SecondaryAttributeModifiers.
An Equipment is created whenever the player collect loot from the ground(example) and it calls the Equipment constructor which accepts an EquipmentSO.
This far, everything works great. It serializes the data correctly and by debugging the load call on the Json, also reads everything correctly. All the lists work in exception of the attribute modifiers.
I've tried a plethora of solutions but it seems to not be able to deserialize the attribute modifier list by any means at all.
Things i've tried:
-Simpliying attribute modifer inheritance to not include vector 2(newtonsoft doesnt like the normalize properties)
-Changing serialization and deserialization settings
-Removing the Unity's SerializeField properties and just using JsonProperty instead.
-Adding parameterless constructors with the JsonConstructor attribute.
-Saving and loading the items while equipped (changing the list type)
for the first point, you can add converters that correctly handle things like Vector2
you'll need to show us how an attribute modifier is defined and how you're storing them
Ok.
namespace Attributes
{
[Serializable]
public abstract class AttributeModifier
{
[JsonIgnore] public Action OnValueChanged;
[field: SerializeField, JsonProperty] public bool isPercentage { get; set; }
[field: SerializeField, JsonProperty] public float timeActive { get; private set; }
[field: SerializeField, JsonProperty] public int minRoll { get; private set; }
[field: SerializeField, JsonProperty] public int maxRoll { get; private set; }
[field: SerializeField, JsonProperty] public bool isRolled { get; private set; }
[field: SerializeField, JsonProperty] public float value { get; private set; }
[JsonIgnore]
public float Value
{
get
{
if (!isRolled) return RollModifier();
return value;
}
}
[JsonConstructor]
public AttributeModifier() { }
public AttributeModifier(int minRoll, int maxRoll, bool isPercentage = false, float timeActive = 0)
{
this.minRoll = minRoll;
this.maxRoll = maxRoll;
this.isRolled = false;
this.timeActive = timeActive;
this.isPercentage = isPercentage;
}
namespace Attributes
{
[Serializable]
public class PrimaryAttributeModifier : AttributeModifier
{
[field: SerializeField, JsonProperty] public PrimaryAttributes stat { get; set; }
[JsonConstructor]
public PrimaryAttributeModifier() : base() { }
public PrimaryAttributeModifier(PrimaryAttributes stat, int minRoll, int maxRoll, bool isPercentage) : base(minRoll, maxRoll, isPercentage)
{
this.stat = stat;
}
}
}
CLASS EQUIPMENT CONSTRUCTOR
public Equipment(EquipmentSO preset) : base(preset)
{
Debug.Log(this);
enchantItems = new();
upgradeLevel = 0;
primaryModifiers = new();
secondaryModifiers = new();
this.slot = preset.slot;
this.enchantSlots = preset.enchantSlots;
foreach (PrimaryAttributeModifier modifier in preset.primaryModifiers)
{
PrimaryAttributeModifier newMod = new PrimaryAttributeModifier(modifier.stat, modifier.minRoll, modifier.maxRoll, modifier.isPercentage);
newMod.RollModifier();
primaryModifiers.Add(newMod);
}
foreach (SecondaryAttributeModifier modifier in preset.secondaryModifiers)
{
SecondaryAttributeModifier newMod = new SecondaryAttributeModifier(modifier.stat, modifier.minRoll, modifier.maxRoll, modifier.isPercentage);
newMod.RollModifier();
secondaryModifiers.Add(newMod);
}
}
and its stored here
also just tried sving the equipment while it is equipped, so the list is List<Equipment> instead of List<item> and the same result, so. yeah
wait, so the issue is that this class doesn't get serialized/deserialized properly, yes?
The equipment class doesnt get deserialized properly. The Serialized Json data is totally fine.
The only things missing are the modifiers
doesnt matter what happens, the list storing the modifiers gets set to empty
but where exactly is the issue - those foreach loops in Equipment constructor, do they run properly?
they do. If i kill a mob, loot the item everything is fine
After i close the game and check the serialized data
everything is fine
when i open the game and debug.log the data that i will deserialize, everything is fine
when rebuilding the Equipment, lists are empty
So wait, let me clarify - deserialization happens here, right? in this constructor you sent here?
EquipmentSO is your serialized data and you make your equipment from it
so those foreach loops, in that constructor, do they run?
no. i have a default parameterless constructor in the same class.
No EquipmentSO is a scriptable object that i use to create normal instances of equipments(since i want to have randomized stats per drop)
[JsonConstructor]
public Equipment() : base()
{
}
this is what gets called for deserializing
My Json settings are as follows:
Serializing
TypeNameHandling = TypeNameHandling.All,
ObjectCreationHandling = ObjectCreationHandling.Replace,
DefaultValueHandling = DefaultValueHandling.Ignore,
Formatting = Formatting.Indented,
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
Deserializing:
TypeNameHandling = TypeNameHandling.Auto,
ObjectCreationHandling = ObjectCreationHandling.Replace,
DefaultValueHandling = DefaultValueHandling.Ignore,
PreserveReferencesHandling = PreserveReferencesHandling.Objects
don't you want to use the other constructor with the actual parameters? this way you're telling the deserializer to simply create a new instance with default values
but i am using ObjectCreatingHandling.Replace and PreserReferencesHandling.Objects.
It works fine with all the other data that i'm saving and loading
not sure how i can pass a scriptable object parameter to the actual deserializing construtor tbh
why TypeNameHandling.Auto and not TypeNameHandling.All? not saying that's the issue, just asking what's the reason
Auto is basically an optimization where the type name isn't included when it's not ambiguous.
I'd double-check with .All anyway, had stranger bugs than that in the past
ive almost done all possible combinations of serializer settings in there
Yeah i've just removed all parameterless constructors from equipment, item and attribute modifiers
where exactly is deserialization happening?
public Profile LoadProfile(string name)
{
string fileLocation = GetPathToFile(name);
var settings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto,
ObjectCreationHandling = ObjectCreationHandling.Replace,
DefaultValueHandling = DefaultValueHandling.Ignore,
PreserveReferencesHandling = PreserveReferencesHandling.Objects
};
if (!File.Exists(fileLocation))
{
throw new ArgumentException($"No persisted GameData with name '{name}'");
}
Debug.Log(JsonConvert.DeserializeObject<Profile>(File.ReadAllText(fileLocation), settings));
Debug.Log(File.ReadAllText(fileLocation));
var profile = JsonConvert.DeserializeObject<Profile>(File.ReadAllText(fileLocation), settings);
return JsonConvert.DeserializeObject<Profile>(File.ReadAllText(fileLocation), settings);
}
it just can't create items anymore because it doesnt know the parameter, of course
Howdy folks, quick question. Is it possible to change a setting or something to make it so FixedUpdate waits for Start before running? Maybe I am confused or something but it seems like it oftentimes a frame of FixedUpdate will occur before Start.
use Awake instead of start, that's guaranteed to always run first, although ngl that's a new one for me
I did consider that, but it depends on a reference to another script which gets some stuff during Awake, so it would mess everything up
Currently I just have a variable called "started" which is set to true once Start runs, but it feels like bad practice to do
It should run awake on all objects before any fixedupdate calls afaik
Awake will run as soon as the object comes into existence, yeah
sanity check... try serializing/deserializing an array instead of a list
(as long as the game object is activated)
There’s also lateupdate, but not sure if there’s latefixedupdate?
if you REALLY cannot figure out how to put your stuff inside Awake, then I guess that's the best you can do...
not that I'm aware of
But you could probably also run if (whatever != null) in an update to make sure
pretty sure I had similar issues with lists a looong time ago, so maybe that'll be the solution... although can't quite remember
also a good option I guess
very weird that fixedupdate can run before start, that's funny
can it run before onenable? that could be a good idea as well
You know, I was going to say LateFixedUpdate wouldn't make any sense, but it would be kind of handy to have code run after the physics update
No, because OnEnable runs at the same time as Awake (immediately)
How can it run at the same time?
I am pretty damn sure that from some testing I did, all Awakes run everywhere first, then OnEnable and Start run in said order per object
as in, together
I get that it will run both on the same frame, but I’m pretty sure it will create and call references in Awake before it makes it to OnEnable
not literally simultaneously
Awake and OnEnable execute together as a pair if the behaviour is enabled upon creation
so
obj1.Awake
obj2.Awake
obj3.Awake
obj1.OnEnable
obj1.Start
obj2.OnEnable
obj2.Start
obj3.OnEnable
obj3.Start
that's how I remember it
This is not the behavior I have observed.
I might have it mixed up I admit
it was a while since I last checked it
public SecondaryAttributeModifier[] secondaryModifiers { get; private set } = new SecondaryAttributeModifier[10];
Json serializes correctly
but same thing, it deserializes the array with 10 null values
but something similar to this was happening xd
Oh that's significantly different!!! than an empty array!!!
Just checked, the reason awake has been causing problems is because there's info given to that other script when it's spawned in, and so running Awake actually runs before that information is given sometimes
think i might have lost you here actualy
More like this:
obj1.Awake
obj1.OnEnable
obj2.Awake
obj2.OnEnable
obj3.Awake
obj3.OnEnable
obj1.Start
obj2.Start
obj3.Start
an array with 10 null values is a different problem than a null array
Yeah. You often have problems like that
Awake is too fast. Start is too slow.
it was a long time ago that I checked that xd ¯_(ツ)_/¯
I'll often create an "Init" method that I manually call after doing some setup
yeah, sure. But the underlining reason why it has 10 null values seems to be the same reason why the list wouldnt serialize
Yup, I've improved it a lot now by getting rid of like 90% of the stuff in my dumb CharacterInfo scriptable object
wait, explain - was the list null and the array has null values?
It just has the stuff for input actions and starting positions
can you show an example of an object that gets deserialized properly?
So maybe what I'll look at doing is moving the Start code to Awake, and then setting the starting position of that object in the other script
And I'm getting closer and closer to being able to get rid of the scriptableObject entirely
the list was null because i wans't starting it on the property declaration, only in the constructor that actually takes parameters. and the array is empty and not null because i'm starting it on the class declaration
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
thats my entire json file, as i said, im using a single entry point
inside it there are many objects being serialized correctly
including lists and polymorphic types
uhhh am I seeing this right? all the primary/secondary attributes lists are empty or null in there...
because thats one that has been loaded already and then saved again
let me send you another one then
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
check id 125 at line 660
Hi I did not know this but the Mesh API with RecalculateNormals() has UV seam issues: Imported Meshes sometimes don't share all vertices. For example, a vertex at a UV seam is split into two vertices, so the RecalculateNormals function creates normals that are NOT SMOOTH at the UV seam!
I can understand from a speed perspective but they ought to offer a slower version that fixes this
I know that using the "Mikktspace" option for calculating tangent vectors can cause meshes to be split along UV seams
(since it uses the UV map to figure out the tangent)
However, the resulting vertices should have identical normal vectors
any idea?
so this is posted in the forums, Unity will not blend across a UV seam as it is like a hard edge internally when 2 vertices share same pos/normal (in order to have different UVs) - oh well
known normal calculation issue
Oh right, duh. It has to split across uv islands
heya, I was hoping someone could help me out a bit with an issue I'm out of my depth on. I have a cinemachine camera (unrelated to this issue) that's tracking a target, and I have a pixel perfect component on said camera (my own, I ripped out the pixel position rounding component from the 2d one). as you can see in the video, when moving horizontally there's zero jitter, perfect. but when moving in the z axis, there's quite a bit of jitter, even though the code should be rounding it the same
public Vector3 RoundToPixel(Vector3 position) {
float unitsPerPixel = 1.0f / pixelsPerUnit;
if (unitsPerPixel == 0.0f)
return position;
Vector3 result;
result.x = Mathf.Round(position.x / unitsPerPixel) * unitsPerPixel;
result.y = Mathf.Round(position.y / unitsPerPixel) * unitsPerPixel;
result.z = Mathf.Round(position.z / unitsPerPixel) * unitsPerPixel;
return result;
}
// Snap camera position to pixels using Camera.worldToCameraMatrix.
void PixelSnap() {
Vector3 cameraPosition = m_Camera.transform.position;
Vector3 roundedCameraPosition = RoundToPixel(cameraPosition);
Vector3 offset = roundedCameraPosition - cameraPosition;
offset.z = -offset.z;
// Get world to local camera matrix without scale
var invPos = Matrix4x4.TRS(cameraPosition + offset, Quaternion.identity, Vector3.one).inverse;
var invRot = Matrix4x4.Rotate(m_Camera.transform.rotation).inverse;
var scaleMatrix = Matrix4x4.Scale(new Vector3(1.0f, 1.0f, -1.0f));
// Calculate inverse TRS
m_Camera.worldToCameraMatrix = scaleMatrix * invRot * invPos;
}
i was hoping someone here might be able to provide insight into what i'm doing wrong here
a thought I've had is that since my outlines are depth and viewnormal based, it might be because the depth values are changing? I'm not sure
Hi, is there a way so the input to result is such:
0 = (0,0,1)
1 = (1,0,0)
2 = (0,0,-1)
3= (-1,0,0)
Or, return in Vector3Int.forward, right, down, left ?
With sine ? Or...?
Is the camera looking at the player at an angle? That could be relevant..
it is, at a 30* tilt, which would make sense... adding a pan angle introduces x jitter
create your own mapping?
[SerializeField] private Vector3Int[] mapping = new Vector3Int[]
{
new Vector3Int(0, 0, 1),
new Vector3Int(1, 0, 0),
etc
};
var dir = mapping[0] // gets 0,0,1
I bet you need throw in a sin(30deg) or cos(30deg) factor somewhere
that looks like you want a Vector3Int array
yeah I agree, let me mess around with that and I'll try and see, thanks
I am working on a tool that needs to be able to run a set of "Filters". Some filters require no context at all (e.g. a filter that randomly says "yes" or "no"). Others require context (e.g. a position in the world).
I'm having some trouble figuring out how I'll structure this.
An existing implementation of mine has several abstract classes, such as:
public abstract class Filter {
public abstract bool Test();
}
public abstract class PositionFilter {
public abstract bool Test(Vector3 pos);
}
The nuisance here is that I want to be able to put Filters into a List<PositionFilter>. After all, Filter's Test method needs strictly less information than PositionFilter's Test method.
The current fix is to create classes that just hold an instance of a simpler filter:
public abstract class PositionBaseFilter {
[SerializeField] private Filter filter;
public bool Test(Vector3 pos) => filter.Test();
}
This works, but I'm wondering if I can do something to avoid all these "holder" classes.
Ideally, each class will ask for a specific set of information, and I'll be allowed to plug in any class that doesn't require information that my code can't provide.
I'm not sure if I can actually do this with C#'s type system.
the dream scenario would result in something like this:
- RandomFilter <-- no requirements, can fit anywhere
- PositionFilter <-- fits anywhere that can provide a "position" input
- PositionAndRotationFilter <-- fits anywhere that can provide both a "position" input and a "rotation" input
Why not have a main class to inherit from or an interface?
The nuisance is that this is the opposite of a classic inheritance hierarchy
If I made PositionFilter inherit from Filter, it would have this pointless Test method that doesn't work
Why does Filter need the test() then?
Because Filter represents a filter that can make a decision without any input
So its a DecisionFilter, not a plain filter
the point is that inheritance makes no sense here -- filters that require more inputs aren't a "subclass" of filters that require fewer inputs
You cannot use a PositionFilter like a Filter. It's actually the exact opposite
a Filter works anywhere that a PositionFilter does
some kind of inverse Liskov substitution principle
This also makes interfaces non-useful
So, what do you want to achieve actually? You want to have a list of different types?
Suppose I have some code that knows a position
It wants to make a decision based on that position
I want it to be able to run any kind of filter that can operate with only a position input
This includes:
- Filters that require a position
- Filters that require nothing at all
It excludes filters that require any other kind of information
You can do the check at runtime, of course, but that's not very satisfying
so i have a few disconnected trains of thought floating around
- this would require something akin to
superin java (as in, generic constraints) which c# doesn't seem to have - perhaps instead of requiring nothing (
Filter) vs requiringPositionvs requiringPosition&Rotation, you could make it unary?- a nullary filter would just ignore the input, perhaps the input could be null
- a unary filter would just have that input, directly?
- a binary+ filter would have the inputs as a struct
along that latter train of thought; maybe you could have a unified FilterData type? that doesn't seem too great to work with though, static checking would be hard
maybe something via attributes...
the FilterData idea is roughly what I've done in another place in my game
It's kind of gross. I have an interface for each kind of data that adds a property, and I downcast to those types to see if I can give them the information
Then, when the class does work, it checks if it got all of its information and throws an exception if that didn't happen
Obviously, static type checking goes out the window here
oh wait, super does exist, it's in
Contravariance did come to mind
But inheritance is fundamentally not compatible with this design. Deriving from a type implies that you can do everything the parent does
And that is not the case here.
if the parent is generic, perhaps that could work
The "current fix" I mentioned here does work. I just have to explicitly implement every possible combination of "more specific filter" and "less specific filter"
but that goes back to the FilterData thing
ive been thinking about java.lang.Comparable
I am just trying to wrap my head around what combinations you have and how you distinguish your filters as well as how do you applay them. where do you want to filter them out?
imagine I have three arbitrary kinds of data: foo, bar, baz
One filter might need to know about foo, bar, and baz to be able to make a decision
Another might need just foo
And a third might need nothing at all
But shouldnt your filters just get the data available and decide on their own?
Any context where I can execute the first filter -- meaning I provide it with foo, bar, baz -- is also a context where the second filter and third filter are valid
Right, I'm just hoping I can get some kind of static type checking here
But I think that's not possible
a given Comparable<T> can make a decision based on T
T can get more specific
in usage, U super T is used, so Comparable<Object> is assignable to Comparable<String> for example
what about having interfaces for each input data point?
that's what I did here #archived-code-general message
I'm asking a negative question here
It's not "Does it implement X?"
it's "Does it ONLY implement X?"
Having one interface for each type also implies that you can ask questions based on exactly one piece of information
isn't that intended though
No. If a filter demands foo, bar, and baz, you must give it all three of those to make a decision.
but there could also be "does it ONLY implement X AND Y?" which ends in up in a problem of how you ask, at least feels like 😄
yeah ok i think i misunderstood the perspective
public interface INeedsPosition {
public bool Test(Vector3 pos);
}
public interface INeedsRotation {
public bool Test(Quaternion rot);
}
public class SomeFilter : INeedsPosition, INeedsRotation {
// ...
}
This doesn't fit my design.
ah no that's not what im talking about
I want this filter to have one method that makes a decision based on a position and a rotation
And that just doesn't fit at all, yeah
IHasRotation and such, rather
Yeah, interfaces work the other way
i think im explaining my idea poorly, i'll go back to making my example
This has convinced me that I can't warp the C# type system into doing this 😛
How about custom "tags" to assign and based on that Init the filter and do its local thing?
That's roughly what I did here (through interface abuse) #archived-code-general message
Sounds to me like you need a base class to make a variable able to hold multiple class types then use reflection to find which Test method is implemented
I also wonder, do you want to run the filters runtime but prefiltered on editor? or do you want to filter them out in runtime?
I'm setting these up in the inspector
Ah got it.
Which does mean I can just filter the list of choices based on, say, attributes
That's probably going to be the way forward
So you could just reflect to the methods available and add them to a custom event to call those functions?
I'm envisioning something like this
Thats what I did to call stuff on scripts from UI and not to have tie up everything. Just select the type in inspector, update the dropdown to add the functinos to call and then just call the singleton of it and fire those methods.
[Provides(typeof(FooInformation)), SerializeReference] List<Filter> filters;
The inspector would only show me classes that don't require any other kind of information.
Filter would wind up looking like this:
public abstract class Filter {
public abstract bool Test(FilterData data));
}
and FilterData would contain all the possible things you could give to a filter
So it would be perfectly legal to run a filter without all of the data that it needs
But the inspector would forbid me from assigning such filters in the inspector
How do I fix that Don'tDestroyOnLoad does not keep deavtivated gameobjects?
or how do I work around that
whatcha mean
Don'tDestroyOnLoad does not keep deavtivated gameobjects?
What do you mean by that?
I don't remember that behaviour
that's not a thing
How would that prevent you from assigning?
Oh I think what you may mean is that because the object is deactived it may not be flagging DDOL
deactivated objects are not shown in "DontDestroyOnLoad" in the UI
I already use a package to support SerializeReference (it's vertx's package, actually)
I don't think it matters if they're active or not. You have to have called DDOL on them to put them there.
Show your code and what's happening exactly
I would throw out any types that need information I'm not giving
is the object ever calling start^
oh
Ah got it, okay, makes sense
should it be in Awake?
Awake won't run if the object is not active either
The problem is trying to run code on a script that isn't active
do I give up or how do I make it run?
What are you trying to do
put the code on an active object is the solution
oh
I did not think about that
big brain
thanks
I am still learning
All of us are
i can't even warp the java type system into doing this
Is there a TL;DR explanation of what you're trying to do?
I've been messing around with Roslyn Source Generators for a few weeks now and am convinced those are the solution to almost every problem at this point 🤣
@leaden ice
It all started from there 😄
I want to be able to plug less-specific filters into places that support more-specific filters
If I can provide ABC, then filters that need ABC, or AB, or C, or nothing at all should all fit
But filters that need D shouldn't fit
I'd prefer the former. I can already achieve this (with some headaches) if I just check at runtime
So what's the typical use case look like?
Something like... uh...
myThing.Filter(new FilterA());```?
(i am still trying btw. i think i broke the java playground...)
Where myThing is of some specific type that should accept certain filters and not others?
The typical form is something like this
wait, typing code on my ipad sucks
it sends the message early like 50% of the time
Suppose I'm spawning prefabs along a line
I want to be able to reject certain placements based on the chosen position
This could probably be done with a Roslyn Analyzer btw
But I should also be able to reject placements based on nothing at all (e.g. a coinflip)
which lets you add new rules to the compiler basically
also, this particular thing is editor-only -- but I've run into identical problems in runtime code
But in both cases, I'm setting everything up in the inspector in advance
so I can get away with a custom editor that enforces the rules
Could you explain a bit more, how you add those filters. or rather, to what? its in inspector, right? so you have some kind of serialised list in inspector and you want to give the list some kind of property, so it knows what iflters to accept?
I'm not even sure "type information" is enough to work with.
Knowing the filters operates on a Vector3, for example, doesn't mean the filter works on any Vector3
it might take only positions
or euler angle rotations or something
@heady iris sorry, was meant for you
Yeah, it'd be more than just the literal type of the argument. That's okay
wait i might have a system going in java...
[Serializable]
public abstract class Scorer : IPolymorphic
{
public abstract float GetRawScore();
}
[Serializable]
public abstract class EntityScorer : IPolymorphic
{
public abstract float GetRawScore(Entity entity);
}
[Serializable]
public class EntityConstantScorer : EntityScorer
{
[SerializeReference] private Scorer scorer;
public override float GetRawScore(Entity entity)
{
return scorer.GetRawScore();
}
}
Here's an example of what I've done before.
I'll store a List<EntityScorer> on something that needs to compute a score based on an entity
Rather than also having a List<Scorer>, I created EntityConstantScorer
That lets me fit a Scorer into a list of EntityScorer (through a wrapper)
phew, that feels hacky 😄
I did another approach, because I had issues referencing the gameobject in the other gameobject, so what I did was have the other gameobject active but the canvas turned off. then the code will run so DDOL will run and then I enable the canvas back and deactivate the gameovject. and it worked. I am doing a lot wrong. ik
I really don't feel like I have enough context to answer if you're doing anything wrong here but it sounds like the code is now on an active object, which is exactly what I suggested.
oh, ok
thanks for the help anyway
I would be helpelss else
It's tolerable so far because I haven't had a need for too many kinds of scorers
and they don't overlap much in what information they get
The punchline might be that this problem doesn't exist at all 😉
i.e. instead of having filters like:
- ABD
- BD
- ABCD
I just have:
- ABC
- AB
- A
I think we all knew almost form the start of this conversation, but eager to get the perfect solution 😄
with very little crosstalk
Yeah :p
I've banged into this several times and dealt with it in varying ways
It was very helpful to talk about it! Thanks!
Oh, thank you too. Very challenging and was fun to think about that whole structuring , great insightful conversation 🙂
If I do run into a situation where I have lots and lots of overlap, I'll just do a runtime check
If you have ABC, AB, A, you could even just use an enum. But as soon as you have a mixture of those, it wont work
u can use enum bitmask to combine
I just use enum to control roles for example. the higher the enum value, the higher the role and less things are restricted or what not
This does remind me of "blackboards" in the context of game AI
where you have a shared pool of information and you can't really be sure what will be in it
!code
📃 Large Code Blocks
Use links to services like:
https://paste.mod.gg/, https://hastebin.skyra.pw/, https://paste.ofcode.org/, https://paste.myst.rs/, https://scriptbin.xyz/
📃 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.
this is as far as i got with java (im more familiar with it)
https://paste.ofcode.org/M3ueVR5kQEKKb5qhagaxmE
can't construct multiple-datapoint-filters with this, T & U can't be used as a type like that, unfortunately...
hello, I'm using this code to force a 4:3 aspect ratio on the game I'm working on
it works well on a 1920x1080 laptop screen, but I got a friend to try the game on steam deck, and the aspect ratio change did not work. The game just filled the screen.
Any idea how I could fix this?
How about just something like...:
public class Context {
public Vector3 position;
public Entity entity;
public Color color;
}
public abstract class AbstractFilter {
public abstract bool Filter(Context ctx);
}
public class PositionFilter : AbstractFilter {
public override bool Filter(Context ctx) {
return ctx.position.x > 5;
}
}```
And just let the filters optionally take whatever data they want from the Context object
typescript is just 2 programming languages on top of each other with one masquerading as a type system
is it possible to change something in the inspector when the game is running and have those changes be persistent?
i believe we did discuss this briefly, it loses the part about static checking what data is available
I know that Cinemachine does this.
yes, I think there is (was) an option to keep values somehow, but that can mess up a lot of things. you can always right click copy component and paste when in edit mode
Understood.
Thanks
That's what I'll do if I just need one component
private void AddMovementForce()
{
Vector2 movementForce = _moveDirection * _speed;
float angle = Vector3.Angle(transform.up, _wheels.TurnDirection);
Quaternion rotation = Quaternion.Euler(0, 0, -angle); // take the
Vector2 finalDirection = rotation * movementForce;
_rb.AddForce(finalDirection, ForceMode2D.Force);
}```I'm trying to make it so that the direction the object at the front travels becomes influenced by the direction that the back object is facing. I've tried a few different things, and nothing seems to do the right thing
Something more like this
_moveDirection is the way the user aims the front half of the train, but its the back wheels that need to influence some steering
@heady iris in ts it Just Works™️ lmao
playground
yeh, typescript, python, just throw in whatever you want and get whatever you want 😄
Yep! & is the secret sauce there
One immediate problem
Vector3.Angle is not signed
So you can't tell left from right
java kinda has it but just doesn't allow it as broadly 😔
Consider using Quaternion.FromToRotation
This gives you a rotation from one direction to another
That might misbehave for an exact 180 degree mismatch, though
In that case, Vector3.SignedAngle would be more reliable. It needs a third direction as a reference point
Vector3.SignedAngle(one, two, Vector3.forward);
This would be appropriate.
SignedAngle gives you a number in the [-180..180] range. I can never remember which way is negative
float angle = Vector3.SignedAngle(_moveDirection, _wheels.TurnDirection, Vector3.up); Are these the right properties to use in it? I've tried a number of combinations and none seem correct
ooooohh right
in a 2D game, forward points into the screen
You might want to calculate two signed angles relative to some arbitrary reference point
float moveAngle = Vector3.SignedAngle(_moveDirection, Vector3.right, Vector3.forward);
float wheelsAngle = Vector3.SignedAngle(_wheels.TurnDirection, Vector3.right, Vector3.forward);
float skewedAngle = Mathf.LerpAngle(moveAngle, wheelsAngle, 0.5f);
Vector3 resultDirection = Quaternion.AngleAxis(skewedAngle, Vector3.forward);
I think that'll do it.
Note that it'd be dramatically simpler to just do
Vector3.Slerp(_moveDirection, _wheels.TurnDirection, 0.5f);
I just don't know what's going to happen if those two vectors are antiparallel
(i.e. exactly 180 degrees apart)
float moveAngle = Vector3.SignedAngle(_moveDirection, Vector3.right, Vector3.forward);
float wheelsAngle = Vector3.SignedAngle(_wheels.TurnDirection, Vector3.right, Vector3.forward);
float skewedAngle = Mathf.LerpAngle(moveAngle, wheelsAngle, 0.5f);
Quaternion angleAxis = Quaternion.AngleAxis(skewedAngle, Vector3.forward);
Vector2 finalDirection = (Vector2)(angleAxis * Vector3.up);```I wasnt able to use the Quaternion how it is at the end, is this right?
You'd want to multiply with Vector3.right at the end
since that was your reference point
if I have an event trigger to play an audio on PointerClick, and a OnClick Playgame (it is changing the scene) will the audio not play then?
you mean the audio gets destryoed on scene change?
it ends up doing this
does it?
You can test this in your unity editor 😉
if the audio source goes away, the audio will stop playing
I did and I can't hear anyting
Don't tell me I need to put my buttons in DDOL?
not the buttons -- but what about a single audio source that's used by all of your buttons?
is it abruptly turning to the right here?
i can't tell what the issue is
I'm not pressing anything, it just propels to the right
are you sure vector.up isnt correct? It would be (0,1,0) and its the Y axis that the front of the train heads towards
Vector3.forward is a world-space direction here. It's an axis pointing into the screen
you're finding the angle between your vehicle's move direction and a reference point
(which is Vector3.right)
that angle is measured around the forward vector
that's a completely separate issue though
all this is doing is finding a direction that's halfway between _moveDirection and _wheels.TurnDirection
if _moveDirection is zero it could get a bit weird
Vector2 movementForce = _moveDirection * _speed;
Vector3 finalDirection = Vector3.Slerp(movementForce, _wheels.TurnDirection * new Vector2(-1, 0), 0.5f);
_rb.AddForce(finalDirection, ForceMode2D.Force);```Quick thing to note, I did give the lerp a try. It sort of works, but at the start of the video I try and press A and D to turn the front and it doesnt move
it only turns when the back gets tilted
what's with the scaling on TurnDirection?
to invert the direction
that's throwing out the Y component entirely
yeah
late to the party but this approach may be helpfull
I'll work on it more tomorrow, its past 8pm so I'm going to stop working for the evening
will give me time to reflect on the code, I think in general the steering part of the code doesnt do quite the right thing
(also havent eaten anything today so I'm probably running on empty 😅)
Why without animation my character is under root object with colliders? Child object(model) have (0,0,0) coords its not offset or smth else. Just weird thing
You need to set this to "pivot"
Then you can see the actual positions of the objects when you select them
It will probably show you that the center of the model is offset
this is a problem in the 3D model itself
You would fix it in Blender (or any other 3D modeling software)
Set by pivot and this happened 🙂 Download model from mixamo
if I spam onenter sound many times all sound in the scene is gradually being muted and then if I stop it gradually comes back, is that supposed to be like that?
Yes now you can see where your object actually is
See how the collider is super offset from the model?
You should adjust the Center of your collider so the pivot is starting from the bottom like the model
Yes, but can I fix this somehow without blender and etc. I would like to use Root Motion anims. Would it be compatible with pivot in center of model?
Add an empty parent and offset the model
but if one of the animations is completely offset from the others there's not much you can do about that
It's generally much better IMO to have the object's pivot on the ground rather than the center - makes code much simpler.
That's how it works now. Root is rigidbody and colliders, first child animators and etc
The colliders can always be offset by either:
- simply adjusting the center property in the inspector
- moving them to child objects
you can also just offset the visuals separately
you can do whatever you'd like inside that hierarchy more or less
It seems like when I have the exit to menu button (works by onClick: SceneManger.LoadScene(buildnumber_toMainMenu)) But when I do this the music starts to play again
music that I have in main menu
what would be the best apporach to fix this
What do you want to happen instead?
Shouldn't the main menu music play when you start the main menu?
yes but since I put DDOL on the music
oh
nvm
I need to put another music in the game instead which is not DDOL
if you have DDOL on the music playing object you should make the code ensure there is only one copy of it
the pattern is a "DDOL singleton"
If you want to simply have one in each scene, you wouldn't use DDOL at all
Yeah I figured that would be best
I don't do DDOL if I not have too
so I've got an interesting idea that I'm implementing now
it's a bit like this
public class SimplexNoiseFilter : Filter
{
[SerializeField, SerializeReference, SerializeReferenceDropdown]
private PositionSource positionSource;
// ... more stuff
}
PositionSource is another abstract class that tells you how to get a position
One position source just grabs the "position" member from a FilterData object that gets thrown into the filter's Test method
Another gets a position from a TransformSource!
...one kind of which, in turn, can look to see if you provided a "root" member in the FilterData
this also leads to a hilarious function signature
public abstract bool TryTest(FilterData data, out bool result);
hang on, this is just dollar store dependency injection
and more layers of indirection than a main-story fetch quest
Hey, I'm not sure where to ask this but im trying to make a car with the wheel colliders and it has low acceleration but fast top speed and im looking to make it a little more realistic
I know very little about wheel colliders but I would love to learn more about it
Maybe lookup the Internet for some tutorials on it. After doing so and getting stuck or having questions for clarity, ask #💻┃unity-talk
If it's a general programming question, you can ask here.
ok, thank you. no harm ment
Hey, I'm trying to get my simulation from c# to a compute shader, it's an implementation of an XPBD solver, distance constraint of the edges and volume constraint of the tetrahedrons, but it looks bad and jitters. Even ensuring no parallel execution so there's no race condition with the numthreads set to 1 (I don't know if this really ensures that it doesn't run in parallel, because it's the first time i write a compute shader in my life). I also tried to compute the rest length and rest volume of the constraints in the gpu to make sure it's not caused due to a difference in floating point accuracy between the cpu and gpu, nothing works, the simulation is not totally broken, it's jittery, This is an example of the distance constraint in c# and on the compute shader:
public void Solve(NativeArray<Particle> particles, float deltaTime)
{
float alpha = compliance / (deltaTime * deltaTime);
Particle pA = particles[indexA];
Particle pB = particles[indexB];
float w0 = pA.InverseMass;
float w1 = pB.InverseMass;
float w = w0 + w1;
if (w == 0f)
return;
Vector3 grad = pA.Position - pB.Position;
float len = grad.magnitude;
if (len == 0f)
return;
grad = grad / len;
float C = len - restLength;
float s = -C / (w + alpha);
pA.Position += s * w0 * grad;
pB.Position += -s * w1 * grad;
particles[indexA] = pA;
particles[indexB] = pB;
}
the compute shader:
[numthreads(1, 1, 1)]
void SolveDistances(uint3 dispatchThreadID : SV_DispatchThreadID)
{
DistanceConstraint constraint = distanceConstraints[dispatchThreadID.x];
Particle pA = particles[constraint.indexA];
Particle pB = particles[constraint.indexB];
float w0 = pA.InverseMass;
float w1 = pB.InverseMass;
float w = w0 + w1;
if (w == 0.0f)
return;
float3 grad = pA.Position - pB.Position;
float len = length(grad);
if (len == 0.0f)
return;
float3 norm = grad / len;
float C = len - constraint.restLength;
float alpha = constraint.compliance / (deltaTime * deltaTime);
float s = -C / (w + alpha);
pA.Position += s * w0 * norm;
pB.Position += -s * w1 * norm;
particles[constraint.indexA] = pA;
particles[constraint.indexB] = pB;
}
the rest of the code is here: https://paste.mod.gg/jqvmdmgahcgb
A tool for sharing your source code with the world!
(Compute) shaders will run in parallel no matter what you do. It's their nature and what makes them fast.
Numthreads just defines the number of threads in a thread group.
As for the jitter, can you record a video?
How are you executing the shader and getting the results? Are you sure it's caused by the compute shader?
Solved, the problem was exactly that, instead of trying to dispatch the shader one time, I dispatch it for every parallelizable group of constraints that i generated using the graph coloring algorithm so no race condition occurs, thank you
Does anyone know how to spawn a player prefab like with DefaultPlayerPrefab at runtime in unity transport unity 6?
in unity transport unity 6
wdym by this? Netcode for GameObjects?
uh... how do i get the clientid?
the clientID of what
whatever defaultplayerprefab uses idk
I don't understand the question.
it's asking for a client id
Player objects get spawned in as soon as the client connects
what is?
What are you trying to accomplish here?
To manually spawn an object as PlayerObject, use the following method:
GetComponent<NetworkObject>().SpawnAsPlayerObject(clientId);
Just use your own client id (assuming this is from the client)
where do i find that?
How does one get around UnityWebRequest.PostWwwForm(url, JsonUtility.ToJson(payload)) spitting out ascii on the receiving end? Server keeps coming back to me with %7b which is ascii for {
WWWForm() doesn't work though cause that needs to be paired with a content header of x-www-url-encoded .
I find it weird that unity's default post is a x-www-url-encoded but their service api docs only accepts application/json
Server keeps coming back to me with %7b
Not sure I understand what you mean exactly here - you mean your code on the server side is receiving that data? Or the server is responding with that?
Also what are you trying to do exactly?
requesting allocations with multiplay requires me to use the TokenExchange API with a payload of projectID and environmentID.
created a class ExchangePayload with the previously mentioned requirements as variables. plugged it into a JsonUtility.ToJson() and slapped that as the form for the UnityWebRequest.Post(url, payload)
Debugging the JsonUtility.ToJson() showed me that it was converting the class to json just fine. Sent it over to the server only to get back a unable to parse body. %7b... is not a valid json
Well - pretty sure PostWwwForm is going to URLEncode the data at the very least
Are you sure the server is expecting form data?
It's weird that you would be using both HTTP Form data AND json 🤔
does this API have documentation?
Admin APIs allow you to access and configure Unity Services as an administrator. To authenticate admin APIs, you must create and use service accounts.
its expecting application/json
unless i've butchered this somehow
then you shouldn't be using PostWwwForm
just make regular UnityWebRequest Post with that payload
hmm its screaming at me because of the obsolete function
which one ? UnityWebRequest is not obsolete at all
www class is
just that overload is obsolete
wOt
try like in the link I shared
you have to set the headers like the link ^
here is the Post that works if you want to do it all in one line
https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Networking.UnityWebRequest.Post.html
its 3 args
thanks a lot guys for helping out @leaden ice @rigid island
My bro and I are having trouble with the Kinematic Character Controller again.
if(InputMod.GetButtonDown(CrouchInput)) {
characterInputs.Crouch = (!characterInputs.Crouch);
Debug.LogError("We press crouch and are now " + (characterInputs.Crouch ? "crouching" : "standing"));
}```
```C#
// Crouching input
if (inputs.Crouch)
{
Debug.LogError("Be crouching");
_shouldBeCrouching = true;
if (!_isCrouching)
{
_isCrouching = true;
Motor.SetCapsuleDimensions(0.5f, CrouchedCapsuleHeight, CrouchedCapsuleHeight * 0.5f);
MeshRoot.localScale = new Vector3(1f, 0.5f, 1f);
}
}
else if (!inputs.Crouch)
{
Debug.LogError("All rise");
_shouldBeCrouching = false;
}```
Segments taken from two scripts, and we're trying to make a "toggle crouch". What keeps setting "_shouldBeCrouching" to false, causing the character to only remain crouched for one frame?
if (inputs.Crouch)
{
Debug.LogError("Be crouching");
_shouldBeCrouching = true;
if (!_isCrouching)
{
_isCrouching = true;
Motor.SetCapsuleDimensions(0.5f, CrouchedCapsuleHeight, CrouchedCapsuleHeight * 0.5f);
MeshRoot.localScale = new Vector3(1f, 0.5f, 1f);
}
}```
Why wouldnt you be crouching if input.Crouch here is to be true? Feels like you've one too many flags going on
@arctic sparrow
public void SetInputs(ref PlayerCharacterInputs inputs)
Here's the problem. I have never used ref in any of my code, but I can only theorize that it's responsible for resetting the crouch bool
What's your take on this, @latent latch ?
ref keyword is used to send value types into methods as references, so unless PlayerCharacterInputs is a struct then it's probably not needed... but you should probably understand what yall are doing with it anyway
It is indeed a struct.
As for the code in general, it would probably be more helpful if it was posted via paste site cause I can't figure the flow of it with what's there.
May want to look into a statemachine and eliminate a lot of those flags
Pls don't use ref, ever
If you don't know what it does, it's not a good idea to use it
If you have to pass structs by reference and you don't know what ref is then that's a good candidate for refactoring in general
It also ruins the idea of a struct
https://hastebin.skyra.pw/ulamobamuy.csharp
ExamplePlayer
https://hastebin.skyra.pw/elefacuged.csharp
ExampleCharacterController
That's the way KinematicCharacterController had it.
That's how it was originally. Seek is still learning how this all works
Then I would just remove it
If your other script requires mutation of this object then I suggest you get a reference to the class directly and mutate it from there
There's very little reason to actually use ref
Not because it's "bad". ref is very specific and generally you should just use another approach
I think Mao generally gave a good answer too. You probably just want to use a class here.
Ok, so this is probably what's happening. Every frame it's making a new Input struct
and because it's being read every frame, Crouch is being acted upon even if the value isn't being set explicitly by the player
the same thing would happen whether it was a class or a struct because it's just being newed every frame
right, so the bool value is by default false and that's what's being read into the input
store the state of the crouch at the ExamplePlayer class, and set a toggled version of that to the input struct
So if we only initialized the class/struct once, then we could have the variables be persistent?
The design of the example input is stateless. You have to add your own state, just set the crouch input based on a bool you yourself control at the class level
KC is pretty good, but such a pain to get it working with cinemachine cause there's a lot of it is hardcoded for the basic main camera
Okay, it is fixed!
Hey, wanted to ask for some tips or ideas on something im trying to do.
My current goal is to have a slider where I can drag, and if it reaches max or min value, it can loop around. Visually the slider will be radial in nature. Any ideas how I should go about the looping aspect? I dont need direct code, just ideas or opinions on how to tackle the issue
Looping as in it loops back to min if it goes past max? If so simply value %= max; value = Mathf.Max(value, min)
Didn’t realize that’s a thing, cool
Aight thanks! Ill test both out! Also agreed, never knew Mathf.Repeat was a thing! Cheers you lot
I'm developing a 2D game, primarily focused on UI, and I'm looking for a better way to save and load game states. Currently, I have a lot of UI elements and game objects that need to be saved. My current approach is to manually serialize each script's data to JSON and then load it back when the game resumes. This works, but it's very cumbersome and requires manual updates to the saving and loading logic every time I change my UI or game logic.
My game consists of several mini-games, so I end up having separate saving/loading systems for each one. I'm hoping to find a solution that's more automated and less error-prone. I'm working offline and only need to save locally.
Is there a package or resource you would recommend for saving and loading complex 2D UI scenes? I'm looking for a solution that avoids me having to write all the saving and loading logic manually.
Any help would be appreciated!
You could generate a unique ID when first adding the script and then save its ID and state to a static global list and save that list as JSON.
And when then loaded, the script will just onenable check itself inside that list and get its values from there
Sounds like a job for my Save for Unity asset
every time
which one?
without knowing exactly what you are doing I'm guessing the Core asset and the UI Add-on will do the job
You might want to look at the Core+ bundle as it has a 50% New Release discount atm
So, in the Kinematic Character Controller, where in the scripts is the value that determines which direction the player is facing?
Seek, I literally said to follow the movement values from the inputs class.
What are some recommendations from people here, for serialized dictionary packages?
I need a good one, and there's plenty, but I don't know how to choose
and last time I tried to find one myself, I couldn't find a good one
ideally not paid, or at least cheap
As in a package that allows you to serialize a dictionary?
I assume this is binary serialization or just being able to show them in the inspector?
show them in inspector, specifically
IIRC Odin does it, and that's the best
I can imagine this is a pretty common problem which has a free solution
isn't odin insanely expensive
dunno, go look
First Google search: https://assetstore.unity.com/packages/tools/utilities/serialized-dictionary-243052
I don't want a first result from google search
I wouldn’t really recommend Odin for it
last I tried that it ended up shit
and had to remove it
I want a recommendation
can't count on google for that
not these days for sure
Lol
regarding that ? emoji - google went to shit
At least try it before you judge
I tried a bunch a while ago
Did you try this one?
and got tired searching for a solution that didn't require modifications to work and wasn't crap
I dunno it was a while ago, I am asking for a recommendation from someone who uses a serialized dictionary package
so that I don't have to try 20 of them
This package averages nearly 5 stars. I would just try it
Odin requires whole different serialization for it, means impossible to get rid of it
I'm not asking for a lot, please I just want a recommendation from someone who actually uses one
https://hastebin.skyra.pw/ahivivagig.csharp
Okay, Chirz and I are having trouble making a "Recenter Camera" input.
please dont recommend me random things you find on google
please
if you don't use one, please
I am not looking for the top 5 google results right now
because I already tried a bunch and they were crap
so I'm asking for someone who knows what they're talking about
to recommend me something
What is your usecase and definition of “good one”
it's subjective, and I'm asking for a subjective recommendation
Just answer?
holy crap friends this is insanely unproductive I am just asking for someone who is already using one to say what they're using and if it's any good
that's really not much to ask for
i'm pretty sure 99% of people are using that first one off google lol
I make my own serialised dictionary
So hard to say what is your detailed usecase and what you want
yea is it any good
Lol
which ones have you tried?
Generally Google results by relevancy so the first few results are the best ones
I'm looking for people who tried them I said it like 10 times now
Just stuff them in List
that's exactly my point!!! top results aren't the best
Load as Dictionary at some point
There's no other libraries
Coming from someone who's already tried it
Just diy
Which is incredibly unspecific
What's wrong with this one? https://assetstore.unity.com/packages/tools/utilities/serialized-dictionary-243052
You instantly shoot down suggestions, but generally these work fine
this is the type of thing I'm looking for
someone who also looked for it and went through the pain
Ideally I'd find a premade package but if it's not possible then I guess I gotta make one myself although I wanted to avoid it
There are loads of reviews on that one for you to get a wider range of opinions on it too
yea I'll just share my experience
do you understand why I came here
I am not looking for a suggestion
I can google, I know how to do that
I'm looking for a recommendation from someone who already uses one
that's different
you don't have to understand my thought process
my experience is that all the packages do too much
it's not worth asking around
everyone makes their own
Can somebody help with this?
I'd wager more people use a premade one than make their own
see below !ask
:thinking: Asking Questions
:mag: Search the internet for your question!
:book: Use the API Scripting Reference and User Manual and this troubleshooting site for commonly posted issues.
:wrench: Attempt to debug your issue.
:thought_balloon: Find an appropriate channel by reading the name and description in #🔎┃find-a-channel
:grey_question: And don't ask to ask, ask a full question illustrating with screenshots if needed.
-# For more posting guidelines, go to #854851968446365696
How may we help?
I have no idea who the hell is Chirz
What works for others might not work for you, just saying. so even a recommendation from someone else can give you personally a bad result in your system. So you HAVE TO try it anyways. No matter your thought process or why you came here, its the way you have to add features (package in this case), test, try, get a result, adapt
Well, Chirz (@arctic sparrow ) was trying to use the player's current orientation to recenter the camera with. But it didn't seem to work no matter what we set the input to.
Which function does this currently?
What do you have so far
I posted the script here.
I don't see any code for changing the orientation of the camera
I guess, the missing part is inside this method... CharacterCamera.UpdateWithInput(Time.deltaTime, scrollInput, lookInputVector);
Id say, add a bunch of debug.logs first and see, if all your if clauses are actually working as they should
if(InputMod.GetButtonDown(CenterCamInput)) characterInputs.CameraRotation = CharacterCamera.Transform.rotation = Character.transform.rotation;
Wait, I think we might be looking at it the wrong way. It's in the HandleCharacterInput function instead of the HandleCameraInput function
And what are those random brackets?
Phew, hurts me personally, but that might just be my preference to not to 😄
you guess?
who's the one who wrote this code
on a scale of 1-10 how much do you understand the code you wrote
its from the question from chirz and seekingthesky
Not me, apparently
ngl it looks like chatgpt code
Not sure chatgpt would write uppercase camelcase mixtures, but could be
you're confusing people here - cathei isn't involved with the asking of the question, just offered their interpretation as to why the { is randomly there
It’s sometimes useful in C++, not really in C#
ah
Whoever made the Kinematic Character Controller is the one who wrote most of this code.
whatever, so, you were talking about you might looking at the wrong method? Did you start debugging with logs already? Not sure what @arctic sparrow meant exactly about
Well, we had that code segment in the wrong function. Right now, we're getting somewhere, but something in the camera code is causing it to snap back to where it was before centering the camera.
Did you start to comment out all camera affecting parts to see, when that behaviour starts to happen?
Still working on it
OK! I found a fix!
if(InputMod.GetButtonDown(CenterCamInput)) CharacterCamera.PlanarDirection = Character.transform.forward;
"CharacterCamera.PlanarDirection" was one of the values leading into determining the camera's rotation.
It's using the C# convention, so I would hope that it did
So the code was uppercase for public and _lowercase for private, thats not the c# convention, right?
Pascal for public, underscore camel for private, yes
Guess I have been too much into unity scripts then 😄
you got anything to read up for me, just wondering why all scripts including unity built ins are not that way
Because Unity is very old
Haha, funny, I thought that _ thing was very old as it remembers me of very very old scripts I wrote back then
All new packages use the correct conventions, but the built-in code does not because it's a legacy codebase with that old style
thanks for enlighting me here! 🙂 guess I will start the next project with those conventions correctly then
Isn't the convention in Unity like this because they used to support a javascript-like language that had these conventions?
Which is obviously long gone, but now this remains
ugh _ is an odd convention when IDEs now color code for private public
They also use Hungarian notation
Which has nothing to do with JavaScript-likes. It's just a really old codebase with very old decisions
Never seen that happen, ever
You get used to it real quick, so imo as long as it's consistent it really doesn't matter
yeah tbh if I work in a team I go with whatever but I do not feel the need for _ or s _ myself ... cant write underscor
There's another good reason to use underscore for private. When you work with a large managing class, and it's hard to track all private class fields, when you start typing with _ you get them to popup easily.
I used to use Unity's conventions, then I switched, and imo it's nicer to use C#'s because then you feel more comfortable when working externally where that convention is practically saturated
But personally I don't like using it for aesthetics and trying avoiding classes get so large that I need that :D
Is this some VS setting that's disabled by default?
ah yes - because otherwise I probably would do it!!
Some people don't have class and struct type names highlighted differently and that freaks me out
I might turn that on then. I think the conventions are still very useful for the reasons listed, but it's definitely an added step in readability
What I do not like is Unity's old camelCase properties which have long been wrong
Is there a convention of not always using properties in structs like with Vector3?
VS supports analyzers using .editorconfig files. I believe it also has conventions for that
Though it might suggest properties rather than fields, which is the opposite in your case
Structs don't necessarily need to protect input because usually they're not doing work, so a property would be unnecessary overhead
Yes though not sure any overhead remains after unity optimises it, at least with il2cpp
In the past Unity does very little method inlining
The Vector structs don't care if you assign X as 1 or 29, it's just data, what good would a property do
Any float is valid, without context it's just raw data
Reducing method call overhead
There is no reason to use a Property in many class cases but it is standard practice afaik. Was not sure if differes for structs
It's only standard to avoid making breaking API changes
If you've got nobody consuming an API, then it's a practice ready to be dropped
thats an interesting read. I thought list.Count caching was not required...
They haven't updated that doc in a long time so I would expect certain things to have changed
Also this is a micro optimisation in most cases
indeed
A field's getter and setter accessibilities are tied together. If you want to have public getter and private setter for example, then property is the only way.
Interface can contain properties but not fields. This means that if you need to latter add an interface to an existing class, you don't need to refactor anything.
It's unfortunate that Unity's serialization doesn't play very well with properties, that property vs field is even a choice we have to consider.
yeah this is a problem since Properties are more common that fields these days!
you can serialize the field but will have odd name if not full property
What
I've got this code that lets you swing the back object around the front.
private void OrbitWheels()
{
_orbitSpeed += (_aimDirection != Vector2.zero ? 1 : -1) * _speedRate * Time.fixedDeltaTime;
_orbitSpeed = Mathf.Clamp(_orbitSpeed, 0f, _maxOrbitSpeed);
Vector2 sideForce = _aimDirection;
Vector2 force = transform.TransformDirection(sideForce) * _orbitSpeed;
_rb.AddForce(force, ForceMode2D.Force);
}```The issue is the orbit direction starts to become confusing when you face other directions instead of moving up. At the start Left/Right makes sense, but at the end when you move downwards, Left/Right become inverted
_aimDirection is set with the arrow keys, so it really should be able to use the correct key based on the direction you are heading
Doesn't TransformDirection there treat sideForce as local space direction and make it world space though? What you seem to want it just use the input vector as a world space vector as is
Are you trying to mimic the physics of a trailer?
oh yeah, that was it!
Sort of. But its actually going to be a train carriage thats driving "offroad"
well, offrail
what do you think guys for a first person game, its better to manage the camera as children of player or both separate gameobjects? i cannot get working smoothly the gamepad, it wors fine mouse only, and maybe its a better approach to add camera as children ?
my gs how do I read a playerpref registry file
I tried google
let me try again
not as in find it as in read the value of it
is there a difference between transform as RectTransform or (RectTransform)transform?
do you want the camera to move with the player at all times? if not, try a position constraint. if you do though, just parent it. kind of depends on what kind of game you're making
some context:
for a first person game, in the past I often did player as child of camera, but keeping them separate is how I'd do it now
Read from playerprefs? I highly doubt you found nothing
what?
anyways I have a bigger problem
I set this to "hey:
"hey"
and this outputs null and saveslot 1
plain text username and password
sorry I dont understand?
it's not a server xd
https://stackoverflow.com/questions/132445/direct-casting-vs-as-operator
string s = (string)o; // 1
Throws InvalidCastException if o is not a string. Otherwise, assigns o to s, even if o is null.string s = o as string; // 2
Assigns null to s if o is not a string or if o is null. For this reason, you cannot use it with value types (the operator could never return null in that case). Otherwise, assigns o to s.string s = o.ToString(); // 3
Causes a NullReferenceException if o is null. Assigns whatever o.ToString() returns to s, no matter what type o is.Use 1 for most conversions - it's simple and straightforward. I tend to almost never use 2 since if something is not the right type, I usually expect an exception to occur. I have only seen a need for this return-null type of functionality with badly designed libraries which use error codes (e.g. return null = error, instead of using exceptions).
3 is not a cast and is just a method invocation. Use it for when you need the string representation of a non-string object.
(i think this explains it)
Consider the following code:
void Handler(object o, EventArgs e)
{
// I swear o is a string
string s = (string)o; // 1
//-OR-
string s = o as string; // 2
// -OR-
string s = o.To...
I know, doesn't make huge deal anyways
for proof that its hey in the registry
hopefully at least
show us your setstring code
and you're absolutely 100% sure that Save.selectedSaveSlot is the same
like dead sure
its a static variable that is not edited anywhere else
public void Submit(string type)
{
user = username.text.ToString();
pass = password.text.ToString();
if(type == "login")
{
Debug.Log(PlayerPrefs.GetString(Save.selectedSaveSlot + "_Username"));
Debug.Log(PlayerPrefs.GetString(Save.selectedSaveSlot + "_Password"));
if(PlayerPrefs.GetString(Save.selectedSaveSlot + "_Username") == name && PlayerPrefs.GetString(Save.selectedSaveSlot + "_Password") == pass)
{
SceneManager.LoadScene(4);
}
else
{
Debug.Log("Wrong password or username");
}
}
if(type == "signup")
{
PlayerPrefs.SetString(Save.selectedSaveSlot + "_Username", user);
PlayerPrefs.SetString(Save.selectedSaveSlot + "_Password", pass);
Instantiate(signUpConfirm, mainCanvas.transform);
Invoke("ConfirmSignup", 2.0f);
}
}
!code
📃 Large Code Blocks
Use links to services like:
https://paste.mod.gg/, https://hastebin.skyra.pw/, https://paste.ofcode.org/, https://paste.myst.rs/, https://scriptbin.xyz/
📃 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.
!code
📃 Large Code Blocks
Use links to services like:
https://paste.mod.gg/, https://hastebin.skyra.pw/, https://paste.ofcode.org/, https://paste.myst.rs/, https://scriptbin.xyz/
📃 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.
hah, beat you to it 
woops 😄
public void Submit(string type)
{
user = username.text.ToString();
pass = password.text.ToString();
if(type == "login")
{
Debug.Log(PlayerPrefs.GetString(Save.selectedSaveSlot + "_Username"));
Debug.Log(PlayerPrefs.GetString(Save.selectedSaveSlot + "_Password"));
if(PlayerPrefs.GetString(Save.selectedSaveSlot + "_Username") == name && PlayerPrefs.GetString(Save.selectedSaveSlot + "_Password") == pass)
{
SceneManager.LoadScene(4);
}
else
{
Debug.Log("Wrong password or username");
}
}
if(type == "signup")
{
PlayerPrefs.SetString(Save.selectedSaveSlot + "_Username", user);
PlayerPrefs.SetString(Save.selectedSaveSlot + "_Password", pass);
Instantiate(signUpConfirm, mainCanvas.transform);
Invoke("ConfirmSignup", 2.0f);
}
}
can you store your playerprefs get in a string before logging it?
string yourName = PlayerPrefs.GetString(Save.selectedSaveSlot + "_Username");
Debug.Log(yourName);
not gonna lie, this should work
like if you do signup and login now, this should work
That's something you can check by diving into the definition of RectTransform. I assume it has an implicit conversion from transform or this code would throw
Alternatively transform is already a RectTransform here. I believe this is in 2d?
So transform's actual type is a base type for both 2d and 3d
transform does not have an implicit conversion to RectTransform, unfortunately
but I think you don't understand what I mean here, I wanted to know the differences between those two ways to cast transform to recttransform, my question was answered
comes out as this
they're effectively the same for my purpose
thats why I'm so confused Im not the ebst at this but the logic should be there
try giving it a default value perhaps? to check if it's saved as a space or sth, or if it's reading an unsaved value
Can I ask the reason why you are doing this casting? You probably want to pattern match
give what a default value?
yourName?
mate you have no clue what you're talking about, from the sounds of it
I would appreciate it if you stop being so passive aggressive constantly
Pattern matching is another way to match against a type, just like casting
OK guys, I think I got it figured out
yeah just for testing, do something like this
PlayerPrefs.SetString(Save.selectedSaveSlot + "_Username", user);
Debug.Log(PlayerPrefs.GetString(Save.selectedSaveSlot + "_Username", "nothing was saved"));
lemmie guess user variable was empty xd
turns out this was not the issue
its the if statement that doesnt show true
for some reason
I think, playerprefs is not "done" when logging it, so you get null/nothing
does anyone know how to lock cursor to a certain position?
No I set the saveslot value when I press the save file I want to enter, lol I was an idiot and worked from the logit scene itself so octia was right its empty
You can lock it, but have to calculate your offset yourtself, as you cant control the input from the user.
certain position being center of the screen?
Cursor.lockState = CursorLockMode.Locked;
otherwise? don't.
yay!
string yourName = PlayerPrefs.GetString(Save.selectedSaveSlot + "_Username");
Debug.Log(user);
Debug.Log("prefs: " + yourName);
string yourPass = PlayerPrefs.GetString(Save.selectedSaveSlot + "_Username");
Debug.Log(user);
Debug.Log("prefs: " + yourPass);
if(PlayerPrefs.GetString(Save.selectedSaveSlot + "_Username") == name && PlayerPrefs.GetString(Save.selectedSaveSlot + "_Password") == pass)
I'd be happy too if I didnt see this:
WHY????
THEY'RE LITERALLY THE SAME
Equals == true?
that's why we hate strings lmao
Hidden unicode? 😄
how would I ever confirm this
debug the lengths of each string
public void Submit(string type)
{
user = username.text.ToString();
pass = password.text.ToString();
if(type == "login")
{
string yourName = PlayerPrefs.GetString(Save.selectedSaveSlot + "_Username");
Debug.Log(user);
Debug.Log("prefs: " + yourName);
string yourPass = PlayerPrefs.GetString(Save.selectedSaveSlot + "_Username");
Debug.Log(user);
Debug.Log("prefs: " + yourPass);
if(yourName == name && yourPass == pass)
{
SceneManager.LoadScene(4);
}
else
{
Debug.Log("Wrong password or username");
}
}
if(type == "signup")
{
PlayerPrefs.SetString(Save.selectedSaveSlot + "_Username", user);
PlayerPrefs.SetString(Save.selectedSaveSlot + "_Password", pass);
Instantiate(signUpConfirm, mainCanvas.transform);
Invoke("ConfirmSignup", 2.0f);
}
}
it literally both uses user
so it doesnt make sense
its like asking if user == user and getting false
sanity check...
try
if((yourName == name) && (yourPass == pass))
if this works istg
yeah XD
No sir
You should not be comparing strings like this. Strings in C# have build in systems that increase performance by reusing them. The reason yours are not used is because they are not reusing the same string instance most likely
So instead of if (a == b), use if (a.Equals(b))
Also pointing out the obvious, but if a person applies a single character with different casing, it will also fail. name != Name. I assume you understand this
I'd consider that intentional if I was building this, tbh
for password obviously, but even for the name
those two are equivalent for String
can you show example?
That was for Sehongbear. If their application doesn't case about casing in usernames (which is quite often), then they should make sure to compare a string whilst ignoring the casing
Im restarted
did it work?
i did name instead of pass
oh lmao
through toLower() and all that?
No, if you provide the StringComparison enum through Equals() it just changes the way comparisons is handled in general
This isn't just by defining how casing works. There are certain cultures where in one case a string might mean the came, but in others it does not
Like weird characters with symbols above them. I don't have a direct example
you should use ToLowerInvarient
OK
You already use Equals here. Just add a second parameter StringComparison.OrdinalIgnoreCase
No need for ToLower or anything like that
if(yourName.Equals(user, StringComparison.OrdinalIgnoreCase) ...
OK
This is generally how string comparison is done
I'll always use .equals from now, thank you sir for teaching me a lifelong lesson
genuinely forgot about allat equals stuff
It's not applicable literally everywhere. You might want to use ToLowerInvariant or ToUpperInvariant in cases for normalization or something
Fun fact, you should actually use ToUpperInvariant because ToLowerInvariant and the other non invariant versions have unexpected quirks to them
That's better suited for this use case, yes
ToUpper/ToLower involve copying the characters into a newly allocated string, passing in the the comparison type changes the comparison logic without needing to do that
private void CheckLetterInput()
{
foreach(Key key in keys)
{
if (Input.GetKeyDown(key.ID))
{
PressKey();
}
if (Input.GetKeyUp(key.ID))
{
ReleaseKey();
}
}
}
private void PressKey()
{
foreach(Key key in keys)
{
if (key.CheckKey())
key.IsPressed();
}
}
private void ReleaseKey()
{
foreach (Key key in keys)
{
if (key.CheckKey())
key.IsReleased();
}
}
public void IsPressed()
{
gameObject.GetComponent<SpriteRenderer>().sprite = keyPressedAlt;
}
public void IsReleased()
{
Debug.Log("hi");
gameObject.GetComponent<SpriteRenderer>().sprite = keyPressed;
}
anyone know why this doesnt work?
"hi" doesnt show up in the console
meaning that key.CheckKey isn't true for release key while it is true for presskey??
hard to understand
Time for clarity then
Start logging the values, see if they return what you expect
If you think the issue is key.CheckKey, then debug what the value returns
First thing you always do is pinpoint the exact part of the code with the issue
understood sir
the foreach part works
ok
using this
the first checkkey for presskey is true then 25 falses
but all checkkeys are falses for releasekey
would it not have been sensible to log which key you were checking?
oh to print all keys?
ok
OK. I pressed the w key which was right and the presskey got it
however, release key always seems to start form Q
actually nvm
it just doesnt work
checkkey returns true for presskey
but doesnt for release key
even if the same P is entered
Keep on rubber ducking
and type in full sentences
This is checkkey btw, for clarification
Looks good to me chief
This is so weird. They both are the exact same methods, so it doesn't make sense that one is returning false while the other is returning true.
Yes
Why do you have that?
I have 26 gameobjects to create a keyboard
Oh, this is a game keyboard?
Yes
Understandable
is pressed and is released are supposed to be to change the sprite of the key, pressed down and greyed out or not
Theres literally nothing more to uncover. Its clear that everything is working, but that CheckKey is not returning true for ReleaseKey for some reason, but the why is unknown
I personally think its a problem with getkeyupo
but I don't know if theres anything I can use other than GetKeyUp for this
private void CheckLetterInput()
{
foreach(Key key in keys)
{
if (Input.GetKeyDown(key.ID))
{
PressKey();
Debug.Log("hi");
}
if (Input.GetKeyUp(key.ID))
{
ReleaseKey();
Debug.Log("hi1");
}
}
}
private void PressKey()
{
foreach(Key key in keys)
{
Debug.Log(key);
Debug.Log(key.CheckKey());
if (key.CheckKey())
key.IsPressed();
}
}
private void ReleaseKey()
{
foreach (Key key in keys)
{
Debug.Log(key + "1");
Debug.Log(key.CheckKey() + "1");
if (key.CheckKey())
key.IsReleased();
}
}
public bool CheckKey()
{
return Input.inputString.Equals(ID, System.StringComparison.OrdinalIgnoreCase);
}
I GOT IT
The inputstring will be empty when I let the key go
duhhhhhh so then if checkkey is called during the time when the key is released, then ofcourse the inputstring will be nothing!
so I need an input for checkkey
Thanks for letting me rubberduck yall
also do I need reload domain opn it takes so long every time. When can I disable it?
Ok new problem
this works but removing the debugs makes it not work anymore, specifically the debuglog on the top
do you not know how to write an if statement?
Holdon this doesnt work?
think about it, what is the difference in logic with and without the Debug statement
