Reputation: 305
I have this code and my objective is to modify the field value to be used in any method in the abstract class. What I understand is that:
private int speed
)public int Speed {get;set;}
or public int Speed {get => speed ; set => speed = value;}
But the editor (variables are not modified there, it is hard code) doesn't throw the expected result, it is, to modify the speed
field value.
A clear and concise explanation is appreciated.
Upvotes: 0
Views: 5702
Reputation: 369
[SerializeField]
marks fields.
Properties are syntactic sugar for methods getting/setting a value.
When you declare a property like public int Speed {get;}
a hidden backing field is generated by the compiler which is where the value is actually stored, this field is private and so will not be serialized automatically by Unity's serializer. (Additionally the compiler will generate a method public int get_Speed()
which is the implementation of the property's get
you can verify this by declaring this method yourself, the compiler should complain about a member with the same signature already existing.)
C# 7.3 added Auto-implemented property field-targeted attributes, allowing you to do this:
[field:SerializeField] public int Speed {get;}
This will apply the SerializeField
attribute to the hidden generated field and Unity should serialize it normally. Note that the name of this hidden field will have the special name <Speed>k__BackingField
something to keep in mind if you plan to implement a custom inspector or property drawer.
Upvotes: 3
Reputation: 90639
You are confusing the terms "field" and "property". Properties can implement additional behavior in the getter and setter.
First of all: Unity does not serialize properties!
This limits the purposes of properties in Unity to the runtime.
So most of the time will want to go for a pattern like
[SerializeField] private int a;
public int A => a;
This e.g. serves the purpose that you can assign a value via the editor, edit it by the class itself but allow others only readonly access => Encapsulation.
And of course for completeness it can perform additional sanity checks like e.g.
private const int min = -3;
private const int max = 17;
private bool allowSet;
[SerializeField] private int a;
public int A
{
get => a;
set
{
if(allowSet) a = Mathf.Clamp(a, min, max);
}
}
An auto-property (in my eyes) is barely needed except you want to directly limit the access like
public int b { get; private set;}
This allows only this class to write but everyone else to read this value
So when something is useful is mostly subjective and depends on the situation.
Now looking at your code there is absolutely no relationship between Speed
- speed
and FireRate
-fireRate
! They are completely independent fields and properties.
The confusion here is probably due to the display names that the Inspector creates. It automatically makes all field names capitalized so
[SerializeField] private int _example;
will be displayed as Example
.
You most probably would simply go for
[SerializeField] protected float Speed;
[SerializeField] protected float FireRate;
Upvotes: 1
Reputation: 999
In your code, fireRate
and FireRate
are completely separate field/property as well as speed
and Speed
. Modifying fireRate
won't affect FireRate
and vice versa.
SerializeField
is used to serialize fields not properties. In both cases only fields(fireRate
and speed
) are serialized.
Try below code:
[SerializeField] public int a;
[SerializeField] public int b { get; set; }
[SerializeField] public int c => a;
Unity doesn't serialize property by default and only a
will be serialized.
Upvotes: 3