# Question
Title: How can I make a crafting system in Unity?
I'm trying to make an crafting system in Unity. The problem is, I don't really know how to finish it. I already have the inventory system, (which I made using this tutorial: HOW TO MAKE AN INVENTORY WITH UNITY & C# - BEGINNER TUTORIAL - 1/2).

The problems I'm having are:

* I don't know how to destroy the materials used for crafting an item
* And I don't really know how to check if these materials are in the inventory (or basically the scene)

Here's the code:

```
private Inventory inventory;

public GameObject CraftedItem;
public GameObject[] ReqMats; //This array is for requied materials

private void Start()
{
    inventory = GameObject.FindGameObjectWithTag("Player").GetComponent<Inventory>();
}

public void Craft()
{
    for (int i = 0; i < inventory.slots.Length; i++)
    {
        if (inventory.isFull[i] == false)
        {
            if (check if ReqMats are in inventory here)
            {
                inventory.isFull[i] = true;
                //Destroy ReqMats here
                Instantiate(CraftedItem, inventory.slots[i].transform, false);
                break;
            }
        }
    }
}

```

I also need to say that the items and itemsButtons are prefabs, and so I put needed "materials" (which are few item buttons) in the ReqMats, so I can't just use the Destroy() method cause I don't want to delete the original prefab, just the button of it's copy.

Any help will be appreciated :D

# Answer
> 8 votes
The design pattern I would adopt revolves around creating an abstract **Item** class that derives from ScriptableObject. From there I would derive **Element** and **CraftableItem** and classes to provide basic functionality for raw materials and items that you can assemble from them.

The following shows how you can put this together . This example comprises a simple scene layout, 1 UI prefab and 5 scripts:

* Item.cs
* Element.cs
* CraftableItem.cs
* CraftingStuff.cs
* CraftingController.cs

`Item` prescribes the basic properties and methods of any inventory item, such as prefabs and sprites used by the UI, name and inventory slots used. Methods include functions to generate runtime instances, as well as basic inventory actions like `AddItem`, `DropItem`, and `UseItem`.

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using CraftingStuff;

public abstract class Item : ScriptableObject
{
    [Tooltip("What is this thing called?")]
    public string title;
    [Tooltip("2D image for use in dialogs, etc")]
    public Sprite sprite;
    [Tooltip ("How many inventory slots does this item occupy")]
    public int size;
    [Tooltip("game object to be instantiated")]
    public GameObject pickup;
    public abstract ItemType Type { get; }

    /// <summary>
    /// Creates the derived runtime class instance and populates it as required.
    /// </summary>
    /// <returns>The derived class runtime, cast to ItemRuntime.</returns>
    public abstract ItemRuntime GenerateRuntime();

    /// <summary>
    /// Perform an necessary actions to instantiate the object in the game world.
    /// </summary>
    /// <param name="runtime">Runtime.</param>
    public abstract GameObject InstantiatePickup(ItemRuntime runtime);

    /// <summary>
    /// Called when the player chooses to add the item to inventory.
    /// </summary>
    /// <param name="runtime">the item runtime.</param>
    public abstract void AddItem(ItemRuntime runtime);
    /// <summary>
    /// Called when the player uses the item, For instance, to subtract health from the item.
    /// </summary>
    /// <param name="runtime">Runtime.</param>
    public abstract void UseItem(ItemRuntime runtime);

    /// <summary>
    /// Called when the player drops the item. Performs housekeeping such as removing gameobjects, cancelling loans, etc.
    /// </summary>
    /// <param name="runtime">The item runtime.</param>
    public abstract void DropItem(ItemRuntime runtime);
}

```

We need to define a few enums and serializeable classes, we'll use the namespace `CraftingStuff` for this. *Note that some of this stuff is notional in terms of this tutorial, but also reasonable - for instance we aren't actually doing anything with bench types in demo code...*:

```
using UnityEngine;

namespace CraftingStuff
{
    public enum ItemType
    {
        element,
        rareElement,
        craftable,
        weapon,
        tool,
        food,
        bench
    }

    public enum BenchType
    {
        tool1,
        forge1,
        food1,
        weapon1,
        tool2,
        forge2,
        weapon2
    }

    [System.Serializable]
    public class Ingredient
    {
        public Item item;
        public int amount;
    }

    [System.Serializable]
    public abstract class ItemRuntime
    {
        public int id;
        public abstract Item Immutable { get; set; }
        public GameObject pickup;

        public virtual void SomeHandler(Transform t)
        {
           //do something with t
        }
    }
}

```

`Element` in our example is simply a basic implementation of `Item`, with the methods wired up. Those methods are:

**GenerateRuntime()** creates an `ItemRuntime` object and casts it to `ElementRuntime`. This object is what will be held in inventories, etc. It has a reference this element type's definition (the Immutable) as well as a few runtime properties.

**InstantiatePickup()** instantiates the gameObject that will be used by the UI. It configures that object (which is a UI button) by decorating its sprite and text, and adds a onClick listener to the button. Finally it stashes a reference to the gameobject in the runtime object.

**AddItem()** is the callback when the button is clicked. Basically it swaps out the button's listener and passes the button's transform as well as the runtime to the controller's `AddItemToInventory` method, which is described below.

This file also defines `ElementRuntime`, which extends ItemRuntime. Its basic function is to cast the Immutable to Element.

```
using System.Collections;
using System.Collections.Generic;
using CraftingStuff;
using UnityEngine;
using UnityEngine.UI;

[CreateAssetMenu(menuName = "Item/ New Element")]
public class Element : Item
{
    public override ItemType Type { get { return ItemType.element; } }

    public override void AddItem(ItemRuntime runtime)
    {
        var button = runtime.pickup.GetComponent<Button>();
        button.onClick.RemoveAllListeners();
        button.onClick.AddListener(() => UseItem(runtime));
        CraftingController.instance.AddItemToInventory(runtime.pickup.transform, runtime);
    }

    public override void UseItem(ItemRuntime runtime)
    {
        //do any housekeeping after using -- example: reduce health
    }

    public override ItemRuntime GenerateRuntime()
    {
        var element_rt = new ElementRuntime();
        element_rt.Immutable = this;
        // do other initialization for runtime instance
        return element_rt;
    }

    public override GameObject InstantiatePickup(ItemRuntime runtime)
    {
        runtime.pickup = Instantiate(pickup);
        runtime.pickup.name = title;
        runtime.pickup.transform.Find("Text").GetComponent<Text>().text = title;
        runtime.pickup.transform.Find("Sprite").GetComponent<Image>().sprite = sprite;
        runtime.pickup.GetComponent<Button>().onClick.AddListener(() => AddItem(runtime));
        return runtime.pickup;
    }

    public override void DropItem(ItemRuntime runtime)
    {

    }
}

public class ElementRuntime : ItemRuntime
{
    private Element element;
    public override Item Immutable { get { return element; } set { element = (Element)value; } }
}

```

`CraftableItem` is similar to `Element`, but adds prerequisites in the form of a list of ingredients (Items with amounts) and a specific crafting bench that is required. There is also a time property. A `CraftItem` method is specified. Some of the implemented methods are slightly different than `Element` as well.

**CraftItem()** calls the controller's `RecipeCheck` method with the item's list of ingredients and bench requirement. If `RecipeCheck` returns true, it then call's the controller's `AddCraftedItem` method, passing the runtime cast to `CraftedItemRuntime` as a parameter.

**AddItem()** is slightly different than Element's version -- in this case were need to instantiate a new UI object for the inventory as we want to keep the crafting item in the crafting grid.

```
using System.Collections;
using System.Collections.Generic;
using CraftingStuff;
using UnityEngine;
using UnityEngine.UI;

[CreateAssetMenu(menuName = "Item/ New CraftableItem")]
public class CraftableItem : Item
{
    //new properties unique to craftables:
    public List<Ingredient> ingredients;
    public BenchType benchType;
    public float craftingTime;

    public override ItemType Type { get { return ItemType.craftable; } }

    public void CraftItem(ItemRuntime runtime)
    {
        //if prereqs are met, begin crafting
        var controller = CraftingController.instance;
        if (controller.RecipeCheck(ingredients, benchType))
        {
            controller.AddCraftedItem(runtime as CraftableRuntime);
        }
        else
        {
            Debug.Log("necessary prereqs missing");
        }
    }

    public override void AddItem(ItemRuntime runtime)
    {
        var go = Instantiate(pickup);
        go.name = title;
        go.transform.Find("Text").GetComponent<Text>().text = title;
        go.transform.Find("Sprite").GetComponent<Image>().sprite = sprite;
        var button = go.GetComponent<Button>();
        var new_runtime = GenerateRuntime(); //this is a new instance
        new_runtime.pickup = go;
        button.onClick.AddListener(() => UseItem(runtime));
        CraftingController.instance.AddItemToInventory(go.transform, new_runtime);
    }

    public override void UseItem(ItemRuntime runtime)
    {
        //do any housekeeping after item is used. Example: tool wears out
    }

    public override ItemRuntime GenerateRuntime()
    {
        var craftable_rt = new CraftableRuntime();
        craftable_rt.Immutable = this;
        // do other initialization for runtime instance
        return craftable_rt;
    }

    public override GameObject InstantiatePickup(ItemRuntime runtime)
    {
        runtime.pickup = Instantiate(pickup);
        runtime.pickup.name = "Craft a " + title;
        string legend = $"Craft a {title}\n";
        for(int i = 0; i < ingredients.Count; i++)
        {
            legend += $"\n{ingredients[i].amount} x {ingredients[i].item.title}";
        }
        runtime.pickup.transform.Find("Text").GetComponent<Text>().text = legend;
        runtime.pickup.transform.Find("Sprite").GetComponent<Image>().sprite = sprite;
        runtime.pickup.GetComponent<Button>().onClick.AddListener(() => CraftItem(runtime));
        return runtime.pickup;
    }

    public override void DropItem(ItemRuntime runtime)
    {
       // Do any housekeeping after item is dropped
    }
}

public class CraftableRuntime : ItemRuntime
{
    private CraftableItem craftable;
    public override Item Immutable { get { return craftable; } set { craftable = (CraftableItem)value; } }
}

```

**Demo**

With our basic item types defined, we can start creating things. First of all, we need a simple UI prefab which we will use to represent the object in its various states.

For this demo it's simply a square image with a `Button` component with two children: one with a `Text` called Text, and another with an `Image` component called Sprite. Heirarchy looks like this:

Now we can define some Elements and some CraftableItems.

Either one can be created with the context menu by right clicking in the project pane:

The result will be a new ScriptableObject that we can fill the details in in the inspector. For instance, this is the definition of an Element called "Rock":

Let's also create an Element called "Stick":

Next, let's create a CraftableItem called "Hammer." Craftable items have a few more fields to fill out. We'll say a hammer costs one stick and one rock, requires a basic tool bench, and takes .5 seconds to craft:

Let's create another Craftable, a super hammer that requires a regular hammer and two rocks to construct:

Now let's construct the scene. This will just be super basic -- Three UI grids, one to hold our current inventory, one for recipes that can be crafted, and another to hold items that can be picked up. Start by adding a Canvas Component (which should bring in an EventSystem along with it). We'll also need a new empty game object that we'll call Controller -- this will hold the singleton component that will be the glue for our demo.

Now, to the Canvas we'll create three empty children which we will call InventoryGrid, CraftingGrid and ItemGrid:

Each of these gameobjects will get a `GridLayoutGroup` component. They are configured similarly, one occupying the top, middle and bottom of the screen. Here's the config for the top grid object:

You can quickly test populate these grids with dummy children that have `Image` components to see how it looks:

Next up, a simple controller script that will be the glue for this demo:

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using CraftingStuff;

public class CraftingController : MonoBehaviour
{
    [Header ("Inventories")]
    public List<ItemRuntime> inventory = new List<ItemRuntime>();
    public List<ItemRuntime> worldItems = new List<ItemRuntime>();
    [Tooltip ("Items that will be constantly replenished")]
    [SerializeField] Item[] freeItems;
    [Tooltip("Items that can be crafted")]
    [SerializeField] CraftableItem[] recipes;

    [Header("UI Stuff")]
    [Tooltip ("parent transforms which generated UI elements will be childed")]
    [SerializeField] Transform inventoryUIParent;
    [SerializeField] Transform craftingUIParent;
    [SerializeField] Transform itemUIParent;

    public static CraftingController instance;

    void Awake()
    {
        instance = this; //Controller is a singleton
    }

    void Start()
    {
        PopulateRecipes();
    }

    void Update()
    {
        if(worldItems.Count < 10) //magic number for demo
        {
            GenerateFreeItem();
        }
    }

    void GenerateFreeItem()
    {
       var item = freeItems[Random.Range(0, freeItems.Length)];
        var itemRuntime = item.GenerateRuntime();
        worldItems.Add(itemRuntime);
        var t = item.InstantiatePickup(itemRuntime).transform;
        t.SetParent(itemUIParent);
        t.localScale = Vector3.one; //prevent weird UI scaling

    }

    public void AddItemToInventory(Transform inventoryObject, ItemRuntime itemRuntime)
    {
        inventoryObject.SetParent(inventoryUIParent);
        inventoryObject.localScale = Vector3.one;
        worldItems.Remove(itemRuntime);
        inventory.Add(itemRuntime);
    }

    void PopulateRecipes()
    {
        for (int i = 0; i < recipes.Length; i++)
        {
            var recipe = recipes[i];
            var recipe_rt = recipe.GenerateRuntime();
            var t = recipe.InstantiatePickup(recipe_rt).transform;
            t.SetParent(craftingUIParent);
            t.localScale = Vector3.one;
        }
    }

    public bool RecipeCheck(List<Ingredient> ingredients, BenchType benchType)
    {

        //Check ingredients are in inventory.
        //This is brute force and probably very inefficient:
        bool ingredientsPresent = true;
        for(int i = 0; i < ingredients.Count; i++)
        {
            int count = 0;
            bool ingredientPresent = false;
            for (int j = 0; j < inventory.Count; j++)
            {
                if(inventory[j].Immutable == ingredients[i].item)
                {
                    count++;
                    if(count == ingredients[i].amount)
                    {
                        ingredientPresent = true;
                        break;
                    }
                }
            }
            if (!ingredientPresent)
            {
                ingredientsPresent = false;
                break; //fail -- all ingredients not present in inventory
            }
        }
        return ingredientsPresent;
        //TODO bench check

    }

    public void AddCraftedItem(CraftableRuntime craftable_rt)
    {
        //Remove ingredients from inventory
        var ingredients = (craftable_rt.Immutable as CraftableItem).ingredients;
        for (int i = 0; i < ingredients.Count; i++)
        {
            for (int j = 0; j < ingredients[i].amount; j++)
            {
                var itemToRemove = inventory.Find(x => x.Immutable == ingredients[i].item);
                Destroy(itemToRemove.pickup); // Should pool instead, but for this demo...
                inventory.Remove(itemToRemove);
            }
        }
        StartCoroutine(CompleteCrafting(craftable_rt));
    }

    IEnumerator CompleteCrafting(CraftableRuntime craftable_rt)
    {
        var craftable = craftable_rt.Immutable as CraftableItem;
        yield return new WaitForSeconds(craftable.craftingTime);
        craftable.AddItem(craftable_rt);
    }
}

```

In **Awake()**, `CraftingController` creates a static reference to itself (simple singleton pattern) so that other objects can reference.

**Start()** populates the crafting bar, using an array of CraftableItems.

**Update()** replenishs the basic objects that can be picked up, by checking whether the number of existing objects is below a certain threshold.

**GenerateFreeItem()** actually creates the free items, with most of the actual work being done in the relevant Item script.

**AddItemToInventory()** is called by `Item` scripts when they have done the necessary housekeeping to add the item to the inventory and UI.

**PopulateRecipes()** is similar to GenerateFreeItem(), it's the scaffolding for a CraftableItem to be added to the CraftingGrid.

**RecipeCheck()** is called by CraftableItems when asked to craft. It's a bit of a brute force implementation to ensure the inventory contains the necessary ingredients. Checking for the proper BenchType is notional at this point; that's left for an exercise for the reader :)

