Better way to ensure a method logic executed once without boolean flag - c#

This is a way to execute Dosomething logic once using flag. (C# code and Update is always called once per frame.)
And it's not so complicated, simple, very plain and well used way.
class Monster {
bool isCalled = false;
float energy = 0.0f;
void Update()
{
energy += Random.Range(0f, 1f);
if((isCalled == false) && (energy>100.0f))
{
isCalled = true;
DoSomething();
}
}
void DoSomething(){}
}
But, I think the management of boolean flag is a kind of tiresome task. So I am trying to find better alternatives.
Is there any better or elegant way to do this (executing Dosomething once) without boolean flag?For example, another design pattern's way, etc.

I'd rather combine all such flags into a single enum, like that:
class Monster {
[Flags]
private enum Status {
Updated,
Called,
Killed,
...
}
private Status status;
void Update() {
if ((status & Status.Updated) == Status.Updated)
return;
try {
....
}
finally {
status |= Status.Updated;
}
}
}

Using dedicated well-named boolean flag is clear and common pattern.
Often you don't need dedicated flag, e.g. old singleton patterns doesn't use bool, but rather testings special value:
if(instance == null)
{
.. // do something
}
Logic is clear enough as you can see. People often use other special values to avoid necessity of introducing flag: string.IsNullOrEmpty, double.IsNaN, negative value, etc.
Important is to have intentions clear, don't obscure logic with too many small details. If there are too many things to take care about - rather introduce a dedicated flag.
In your case you may want to start using state-machine more obviously, because I'd assume what Monster can be in many different states which influence what various methods do:
class Monster
{
enum States { NotInitialized, Dead, Normal, EnergyMax, ... }
States _state;
float _energy;
void Update()
{
_energy += Random.Range(0f, 1f);
switch(_state)
{
case States.Normal:
if(_energy > EnergyMax)
{
DoSomething(); // called once when energy become max
_state = States.EnergyMax;
}
break;
...
}
}
...
}

Well, you can always replace DoSomething with NOP action once it is executed:
class Monster {
float energy = 0.0f;
Action onUpdate;
public Monster()
{
onUpdate = DoSomething;
}
void Update()
{
onUpdate();
}
void DoSomething()
{
energy += Random.Range(0f, 1f);
if(energy > 100.0f)
{
// whatever you need to do
}
onUpdate = () => {};
}
}
However, I believe that most developers are accustomed to using boolean flag to track this, and you might get less raised eyebrows if you go that route.

You could do something like this:
class Monster
{
private Action _doSomething;
public Monster()
{
_doSomething = DoSomething;
}
float energy = 0.0f;
void Update()
{
energy += Random.Range(0f, 1f);
if (energy > 100.0f)
if (_doSomething != null)
_doSomething();
}
void DoSomething()
{
// logic...
_doSomething = null;
}
}
But still i think a flag is a better practice. Something has to be toggled. a flag/reference..

You could use the state pattern like this:
class Monster
{
float energy = 0.0f;
DoSomethingState state;
public Monster()
{
this.state = new DoSomethingStateNotCalled(this);
}
public void Update()
{
energy += Random.Range(0f, 1f);
this.state.Update();
}
public void DoSomething() {
System.Diagnostics.Debug.Write("done something");
}
public float GetEnergy() {
return this.energy;
}
public void SetState(DoSomethingState state) {
this.state = state;
}
}
abstract class DoSomethingState {
protected Monster Monster;
public DoSomethingState(Monster monster) {
this.Monster = monster;
}
public abstract void Update();
}
class DoSomethingStateCalled : DoSomethingState
{
public DoSomethingStateCalled(Monster monster)
: base(monster)
{
}
public override void Update()
{
}
}
class DoSomethingStateNotCalled : DoSomethingState
{
public DoSomethingStateNotCalled(Monster monster)
: base(monster)
{
}
public override void Update()
{
if (this.Monster.GetEnergy() > 100.0f)
{
this.Monster.DoSomething();
this.Monster.SetState(new DoSomethingStateCalled(this.Monster));
}
}
}

Related

In Unity how do I stop perpetual math statements?

The question is simple but I can't for the life of me, figure it out.
My logic goes like this
// Static floats are StatBase.maxHealth = 0 and rStat.maxHealth = 70
class rStat : Monobehaviour
{
public bool nomatter = false;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
nomatter = true;
}
if (nomatter == true)
{
healthcalc();
}
void healthcalc()
{
StatBase.maxHealth += rstat.maxHealth; // StatBase.maxHealth should = 70 but the
// number never stops adding
nomatter = false;
}
}
}
To be honest that logic is quite strange.
Why have this bool flag if you already have one you want to act on? You can simply do
void Update()
{
if (Input.GetMouseButtonDown(0))
{
healthcalc();
}
}
// in general rather put this on class level and don't nest it under Update
void healthcalc()
{
StatBase.maxHealth += rstat.maxHealth;
}
or if there is only one line anyway even
void Update()
{
if (Input.GetMouseButtonDown(0))
{
StatBase.maxHealth += rstat.maxHealth;
}
}

