I am trying to save a floating point values (from a Float[] array) to a variable property (of type float), but I am not able to save it correctly. Everytime I want to save a new value, the variable property never accepts the new value and keep retaining the intialized value only. Here I am trying to save value,
CommandLineVariables.PiSenseResistor = tempFloatArray[0];
Where,
CommandLineVariables is the class name
PiSenseResistor is the variable property
tempFloatArray is the float array from which I want to save value
I tried using single stepping and watching the variable property value, but always after the execution of the above mentioned instruction, it shows the initialized value only.
The same thing I am doing with other variable properties as well and they are working correctly. I am wondering what I am doing wrong with this saving of floating point number into variable property.
Edited
Adding some extract of the code:
//variable initialization
private static float piOffsetPressure = 1.01295f;
//Property definition for the variable
public float PiOffsetPressure
{
get
{
return piOffsetPressure;
}
set
{
piOffsetPressure = value;
}
}
//Copy the parameter value into its corresponding property
if (!Convert.ToBoolean(ReturnCode))
{
CommandLineVariables.PiOffsetPressure = tempFloatArray[0];
CommandLineVariables.PdOffsetPressure = tempFloatArray[1];
}
You are setting PiOffsetPressure, but the property you posted is PiSenseResistor. Why would setting one affect the other?
Related
I have a simple class called Behaviour that saves a string and a string-array. It looks like this:
[System.Serializable]
public class Behaviour {
public string Methodname;
public string[] Parameters;
}
As you might already expect, this class is to save a method to make it possible to plug methods into the unity inspector. Methodname is the name of the method plugged in, while Parameters are all the parameters for that method formatted in a way that a static utility class can read (these string get converted to objects to then be used as parameters. so a string of "i25" would get converted to an integer parameter of 25. the array is a string as object[] cannot be serialized and thusly not saved.
I will strip out all unnecessary logic and focus on what's going wrong. Lets just assume that we want to save a single integer into the first index of the parameters array. The PropertyDrawer of Behaviour would then look like this:
[CustomPropertyDrawer(typeof(Behaviour))]
public class BehaviourEditor : PropertyDrawer {
private Behaviour propertyReference;
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
propertyReference = fieldInfo.GetValue(property.serializedObject.targetObject) as Behaviour;
// Check if the string array is null. This happens the very first time the scriptable object is created
if(propertyReference.Parameters == null) propertyReference.Parameters = new string[1];
// Check if the first index is null. In this simplified example also only happening the very first time.
if(propertyReference.Parameters[0] == null) propertyReference.Parameters[0] = "i0";
int value = (int)DataConverter.StringToObject(propertyReference.Parameters[index]);
value = EditorGUILayout.IntField(value);
propertyReference.Parameters[0] = DataConverter.ObjectToString(value);
}
}
The DataConverter simply converts from object to string and vice versa (so int n = 9 would become "i9" or "i255" would become object x = 255). All of this logic works.
Again to clarify: This is the PropertyDrawer of Behaviour. Behaviour is a private [SerializedProperty] within a ScriptableObject.
If the array is null, the if == null triggers and puts the array Parameters to the length of one. The later logic all works, we can assign values to the int field from the EditorGUILayout and the value there gets correctly saved into the array. All of that logic works.
BUT: something is changing the Parameters-Array of Behaviour. I believe that something to be the ScriptableObject. The very next frame, Parameters is no longer null (obviously) and we try to thusly access index position 0. Which results in an index out of range exception because something changed Parameters to new string[0]. They didn't set it to null, they set it's length to 0.
Why? What could possible trigger this logic? If I make Parameters a property and set a breakpoint into the set-method, noone else calls it but my own code above, yet the array still becomes length of 0. Any ideas?
Unity's Serializer indeed auto-initializes any fields of a serializable type such as a list or array or string etc! -> They will never be null, worst case they will be empty.
If you simply want defau values for your fields you can simply assign them in your class itself, no drawer needed for this:
[Serializable]
public class Behaviour
{
public string Methodname = "ExampleMethod";
public string[] Parameters = new string[1] { "i0" };
}
In general do not directly change values via the target in editor scripts!
This will cause you a lot of headaches regarding marking changed objects as dirty, serialize/save values correctly persistent, handle undo/redo etc
Always rather go through the SerializedProperty and use e.g.
var methodName = property.FindPropertyRelative(nameof(Behavior.Methodname));
var parameters = property.FindPropertyRelative(nameof(Behavior.Parameters));
and then do e.g.
EditorGUILayout.PropertyField(methodName);
and access and assign e.g.
parameters.arraySize = 1;
var parameter = parameters.GetElementAtIndex(0);
parameter.stringValue = "i0";
but as said that's only an example, you really want to simply put the default values in the class, not the drawer.
Also putting
EditorGUI.BeginProperty(position, label, property);
...
EditorGUI.EndProperty();
around your property drawer content is essential for the dirty state handling! See Property Drawers
I am having a problem assigning values in my function. Here is my code
//Player cents
private int add_cents = 3;
public int player_1, enemy_1, enemy_2, enemy_3;
public void players_ready()
{
add_cents_player(player_1, add_cents);
}
public void add_cents_player(int player, int cent_v)
{
player = player + cent_v;
}
I want to be able to call this function and input whoever is the active player (player) and increase their value by (cent_v). However, player = player + cent_v; is saying "Unnecessary assignment of a value to 'player" and I don't understand why. It wouldn't be possible to hard code, as it is dependant on what who is the active player.
One option is to change the method return type:
private int add_cents = 3;
public int player_1, enemy_1, enemy_2, enemy_3;
public void players_ready()
{
player_1 = add_cents_player(player_1, add_cents);
}
public int add_cents_player(int player, int cent_v)
{
return player + cent_v;
}
int is a value type. It is passed by value meaning the player will actually be a copy of player_1. If you then change the player inside your method this doesn't affect in any way the player_1 since it is no reference and no relationship between them.
It looks like what you wanted to do would be using ref in order to "force" the value to be passed by reference
public void players_ready()
{
add_cents_player(ref player_1, add_cents);
}
public void add_cents_player(ref int player, int cent_v)
{
player += cent_v;
}
thus that after calling players_ready the value player_1 is actually increased
There are 2 ways to pass a variable to a function. 1 is by reference, meaning you pass a reference to a variable into the function. This is what happens with variables of type object - not the whole object's memory is copied and supplied to the function, but only an address to the piece of memory where that object resides.
For int, float etc. this is different. The values are passed by value.
Also see the relevant msdn docs.
There is a fundamental difference between the two options: reference types are passed by reference and can be altered and the original object also gets altered. E.g. this works:
class MySimpleObject // an object is a reference type
{
public int someValueType; // int is a value type
}
...
var x = new MySimpleObject();
myFunc(x); // increment x.someValueType by 5
This does not count for objects passed by value, which is what happens with int, as its a value type. Therefore your function does nothing, because its only manpulating the local value, the reference is not passed.
var player_1 = 5;
add_cents_player(player_1, 15);
// Player_1 is still 5
add_cents_player(player_1, 15);
// Player_1 is still 5
...
And thats what the compiler is complaining about; you're adding a value to the local parameter in the function. But since you don't return this, or read the value at some point the compiler is like 'hey this code does nothing, and therefore its better to remove it.
I set the following property:
public Object Value
{
get
{
return AdministrationSettings.Default[settingCode];
}
set
{
AdministrationSettings.Default[settingCode] = value; // <<< Error occurs here
this.RaisePropertyChanged(() => this.Value);
}
}
This property provides the link between the fields of my interface and those of the object AdministrationSettings
AdministrationSettigs represents Settings class .net (having an extension .Settings)
Inside I defined within the properties here is an example:
When I made the entered data in a field in my interface, here display this interface:
the program stops at the instruction of line 9, and generates this error:
The settings property "ExclusionZone" is of a non-compatible type, here the code
the ExclusionZone is one parameter which defined in the .Settings File. its type is double. It is also in the same file (. Settings) they set other parameters, there are those who are of type string, double, Boolean
the problem is only in the Set, for the Get get it's right
I hope there will be someone who can help me
Thanks
private int value = Convert.ToInt32(Properties.Settings.Default.Setting);
Properties.Settings.Default["Setting"] = value + 1;
This crashed for me but when I changed to value + 1.tostring(); It worked. Ofcourse because my "setting" is of type string. So check that ur value is of the right type :)
First of all you might want to change the manner in which you are trying to access the application level properties that you defined.
As alexander points out try: Properties.Settings.Default["PropertyVariable"] instead of AdministrationSettings.Default["PropertyVariable"]
Secondly you have defined three properties namely: (1) ExclusionZone, (2)AlertZone (3)ExcessiveSpeed but you are trying to access 'settingCode' which is not defined.
Thirdly you are missing inverted commas.
Once you sort these three things, make sure you cast 'value' to the correct data type.
I use ProfileBase to get and maintain extra settings in a user profile. The ProfileBase object that you get from the ProfileBase.Create() function seems to return something like a dictionary of string-to-string. Therefore, when I make changes to values and save them, I have to cast them to string, and then call the Save() function on the ProfileBase object. Here's me saving a bool flag, but first converting it to an int (1 or 0) and then saving that as a string...
ProfileBase pb = ProfileBase.Create(userNew.UserName, true);
if (pb != null)
{
int iCreateFlag = createDefaultDummyAccounts ? 1 : 0;
pb["CREATEDEFAULTDUMMYACCOUNTS"] = iCreateFlag.ToString();
pb.Save();
}
If I do not cast iCreateFlag to string, and I try to save the iCreateFlag as an int, I get "The settings property is of a non compatible type", even though my column is defined in the database as INT. Hope this helps anyone else out with this problem.
When I declare a method with parameters, and inside my method I assign value to those parameters, those parameters turn into variables?
My question is, can I Say: "The parameter of my method is also a variable when I use it inside my method"?
Example:
public int returnDays(int month)
{
month = getMonth();
//"Can I say : month is a variable?"
}
//"Can I say : month is a variable?"
yes it is a local variable to that method.
Official docs on passing arguments
Yes it is called variable and you can call it variable and you can use it. Variable is a named place holder in memory whoes value could be changed in program
In computer programming, a variable is a storage location and an
associated symbolic name (an identifier) which contains some known or
unknown quantity or information, a value. The variable name is the
usual way to reference the stored value; this separation of name and
content allows the name to be used independently of the exact
information it represents. The identifier in computer source code can
be bound to a value during run time, and the value of the variable may
thus change during the course of program execution, reference.
You have 2 questions
I declare a method with parameters, and inside my method I assign
value to those parameters, those parameters turn into variables
Short Answer YES they are variables
can I call variables to the parameters of the method when I use them
inside my method
As far as your context is concerned Yes you can use them but in a broader perspective what variables are accessible to you inside the method scope you should read this before going in to development details
I don't entirely get your question. Yes, "month" is a variable. However, I'm unsure on what you're trying to achieve by assigning it.
The int type derives from struct, and this means that it isn't passed by reference. When you call returnDays(x), x itself isn't passed and a copy of it is made.
If you, instead, wanted to change its value AND return the days, you'd need to use the ref or out keywords. The former basically passes a pointer to x, which can be used as your function pleases. The latter, however, is stricter and requires the function to initialize whatever value is passed through it.
So, this is the code you'd end up with
public int ReturnDays(out int month)
{
month = GetCurrentMonth();
return GetDays(month);
}
But still, I am not sure if this is the kind of answer you wanted.
First of all, is this C# or Java? Each language has its own eccentricities.
If C# use the out statement that KappaG3 showed.
If Java,
just use a return statement inside your function/method:
return getMonth();
If you need to return multiple values, you can pass objects and then assign to those objects inside the function/method. Objects are passed by reference where as primitives are passed by value. integer is an Object but doesn't act like one as you can see from:
//
public class Main {
public static void main(String[] args) {
int value1 = 0;
Integer value2 = new Integer(0);
MyObject value3 = (new Main()).new MyObject(0);
passByVal(value1);
passByRef(value2);
passByRef(value3);
System.out.println("value1 = " + value1);
System.out.println("value2 = " + value2);
System.out.println("value3 = " + value3);
}
class MyObject
{
public int value = 0;
public MyObject(int value) { this.value = value; }
#Override
public String toString() {
return value + "";
}
}
public static void passByVal(int i)
{
i = 7;
}
public static void passByRef(Integer i)
{
i = new Integer(7);
}
public static void passByRef(MyObject o)
{
o.value = 7;
}
}
which return the output:
0
0
7
so if you need to return a bunch of values I recommend passing objects or returning an object that is specially designed to hold all those values
I will first illustrate my issue with some code:
class ExampleClass
{
private Vector2 _myVector;
public Vector2 MyVectorProperty { get { return _myVector; } set { _myVector = value; } }
private void MyMethod()
{
_myVector = Vector2.Zero; // Setting to zero
MyVectorProperty.X = 5; //Cannot modify the expression because it is not a variable (returns an error)
_myVector.X = 5; //Works fine!
}
}
As you can see, I am getting the error "Cannot modify the expression because it is not a variable" when trying to change the value of X and Y on the vector using the property. I am unsure why this happens and haven't had any luck looking on the net and i was wondering why this is and how (if) I can fix it?
Another sub question, is it good programming practice to use the public properties or the private/protected fields when working inside the class they belong to?
You should be happy compiler does not let you do so, otherwise you'll be really surprised with result of operation being lost.
MyVectorProperty is property - which means getting the value is call to a function returning the value (something like this.get_MyVectorProperty()).
Since type of the MyVectorProperty is Vector2 which is struct it means that value returned by the get_... function is a copy of value, not reference like it would be in case of normal class.
Changing field X of above copy would simply change X inside of copy of the value, and since that copy of the value is not assigned to anything it will be lost.
Vector2 is a struct (value type), so your property returns the value of _myVector (i.e. a copy) and you can't change that.