- Home /
Setting a property, and then making it readonly. (c#)
Hello there, I'm attempting to make an ability/spell system for my game project. The Abilities utilize interfaces for common characteristics, while providing more custom functionality on their own.
So far, this works great. However; as this is meant to be a multiplayer game, I'm thinking that much of the information is too open, and would like to limit it's access as much as possible.
On a step down this road, I was thinking that the properties inherited from my interfaces should be readonly when possible. Sadly, I'm not sure how to do this and still set the property within the Ability itself.
Here is the current baselevel interface, IAbility.
using UnityEngine;
interface IAbility
{
int ID {get;set;} //Identification
string Name {get;set;} //Ability Name
string Description {get;set;} //Description
float Cost {get;set;} //Energy Cost
GameObject Effect {get;set;} //Particle Effect
bool LineOfSight {get;set;} //Require LOS?
float BaseCooldownTime {get;set;} //Default Cooldown
float CastTime {get;set;} //Time to cast
void Cast();
}
And here is an example of a spell, with the custom functionality left out.
using UnityEngine;
using System.Collections;
public class Fireball : MonoBehaviour, IAbility
{
#region IAbility implementation
public int ID {get;set;}
public string Name {get;set;}
public string Description {get;set;}
public float Cost {get;set;}
public GameObject Effect {get;set;}
public bool LineOfSight {get;set;}
public float BaseCooldownTime {get;set;}
public float CastTime {get;set;}
#endregion
Fireball ()
{
ID = 0;
Name = "Fireball";
Description = "Hurl a molten core towards your foe.";
Cost = 15;
Effect = fireballEffect; //Prefab set later in script
LineOfSight = false;
BaseCooldownTime = 2.0f;
CastTime = 1.5f;
}
public Cast ()
{
//Spell's functionality
}
Finally, here is an example of the kind of script (on the player) that will handle actually casting the spell. It is still in test form. I have decided to do many of the common ability functions on this side, to save code.
using UnityEngine;
using System.Collections;
public class Caster : MonoBehaviour
{
IAbility ability1;
float ability1Timer;
PlayerEnergy energyScript;
// Use this for initialization
void Start ()
{
energyScript = GetComponent<PlayerEnergy>();
ability1 = GetComponent<Fireball>(); //This will be done by playerPrefs in the future.
ability1Timer = 0;
}
// Update is called once per frame
void Update ()
{
if(Input.GetButtonDown("Fire1")
&& Screen.lockCursor == true
&& energyScript.energy >= ability1.Cost
&& Time.time >= ability1Timer)
{
energyScript.energy -= ability1.Cost;
ability1Timer = Time.time + ability1.BaseCooldownTime;
ability1.Cast();
}
}
}
I'm still quite new to Unity and programming in general, so I'm sure all of this is inelegant and not very secure. To reiterate, this works, but I'm looking for advice on how to make it more secure, and efficient. Particularly in regards to the inherited properties and how to make them readonly after the ability sets them.
If you took the time to read through all of that, thank you. If there is anything I can do to make this more complete, please let me know.
A discussion about readonly
and why it's a bit awkward. http://answers.unity3d.com/questions/592854/readonly-c-keyword-not-so-usefull-in-unity.html
Answer by Tomer-Barkan · Dec 10, 2013 at 10:00 PM
I'm not sure I understand 100% what you're trying to do, but if you want to make a property that is read-only after the first time that it has been set, you can use the following C# code:
class SomeClass : MonoBehaviour {
private SomeObj _obj = null;
public SomeObj Obj {
get {return _obj;}
set {
if (_obj == null) {
_obj = value;
}
}
}
}
So what we have here, is a property name Obj, that starts as null, and can always be read. But when trying to set it's value, it will only set it if it's null. Once it's been set, you cannot set it again, because it is no longer null.
Answer by bobenko · Mar 28, 2019 at 04:54 PM
https://stackoverflow.com/questions/839788/is-there-a-way-of-setting-a-property-once-only-in-c-sharp - this question contains WriteOnly and other generic examples, that can be useful for setting once
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
C# - Doesn't Unity support Expression Bodied Properties? 3 Answers
Annoying MissingReferenceException with Interfaces and Monobehavior 1 Answer
Recursive properties crash Unity 2 Answers