- Home /
c# unity increment power on click by multiplying
Hi guys !
I could use a bit of help with my game / code.
I am working on a clicker-type game. Currently i have an upgrade button that increment 'power' by 1 after every click, like so:
no upgrade : 1 G/ click
1st upgrade : 2 G/ click (+1)
2nd upgrade : 3 G/ click (+1)
and so on.
What i want to achieve is something like that :
no upgrade : 1 G/ click ( base 'power' = 1, button power = 0 )
1st upgrade : 2 G/ click (+1) ( button power = 1 + 1 base power = 2f total power )
2nd upgrade : 3.2 G/ click [increase button power by 1.2f (1*1.2=1.2) + total power => new total power =3.2f ]
3rd upgrade 4.64 G/click (increase button power by 1.2f ( 1.2*1.2 = 1.44) + total power => new total power =4.64f ]
4th upgrade 5.86 G/click [increase button power by 1.2f (1.44*1.2 = 1.73) + total power => new total power =6.37f]
and so on.
I tried incrementing 'power' with by 1.2f * power, etc. But i cannot get the behavior that want.
I google'd for answers, i found nothing.
The closest i got to what i need looks something like this :
-no upgrade : 1G/click -1st upgrade : 2.2G/click -2nd upgrade : 3.4G/click
and
-no upgrade :1G/click -1st upgrade : 1.2G/click -2nd upgrade : 2.44G/click etc
Basically, i want to increase my 'power' by 1 the first time and by 1.2*current button power, if that makes sense.
The problem i think i have is that i declared my 'power' at the start of the game as 1f, but i cannot find a way around that.
I hope you guys understand what i mean
If someone could lead me into the right direction , i would be very grateful. Thanks !
Answer by Kona · Sep 20, 2021 at 04:41 PM
I got slightly confused while reading your description but I think I get what you want to do.
public float basePower = 1f; //Base power pts
private int _upgrades = 0; //No. of applied upgrades
private float _powerMultiplier = 1.2f;
///<summary>
///Returns the current power value
///</summary>
public float CurrentPower {
get{ return basePower + (( basePower * _powerMultiplier ) * _upgrades ); }
}
CurrentPower accessor will calculate the current power and include all upgrade points, ie. Start level : 1 pts = ( 1 + (( 1 x 1.2 ) x 0 ) Upgrade 2: 2.2pts = ( 1 + (( 1 x 1.2 ) x 1 ) Upgrade 3: 3.4pts = ( 1 + (( 1 x 1.2 ) x 2 ) Upgrade 4: 4.6pts = ( 1 + (( 1 x 1.2 ) x 3 )
You would then increase the "_upgrade" counter when you press the upgrade button in order to get this to work ofcourse.
Another way could be to keep building on the previously modified value instead of just adding a modified "base power"
private float _curPower = 1f;
private float _powerMultiplier = 1.2f;
public void IncrementPower() {
_curPower *= _powerMultiplier; //Multiplies the current power value by 1.2 pts
}
Hi, and thank you for the answer.
I tried that already, but, as you stated above, "CurrentPower" will have the next values : 1->2.2->3.4->4.6 etc;
What i am looking for is something else, BUT you gave me an idea, gonna test it and come back with the result.
Answer by Poly_RO · Sep 23, 2021 at 05:28 PM
Ok, so i tried different ways to make the code do what i want to do, no success.
So, i am open to suggestions on how to do that.
Bassically, what i want to do is :
given that BasePower = 1f and will stay the same
multiplierForUpgrade = 1.2f ( +20% ) upgradePower = 0f- at the start, but will increase to 1 first upgrade, and from the 2nd upgrade onwards, i want of the last upgrade power ( ex : upgr 1 = +1 dmg , upgr 2 = +2.2 dmg, upgr 3 = +4.64 dmg etc. )
so, i try to explain a bit better here :
StartGame => TotalPower = 1
Upgrade1 => TP = (BasePower + UpgradeMultiplier) = 1 + 1 = 2f {{ 1 added to TotalPower }}
U2 => TP = 1 + [1 +(1 1.2) = 1 + (1 + 1.2) = 1 + 2.2* = 3.2f {{ 1.2 added to TotalPower }}
U3 => TP = 1 + [2.2 +(1.2 1.2)] = 1 + (2.2 + 1.44) = 1 + 3.64* = 4.64f {{ 1.44 added to TotalPower }}
U4 => TP = 1 + [3.64 + (1.44 * 1.2)] = 1 + (3.64 + 1.73) = 1+ 5.37 = 6.37f {{ 1.73 added to TotalPower }}
Does that makes sense ?
Thanks for an eventual answer !
Answer by BradyIrv · Sep 23, 2021 at 08:01 PM
// Something like this?
public class ClickPower : MonoBehaviour
{
public float basePower = 1f;
public float buttonPower = 1f;
public float powerMulti = 1.2f;
public float upgradeLevel = 0;
public void Click()
{
float TP = 0;
TP = basePower + Mathf.Min(buttonPower, upgradeLevel);
Debug.Log(TP);
// Start 0: 1 = 1 + (0)
// Upgrade 1: 2 = 1 + (1)
// Upgrade 2: 2.2 = 1 + (1.2)
// Upgrade 3: 2.44 = 1 + (1.44)
// Upgrade 4: 2.728 = 1 + (1.728)
// Upgrade 5: 3.073 = 1 + (2.073)
// Upgrade 6: 3.488 = 1 + (2.488)
}
public void Upgrade()
{
buttonPower = Mathf.Max(1, Mathf.Pow(powerMulti, upgradeLevel));
upgradeLevel++;
}
// OR: Button strength with Power Upgrades (all previous button strengths as well)
public void UpgradeWithPower()
{
buttonPower = Mathf.Max(1, Mathf.Pow(powerMulti + (powerMulti * upgradePower), upgradeLevel));
upgradeLevel++;
}
}
There's one limitation to this, you can't "One-Time" upgrade the buttonPower because it's doing the math real-time with constants. There's probably a way to work in another variable like "currentButtonPower" and store/reference it when needed. But, hopefully this helps.
**// OR: Button strength with Power Upgrades (all previous button strengths as well)**
public void UpgradeWithPower()
{
buttonPower = Mathf.Max(1, Mathf.Pow(powerMulti + (powerMulti * upgradePower), upgradeLevel));
upgradeLevel++;
}
I think this is what i am looking for, ițm gonna test it and will come with a feedback.
That one time upgrade i think i will achieve with if/else;
Will try it out and come with an answer.
Thanks !
Answer by Eno-Khaon · Sep 24, 2021 at 08:09 PM
After a bunch of digging and verification, I think I can offer the solution you've been looking for.
Using this source as my basis, I can produce an approximate match to your progression of terms by slightly tweaking it like this:
public float a = 1f;
public float d = 0f;
public float b = 1f;
public float r = 1.2f;
public int n = 3;
// Return the sum of first n term of AGP
static float sumofNterm(float a, float d, float b, float r, float n)
{
float ans = 0;
ans += a;
ans += ((d * r * (1f - Mathf.Pow(r, n - 1f))) / (1f - r));
ans -= (a + (n - 1f) * d) * Mathf.Pow(r, n);
return (ans * b) / (1f - r);
}
// Driver Code
public void Start()
{
Debug.Log(1f + sumofNterm(a, d, b, r, n));
}
The problem, though, is that this is pretty ugly as-is. Let's reorganize and rename this a bit to give it some more clarity and relevance, but before we do that, let's look at how this is constructed to begin with:
Starting with the Wikipedia entry on Arithmetico-geometric sequences, here's an example of a progression of terms:
0/1, 1/2, 2/4, 3/8, 4/16
In this case, the numerator increments additively (+1) while the denominator increments multiplicatively (x2). However, this isn't also factoring in the sums of these values; this is just the sequence itself. If you also add each new value to the running total, it would look more like:
0/1, 1/2, 4/4, 11/8, 26/16
Going based on the example script I gave above, this pattern would come about with:
(A) (D) (B) (R) (N)
sumofNterm(0f, 1f, 1f, 0.5f, N);
where the first value (A) is the initial value of the additive sequence, the second (D) is the additive incrementing rate, the third (B) is the initial value of the multiplicative sequence, the fourth (R) is the multiplier for each step, and the fifth (N) is the number of times this is repeated and added together. To write out the sequence:
A*B
(A+D)*BR
(A+2D)*BR2
(A+3D)*BR3
(A+4D)*BR4
(A+5D)*BR5
...
(A+ND)*BRN
First, how does the fractional example fit into this?
0.5 = 1/2
1/2*1/2 = 1/4
1/4*1/2 = 1/8
In this case, the denominator is multiplied by 2 for each step in the sequence. Extrapolating from this, we can fit it into your own sequence using 1.2 (or, rather, 1.2/1) instead.
(A+ND)*BRN
(1+(N*0))*1*1.2N
1*1.2N
1.2N
Well, that became simple. Let's see what the first few values are, anyway:
1.20 = 1
1.21 = 1.2
1.22 = 1.44
Well, that already starts to check out. Incidentally, that script example at the top of this post already factors in a lot of (n-1) elements, which inherently accommodates a few convenient cases. This means that we can plug in your numbers, add 1, and we have a perfect(-enough) match to your goal...
So now, let's rewrite it for clarity, and make a simplified version for efficiency:
public static float ArithmeticGeometricSequenceSum(float arithBase, float arithIncrement, float geoBase, float geoMultiplier, int term)
{
float result = arithBase;
result += ((arithIncrement * geoMultiplier * (1f - Mathf.Pow(geoMultiplier, term - 1f))) / (1f - geoMultiplier));
result -= (arithBase + (term - 1f) * arithIncrement) * Mathf.Pow(geoMultiplier, term);
return (result * geoBase) / (1f - geoMultiplier);
}
// Simplified version, since you aren't using arithmetic incrementing (0)
// and your arithmetic and geometric bases are both 1
public static float CalculateClickPower(float basePower, float multiplier, int ranks)
{
return basePower + ((1f - Mathf.Pow(multiplier, ranks)) / (1f - multiplier));
}
// ...
public float clickBasePower = 1f;
public float clickMultiplier = 1.2f;
public int clickRanks = 0;
private float clickPower;
// On upgrade...
clickRanks++;
clickPower = CalculateClickPower(clickBasePower, clickMultiplier, clickRanks);
Edit: To clarify why I describe this as "approximate" as much as I do is because there are clearly, definitely small floating point errors that come up regularly under these conditions. They're basically all negligible, but it's why I've phrased things the way I have.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Understanding Profiler and Optimization ! 0 Answers
How to add score after destroying object? 1 Answer
Distribute terrain in zones 3 Answers
Save randomly placed objects 0 Answers