Unity5 : Is there any idea to write code FadeIn/Out without Coroutine?

I'm thinking to make FadeIn/Out effect by C#.
// so, If there's a code like this :
float targetAlpha = 0.7f;
Color targetColor = new Color();
public void FadeIn() {
if(color.a < targetAlpha) { color.a += Time.deltaTime; }
sprite.color = targetColor;
}
1) I don't want to put FadeIn() in Update() because I don't use this FadeIn() function often.
2) I don't want to use Coroutine because StartCoroutine() makes garbage. I will set active on/off this object very often.
3) Animator... There's no way, right?
So I'm going to make 1 event, which will always work on Update(), and then I will put everything in that event. (add when OnEnable(), remove when OnDisable())
Is there a better solution?
If you don't want to put it in update because it won't be used often, maybe you can consider a state machine approach. I would only consider this if performance really is more important than readability. Because this approach will add a lot of additional code.
For simplicity the code below is more verbose than it has to be.
public interface IState
{
void Update();
}
public class FadeInState : IState
{
private readonly float targetAlpha;
private readonly Sprite sprite;
private readonly Action onComplete;
public FadeInState(Sprite sprite, float targetAlpha, Action onComplete)
{
this.targetAlpha = targetAlpha;
this.sprite = sprite;
this.onComplete = onComplete;
}
public void Update()
{
// Your fade-in code
if (sprite.color.a < targetAlpha)
{
Color tmp = sprite.color;
tmp.a += Time.deltaTime;
sprite.color = tmp;
}
else
{
this.onComplete.Invoke();
}
}
}
public class FadeOutState : IState
{
private readonly float targetAlpha;
private readonly Sprite sprite;
private readonly Action onComplete;
public FadeOutState(Sprite sprite, float targetAlpha, Action onComplete)
{
this.targetAlpha = targetAlpha;
this.sprite = sprite;
this.onComplete = onComplete;
}
public void Update()
{
// Your fade-out code
if (sprite.color.a > targetAlpha)
{
Color tmp = sprite.color;
tmp.a -= Time.deltaTime;
sprite.color = tmp;
}
else
{
this.onComplete.Invoke();
}
}
}
public class DoNothingState : IState
{
public void Update()
{
// Do nothing
}
}
public class YourClass : MonoBehaviour
{
private IState currentState;
void Awake()
{
this.currentState = new DoNothingState();
}
void Update()
{
this.currentState.Update();
}
public void FadeIn(Sprite sprite, float targetAlpha)
{
this.currentState = new FadeInState(sprite, targetAlpha,
() =>
{
this.currentState = new DoNothingState();
});
}
public void FadeOut(Sprite sprite, float targetAlpha)
{
this.currentState = new FadeOutState(sprite, targetAlpha,
() =>
{
this.currentState = new DoNothingState();
});
}
}
Initially your class is in the DoNothing state. So update will effectively do nothing.
If someone calls FadeIn, your FadeInState will do your fading logic as if it were in the MonoBehaviour.Update().
The state takes an Action in the constructor that is executed when it is finished. This way you can control what happens after the animation completes from within YourClass. In the example I just set the state to DoNothing but you can probably disable the gameObject.
If you go with this approach and you start using it for other things, you should just look into some better StateMachine implementations. Otherwise you will eventually end up with tons of state classes. This one is decent.

Better way to count all existing citizens?

