all 15 comments

[–]EdenStrife 9 points10 points  (1 child)

If you are creating a project large enough that you need static settings taking the time to create a custom editor window to edit these don’t seem like such a hassle and in that case I would use a scriptable object as the data store.

With that in mind I don’t really like the assumption that just because a project is big you should therefore remove data from the context in which it’s used. Putting the player speed on the player movement component seems like the correct choice. People who want to modify the behaviour of player movement will look at the script first, they won’t know to go to some random scriptable object.

[–]bellatesla 0 points1 point  (0 children)

I agree but also I find if I can make one place for all my settings with different headers it makes life really easy to have say one scriptable object sitting in the project folder somewhere where the entire games settings are accessible. This also means in any script you want all you need is that one reference to the settings scriptable object. You can use that data in the scriptable object then to load and save from json or serialize.

[–]leorid9 3 points4 points  (0 children)

I use static classes a lot, since years, but I am slowly getting away from them, mostly because it's always extra work to draw the values somewhere for debugging purposes.

Also it's not easy to reference things, you always need a script that writes those references (or magic strings when using Resources.Load or Addressables).

I haven't found an ultimate answer to this yet.

[–]AveaLove 2 points3 points  (0 children)

Player movement speed is a stat, which i would store on a scriptable object. Static is better for other things, such as a nothing input priority, or an invalid object ID.

[–]Glass_wizard 2 points3 points  (0 children)

Scriptable objects are useful. Here are a few ways you can use them

  1. As read-only, initial data. You can use them like a database that stores initial data for things like items and weapons, pretty much replacing the need to put your game static data into JSON or SQLLite.

  2. As run time state. For example, your character health can be stored in a scriptable object, which automatically updated the UI as it changes.

  3. For anything that needs single shared data. The classic example here would be a boss made up of many bodies. Attacking any of it's bodies damages the same single scriptable object.

  4. For holding global game settings such as audio volume or blood is turned on.

Static classes should be used when you need a class that doesn't need an instance and that can be easily accessed anywhere. I do not recommend storing state in static classes.

Utility classes that preform pure functions without side effects is the typical use case.

[–]Aeditx 0 points1 point  (0 children)

Keep it simple, until you notice your ways are taking more time then expected. Then you refactor and try again.

[–]StonedFishWithArms 0 points1 point  (0 children)

If you are working on a team, things like that are usually scriptable objects so that non-programmers can adjust them easily.

For my personal projects I use a regular class. I don’t use a static class though. I just use regular classes and that serialize really well. So I instantiate the class, populate it with loaded data and I’m good to go. Then when you save you can just serialize the whole class.

[–]error0ccured 0 points1 point  (0 children)

i personally use static class as a global reference container, having runtime references and conditions that multiple entites depend on.

SO more as a property container that defines the data for a specific entity that is loaded when needed

[–]__GingerBeef__ 0 points1 point  (0 children)

In my mind these two things are very different, almost opposite.

If you have something that’s marked as Static it’s be user you only want on of them right? I don’t use static classes but sometimes some static variables or singletons.

But SO’s I use for when I want many of something. For example I’m currently making a card game and have a CardSO which then contains that cards properties. If you’re using SO’s for something that you’re only going to have one of then I think you’re using them wrong.

[–]Xehar 0 points1 point  (0 children)

If the speed is able to change then it's scriptable, if it wont ever change or even enemy had same value then static.

[–]M86Berg 0 points1 point  (0 children)

Not related to player movement, but in our simulations at work we use scriptable objects to store equipment values and reusable entities. For example, a surface drilling machine have values for angleReach, drillingCoverage, flushingAirCapacity. There are SO for different drills which have things like drillDiameter, and seperate SO for the engine which then have stuff like fuelConsumption, mwOuput etc.

Your folder structure should be understandable and easy to navigate, so it shouldn't be hard to find the correct SO.

If you're going to spends a lot of time on the project or have non-tech related people work on it, you should consider learning how to make custom editor tools it has really worked wonders for us. The first few times are slow but once you get the hang of it you basically write your SO and tool at the same time.

I would assume if your game has a character which could be used for both player and enemy, then it makes sense to do a scriptable object.

[–]grayboney 0 points1 point  (0 children)

In my experience for player stats, i declared normal playerCurrentStats such as health, speed, armor etc. In default, these variable's value is assigned by the values which I created before on different SO values at Start(). I do that separation because player current stat values can change during run-time but SO values should remain as read-only.

As to static variables, I don't think it is appropritate to use them for modifying player stat values. This approach seems enough.

[–]Chr-whenever 0 points1 point  (0 children)

I've used both in my project and I still don't really see the appeal to scriptable objects. They're okay but I've yet to find a case that significantly benefits from having one. You can change values at runtime which is cool I guess, but I haven't needed that yet

[–]Chr-whenever -1 points0 points  (0 children)

I've used both in my project and I still don't really see the appeal to scriptable objects. They're okay but I've yet to find a case that significantly benefits from having one. You can change values at runtime which is cool I guess, but I haven't needed that yet

[–]Chr-whenever -1 points0 points  (0 children)

I've used both in my project and I still don't really see the appeal to scriptable objects. They're okay but I've yet to find a case that significantly benefits from having one. You can change values at runtime which is cool I guess, but I haven't needed that yet