I'm trying to make a class selecting system and I have 2 scriptable objects one for the player and the other for classes and I'm trying to figure out how to change the values in PlayerSettings
to the ones in BaseClass
when a class is selected.
public class BaseClass : ScriptableObject
{
public float health;
public float walkSpeed;
public float fallSpeed;
public float jumpForce;
public string displayName;
public List<BaseAbility> abilities;
}
public class PlayerSettings : ScriptableObject
{
public float health;
public float walkSpeed;
public float fallSpeed;
public float jumpForce;
public BaseClass playerClass;
}
Heres the code I have for setting a class I use an event that gets called when a button is pressed and then I just change the values in the PlaerSettings
SO to the ones from the newClass
argument
public class Player : MonoBehaviour
{
public PlayerSettings playerSettings;
public Controls keybinds;
void Start()
{
ClassSelectButton.OnClassSelected = SetPlayerClass;
}
void SetPlayerClass(BaseClass newClass)
{
Debug.Log("Setting player class to: " newClass.displayName);
playerClass = newClass;
playerSettings.walkSpeed = playerClass.walkSpeed;
//etc
}
}
I'm not sure if what I have is fine although I have a feeling it's probably not though. Also, a quick second question as you can see PlayerSettings
and BaseClass
are basically the same would I want to use inheritance here or is it fine to keep it separate?
CodePudding user response:
At the top of your scriptable object code, you should add the line:
[UnityEngine.CreateAssetMenu(fileName = "Data", menuName = "ScriptableObjects/BaseClassScriptableObject", order = 1)]
Then, you should see this added to your right click menu.
Upon creating an object, it should look like this in your inspector:
An example with your code:
[UnityEngine.CreateAssetMenu(fileName = "Data", menuName = "ScriptableObjects/BaseClassScriptableObject", order = 1)]
public class BaseClass : UnityEngine.ScriptableObject
{
public float health;
public float walkSpeed;
public float fallSpeed;
public float jumpForce;
public string displayName;
}
CodePudding user response:
So what you could do is to make the playerClass a property and set the values in the set function, but maybe it's easier to just make the fields be properties that forward the playerClass values. I'll use the null coalescing and null conditional operators here, but hopefully this gives you an idea.
Also a good IDE should complain about the properties not beginning with a capital letter here but I'm trying to give you an example that won't break your current code:
public class PlayerSettings : ScriptableObject
{
public float health => playerClass?. health ?? 100f;
public float walkspeed => playerClass?.walkspeed ?? 1f;
public float fallSpeed => playerClass?.fallSpeed ?? 1f;
public float jumpForce => playerClass?.jumpForce ?? 1f;
public BaseClass playerClass;
}
The numbers after ?? are the default values you'd use if playerClass is null. These are all getters, though, so they're read-only. Again you could have the playerClass assign those values when it's set as part of the setter function, if you make it a property, but I don't know enough about your project to really make suggestions here. If you're leaving playerClass public here though it might just be easier to reach into that and get those values directly. I don't know what the point of your ScriptableObject is if it's just a public class to hold one public class.