I've started making a simple city builder game, in the spirit of Zeus/Poseidon, but much simpler. I have the grid system ready and ability to add houses and roads. Yesterday I began to add citizens, in a simple way, that is, whenever a house is created, 5 people are created and move directly from one edge of the map to that particular house. Once they reach that particular house, I consider they became citizens, and add them to the list of residents of the house, and also to the list of citizens of the city.
For that, each house instance has a List of Human, and my Game class which contains all the information of the game also has one List of human.
To simplify it looks like this:
Game.cs
public class Game {
private static Game instance; // this is a singleton
private int currentAmount; //this is the value I'm using to display the number of citizens on screen
private List<Human> humen;
public List<Human> Humen
{
get { return humen; }
set
{
humen = value;
currentAmount = humen != null ? humen.Count : 0;
}
}
public void AddHuman(Human human)
{
humen.Add(human);
currentAmount = humen.Count;
}
/// <summary>
/// Private constructor to ensure it's only called when we want it
/// </summary>
private Game()
{
humen = new List<Human>();
}
public static void setGame(Game game)
{
instance = game;
}
/// <summary>
/// Returns the instance, creates it first if it does not exist
/// </summary>
/// <returns></returns>
public static Game getInstance() {
if (instance == null)
instance = new Game();
return instance;
}
}
House.cs
public class House : Building {
public static int CAPACITY = 5;
private List<Human> habitants;
public List<Human> Habitants
{
get { return habitants; }
set { habitants = value; }
}
public House() {
habitants = new List<Human>();
}
}
HumanEntity.cs
public class HumanEntity : MonoBehaviour {
private Human human;
private float speed;
public Human Human
{
get { return human; }
set { human = value; }
}
// Use this for initialization
void Start () {
speed = Random.Range(5.0f, 10.0f);
}
// Update is called once per frame
void Update () {
if (human != null)
{
Vector3 targetPosition = human.Target.GameObject.transform.position;
if (transform.position.Equals(targetPosition)) {
if (!human.HasAHouse)
{
human.HasAHouse = true;
Game.getInstance().AddHuman(human); // here I'm adding the human to the list of citizens
((House)human.Target).Habitants.Add(human); // here I'm adding it to the house list of habitants
}
}
else {
float step = speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, targetPosition, step);
}
}
}
}
And this is working as expected, but I'm wondering if having one list of human by house in addition with a global list in the game class is not a little overkill, and if there was maybe a more elegant way to achieve that count on the Game class, maybe something more "Unity friendly" if I may say so, as I don't really know a lot about the capacities of Unity. Do you have any advice on what to do, is that okay to keep it this way or is there a more elegant way?
Fast and appropriate way to know how many human would be to have a static counter on HumanEntity class:
public class HumanEntity : MonoBehaviour
{
public static int HousedHuman { get; private set; }
public static int HumanCount { get; private set; }
void Awake() { HumanCount++; }
void OnDestroy()
{
HumanCount--;
if(human.HasAHouse == true){ HousedHuman--; }
}
public static void ResetCounter() { HouseHuman = HumanCount = 0; }
void Update () {
if (human != null)
{
Vector3 targetPosition = human.Target.GameObject.transform.position;
if (transform.position.Equals(targetPosition)) {
if (!human.HasAHouse)
{
HouseHuman++; // Added
human.HasAHouse = true;
// Rest of code
}
}
// Rest of code
}
}
}
When a new instance is added, the counter is increased, when the instance is destroyed, the counter is decreased.
You can access via HumanEntity.HumanCount. You won't be able to set it elsewhere than in the HumanEntity class.
Make sure to reset the counter when you start/leave the scene.
EDIT: based on comment, I added a second static counter for HousedHuman. This is increased when the entity reaches the house. It gets decreased when the entity is destroyed if the entity was housed. It also gets reset when needed along with the overall counter.
Building on Everts's idea...
Game:
public class Game {
private static Game instance; // this is a singleton
public static int currentAmount { get; set; }
//rest of class
}
House:
public class House : Building {
public static int CAPACITY = 5;
private List<Human> habitants;
public List<Human> Habitants
{
get { return habitants; }
set { habitants = value; }
}
public House() {
habitants = new List<Human>();
}
public void AddHuman(Human human)
{
human.HasAHouse = true;
habitants.Add(human);
Game.currentAmount++;
}
}
UpdateLoop:
// Update is called once per frame
void Update () {
if (human != null)
{
Vector3 targetPosition = human.Target.GameObject.transform.position;
if (transform.position.Equals(targetPosition)) {
if (!human.HasAHouse)
((House)human.Target).AddHuman(human);
}
else {
float step = speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, targetPosition, step);
}
}
}
If checking house capacity is required, you can change the AddHuman method to a bool return type, do a capacity check inside and return whether or not it was successfully added.
You can also add a RemoveHuman method that would count humans down via Game.currentAmount--;
As for the list in Game, it really depends on the context. The List in your Game class could be useful to differentiate between wandering humans, and humans who are housed, if this behavior is required. (Wandering humans in the Game list, housed in the housed list)

Are command patterns efficient enough, and what's the concrete benefit of it?

