1

I am still quite new to programming in Unity and I am currently experimenting on a spell-based platformer.

My problem is following: I've got a struct containing 6 floats (this number will increase as I am to implement new spell proporties) and I need to add another float to each of the floats inside of this struct. I only got 6 elements and I've done it manually by adding each float, but as I intend to expand this struct I need a better solution then this brute and useless implementaion.

Furthermore, the code below shows the example for one spell, I am working on two at the same time, so there is two times more lines of code for such a simple thing

            //Adding proporties to controller
        manager.GetComponent<Controller> ().firstSpell.damage += adder.damage;
        manager.GetComponent<Controller> ().firstSpell.force += adder.force;
        manager.GetComponent<Controller> ().firstSpell.cooldown += adder.cooldown;
        manager.GetComponent<Controller> ().firstSpell.damageOverTime += adder.damageOverTime;
        manager.GetComponent<Controller> ().firstSpell.size += adder.size;
        manager.GetComponent<Controller> ().firstSpell.gravity += adder.gravity;

        manager.GetComponent<Controller> ().firstSpell.damage = Mathf.Clamp (manager.GetComponent<Controller> ().firstSpell.damage, Spells.damageMin, Spells.damageMax);
        manager.GetComponent<Controller> ().firstSpell.force = Mathf.Clamp (manager.GetComponent<Controller> ().firstSpell.force, Spells.forceMin, Spells.forceMax);
        manager.GetComponent<Controller> ().firstSpell.cooldown = Mathf.Clamp (manager.GetComponent<Controller> ().firstSpell.cooldown, Spells.cooldownMin, Spells.cooldownMax);
        manager.GetComponent<Controller> ().firstSpell.damageOverTime = Mathf.Clamp (manager.GetComponent<Controller> ().firstSpell.damageOverTime, Spells.damageOverTimeMin, Spells.damageOverTimeMax);
        manager.GetComponent<Controller> ().firstSpell.size = Mathf.Clamp (manager.GetComponent<Controller> ().firstSpell.size, Spells.sizeMin, Spells.sizeMax);
        manager.GetComponent<Controller> ().firstSpell.gravity = Mathf.Clamp (manager.GetComponent<Controller> ().firstSpell.gravity, Spells.gravityMin, Spells.gravityMax);

As you can see in the above code I have to Clamp those values as well. Is there a simple way to add two struct variables of the same type (and also clamp their values on the way)?

EDIT This is how I changed it, now there is a public class:

public class spell{
    public float damage;
    public float force;
    public float cooldown;
    public float damageOverTime;
    public float size;
    public float gravity;

    public void addValues(spell other){
        damage += other.damage;
        force += other.force;
        cooldown += other.cooldown;
        damageOverTime += other.damageOverTime;
        size += other.size;
        gravity += other.gravity;
    }

    public void clampValues(){
        damage = Mathf.Clamp(damage, Boundaries.damageMin, Boundaries.damageMax);
        force = Mathf.Clamp(force , Boundaries.forceMin, Boundaries.forceMax);
        cooldown = Mathf.Clamp(cooldown, Boundaries.cooldownMin, Boundaries.cooldownMax);
        damageOverTime = Mathf.Clamp(damageOverTime, Boundaries.damageOverTimeMin, Boundaries.damageOverTimeMax);
        size = Mathf.Clamp(size, Boundaries.sizeMin, Boundaries.sizeMax);
        gravity = Mathf.Clamp(gravity, Boundaries.gravityMin, Boundaries.gravityMax);
    }
}

And this is what I do with it:

Controller managerController = manager.GetComponent<Controller> ();
managerController.firstSpell.addValues (adder);
managerController.firstSpell.clampValues ();
Shrimp
  • 514
  • 5
  • 9
  • 2
    First off instances of a `struct` should generally be immutable, that is they don´t change once instantiated. You should use a `class` instead. – MakePeaceGreatAgain Mar 01 '17 at 14:51
  • Alright, so structs are only used for constants? – Shrimp Mar 01 '17 at 14:54
  • 1
    @Shrimp Here's a good read on the subject: https://blogs.msdn.microsoft.com/ericlippert/2008/05/14/mutating-readonly-structs/ and http://stackoverflow.com/questions/441309/why-are-mutable-structs-evil – asawyer Mar 01 '17 at 14:59
  • Thanks for the links. So I should change this struct to class and then create functions inside the class that would deal with adding and clamping, right? – Shrimp Mar 01 '17 at 15:06
  • 2
    Secondly, you need to cache that GetComponent. It's very mean to the aesthetics of your code and to Unity, as Unity has to search the unknown for a potential component and handle everything that may happen when doing so. `Controller managerController = manager.GetComponent();`. – Fredrik Schön Mar 01 '17 at 15:21
  • @Fredrik Yeah, that will help too, thanks! Should I always be doing that or only for bulk operations? – Shrimp Mar 01 '17 at 15:24
  • I'm not quite sure about the immutable struct debate. A struct content can be changed. – Everts Mar 01 '17 at 15:35
  • 1
    @Shrimp To clarify the situation, are both `firstSpell` and `adder` instances of your `Spell` (or whatever the name is) struct? Also, if it's not too long, can you edit your question to include the definition for your struct? There's some details I want to see before I start writing up an answer. – Serlite Mar 01 '17 at 16:16
  • @Serlite Well, due to above comments I have already changed struct to class. Yes, both adder and firstSpell are instances of Spell. One object has adder which has some small values that should be added to firstSpell when they collide - that is the concept. firstSpell is the sum of all adders. – Shrimp Mar 01 '17 at 16:44
  • 1
    @Fredrik I'm told that Unity 5 manages an internal cache for GetComponent calls so there shouldnt be a performance penalty with multiple calls. It sure is ugly to look at though. – asawyer Mar 01 '17 at 18:31
  • 1
    @Shrimp I looked over your changed code example and I do have one bit of feedback: It may be advantages to instead of just adding the spells together instead return a new spell with the combined properties. Then you could do things like make your spell structure a stack that each change you create a new spell combination and push, then say your timer or mana or whatever runs out and you loose that power? Just pop the stack! Just a suggestion, good luck! – asawyer Mar 01 '17 at 18:36
  • @asawyer Thanks for the idea, however the game differs a little bit from standard spell-casting games. I want to make a game where you craft your 2 main spells in a 3D environment and then you switch to levels where you play a more classic 2D game, but with the spells you have just crafted. [HERE](http://imgur.com/a/JlfTu) is a prototype of spell-creation, it's all a learning curve for me as I am still quite new to Unity. I wanted to make this a local multiplayer game, where people craft their spells and fight one another, but it's tough for me at this point, so I stick to 1 player. – Shrimp Mar 01 '17 at 18:49

0 Answers0