then what the function will return is going to be int. If you want more precision (float), you will have to return float and convert the float that the function returned into a int outside of the function.
public float Func_name(){ return 0.1f;}
int myInt = (int)Func_name(); //Search: c# casting float to int / int to float
Is there a reason you’re using string comparisons for something like this? C# is a highly typed language - you can, however, cast any object in C# as an object and return it…
However, I wouldn’t do this kind of thing at all… In general you want to have one function return one type each time no matter what.
You look like you might benefit from learning about interfaces which allow you to operate on an indefinite number of objects generically by creating a “contract” that defines the kinds of methods that every kind of object derived from that interface will employ.
Random ramblings, apparently my head is off tonight.
You could just pass around objects and use reflection to determine their type, then act on them. But reflection is like fight club and static variables. Its one of those things that is only for use by those who already understand it.
You could also use a generic method. Generic methods can return values based on the type of value passed in.
You could just make everything a float
But I ultimately think you will do far better off by using a strong type, rather then all this string manipulation. Lazy variables are useful in some situations, but slow and error prone. There is a reason they are not included in the language by default. One typo in the string for the calling method, or the variable set up, and you have introduced a hard to spot bug. You also fry your autocomplete.
Thanks for all your inputs guys.
The main purpose was to reduce repetition in code. I tried using objects " return(object)((int)value); " but unfortunately it broke other things.
I think I will have to make 2 functions to return ints and floats.
damage = unitStats.combatStatsInt(coll.gameObject.tag, "damage"); // Find out the opponents damage
attackSpeed = unitStats.combatStatsFloat(coll.gameObject.tag, "attackSpeed"); // Find out the opponents attack speed
This seems like really poor design that’s going to lead to a debugging nightmare when you make a typo.
Why not create a component script (UnitAttributes) and attach it to your prefabs? That way you can edit the values in the editor, instead of searching a giant switch block statement, and finding all the information for any unit is as simple as GetComponent()?
I’m going to agree with GroZZleR on this… (although I already did above)… You shouldn’t use tags for something like this. Instead you should attach a script to everything that needs its collisions examined and use “GetComponent” on the colliding object. After you do that, you can communicate freely with the colliding object directly between scripts. It will save the overhead of string comparisons which are a nasty type of comparison (switch implementation for a string is sometimes even more processing time than a whole bunch of “if … else if” blocks). Regardless, you want to avoid, in any programming you do, string comparisons unless it’s absolutely necessary - they have a lot of overhead and most of the time (with the exception of this tag method you’re using) an enum will suffice and be much faster.
I know what it’s like to be on the “don’t ever do what you’re doing” side of a programming forum post - so no offense intended, just trying to push some more proper technique on you.
I appreciate any input and want to do whats best, I understand where your coming from. Will I need a unitStats script for every type of unit?
So " if tag is alienWalker GetComponent "
" if tag is humanTank GetComponent "
Unit prefab can have its own stats but will need to know how much damage to take when colliding with different unit types.
Why isn’t there a ‘comboStatsDamage’ and a ‘comboStatsAttackSpeed’ methods that return the appropriate types for each, and you don’t have to pass in some magic string for it to work…
I don’t even understand the design here. Why are you passing in the ‘field’ and the ‘type’???
Have functions for each field!
And what is ‘type’ even for? Why would you ever call this method with anything other than “humanTank”?
You can use one kind of script that holds an interface perhaps…
I’m not sure exactly what you’re doing… but this would be my approach to what I think you’re doing…
eg:
public class DamageStats
{
public float attack;
public float armor;
public float ...
}
public interface ICollidable
{
DamageStats Stats { get; set; }
float DamageAmount();
}
public class HumanTank : ICollidable
{
private DamageStats stats;
public DamageStats Stats { get { return stats; } set { stats = value; } }
public float DamageAmount()
{
... Unique calculations here ...
}
}
public class AlienWalker : ICollidable
{
private DamageStats stats;
public DamageStats Stats { get { return stats; } set { stats = value; } }
public float DamageAmount()
{
... Unique calculations here ...
}
}
public class TagScript : MonoBehavior
{
public ICollidable MyType;
public int typenumber; // set in inspector
Start()
{
switch(typenumber)
{
case 0:
MyType = new HumanTank();
break;
case 1:
MyType = new AlienWalker();
break;
default:
throw new UniverseImpodesException();
}
}
}
How does each unit get unique sets of stats from damageStats if they get it all from public class DamageStats?
What I was trying to do was this;
Game object “humanTank” hits “alienWalker”
“humanTank” finds out alienWalkers damage and attackSpeed and gets damaged.
“alienWalker” finds out humanTanks damage and attackSpeed and gets damaged.
One will be victorious.
One script stores all stats for all units.
The script attached to each game object are identical so 1 script can handle all game objects damage taken when they collide.
You only need one script here with public variables that you can set in the inspector. Then it doesn’t matter what it bumps into , it will read the values and act upon them.
using UnityEngine;
using System.Collections;
public class UnitAttributes : MonoBehaviour
{
public int health = 100;
public int armour = 0;
public int damage = 1;
public float attackSpeed = 0.03f;
public float moveSpeed = 0.02f;
}
Then add the script to your prefab so you can edit in the inspector like this:
Then access the data from the appropriate game object with:
UnitAttributes attributes = tank.GetComponent();
// attributes.health, attributes.armour, etc
Drag a prefab onto the scene, add the script to it. Edit the values in the inspector then drag the object off the heirarchy and back onto the prefab and now it will always spawn with those values, which can be edited at runtime.
Hah… guess I was over complicating it just a tad. Thanks all.
Guess then I can set its level when creating the game object? As in there can be harder units without duplicating prefabs for each unit?
Then damage = attributes.damage + (attributes.level * 0.623) or something?
GameObject go = Instantiate(MyPrefab, overHere, thisRotation) as GameObject;
Stats stats = go.GetComponent<Stats>();
stats.health = "whatever"
etc.
etc.