So today I am learning and implementing Command Patterns for handling input and movement for objects.
So my question is:
Am I getting the implementation of Command Patterns right or do I need to modify it? If so, can somebody give me a little example on to improve it.
I know that it improves code reusability. But what difference does it make when I just use a simple MovementScript.cs to my game object component? Wouldn't it just be the same and take less time to write rather than making a whole Command Pattern?
The one I attached to the gameobject is only the InputHandler. Here's my code which involves moving an object:
This is my Input Handler or as far as I know as The Client
public class InputHandler : MonoBehaviour
{
GameObject theObject;
public Command buttonA, buttonD;
public float acceleration, maxSpeed;
Movement moves;
void Awake()
{
theObject = gameObject;
moves = new Movement(theObject, acceleration, maxSpeed);
}
void Start()
{
buttonA = new MoveLeft(moves);
buttonD = new MoveRight(moves);
}
void Update()
{
HandleInput();
}
public void HandleInput()
{
if (Input.GetKey(KeyCode.A))
{
buttonA.Execute();
}
else if (Input.GetKey(KeyCode.D))
{
buttonD.Execute();
}
}
}
The Command abstract class
public abstract class Command
{
//The Receiver of the command..
protected IReceiver receiver = null;
public Command(IReceiver receiver)
{
this.receiver = receiver;
}
public abstract void Execute();
}
The Receiver class (where I implemented the logic, which is the movement)
public class Movement : IReceiver
{
public ACTION_LIST currentMoves;
private GameObject theObject;
private float acceleration;
private float maxspeed;
public Movement(GameObject theObject, float acceleration, float maxspeed)
{
this.theObject = theObject;
this.acceleration = acceleration;
this.maxspeed = maxspeed;
}
public void Action(ACTION_LIST moves)
{
if (moves == ACTION_LIST.MOVERIGHT)
MoveRight(theObject);
else if (moves == ACTION_LIST.MOVELEFT)
MoveLeft(theObject);
}
public void MoveRight(GameObject obj)
{
obj.GetComponent<Rigidbody2D>().AddForce(new Vector2(acceleration, obj.GetComponent<Rigidbody2D>().velocity.y));
}
public void MoveLeft(GameObject obj)
{
obj.GetComponent<Rigidbody2D>().AddForce(new Vector2(-acceleration, obj.GetComponent<Rigidbody2D>().velocity.y));
}
}
Interface of receiver, to make things easier..
public enum ACTION_LIST
{
MOVERIGHT,
MOVELEFT
}
public interface IReceiver
{
void Action(ACTION_LIST moves);
}
The concrete command. I only posted 1 of the movements..
public class MoveRight : Command
{
public MoveRight(IReceiver receiver):base(receiver)
{
}
public override void Execute()
{
receiver.Action(ACTION_LIST.MOVERIGHT);
}
}
I disagree with Joe Blow and others saying that Unity is a bunch of scripts and not OOP. I use main script with single entry point and create all objects and components dynamically. I even use interfaces, mock and unit tests.
So, using Command pattern is ok. But I don't see a reason to use it in your case. Command pattern could be very handy in case when you need a stack of commands to be able Do() and Undo() your commands (Editor, Strategy game). Please read more here: http://gameprogrammingpatterns.com/command.html

Generics in Unity C#

I am having a lot of trouble with the syntax and the rules for using Generics. I am trying to make a structure, where different classes, can use the WaitAction class to disable input while a couroutine is running, an re-enable it once the coroutine is finished.
This example is a simplified version, and in reality I will not be using a count float to define the length of the coroutine, but the length will based on animations and translation.
Is what I am trying to do at all possible?
"Somehow use "T _ready" to change the "bool ready" in "Main Class" back to "true""
public class Main : Monobehaviour {
WaitAction _waitAction = new WaitAction();
public bool ready;
float delay = 5f;
void Update()
{
if(Input.GetMouseButton(0) && ready)
{
ready = false;
StartCoroutine(_waitAction.SomeCoroutine((delay, this));
}
}
public class WaitAction {
public IEnumerator SomeCoroutine<T>(float count, T _ready)
{
float time = Time.time;
while(Time.time < time + count)
{
yield return null;
}
// Somehow use "T _ready" to change the "bool ready" in "Main Class" back to "true"
}
}
The solution is to constrain the generic type, such that the generic method knows how to set the ready flag. This is easily done using an interface:
public interface IReady
{
bool ready { get; set; }
}
public class Main : Monobehaviour, IReady {
...
public bool bool ready { get; set; }
...
}
public class WaitAction {
public IEnumerator SomeCoroutine<T>(float count, T _ready) where T : IReady
{
...
_ready.Ready = true;
}
}

Categories