**AddCraftedItem()** is called when RecipeCheck() passes; it deducts the ingredients from the inventory and then starts a coroutine which waits however many seconds the recipe requires before actually adding the crafted item to the inventory.

**Going Further** This architecture pattern is simple to extend. For instance, you might want to further define a craftable weapon with properties for ammunition and methods for using it in combat. It's all up to you!

---
Tags: unity, c#
---


# Question
Title: How to calculate Chance of Success in a turn-based battle with chance to hit and damage roll + damage modifier?
I'm coding a choice-driven role-playing game and I want to give the player a percentage of his success chance in winning a battle before he chooses to start it. However, I have no clue how to make this calculation. I'd really appreciate any guidance you can provide!

The battle system is a simplified version of D&D battles:

1. Battles are turn-based and always **1vs1** (Player vs Enemy).
2. Both have **HP**, **CP**, **DP** (Health, Combat and Defense Points) and a **Weapon Modifier**.
3. Before an attack, the attacker has to roll a **Hit Roll** (1d20). The result + his Modifier is compared against the target's DP. If the value is equal or higher, the attack will hit.
4. Then I calculate the **Damage** inflicted with a **Weapon Roll**, which uses the weapon die (the die is equivalent to the CP value, so if CP = 10, the die is 1d10) + the Modifier.

I need to calculate the chance the Player will be able to land enough hits to kill the Enemy before he kills him. I can calculate the **Chance to hit** by using this formula provided by the D&D community, but I also need to take into account the rest of the variables:

**Chance to hit** = ((21-(Target’s DP-(Attacker's Modifier))) / 20) * 100

**21 because: 20 = always hit, 1 = always miss*

Here's an example:

|  | Player | Enemy |
| --- | --- | --- |
| DP | 10 | 20 |
| CP | 10 | 8 |
| HP | 80 | 60 |
| Modifier | 8 | 5 |
| Chance to hit | 45% | 80% |
| Avg. damage | 9 | 7 |

The final result should be a single percentage. For example: **Battle success chance = 47%**

---

**Edit:**

I simulated 100 battles as @Zibelas suggested to get the result. However, I'd still prefer to find a single formula to get the succes percentage, for efficiency reasons...

# Answer
I ended up calculating it as @Zibelas suggested: simulating 500 battles and then getting the percentage with this formula:

$$\text{Probability} = \frac{\text{Favorable Outcomes}}{\text{Total Number of Outcomes}}$$

**In case anyone is curious, the battle simulation process goes like this:**

1. Run a *for* loop 500 times.
2. Inside the loop, calculate how many turns it will take the Player and the Enemy to die, taking into account their current health (*while* there is HP, continue taking damage, and count iterations). If the enemy dies first, return *true*.
3. Count how many *true* values we've got (Favorable Outcomes).
4. Calculate the probability and multiply it by 100 to get a percentage.

I found simulating 500 battles gave an accurate enough probability. And overall the entire script runs in less than 2 ms.
> 3 votes

# Answer
I started looking for a more deterministic way to compute this, without relying on Monte Carlo simulation, gathering statistics of a sample of randomized battles.

It's a bit of a long road showing how I derived this, so scroll to the bottom if you just want the **tl;dr**.

---

To start, I asked "**What is the probability that the enemy has exactly \\$x\\$ HP after \\$n\\$ turns?**" Let's call the function that answers this question \\$P\_{\text{enemy HP}}(x, n)\\$

I'm also going to make a strange simplification, which is to assume the HP value \\$x\\$ can go to zero or negative and the battle keeps going anyway. This avoids special-casing zero, even though it gives us an unrealistic answer for some cases. That's fine: we'll use this unrealistic answer as a building block to work toward a realistically useful derived answer.

The base case \\$P\_{\text{enemy HP}}(x, 0)\\$ is easy to calculate, since this is the state before anyone has made a move:

$$P\_{\text{enemy HP}}(x, 0) = \begin{cases} 1, & \text{if $x$ = Enemy Starting HP}\\ 0, & \text{otherwise} \end{cases}$$

We can compute the values for turn \\$n\\$ from turn \\$n-1\\$ by summing two cases:

* If the player **misses**, then the chance the enemy has \\$x\\$ HP after this round is the same as the chance they had \\$x\\$ HP at the end of the round before. So that gives us a \\$(1 - \text{Player Hit %}) \cdot P\_{\text{enemy HP}}(x, n-1)\\$ term.
* If the player **hits**, then the chance the enemy has \\$x\\$ HP after this round is a sum. For each value \\$i\\$ from \\$(\text{Player Modifier} + 1)\\$ to \\$(\text{Player Modifier} + \text{Player CP})\\$ (ie. their min to max damage), we add up \\$ \frac 1 {\text{Player CP}}P\_{\text{enemy HP}}(x+i, n - 1)\\$ (ie. the chance the enemy had exactly \\$i\\$ more HP last round, and the player rolled exactly \\$i\\$ damage). That gives us a term like this:

$$\frac {\text{Player Hit %}} {\text{Player CP}} \cdot \sum\_{i = \text{Player Modifier} + 1}^{\text{Player Modifier} + \text{Player CP}}P\_{\text{enemy HP}}(x + i, n - 1)$$

Now we can recursively calculate \\$P\_{\text{enemy HP}}(x, n)\\$ for any \\$n \geq 0\\$.

I implemented this in Google Sheets for a range of HP from -100 to +100, and up to 63 turns - see the "Battle Sim" tab.

We can sum the values for all cells with HP \> 0 in a row to get the probability the enemy survives \\$n\\$ turns.

The trouble is, we had to do a metric crapton of calculations to get this number! Enough so that doing many rounds of Monte Carlo sims is probably just as fast, and has the advantage of being much simpler to reason about.

But we're not done - I did this to establish a ground truth data set that we can use to derive a close approximation that's easier to compute, and verify the accuracy of that value.

This calculation is effectively a convolution filter applied to the discrete probability distribution of enemy HP at each turn. You can see with each passing turn, the distribution gets more and more smeared-out - and, thanks to the central limit theorem, more and more normally distributed. We're going to exploit that, to see if we can usefully approximate HP as a bell curve with a mean and standard deviation.

Calculating the mean and standard deviation of this distribution at each turn is a bit tricky - once the left tail of the distribution goes past the lowest negative HP I'm simulating, the mean and SD values we compute are no longer trustworthy (though the total probability of being alive is still accurate). To stave that off as long as possible, let's give the enemy a lot of HP, say 100, and shrink the player's damage output, say we keep CP = 10 and lower Mod = 6. That gives us a good 13 rows of trustworthy data points to check our work.

The first thing we notice is that the mean decreases linearly: exactly the same delta in every trustworthy row. That's to be expected, given we have the same probability distribution of damage dealt every turn. So we can compute the mean HP after \\$n\\$ turns using the player's expected damage dealt, \\$E\_\text{player damage}\\$:

$$ \text{Mean}\_{\text{enemy HP}}(n) = \text{Enemy Starting HP} - n \cdot E\_\text{player damage}\\ \text{where}\\ E\_\text{player damage} = \left( \text{Player Hit %} \right) \left( \text{Player Modifier} + \frac {1 + \text{Player CP}} 2\right) $$

The standard deviation follows the curve of a square root function (meaning linearly increasing variance - again, maybe expected since we're applying the same convolution each turn). We can compute that function like so:

$$ \text{SD}\_{\text{enemy HP}} = \sqrt {n \cdot \Delta \sigma ^2}\\ \text{where}\\\begin{align}\\ \Delta \sigma^2 = &\sum\_{i = \text{Player Modifier} + 1}^{\text{Player Modifier} + \text{Player CP}} \left(\text{Enemy Starting HP} - i - \text{Mean}\_{\text{enemy HP}}(1)\right)^2 \frac {\text{Player Hit %}} {\text{Player CP}} \\\&+ \left(\text{Enemy Starting HP} - \text{Mean}\_{\text{enemy HP}}(1)\right)^2 \cdot (1 - \text{Player Hit %})\\\\\\ = &\sum\_{i = \text{Player Modifier} + 1}^{\text{Player Modifier} + \text{Player CP}} \left(E\_{\text{player damage} - i}\right)^2 \frac {\text{Player Hit %}} {\text{Player CP}} \\\&+ \left(E\_{\text{player damage}}\right)^2 \cdot (1 - \text{Player Hit %}) \end{align}$$

So once we calculate the constants \\$E\_\text{player damage}\\$ and \\$\Delta \sigma^2\\$, we can compute the mean and standard deviation of our HP distribution on any turn \\$n\\$ with very simple functions:

$$\begin{align} \text{Mean}\_{\text{enemy HP}}(n) &= \text{Enemy Starting HP} - n \cdot E\_\text{player damage}\\\\ \text{SD}\_{\text{enemy HP}} &= \sqrt {n \cdot \Delta \sigma ^2}\\ \end{align}$$

That lets us estimate the probability that the enemy is dead by the time \\$n\\$ turns have passed, using the cumulative distribution function of the normal distribution:

$$P\_\text{enemy dead}(n) = \frac 1 2 \left\[ 1 + \text{erf}\left( \frac {0 - \text{Mean}\_\text{enemy HP}(n)} { \text{SD}\_\text{enemy HP}(n) \sqrt 2} \right) \right\]$$

...where \\$\text{erf}\\$ is the Error Function \- this can't be expressed in terms of elementary functions, but a standard statistics library should contain an implementation you can use.

In the Google Sheets example, the probability of enemy death calculated this way very closely matches the one we computed exhaustively - differing by less than 1% at worst (ie. it underestimates the chance of dying by the end of 16 as 9.12% in this example, when the true value to within the accuracy of our double precision floating point math is 9.98%)

So, I'd say that gives us a very good approximation of the true chance of being dead. Note that since we're lumping together the whole part of the distribution \<= 0, the unrealism I called out earlier of pretending the enemy could have negative HP values gets erased.

But this still isn't quite the answer we're looking for, because it assumes the player character is immortal and has no chance to die and stop dealing damage. What we really want is the probability that the enemy dies before the player character does. But we can use this \\$P\_\text{enemy dead}(n)\\$ function to get that.

Let's assume we've built a data structure with a constructor like:

```
DeathPredictor(int hp, int dp, int opponentCP, int opponentMod)

```

This will compute and cache the constants we need, and expose a `double DeathPredictor.ChanceToBeDeadAfter(int turnNumber)` method that implements the probability function discussed above.

Then a method to compute the probability of victory might look something like this (assuming the player character acts first each turn):

```
float ChanceOfPlayerWin(Character player, Character enemy, out double expectedTurnCount) {
    var playerDeath = new DeathPredictor(player.hp, player.dp, enemy.cp, enemy.weaponModifier);
    var enemyDeath = new DeathPredictor(enemy.hp, enemy.dp, player.cp, player.weaponModifier);

    double pPlayerAlreadyDead = 0;
    double pEnemyAlreadyDead = 0;
    double pBattleOngoing = 1;

    int turnsCounted = 0;

    double pPlayerWins = 0;
    double pEnemyWins = 0;

    while(pBattleOngoing > CHANCE_THRESHOLD && turnsCounted < TURN_LIMIT) {
        turnsCounted++;

        double pPlayerDead = playerDeath.ChanceToBeDeadAfter(turnsCounted);
        double pEnemyDead = enemyDeath.ChanceToBeDeadAfter(turnsCounted);

        double pPlayerDiesThisTurn = pPlayerDead - pPlayerAlreadyDead;
        double pEnemyDiesThisTurn = pEnemyDead - pEnemyAlreadyDead;

        pPlayerWins += (1 - playerAlreadyDead) * pEnemyDiesThisTurn;

        pEnemyWins += (1 - pEnemyDead) * pPlayerDiesThisTurn;

        pPlayerAlreadyDead = pPlayerDead;
        pEnemyAlreadyDead = pEnemyDead;

        double pStillGoing =  1 - pPlayerWins - pEnemyWins

        expectedTurnCount += (pBattleOngoing - pStillGoing) * turnsCounted;

        pBattleOngoing = pStillGoing;
    }

    return (float)(pPlayerWins / (pPlayerWins + pEnemyWins));
}

```

Couldn't entirely escape iteration in the end, but now our computation is proportional to the expected duration of the battle (probably in the dozens of turns).

All this being said, myself, **I'd probably still implement this the Monte Carlo way** (and have, when I needed battle predictions in the past). I just did this because I was nerd sniped and wanted to prove it could be done.

The reason I would not recommend implementing it this way is that most of what I've done above is *non-obvious*, making it hard to spot an error if I've made one (I probably have!), and *brittle*: it only works for *exactly* the battle mechanics you've described. If you later decide to change your mechanics, add a new special ability, etc., then you have to re-do this whole derivation to account for the new effect.

With the Monte Carlo approach, if you architect it right, you can use exactly the same code for both normal battle resolution and the prediction loop: so any change you make to your battle mechanics *automatically* updates your predictions too! That's a huge win, and probably worth even several milliseconds of extra computation. (Especially if you can do this on a background thread and hide the latency with a UI animation, so the player doesn't notice even the slightest hitch when a new battle prediction is being computed)
> 2 votes

---
Tags: turn-based, probability
---


# Question
Title: Calculate angle for arrow tip to hit a point
For an archer in my game, I want to calculate the launch angle to hit a point (x,y) when fired from (0,0). The initial power is known, so I use the following formula: https://en.wikipedia.org/wiki/Projectile\_motion#Angle\_%CE%B8\_required\_to\_hit\_coordinate\_(x,\_y)

The problem is that the arrow is not a point and depending on the angle the archer shoots at, only the location of the base of the arrow is constant. The displacements from the base of the arrow to the center of the arrow, which is the center of gravity and the arrow tip are dependent on the angle. These displacements are of the form (cos(theta), sin(theta)) * r where r is some constant. i.e. the arrow is rotated by the aim angle around its base. As the arrow travels through the air it is rotated around its center to face the direction it is moving.

How can I calculate the angle required for the tip of the arrow to hit a point?

Example to illustrate (two different angles, base of arrow = blue, center of gravity = green, tip of arrow = red):

# Answer
Myself, I would solve this by insisting that the point I'm calculating for *always* represents the tip of the arrow — just possibly back in time. That way all your standard physics formulas still work fine as is, and we just need to adjust the visuals a little.

If at the moment the player *sees* the arrow fire, the arrow base is the point at (0,0), I'd pretend the arrow actually "fired" a tiny fraction of a second in the past — the tip passed *through* (0, 0), invisibly, and emerged on the other side to where the player sees it now, a fraction of a second later.

So, use your angle calculation as normal. Then compute the point on the resulting parabola 1 arrow length from the firing point — a tiny bit forward in time along its trajectory. When you draw the visible arrow in the aiming pose or at the moment of release, draw it with the angle that puts the tip at that point (which in general will be a tiny hair shallower than the angle at time 0).

If your computed velocity is \\$\vec v\\$ and the arrow has length \\$l\\$, this will be well approximated by the time \\$t\_\* = \frac l {||\vec v||}\\$ and the point to aim the arrow tip at will be:

$$\vec p(t\_\*) = \vec p\_0 + \vec v \cdot t\_\* + \frac {\vec g} 2 \cdot t\_\*^2$$

You'll also likely want to move the arrow asset's pivot so it's at its tip — this is reasonably well justified as the arrow head is the heaviest part, so the center of mass will be closer to the front than to the back.
> 0 votes

---
Tags: 2d, rotation, projectile-physics, trajectory
---


# Question
Title: Where should I put a JSON file to be readable in a Unity build?
I have a file which is created manually. In what folder should I put it so I can read it in a build?

For example `Application.dataPath` in editor reads the file from the assets folder, but if I put it there, will my code find that file in a build if I search it by Application.dataPath + folder name?

# Answer
If the file is modified at edit time, and not modified in the built version of the game, just put the file somewhere in your Assets directory like you do with other assets including textures, models, scripts, etc.

Files with the .JSON extension will automatically be imported as TextAssets. (The same goes for various other extensions listed at that link, including .txt, .bytes, .csv, .xml...) This lets you load data out of the file using the engine's native referencing features, without writing your own file IO code or hard-coding any specific paths.

In the script that needs to use this JSON data, just create a `public` or `[SerializeField]` variable of type `TextAsset`. That will give you a slot in the Inspector where you can drag this JSON file to be referenced.

Doing it this way, Unity's build process and loading systems will be able to see where this file is referenced from, and ensure it's loaded into memory when you load a scene or prefab that references it - so you don't need to worry about blocking or asynchronous file reading in your own code. It also means if you have gobs of these JSON files and some are out of date / unneeded / no longer referenced anywhere, the engine can detect that and strip them out so they don't add bloat or leak any development secrets in your build.

`TextAsset`s also work with the Unity Addressable Assets system if you need to load it dynamically or stream it from an asset package hosted online.

You can then get at the JSON text in the file with `myJsonTextAsset.text` and use the JsonUtility or other library of your choice to parse it.
> 2 votes

---
Tags: unity, c#, json, asset-workflow, filesystem
---


# Question
Title: Is there a way to check if a Texture2D has unapplied changes?
In Unity, we can use the `Apply()` function of Texture2D to apply any changes that we've made with `SetPixel()` or `SetPixels()`.

Is there a way to check whether the texture currently has any unapplied changes? I don't see any relevant properties like `IsDirty` or `HasUnappliedChanges`, but perhaps there's a less obvious way to check.

My particular use case is that I have a texture which is normally only used for calculations and does not need to be displayed on the screen, so it's normally not necessary to call `Apply()` after changing the texture. However, I'd like to be able to preview the texture in the Inspector when a particular component is selected, which does require that the texture is Applied. I'm wondering if Texture2D has a built-in way to check for unapplied changes; if not, it won't be difficult to write custom code for tracking this.

# Answer
I've tried `Texture2D.updateCount` but this apparently does not record the count of unapplied changes. So I just use a separate `bool[]` to record which textures I've made changes to. Not as efficient as dealing with all the data directly in `Texture2D` I guess, but it works.
> 2 votes

---
Tags: unity
---


title: Surface normal vs tangent space

text:
# Question
Title: Surface normal vs tangent space
I am having a hard time being convinced why calculating the tangent space the way most textbooks do is the best thing to do? Why shouldn't we just simply use the edges of our triangle as Tangent and BiTangent and use their cross product as the normal and use the resulting matrix in bump mapping. These two approach give the same result but what I have described is arguably far more intuitive? Any thoughts?

# Answer
> 1 votes
Keep in mind the reason why tangent space is used. It's to provide an orientation for the normal map to know whether the normal needs to be adjusted in the u or v direction.

For that you need to know which way the u and v axis point at the fragment you are computing and *it needs to be consistent across multiple triangles*.

Also you have 6 ways to pick the edge pairs of a triangle (3 if you fix winding order), how would you know in the fragment shader which way was picked.

---
Tags: lighting, normal-mapping, bump-map
---


# Question
Title: Check if point is within Unity NavMeshSurface walkable area
I am using the **NavMeshSurface** component in Unity to generate a navmesh of walkable areas in a procedurally generated level. I am working on some basic behavior to use with a NavMeshAgent. I want to find a random point for the agent to wander to, but I want to check if the position is within the walkable area before telling the agent to start navigating.

The problem is that I can't find a method to check if a point is within the NavMeshSurface. My search results reference the NavMesh having a similar method but not NavMeshSurface. Is there an easy way to check if the point is in bounds? Can I access the NavMesh and ray/sphere cast against it? Any solutions would be great. If there is a different free option, I am open to exploring it.

Thanks. Let me know if you require more information.

# Answer
If you just want to designate a random destination for the agent to wander to, you can use NavMeshSurface.NavMeshData.sourceBounds to find a point within the bounds of the NavMeshSurface. Sure, it will contain points that aren't strictly on the path, but in most cases this shouldn't really matter -- the agent will simply wander to the nearest point that is on the path.

Here is a test script. It assumes the navmeshsurface gameobject is at origin.

It resets the agents destination every 5 seconds.

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class TestThing : MonoBehaviour
{
    public NavMeshSurface surface;
    NavMeshData data;
    public NavMeshAgent agent;
    public Transform target;

    float timer;

    Vector3 destination;

    void Start()
    {
        data = surface.navMeshData;
        agent.destination = SetRandomDest(data.sourceBounds);
        Debug.Log(data.sourceBounds);
        timer = 0;
    }

   //Update destination every 5 seconds to test
    void Update()
    {
        timer += Time.deltaTime;
        if(timer > 5)
        {
            agent.destination = SetRandomDest(data.sourceBounds);
            Debug.Log(data.sourceBounds);
            timer = 0;
        }

    }

    Vector3 SetRandomDest(Bounds bounds)
    {
        var x = Random.Range(bounds.min.x, bounds.max.x);
        var z = Random.Range(bounds.min.z, bounds.max.z);

        destination = new Vector3(x,1, z);
        target.position = destination;
        return destination;
    }
}

Hope that helps.

```
> 2 votes

---
Tags: unity, navmesh, navmeshsurface
---


# Question
Title: How do I identify bank deposits by Valve for Steam revenue?
I recently published a game on steam and I saw a deposit in my bank account with description of WPS-xxxxx (where the x's are a string of mostly numbers) Also, I do not live in the US

I've been looking around online to confirm whether this was steam sending me money for my game's sales but can't find anything. I need to confirm this fairly soon for personal reasons, so if any developers who've received money from steam can confirm or deny whether steam's payments have description starting with "WPS" I'd appreciate it.

I know this is an unusual question for this site so if someone can direct me to another place to ask I'd also appreciate the help, thanks.

# Answer
**Log into the portal and check**

> The Sales & Activations Reports portal provides a near real-time view into revenue, units, player counts, geographic breakdown, and other statistics related to your product.

https://partner.steamgames.com/doc/finance/payments\_salesreporting
> 3 votes

---
Tags: steam, steamworks, payment
---


title: Best way to save game data in Unity

text:
# Question
Title: Best way to save game data in Unity
I am currently developing a game in unity and I want to add some sort of saving system that saves the following:

* Locked / unlocked level.
* The amount of money the player has.
* Items / perks that the player has.

As you can see, the data I want to save is global, and has nothing to do with any specific scene.

How would you reccomend save this kind of data? I have heard about the EasySave asset but I don't know if it is the right choice: it is pretty expensive and I belive that there has to be some easier, cheaper (even free) way to save the data.

I'll appreciate any answer or consideration.

# Answer
> 2 votes
Unfortunately Unity does not have a build-in savegame system. So every game needs to develop an own savegame system which is tailored to the architecture and requirements of that specific game. That means there is no "best" way to save data, only the way which is best for *you*.

When you have very little data to save, then using the PlayerPrefs class can be a quick and easy way to do it. In your particular case, this could be sufficient. But it is intended for, well, preferences. A short list of key-value pairs. It is not designed to hold large amounts of data, and even allowing more than one savegame quickly becomes messy.

So you likely won't get around inventing your own savegame file format which you read and write with the standard C# classes like `StreamWriter` / `StreamReader` (for text-based formats) or `FileStream` (for binary-based format).

When you only want to save the game state between scene changes, then you only need to persist the data which you already need to handle between scenes. That makes a lot of things a lot easier, because you already have a good overview of what data you have.

But if you want to have a system which allows to save and reload the game at *any* time, then it gets a lot more complicated. Such a system needs to:

* Find out which gameObjects are currently in the game
* Read any data about them which is worth persisting
* Compile all that data into a file format
* Save that file
* Read that file and parse it
* Recreate all the gameObjects with their components based on the content of the file
* Set their variables according to the content of the file

As you can see from the complexity of some of these points, this is not something where one solution fits every game. But a couple tools that could come in handy for creating your savegame system could be:

* Using the Unity serialization system and see how far it gets you (unfortunately it has some limitations)
* Interfaces which mark a MonoBehaviour as "Saveable" and includes methods which turn that component into a data representation and can set the state of that component from such a data representation. (Unfortunately that won't help you with Unity standard components).
* Behaviours which take care of persisting / restoring all the components on a specific type of gameObject they are on, including Unity-specific components. But that might create quite a lot of maintenance work in the long run.
* Reflection to find out what variables an object has and attempt to persist / restore it automatically
    + Attributes to mark variables which should / should not be saved by your reflection-based system

# Answer
> 0 votes
Easy Save is the best suitable for your game. Have used it in multiple games and it's very easy to use, fast, time saver and supports lots of types ranging from primitive data types, collections and even unity types. It also provides options for data encryption and is very fast.

---
Tags: unity, savegame
---


title: How to save large data in Unity?

text:
# Question
Title: How to save large data in Unity?
Can anyone please tell me how to save data for Android.

I have too much data to save (many npc-enemy stats). Also, it should work after updating: I read on stack overflow that, with `BinaryFormatter`, when you update or change the class, your old settings might be lost since the classes no longer match. Sometimes, you get an exception when reading the saved data due to this.

I also read about JSON/XML. Does JSON/XML throw an error if I change class?

# Answer
> 2 votes
If I want my data to be readable I would go with JSON. With JSON.NET for example, it's easy to set default values for fields or ignore unknown fields. So if you either add or remove fields from your class it might be out of balance but it won't break.

But what exactly is too much data? Do you need to serialize billions of large objects without cutting corners? If this is the case, JSON might be too sow for you. But be careful when you say large, it's a relative term and my intuition tells me you are talking about serializing a relatively small amount of data.

If it really is a huge amount of data and it does not need to be humanly readable you can use a binary writer. This is a lot faster but without all the handy functions from JSON libraries, you need to tell it what fields to serialize and de-serialize.

# Answer
> 2 votes
### Short version

Use sqlite. Really. I know it's more work than just using a serializer, but that's the way all normal android apps do it, and its the *right* way to do it, as I'll explain below.

See https://github.com/codecoding/SQLite4Unity3d for how to do that.

If that's too much work, checkout out custom serialization using https://github.com/jacobdufault/fullserializer

### Long version

The *format* that you save your data in is an orthogonal concern to the *way* in which you save large data sets.

There are two issues here:

* When I save a record, I need to be able to restore that record, even if the data model has potentially changed *in code* compared to when I saved the record.
* I need to save a large number of records, and it's too slow.

Lets address these problems one by one:

### Deserializing when the model has changed

An XML/json serializer will solve this problem to some extent, but ultimately, if your data model changes you need to use a *migration* to migrate old data to the new schema.

There is no way to avoid this problem.

Using a weakly typed serializer (eg. json) will allow you to receive null values for missing keys, but ultimately, if a field changes type, you'll still have broken data.

Don't ever use `BinarySerializer`.

The standard solution to this problem is to use a database, and migrate data on a per-table basis using migrations, as though you were writing any other kind of database driver application.

Although android has built-in support for sqlite and migrations, unity doesn't; you'll have to write some custom code for it.

You could also use a custom json deserializer to apply your migrations 'on the fly' as you deserialize objects, but the inbuilt `JsonUtility` doesn't not support this; you'll have to use a custom serializer like https://github.com/jacobdufault/fullserializer

### Saving large data sets

Now, *regardless* of the storage format for individual records, the key to saving large datasets is to do it in parts.

In sqlite, partition your data per table.

If serializing manually, split the data model into a series of small objects and save them one by one.

The reason for this is that the UI thread will block while you perform slow operations like saving. The correct approach here is to do something logically equivalent to this:

```
- Split data into records
- Show save progress indicator
- Start a coroutine
-- While there are records left to save:
--- Save a few records
--- `yield` to wait for the next frame and allow the UI to update

```

This is where sqlite really shines; sqlite is naturally partitioned into tables, and tables into rows. Inserting a few rows or updating a few rows is a simple atomic operation that is easy to split into parts.

Doing this by hand with serialized objects means *manually* looking after folders full of multiple distinct serialized objects; it's all the house keeping that sqlite does for you.

Remember that as with *any* UI driven application monolithic (large, slow, do-all-the-things) operations cannot be split onto multiple cores and cannot be deferred; to be responsive, tasks on the UI threads should periodically return control to avoid locking the UI. See this for more background on the topic on android: https://developer.android.com/training/articles/perf-anr.html

Unless the amount of data you're saving is trivial, saving objects using direct serialization is almost certainly not going to scale well (many unity games have ANR issues on android for this reason).

Basically, if you take anything away from this, it should be this:

* You should really invest in learning and using sqlite, even if you're using android. It's the 'right' solution for the problem you describe.

# Answer
> 1 votes
you can use either SQLite(also if you need key-value pair/Doucument database can use UnQLite istead) or JSON(json have less waste characters included and is much smaller if you remove all \r\n in it compare to XML). for json use this : http://www.newtonsoft.com/json

# Answer
> 0 votes
You should give a try to Easy Save. Best suitable for large projects having number of files or large files to manage. Variety of primitive and unity types are supported. Cloud storage, encryption and spreadsheets are also supported. Which may help a lot for large project's save system development.

---
Tags: unity, savegame
---


# Question
Title: How do I determine if a given grid coordinate is fully within a triangle?
I'm using Unity's Grid system, and I'm drawing triangles on the grid. Each triangle is recorded as a `Vector2Int` origin point and a `List` of three `Vector2Int`s recording its relative vertices, for instance:

```
origin = new Vector2Int(0, 0);

relativeVertexPositions = new List<Vector2Int>() {
    new Vector2Int(-3, 0),
    new Vector2Int(3, 0),
    new Vector2Int(0, -3),
};

```

It's a bit weird that the origin is on the bottom of the triangle but it's for an in-game reason - a character is meant to stand there. I can redefine the origin point to elsewhere in the triangle if needs be.

The above code would generate a triangle as follows:

I'm completely stuck on how to find out whether a given `Vector2Int` (i.e. an integer x,y position - this is presumably an engine-agnostic problem) is *fully* inside the triangle. These four squares are marked in blue on my sketch.

Individual instances of triangles vary in the distance that their vertices are located away from the origin (`1..n`), but they all have this shape and the structure `((-m,0),(m,0),(0,-m))` where `m` is an integer. They can also be rotated in 90-degree increments around the origin point - I do this by translating the vertices around the origin, but the *relative* relationship of the vertices to the origin never changes.

# Answer
You seem to be using the centre point of your square as the reference, so I will follow that convention (I'm not familiar with Unity's conventions about this).

You just need to check three inequalities, one for each of the sides of the triangle. Assuming i,j is the centre of your square (I'm using i and j because I want to leave x and y free to show my working):

* For the base, you need to check that j+1/2\<=0, simplifies to 2\*j\<=-1, or j\<=-1 given that we are working with integers.
* For the left side, look at the top left corner of the square, you are checking it against the line x+y=-m, so check (i-1/2)+(j-1/2)\>=-m, simplifies to i+j\>=-m+1
* Similarly for the right side, look at the top right corner of the square, you are checking it against the line x-y=m, so check (i+1/2)-(j-1/2)\<=m, simplifies to i-j\<=m-1.

If it passes all three checks, it is fully inside, otherwise it is not fully inside.

For the rotated case, you can just rotate to this coordinate system and do the checks, or have 3 other cases similar to this one.
> 2 votes

---
Tags: unity, mathematics, grid
---


# Question
Title: How were the invaders programmed to shoot in the original arcade version of Space Invaders?
I'm trying to make a clone of the original classic and mimic its game mechanics as closely as possible, but am stuck on making the invaders shoot.

From playing online versions of the game, it seems as though a random invader is chosen to shoot every x frames, then a random missile is chosen from the three available. x starts off as a random integer within a relatively-high range (say 300 - 600), then gradually decreases as the invaders are killed. Am I close?

Of course, I realise that no-one besides the original devs is likely to know this stuff for certain, but I'm hoping for an expert player to share what they've learned from simply playing the game.

# Answer
> 5 votes
> Of course, I realise (sic) that no-one besides the original devs is likely to know this stuff for certain

That's not entirely true. Computer Archeology has a write up that discusses the original Space Invaders assembly code. Here's a summary of information they present regarding the alien firing logic:

* There are three different alien shots in the game, each with a unique picture:
    + Object 2 is the "Rolling" shot & spirals a bit as it falls.
    + Object 3 is the "Plunger" shot.
    + Object 4 is the "Squiggly" shot.
* The byte timer from Object 2 is used to synchronize the three shots so that only one shot is processed per screen.
* The common handler is responsible for moving each shot.
    + The normal delta Y for the shots is a constant 4 pixels down per step. A shot makes a step every 3 frames. (4 * 60/3 = 80 pixels per second).
    + If the number of aliens is reduced to 8 or less the delta changes up to 5 pixels per step (5\*60/3 = 100 pixels per second).
* The common handler also initiates the alien shots. Each shot has a move-counter that starts with the shot & increments each step as it falls. The game keeps a constant reload rate that determines how fast the aliens can fire. The game takes the smallest count of the other two shots and compares it to the reload rate. If it is too soon since the last shot then no shot is fired.
* The reload rate gets faster as the game progresses. The code uses the upper two digits of the player's score as a lookup into a lookup table & sets the reload rate.
* Object 2 drops right over the player when it falls.
* The other two shots use pointers into a table of columns. The pointers advance very predictably. For instance object 4 shot will fall in columns 11, 1, 6, & 3 in that order.
* When there is only one alien left, object 3 is disabled & the other two are fired more often.

Additional details regarding the specific memory addresses, values, etc. are available here.

---
Tags: game-mechanics
---


# Question
Title: Setting target framerate changes animation speed in editor, while Time.deltaTime stays the same
I have few animations that work similar to this:

```
IEnumerator MoveObjTo(GameObject obj1, GameObject ob2, float time)
{
    var start = obj1.transform.position.x;
    var end = obj2.transform.position.x;

    float passedPath = 0f;
    var s = end - start;
    float speed = (end - start) / time;
    while (passedPath < s)
    {
        var ds = speed * Time.deltaTime;
        var newPos = obj.transform.position;
        newPos.x += ds;
        obj.transform.position = newPos;
        passedPath += ds;
        yield return new WaitForEndOfFrame();
    }
}

```

It worked fine until I added this line to my code:

```
Application.targetFrameRate = 60;

```

After this, inside the Unity editor animation started to work 10 times faster (it's still OK on device). And I noticed that if I set `targetFrameRate` to the same FPS value as shown in the editor's Stats (400 FPS), to the animation speed is fixed.

If I print `Time.deltaTime` and `ds` inside this method, I'll get about the same values and it looks like `Time.timeDelta is always 0.017`, but with different `targetFrameRate` values that same 0.017 corresponds to different real time intervals.

I'll fix it by `ifdef`ing the `targetFrameRate` setup, I'm just curious how this works.

# Answer
> 0 votes
Some things you can check:

1. Make sure you aren't changing `Time.timeScale` anywhere.
2. Make sure you aren't setting `Time.captureDeltaTime` or `Time.captureFramerate` anywhere.
3. See if you can update the Unity Editor to a newer version, in case it's a bug in the Editor.

---
Tags: unity, frame-rate, timestep
---


# Question
Title: Architecting server for real-time multiplayer game with Unity client
I'm thinking about developing a scalable real-time online multiplayer game. it would be an online 2D battle game. I'm an experienced software developer but this is my first experience in game development. After doing some research on the internet I found the following architecture for my online game:

1. **Game Core**: Using Python or C# to build the game logic including the environment, objects, movements, etc. it would be a server-side game. It means that every event would be handled and controlled by the server and users just send their inputs to move around and act (e.g. moving, shooting, ...)
2. **Web Service**: There would be a database to store players' information and a web service (using WebSocket) to authenticate users, interact with them, and stream the data. Players send their requests to this web service, then the requests will be sent to the Game Core using a local network socket.
3. **Unity**: We will use Unity to render the game on the client side.

The problem is the **Game Core**, I don't call it a **Game Engine** because it will not have any graphics on the server side, it's just the game logic. I tried to write a few lines of code for the Game Core, but it doesn't seem right, because I'm creating everything from scratch including player movements, gravity, etc. it's like reinventing the wheel.

How should I approach this server-side development to maximize development speed and minimize duplicated effort?

# Answer
> 2 votes
If you're building your front end in Unity anyway, I'd strongly consider using Unity on the back end too, if feasible, for a few reasons:

* Both the client and server will care about many of the same concepts / classes / etc. If you have to implement these ideas and structures in two different languages/environments, you're **duplicating effort**.
* This duplication creates **new opportunities for bugs** to arise, if a change is made in either the client or server code, but missed (or implemented subtly differently) on its counterpart. If both your client and server are built from the same shared codebase, changes in one automatically get incorporated into the other on the next build. (And without needing complex codegen/transpiler infrastructure to translate for you)
* You're probably going to want some of the server code to run client side *too* \- not to authoritatively decide the next game state, but to *predict* what the server's response is likely to be and begin animating/transitioning toward that state before the server's reply arrives. This **client-side prediction** helps the game feel smooth and responsive, rather than feeling like it's frozen or lagging when waiting for the next server update.

So this means you're likely to save a lot of effort if you can keep your development centralized in one language/engine rather than split.

If you're worried about server bloat, from unnecessary client-side concepts like rendering and animations spilling over, you can use the tips in this answer to conditionally compile out your display logic and assets in server builds, to keep them lean.

If running the full Unity engine on your server is not practical for your needs, I'd still recommend building your server app from the same C# codebase that you use in Unity. Then make whatever minimal shims you need to fill-in for the missing `UnityEngine` namespace code and game loop / messaging infrastructure you need to call into that game code. That can help you get the best of both worlds in terms of reduced duplication and improved server scalability. And you can use the Unity engine's API as a battle-tested guide for how your server-side core API might look.

# Answer
> 0 votes
If you are a Unity developer and have no idea about backend development then I would suggest to include backend developer(s) to the team as in this kind of multiplayer game development, the major role is of backend developer. All gameplay logic, AI are managed by the backend code. Only gameplay user interaction is handled by the frontend unity code. Game runs completely from the backend. Backend developer also helps in architecting the game in a better way to make it scalable. Server side games also help a lot in other ways also, like real time upgradation, difficulty management etc.

---
Tags: c#, multiplayer, python, client-server, realtime
---


# Question
Title: How can I make the hue of a material change over time?
I'm working on a small psychedelic-style game that needs to be done in Unity, with which I have no prior experience.

I'd like to achieve an effect where the material of my objects can change colors over time. The end result would look similar to what is happening in this video:

How can I achieve something like this?

# Answer
Here's how to write a shader that applies this effect.

I'm assuming you want lighting, so I started this shader by right-clicking in the Project view and selecting Create -\> Shader -\> Standard Surface Shader. If you don't need lighting, use the "Unlit" shader template instead.

Our strategy will be:

1. Read the colour of the texture on the material as usual.
2. Convert that colour to HSV, or Hue-Saturation-Value colour space.
3. Add an offset to the hue (.x) part of our HSV triple, proportionate to the amount of time that has passed - we can get that from Unity's built-in shader uniform `_Time`
4. Convert back to RGB colour space, and use that shifted colour in place of the original.

I'm using the colour space conversion formulas shared by Chilliant / Ian Taylor.

```
Shader "Custom/PsychedelicHue"
{
    Properties
    {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
        // Use this to control the speed of the animation.
        _Speed ("Hue Rotation Speed", float) = 2.0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200

        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;
        // Expose the speed parameter to use in our code.
        half _Speed;

        // Colour conversion functions.
        float3 hsv_to_rgb(float h, float s, float v) {
            h = 6.0f * frac(h);

            float3 hue = saturate(float3(
                abs(h-3.0f) - 1.0f,
                2.0f - abs(h - 2.0f),
                2.0f - abs(h - 4.0f)
            ));

            return ((hue - 1.0f) * s + 1.0f) * v;
        }

        // These functions are from https://chilliant.com/rgb2hsv.html
        const float EPSILON = 1e-10;

        float3 rgb_to_hcv(in float3 rgb) {
            // Based on work by Sam Hocevar and Emil Persson
            float4 p = (rgb.g < rgb.b) ? float4(rgb.bg, -1.0, 2.0/3.0) : float4(rgb.gb, 0.0, -1.0/3.0);
            float4 q = (rgb.r < p.x) ? float4(p.xyw, rgb.r) : float4(rgb.r, p.yzx);
            float c = q.x - min(q.w, q.y);
            float h = abs((q.w - q.y) / (6 * c + EPSILON) + q.z);
            return float3(h, c, q.x);
        }

        float3 rgb_to_hsv(float3 rgb) {
            float3 hcv = rgb_to_hcv(rgb);
            float s = hcv.y / (hcv.z + EPSILON);
            return float3(hcv.x, s, hcv.z);
        }

        // Original surface function, with modifications...
        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            // Read the colour from the texture, and apply material tint.
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;

            // Convert colour to HSV colour space.
            float3 hsv = rgb_to_hsv(c.rgb);

            // Shift the hue proportional to time, and convert back.
            o.Albedo = hsv_to_rgb(hsv.x + _Time.x * _Speed, hsv.y, hsv.z);

            // The rest we leave as-is in the default shader.
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

```
> 3 votes

# Answer
You would first want to get the material attached to the gameObject.

```
// If you have a reference to the GameObject called "myGameObject":
Renderer renderer = myGameObject.GetComponent<Renderer>();
// If the object you want is the one this script is attached to:
Renderer renderer = GetComponent<Renderer>();

// This creates a special material just for this one object. If you change this material it will only affect this object:
Material mat = renderer.material;

// This gets the shared material used by this renderer. If there are other renderers that use the same material, changing this material will also affect them.
Material mat = renderer.sharedMaterial;

```

**Note:** Use `.sharedMaterial` if you want to change the material's color on all game objects with this material. **Note 2:** If you have multiple scripts all accessing the same .sharedMaterial, what each one does will stack (meaning if you increase hue, it will increase faster).

Then, later in the script you can increase hue, by doing:

```
public foat speed;

float h, s, v;
void Update()
{
    Color color = mat.color;

    Color.RGBToHSV(color, out h, out s, out v);
    h += Time.deltaTime * speed;
    h = h % 1f; //Max value it can be. For non-hdr, it is 1
//I don't know what it is for hdr, maybe try 255f
    mat.color = Color.HSVToRGb(h, s, v, false);
//set the bool to if it is hdr

```

In the line that goes `h = h % 1f`, set 1f to 1f it is not hdr. (I do not know what hdr max value is for HSV values, as the scripting api was not very clear) if i had to guess though, it would be 1f or 255f.

In the final line of code, set the bool to if it should be hdr.
> 1 votes

---
Tags: unity, shaders, materials, color
---


# Question
Title: Last hole artifact in screen space refection with Hierarchical Z
After lot of efforts I have an almost nice shader doing SSR with HiZ. The shader is provided below. Some parameters are tunable and you can speed up things but the difficulty in my scene (picture) are the spheres that limit the coarsiness of the ray marching. So the benefit of HiZ is not as high as expected for this scene but there’s some (130 FPS instead of 110-120, 960x540).

I'm using a HiZ loop working only with increasing Mip level and a second one is used to get finer result as at that point I did not understand fully how the cell boundary calculations work.

Unfortunately there is a last annoying problem I was not able to solve in this SSR HiZ shader. The problem is shown in green on the left picture and on right what I have without HiZ. It is annoying because I did not have this problem with my regular SSR shader whitout HiZ. I have tried a thickness test like in the McGuirre method but it is not working.

```
 e.g : if abs ( ray.z-zbuff)< thickness.

```

So if someone can help below is my shader. enjoy if you're interested.

The shader is below

```
  //parameter for finer or coarser primary while results
  #define offset0 0.005
  #define offsetR 2
  //my initial resolution (Mip=0)
  static const int2 Resolution = {960, 540};
  //uv offset1 : critical to ensure correct uv sampling. modulate to see effect
  static const float2 offset1 = {1, 1.015};
  //parameter for finer or coarser secondary while results
  #define offset2  1.15
  //parameter for final dicotomic refinement
  #define refinemax 3
  //parameter for removing vertical artifact for objects not on ground
  //based on the normal of the object
  #define dot3falloff 0.00005
  #define falloff 0.00003

  float4 PS_PostDeferredReflex(PS_INPUTQUAD Input) : SV_TARGET
  {
      float D = txDepth1.SampleLevel(samPoint, Input.Tex, 0).r;
      if ( D == 1 ) return float4(0,0,0,0);
      float4 ColorOut = txDiffuse1.SampleLevel(samPoint, Input.Tex, 0);
      if ( ColorOut.a <0.9)  return ColorOut;
      float3 PosV = float3(InvProj.x*(Input.Tex.x*2-1),InvProj.y*(1-Input.Tex.y*2), 1)/(InvProj.z*D+1);
      if ( txDiffuse1.SampleLevel(samPoint, Input.Tex, 0).a == 0)  return ColorOut;

      float3 VSDir = normalize(reflect(normalize(PosV.xyz),txNormal1.SampleLevel(samPoint, Input.Tex, 0).rgb*2-1));
      if ( VSDir.z < 0 ) return ColorOut;

      float4 SSEnd = mul(float4(PosV + VSDir*200, 1), Proj);
      SSEnd/= SSEnd.w;
      SSEnd.xy = SSEnd.xy*float2(0.5,-0.5)+float2(0.5,0.5);
      float3 SSray = float3(Input.Tex, D);
      float3 SSDir = normalize(SSEnd.xyz-SSray);

      float dSS;
      if ( abs(SSDir.x) < abs(SSDir.y) ) dSS = abs(SSDir.y); else dSS = abs(SSDir.x);
      SSDir/=dSS;//"normalize" SSDir according to longest x or y
      SSDir*=offset0;//modulate step size

      int Mip = 0;//you can start at higher Mip level but I don't see improvements
      float ZBufferVal=1;
      float2 CurResol;
      float3 curSSDir = SSDir*pow(2,Mip)*offsetR;//pow useless at Mip=0
//primary while : move ray with Mip-dependant increasing steps
//until ray.z > zbuffer
      float rayZmin = 0;
      float3 poslast = SSray;
      int i=0;
      float4 Color ;
      while ((Mip<10)&&(i<20))//my resolution corresponds to 10 miplevel
      {
          i++;
          rayZmin = SSray.z;
          poslast = SSray;
          float2 MipSize = (Resolution>>Mip);
          SSray+=curSSDir;
          //use Load like below to have better sampling than
          //SampleLevel(samPoint,SSray.xy,Mip).r;
          ZBufferVal = txDepth1.Load(int3(SSray.xy*MipSize*offset1, Mip)).r;
          if ( ZBufferVal==0 ) ZBufferVal=1;    //avoid disappearing reflexions at bottomscreen
          if (SSray.z > ZBufferVal)  break;
          if ( Mip < 9 )
          {
              Mip++;
              curSSDir*=2;
          }
      }
      if (poslast.z>=1) return ColorOut;
      //secondary while : move ray from last position (z<zbuffer) now only at level Mip = 0
      //until ray.z > zbuffer
      SSDir=normalize(SSDir)*0.02;
      i=0;
      SSray = poslast;
      while (i<40)
      {
          i++;
          ZBufferVal = txDepth1.SampleLevel(samPoint, SSray.xy, 0).r;
          if (SSray.z > ZBufferVal)
          {
              float3 MinRay = poslast;
              float3 MaxRay = SSray;
              for(int j = 0; j < refinemax; j++)
              {
                  poslast = (MinRay+MaxRay)*0.5f;
                  ZBufferVal = txDepth1.SampleLevel(samPoint, poslast.xy, 0).r;
                  if ( poslast.z > ZBufferVal) MaxRay = poslast; else MinRay = poslast;
              }
              float3 N = txNormal1.SampleLevel(samPoint, poslast.xy,0).rgb*2-1;
              float Dot3 = ( N.x+N.y+N.z>2.99f)?dot3falloff:(dot(-VSDir, N)<0)?0:dot3falloff;
              if (abs(poslast.z-ZBufferVal)<Dot3)
              {
                  Color = float4(txDiffuse1.SampleLevel(samPoint, poslast.xy, 0).rgb, 1-abs(poslast.z-D)*500);
                  return lerp(Color,ColorOut,1-Color.a);
              }
              return ColorOut;
          }
          poslast = SSray;
          SSray += SSDir;
      }
      return ColorOut;
  }

```

# Answer
After some refinements I have found the solution (see picture). The vertical holes were due to the line "return ColorOut" just after the refinemax loop. This line must be removed to let the while loop continue to find an accurate position. In turn this slows down the shader. I add in this answer a corrected shader. This new shader is more complete and you can set or not HiZ. It is also intended for showing how I managed the deferred multilayers used to fill the last holes due to overlapping objects. How these layers are created is explained in one of my previous questions. After the Hiz search a second loop is used to fill these holes as the HiZ algorithm I used is no table to do it. At the end the speed is still not there but it is possibly because I want to filter off the black background as much as possible.

The corrected shader is below. The HiZ loop comes from (here. It was easy to implement and give fine results) .

```
   Texture2D txDiffuse[3] : register(t0);//0 main scene; 1 object occluded once 2 object occluded >1
   Texture2D txNormal[3] : register(t3);//normals for the 3 layers
   Texture2D txDepth1 : register(t6);//main depth (zbuf) of layer 0. Has mip levels
   Texture2D txDepth23 : register(t7);//rg contains depth fo layers 1 and 2. No mip levels
   Texture2D txDepth4 : register(t8);//not used
   SamplerState samPoint : register(s2);

   cbuffer cbMeshQuad : register(b5)
   {
       matrix Proj;
       float4 InvProj;
       float4 Resol_HiZ_Lay;
       //xy is the resolution of Mip=0; z =0/1 to (de)activate HiZ; w =0/1 to (de)activate multilayers
   }

   struct VS_INPUTQUAD
   {
       float3 Pos : POSITION;
       float2 Tex : TEXCOORD0;
   };

   struct PS_INPUTQUAD
   {
       float4 Pos : SV_POSITION;
       float2 Tex : TEXCOORD0;
   };

   PS_INPUTQUAD VS_PostDeferredReflex(VS_INPUTQUAD Input)
   {
       PS_INPUTQUAD Output;
       Output.Pos = float4(Input.Pos.xyz, 1);
       Output.Tex = Input.Tex;
       return Output;
   };
   #define refinemax 4
   #define dot3falloff 0.00005
   #define Zthickness 0.00005

   void GetZLayer(float3 SSray, inout float3 ZBufferVal, inout float hit)
   {
   //for additional layer no Hierarchical Z is made so sample Mip 0
       ZBufferVal.gb = txDepth23.Load(int3(SSray.xy *Resol_HiZ_Lay.xy, 0)).rg+float2(0.000005f,0.000005f);
       ZBufferVal *= float3(1,ZBufferVal.g<1.000005,ZBufferVal.b<1.000005);
       float3 Delta = abs(SSray.zzz-ZBufferVal);
       hit=1;
       if ( Delta.b  <= Delta.r ) {Delta.r = Delta.b;ZBufferVal.r = ZBufferVal.b;hit=3;}
       if ( Delta.g  <= Delta.r ) {ZBufferVal.r = ZBufferVal.g;hit=2;}
   }

   float4 GetColorSingle(float3 SSray, float Z, float D, float3 VSDir)
   {
       float3 Normal = txNormal[0].SampleLevel(samPoint, SSray.xy,0).rgb;
       float3 Color = txDiffuse[0].SampleLevel(samPoint, SSray.xy, 0).rgb;
       Normal=Normal*2-1;
       float Dot3 = ( Normal.x+Normal.y+Normal.z>2.99f)?dot3falloff:(dot(-VSDir, Normal)<0)?0:dot3falloff;
       if (abs(SSray.z-Z)<Dot3) return float4(Color,1-abs(SSray.z-D)*500);
       return float4(0,0,0,0);
   }

   float4 GetColorLayer(float3 SSray, float hit, float Z, float D, float3 VSDir)
   {
       float3 Normal  = float3(1,1,1);
       float3 Color  = float3(1,1,1);
       if ( hit==1)
       {
           Normal = txNormal[0].SampleLevel(samPoint, SSray.xy,0).rgb;
           Color = txDiffuse[0].SampleLevel(samPoint, SSray.xy, 0).rgb;
       }
       if ( hit==2)
       {
           Normal = txNormal[1].SampleLevel(samPoint, SSray.xy,0).rgb;
           Color = txDiffuse[1].SampleLevel(samPoint, SSray.xy, 0).rgb;
       }
       if ( hit==3)
       {
           Normal = txNormal[2].SampleLevel(samPoint, SSray.xy,0).rgb;
           Color = txDiffuse[2].SampleLevel(samPoint, SSray.xy, 0).rgb;
       }
       Normal=Normal*2-1;
       float Dot3 = ( Normal.x+Normal.y+Normal.z>2.99f)?dot3falloff:(dot(-VSDir, Normal)<0)?0:dot3falloff;
       if (abs(SSray.z-Z)<Dot3) return float4(Color,1-abs(SSray.z-D)*500);
       return float4(0,0,0,0);
   }

   //NOTE the blend state used is classic opaque (no blend, src one dest zero blend add)
   //destination render target is cleared to 0 at start
   float4 PS_PostDeferredReflex(PS_INPUTQUAD Input) : SV_TARGET
   {
       float D = txDepth1.SampleLevel(samPoint, Input.Tex, 0).r;
       float4 ColorOut = txDiffuse[0].SampleLevel(samPoint, Input.Tex, 0);
       if ( D == 1 ) return ColorOut;
       float3 PosV = float3(InvProj.x*(Input.Tex.x*2-1),InvProj.y*(1-Input.Tex.y*2), 1)/(InvProj.z*D+1);
       if ( ColorOut.a <0.9)  return ColorOut;

       float3 VSDir = normalize(reflect(normalize(PosV),txNormal[0].SampleLevel(samPoint, Input.Tex, 0).rgb*2-1));
       if ( VSDir.z < 0 ) return ColorOut;

       float4 SSEnd = mul(float4(PosV + VSDir*200, 1), Proj);
       SSEnd/= SSEnd.w;
       SSEnd.xy = SSEnd.xy*float2(0.5,-0.5)+float2(0.5,0.5);
       float3 SSray = float3(Input.Tex, D);
       float3 SSDir = normalize(SSEnd.xyz-SSray);
       int Mip = 0;//you can start at higher Mip level but I don't see improvements
       float3 ZBufferVal=float3(1,1,1);
       float3 poslast = SSray;
       int i=0;
       int maxi=45;
       float DirSize = 0.02;
       float3 Delta= float3(0,0,0);
       float hit = 1;
       float4 Color ;
   //  mipmax is used to see the maximum mip level reached. see below
   //   int MipMax=0;
       if ( Resol_HiZ_Lay.z )
       {
           float4 X_stepoffset = float4(1,1,Zthickness,Zthickness);
           if (SSDir.x<0) X_stepoffset.x = -1.0;
           if (SSDir.y<0) X_stepoffset.y = -1.0;
           X_stepoffset.zw *= X_stepoffset.xy;
           X_stepoffset.xy = saturate(X_stepoffset.xy);
           float zDir = SSDir.z;//store dir.z for later use
           SSDir/=SSDir.z;// the algorithm needs normalization to SSDir.z = 1
           float2 CurResol;
           float3 tmp_ray;
           SSray+=SSDir*Zthickness;
           while((Mip > -1)&&(i < 40))
           {
               i++;
               CurResol = (int2(Resol_HiZ_Lay.xy)>>Mip);
               float2 old_cell_id = floor(SSray.xy * CurResol);
               ZBufferVal.r = txDepth1.Load(int3(old_cell_id, Mip)).r;
               if ( Resol_HiZ_Lay.w ) GetZLayer(SSray, ZBufferVal, hit);
               if (ZBufferVal.r==0)ZBufferVal.r=1;
               float min_minus_ray = ZBufferVal.r - SSray.z;
               tmp_ray = SSray;
               if ( min_minus_ray > 0)
               {
                   tmp_ray = SSray + SSDir*min_minus_ray;
                   float2 new_cell_id = floor(tmp_ray.xy * CurResol);
                   if ((new_cell_id.x != old_cell_id.x) || (new_cell_id.y != old_cell_id.y))
                   {
           //repositionne tmp_ray to match cell
                       float2 planes = (old_cell_id+ X_stepoffset.xy)/CurResol;
                       float2 solutions = (planes - SSray.xy)/SSDir.xy;
                       tmp_ray = SSray + SSDir * min(solutions.x, solutions.y);
                       tmp_ray.xy += (solutions.x < solutions.y) ? float2(X_stepoffset.z, 0) : float2(0, X_stepoffset.w);
           //going higher than mip 7 generate hole artifacts in my scene on the vertical plane
           //when at bottom screen.
           //help need to solve it if possible
                       Mip = min(7, Mip + 2.0f);
                       //if you wan tto see the maxmip level reached use this line
                       //if ( Mip > MipMax ) MipMax = Mip;
                   }
               }
               Mip--;
               SSray = tmp_ray;
               if ((SSray.x<0 )||(SSray.x >1 )||(SSray.y<0)||(SSray.y>1)) return ColorOut;
           }
           SSDir*=zDir;//restores appropriate SSDir increment for refinement
           if ( Resol_HiZ_Lay.w )
               Color = GetColorLayer(SSray, hit, ZBufferVal.r, D, VSDir);
           else
               Color = GetColorSingle(SSray, ZBufferVal.r, D, VSDir);
           if ( Color.a > 0 ) return lerp(Color,ColorOut,1-Color.a);
         //use these lines instead of previous one to see the maxmip level reached
         /*     float4 MipColor = float4(MipMax==0||MipMax==3||MipMax==4||MipMax==6||MipMax==7, MipMax==1||MipMax==3||MipMax==5||MipMax==6||MipMax==8,                        MipMax==2||MipMax==4||MipMax==5||MipMax==6||MipMax==9,1);
          if ( Color.a > 0 ) return lerp(MipColor,ColorOut,1-Color.a);*/

          //for secondary loop with HiZ parameters maxi can be lower and DirSize coarser
          maxi=25;
          DirSize = 0.05;
          i=0;
      }
  //to skip next while showing vertical holes due to the HiZ algorithm
  //turn on return ColorOut;
  //Any better solution welcome as this makes the shader slower
  //  return ColorOut;
      SSDir*=DirSize;
      while (i<maxi)
      {
          i++;
          poslast = SSray;
          SSray += SSDir;
          if ((SSray.x<0 )||(SSray.x >1 )||(SSray.y<0)||(SSray.y>1)) break;
          ZBufferVal.r = txDepth1.SampleLevel(samPoint, SSray.xy, 0).r;
          if ( Resol_HiZ_Lay.w ) GetZLayer(SSray, ZBufferVal, hit);
          if (SSray.z > ZBufferVal.r)
          {
              float3 MinRay = poslast;
              float3 MaxRay = SSray;
              for(int j = 0; j < refinemax; j++)
              {
                  poslast = (MinRay+MaxRay)*0.5f;
                  if( hit ==1 )
                          ZBufferVal.r = txDepth1.SampleLevel(samPoint, poslast.xy, 0).r;
                  else
                  if (Resol_HiZ_Lay.w)
                  {
                      if( hit ==2 ) ZBufferVal.r = txDepth23.SampleLevel(samPoint, poslast.xy, 0).r;
                      else ZBufferVal.r = txDepth23.SampleLevel(samPoint, poslast.xy, 0).g;
                  }
                  if ( poslast.z > ZBufferVal.r) MaxRay = poslast; else MinRay = poslast;
              }
              if ( Resol_HiZ_Lay.w )
                  Color = GetColorLayer(poslast, hit, ZBufferVal.r, D, VSDir);
              else
                  Color  = GetColorSingle(poslast, ZBufferVal.r, D, VSDir);
              if ( Color.a >0 ) return lerp(Color,ColorOut,1-Color.a);

              //to visualize where refinement apply use this line insteadof previous one
              //if ( Color.a >0 ) return lerp(float4(1,1,1,1),ColorOut,1-Color.a);
          }
      }
      return ColorOut;
  }

```
> 2 votes

---
Tags: directx11, screen, reflection-rendering, spaces, hierarchy
---


# Question
Title: Determine which cannons on a ship can hit a target
I have a ship that will shoot targets, but cannons on the right side should never try to shot at targets on the left side of the ship. Thus I have created sectors using the `SignedAngle` function, this works fine for testing, but its also kind of broken as you can see from the visualization below. I have tried using `boxcast` but alas it also doesnt work for this use case.

The above image visualizes what my script does, but this is not a solution to my problem. As targets close to the side and front of the ship will be outside the sector, for clarification what I mean, see picture 3.

This second image shows what happens when we increase the angle, we can now detect more targets, but we have 2 big incorrect sectors marked in red which shouldnt be there.

Finally, this is how I think it should look, its still a cone, but the big difference is that it starts with a wide bottom, thus it resolves the problem Im having with the current SignedAngle function which determines everything from a single point in the middle.

This is the script for assigning targets to the correct list according to which sector they are in:

```
foreach (Transform target in EnemyListManager.instance.enemyShips.ToArray())
        {

            if (Vector3.Distance(transform.position, target.position) > ship.mainGunCaliber.range)
                continue;

            Vector3 toTarget = target.position - transform.position;
            print(Vector3.SignedAngle(hullParent.forward, toTarget, Vector3.up));

            if (Vector3.SignedAngle(hullParent.forward, toTarget, Vector3.up) >= bowMinAngle &&
                Vector3.SignedAngle(hullParent.forward, toTarget, Vector3.up) <= bowMaxAngle)
            {
                if (!bowTargets.Contains(target))
                {
                    RemoveFromOthers(target);
                    bowTargets.Add(target);
                    print("added target to Bow");
                }
                continue;
            }
            if (Vector3.SignedAngle(hullParent.forward, toTarget, Vector3.up) >= sbMinAngle &&
                Vector3.SignedAngle(hullParent.forward, toTarget, Vector3.up) <= sbMaxAngle)
            {
                if (!sbTargets.Contains(target))
                {
                    RemoveFromOthers(target);
                    sbTargets.Add(target);
                    print("added target to SB");

                }
                continue;

            }
            if (Vector3.SignedAngle(-hullParent.forward, toTarget, Vector3.up) >= aftMinAngle &&
                Vector3.SignedAngle(-hullParent.forward, toTarget, Vector3.up) <= aftMaxAngle)
            {
                if (!aftTargets.Contains(target))
                {
                    RemoveFromOthers(target);
                    aftTargets.Add(target);
                    print("added target to Aft");

                }
                continue;
            }
            if (Vector3.SignedAngle(hullParent.forward, toTarget, Vector3.up) >= psMinAngle &&
                Vector3.SignedAngle(hullParent.forward, toTarget, Vector3.up) <= psMaxAngle)
            {
                if (!psTargets.Contains(target))
                {
                    RemoveFromOthers(target);
                    psTargets.Add(target);
                    print("added target to PS");

                }

            }
        }

```

Any help would be appreciated on how to tackle this problem!

Thank you.

# Answer
> 1 votes
Real warships (before the modern age of relying primarily on guided-missile weaponry) typically have multiple guns that can cover one side of the ship.

Each gun will have its own firing arc. If you want to solve this in a realistic way that doesn't make the math more complex, use a separate arc for each gun emplacement.

# Answer
> 0 votes
# Updated Answer

## Initial calculations

Calculate these once at the beginning as if your ship is static and at origin, and later transform enemy positions with respect to your ship.

* Write the equation for lines `XY`, `WZ` (a line that passes from the front point of the ship with slope `s`, and another one for the bottom of the ship with slope `-s`)
* Solve for points `X, Y, W, Z` by finding intersection points of inner-circle and outer-circle and lines `XY` and `WZ`.
* Write the equation for the line `YW`.
* Using points `X, Y, W, Z`, define regions `A, B, C` in Polar Coordinate System as explained in the **original answer below**. (in the image, for simplicity I placed marks for `A, B, C` outside the outer-circle, but, assume they define regions between the inner and outer circles, that is `A` is `1 & 2`, `B` is `3 & 4`, `C` is `5 & 6`)

## Continuous calculations

* Using polar regions, test if an enemy (point `E`) is in one of the regions `A, B, C`.
* If point `E` is in one of the regions `A, B, C`, then test if point `E` is above or below the relevant line of the region it belongs to:
    + Region `A` & Above line `XY` = Region `2`
    + Region `B` & Below line `YW` = Region `4`
    + Region `C` & Above line `WZ` = Region `5`
* If point `E` is in one of the regions `2, 4, 5`, then it is in range.

**P.S.** I wasn't sure if the inside of the inner-circle is in the target area, so excluded it above. But, if you also want to target the inside of the inner-circle, you can define the inner-circle where the points `X` and `Y` are located at the front and the bottom of the ship, and add an additional test to see if the point `E` is within the upper half of inner-circle (a pretty easy test with polar coordinates).

# Original Answer

(Leaving the original answer here for people looking for a simpler solution.)

You can approach the problem with Polar Coordinate System. Then you can define the regions of interest by defining `r_min, r_max, t_min, t_max` here:

```
x = r * cos t
y = r * sin t

where

r_min < r < r_max

and

t_min < t < t_max

```

Then, for any given point `(x, y)`, you can solve for `(r, t)` and see if the point is in one of the defined regions:

```
r = sqrt(x^2 + y^2), which is hypotenuse.

t = atan2(y, x), which is arctangent.
(see the referenced Wikipedia article for details of this function)

```

---
Tags: unity, c#, raycasting, angles
---


title: Need help with custom health component

text:
# Question
Title: Need help with custom health component
I made health property as component, so any object with that property can be damaged.

```
extends Node

class_name Health, 'res://assets/icons/health_ico.png'

var entity
var stats_name
var init_health = 4
var health = init_health

func _init():

    self.stats_name = 'health'

func _ready():
    entity = get_parent()
    self.entity.stats[self.stats_name] = self
    print('target:' + str(entity))
    print('me:' + str(self))

func apply_damage(damage = 0):
    self.health -= damage
    if health <= 0:
        self.entity.on_0_health()

```

But the problem is that no matter what I attack, all the damage dealt is applied to a single entity.

I'm sure it's a problem with a reference to a component, but can't find/fix it.

The log says that they are all different nodes:

```
target:Target:[StaticBody2D:29762782407]
me:Health:[Node:29779559624]
target:Target2:[StaticBody2D:30651974908]
me:Health:[Node:30668752125]

```

The bullet code that hits entities:

```
extends Area2D

var damage = 1
var speed: int
var lifetime: float
func _init(speed: int = 500, lifetime: float = 1.0):
    self.speed = speed
    self.lifetime = lifetime

func _physics_process(delta: float):
    position += transform.x * speed * delta
    lifetime -= delta
    if lifetime < 0:
        queue_free()

func _on_bullet_body_entered(body):
    print('attack target' + str(body))
    if body.is_in_group('projectile_bound'):
        queue_free()
        return

    print('attack health' + str(body.stats['health']))
    body.stats['health'].apply_damage(damage)
    queue_free()

```

The entity code:

extends Node

@onready var label = get_node("Label")
@onready var health = get_node("Health")
const stats = {} #This is actually the real problem

func on_0_health():
    pass

func _process(delta):
    label.text = 'damage: ' + str(-health.health)
```
</code></pre>

# Answer
> 0 votes
I am using Godot 4.0 alpha 15.

The "fun thing" is that Dictionary defined with **const** keyword is shared between all instances. So when bullet call health component from `stats: Dictionary` property on any attackable entity, it call the same dictionary.

> Here's another work-around for static variable in GDScript, which hasn't been mentioned yet.

> Define a const Dictionary variable on your class. Store and access your static variables as properties on that Dictionary. This works because the const Dictionary instance is shared between instances of the class. Even though the Dictionary is const and can't be re-assigned, it is still "mutable", so you can change its properties as much as you want.

```
class_name Main
extends Node

func _ready() -> void:
    var a := MyClass.new()
    var b := MyClass.new()

    a.STATIC_VARIABLES.is_my_flag_enabled = true

    assert(b.STATIC_VARIABLES.is_my_flag_enabled)

class MyClass extends Reference:

    const STATIC_VARIABLES := {
        is_my_flag_enabled = false,
    }

```

https://godotengine.org/qa/103698/why-are-static-variables-const-not-a-thing-in-gdscript

---
Tags: godot
---


title: Find bone-system given a mesh

text:
# Question
Title: Find bone-system given a mesh
Animation newbie here. Usually, how do people call the process of finding the bone-based system corresponding to given mesh? I'm looking for machine-learning-based solutions that could improve the process.

# Answer
The process of creating bones for a 3d model and linking vertices of the mesh to those bones so they can be animated is usually called "rigging".
> 0 votes

---
Tags: animation, machine-learning
---


# Question
Title: Are thresholds for levelling considered an open problem and each game solves it differently or is there some standard design?
Player gathers points/XP and levels up based on this.

Is there some standard researched system which thresholds work well for level 2, level 3 and so on?

Or is each game basically solving it on its own?

(I want to avoid reinventing something that has a clear answer)

# Answer
Consider for a moment what these thresholds *do*.

They set the pacing of player progression for the early, mid, on into late game.

They do so relative to the rates of XP earning.

So: every game that aims for a different pace of advancement, or a different curve of deceleration, or has different rates of XP earning, will use different thresholds.

You can look up the XP thresholds used in a dozen games by searching various fan wikis, and see that they're all different. So this is one of those questions you can answer for yourself.
> 15 votes

# Answer
If your game has an XP system then there will presumably be some way for the player to choose how much XP they try to acquire; i.e. the player can stay in the current stage of the game and grind for XP, or they can press on to the next stage. (If there is no such choice, and instead the character receives XP on some fixed schedule, then XP is irrelevant and you only need to choose a balanced schedule for giving out character upgrades.) As others have noted, the XP curve can be balanced either by requiring more XP to level up higher, or by giving *less* XP when the player is already at a higher level; these are equivalent, so I'll assume the former.

A player who chooses to "grind" may fight twice or four times as many enemies as another player who just "presses on", and therefore gain twice or four times as much XP. Probably you don't want their character to be twice or four times as powerful; it would trivialise the game to be twice or four times higher level than you are "supposed" to be at a given stage in the game, especially if it's a long game with many levels (e.g. Final Fantasy or Pokémon).

To avoid this you need some sort of diminishing returns. You probably don't want a player to get more than N levels ahead of the curve by grinding, for some number N. So you want a player with, say, twice the expected XP to be (at most) some fixed number of levels higher than the level the game is balanced for. Mathematically, this entails that the relationship between XP and levels must be (at least) exponential, i.e. the XP required to level up grows (at least) by some constant factor per level.

In contrast, a sub-exponential relationship between levels and XP would mean that the grinding player keeps getting further and further ahead of the curve as they progress through the game. This will make the later stages boring when they are supposed to be challenging; the payoff for grinding should be that it makes the game easier but not *too* much easier.

On the other hand, if the relationship is super-exponential then the grinding player (who consistently fights twice or four times as many enemies as another player) will get ahead of the curve early, but fall back towards the curve as they approach the late game. That doesn't sound as bad as letting the player become too overpowered, so maybe it is an option, but perhaps players who grind will feel like they are being "punished" for it.
> 4 votes

# Answer
Each game handles it on its own.

Often these games increases the XP needed by each level, and that's usually handled by some sort of algorithm, but that algorithm varies for each game, as each game progresses at a different pace.

Such Algorithm can be as simple as e.g. `XPNeeded = 100 * 1.2 * level`, but can be more complex depending how fast you want to level up early, and how large you want to scale it at larger levels.

For a unique example of a game that solved it on its own: Paper Mario. This game kept the XP needed the same, but lowers the XP gain as you level. At some point, weaker enemies don't give XP at all. The enemies I'm that game didn't have levels, but these were based on when and where they appear in the world.
> 2 votes

---
Tags: game-design, game-mechanics
---