# Question
Title: How To Destroy one enemy without affecting other enemies of the same type?
I have a problem, I have a universal enemy script, which I use on all enemies, but as in the script when an enemy dies it is set to deactivate the current script and because of that the first enemy goes perfectly to kill him, but when I arrive at the second I can't attack him because he says the script is disabled and he can't access it, how can I do when I kill an enemy not to affect the main script of all enemies?

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

public class Enemy : MonoBehaviour
{
    #region Public Variables

    public int maxHealth = 100; //Enemy max health;
    public int currentHealth; // Enemy current health;

    public Transform leftLimit; //Left limit for patrolling;
    public Transform rightLimit; //Right limit for patrolling;

    [HideInInspector] public Transform target; //Find the Player;

    [HideInInspector] public GameObject heartLeftOne, heartLeftTwo, heartMiddle, heartRightTwo, heartRightOne; //Enemy hearts;
    public GameObject damageText; //Damage Text Popup;
    public GameObject goldPrefab; //Gold Prefab;
    public GameObject enemyHearts; //All enemy Hearts stored in a Empty gameobject for a much easy way to deactivate them;
    public GameObject hitBox; //Where we check if player entered in attackRange for enemy;
    public GameObject hotZone; //Hotzone is where enemy will follow the player;
    public GameObject triggerArea; //TriggerArea detect if player entered in Range of Enemy AI;

    public bool cooling; //Check if Enemy is cooling after attack
    public bool attackMode; //Check when enemy is in Attack mode or not;
    public bool facingRight; //If FacingRight is true or false;
    public bool playerInRange; //If Player is in Range set the bool true;

    [HideInInspector] public bool inRange; //Check if Player is in TriggerArea Range;

    public float attackDistance; //Minimum distance for attack
    public float moveSpeed; //Speed of enemy;
    public float timer; //Timer for cooldown between attacks

    #endregion

    #region Private Variables

    private Animator anim; //Animator;

    private float distance; //Store the distance b/w enemy and player
    private float intTimer; // Cooldown b/w enemy attack;
    private float textPositionX = 0.5f; //Position X for Damage Text;
    private float textPositionY = 1.5f; //Position Y for Damage Text;
    private float goldPositionY = 0.5f; //Gold Positon Y when Enemy Die;
    private float localScaleX = 0.5f; //Scale X for Gold Prefab;
    private float localScaleY = 0.5f; //Scale Y for Gold Prefab;

    private Experience_System experience; //Reference to Leveling system;
    private Player_Health player; //Reference for Player Health;

    #endregion

    //Function Awake;
    public void Awake()
    {
        //Check what limit is closer for patrolling;
        SelectTarget();

        intTimer = timer; //Store the inital value of timer
        anim = GetComponent<Animator>(); //Animator;
    }

    //Start Function;
    public void Start ()
    {
        //Start health for enemy;
        currentHealth = maxHealth;

        //Hearts for enemy;
        heartRightOne.SetActive(true);
        heartRightTwo.SetActive(true);
        heartMiddle.SetActive(true);
        heartRightTwo.SetActive(true);
        heartLeftOne.SetActive(true);

        //Find The GameObject and Take the Scripts Function;
        player = GameObject.FindGameObjectWithTag("Player").GetComponent<Player_Health>();
        experience = GameObject.FindGameObjectWithTag("Experience").GetComponent<Experience_System>();
    }

    //Update Function;
    public void Update()
    {
        if (!attackMode)
        {
            Move();
        }

        if (!InsideOfLimits() && !inRange)
        {
            SelectTarget();
        }

        if (inRange)
        {
            EnemyLogic();
        }
    }

    public void EnemyLogic()
    {
        distance = Vector2.Distance(transform.position, target.position);

        if (distance > attackDistance)
        {
            StopAttack();
        }

        else if (attackDistance >= distance && cooling == false)
        {
            Attack();
        }

        if (cooling)
        {
            Cooldown();
            anim.SetBool("Attack", false);
        }
    }

    public void Move()
    {
        anim.SetBool("Walk", true);

        Vector2 targetPosition = new Vector2(target.position.x, transform.position.y);

        transform.position = Vector2.MoveTowards(transform.position, targetPosition, moveSpeed * Time.deltaTime);
    }

    public void Attack()
    {
        timer = intTimer; //Reset Timer when Player enter Attack Range
        attackMode = true; //To check if Enemy can still attack or not

        anim.SetBool("Walk", false);
        anim.SetBool("Attack", true);
    }

    public void Cooldown()
    {
        timer -= Time.deltaTime;

        if (timer <= 0 && cooling && attackMode)
        {
            cooling = false;
            timer = intTimer;
        }
    }

    public void StopAttack()
    {
        cooling = false;
        attackMode = false;
        anim.SetBool("Attack", false);
    }

    public void TriggerCooling()
    {
        cooling = true;
    }

    //Enemy Take Damage;
    public void TakeDamage(int damage)
    {
        currentHealth -= damage;
        anim.SetTrigger("TakeHit");

        if (currentHealth == 80)
        {
            heartRightOne.SetActive(false);
        }

        else if (currentHealth == 60)
        {
            heartRightOne.SetActive(false);
            heartRightTwo.SetActive(false);
        }

        else if (currentHealth == 40)
        {
            heartRightOne.SetActive(false);
            heartRightTwo.SetActive(false);
            heartMiddle.SetActive(false);
        }

        else if (currentHealth == 20)
        {
            heartRightOne.SetActive(false);
            heartRightTwo.SetActive(false);
            heartMiddle.SetActive(false);
            heartLeftTwo.SetActive(false);
        }

        else if (currentHealth <= 0)
        {
            Die();

            heartRightOne.SetActive(false);
            heartRightTwo.SetActive(false);
            heartMiddle.SetActive(false);
            heartLeftTwo.SetActive(false);
            heartLeftOne.SetActive(false);
        }

        //Check if the enemy is facingRight or not to display the damage text popup;
        if (facingRight == true)
        {
            GameObject go = Instantiate(damageText, transform.position, Quaternion.identity);
            go.GetComponent<TextMesh>().text = damage.ToString();
            go.transform.SetParent(gameObject.transform);
            go.transform.localPosition += new Vector3(Random.Range(-textPositionX, textPositionX), Random.Range(+textPositionY, 2), Random.Range(0, 0));
        }

        else if (!facingRight)
        {
            GameObject go = Instantiate(damageText, transform.position, Quaternion.identity);
            go.GetComponent<TextMesh>().text = damage.ToString();
            go.transform.SetParent(gameObject.transform);
            go.transform.localPosition += new Vector3(Random.Range(-textPositionX, textPositionX), Random.Range(+textPositionY, 2), Random.Range(0, 0));
        }
    }

    //Die Funtction
    public void Die()
    {
        //Set The Animation For Dead and Stop all other functions / animations of the enemy;
        anim.SetBool("Dead", true);
        anim.SetBool("Attack", false);
        anim.SetBool("Walk", false);

        attackMode = false;
        inRange = false;
        cooling = false;

        //Instantiate a Gold Prefab;
        GameObject gold = Instantiate(goldPrefab, transform.position, Quaternion.identity);

        gold.transform.SetParent(gameObject.transform);
        gold.transform.localPosition = new Vector2(0, goldPositionY);
        gold.transform.localScale = new Vector2(localScaleX, localScaleY);

        //Set Player +25 Experience;
        experience.IncraeseExp(25);

        //Deactivate The Enemy Collider;
        GetComponent<Collider2D>().enabled = false;

        //Destroy The Enemy AI;
        Destroy(hotZone);
        Destroy(triggerArea);
        Destroy(hitBox);
        Destroy(enemyHearts);
    }

    //Check if enemy is inside of patrolling limits;
    public bool InsideOfLimits()
    {
        return transform.position.x > leftLimit.position.x && transform.position.x < rightLimit.position.x;
    }

    //Function For Patrolling state;
    public void SelectTarget()
    {
        float distanceToLeft = Vector3.Distance(transform.position, leftLimit.position);
        float distanceToRight = Vector3.Distance(transform.position, rightLimit.position);

        if (distanceToLeft > distanceToRight)
        {
            target = leftLimit;
        }

        else if (distanceToLeft < distanceToRight)
        {
            target = rightLimit;
        }

        Flip();
    }

    //Function for flip the enemy;
    public void Flip()
    {
        Vector3 rotation = transform.eulerAngles;

        if (transform.position.x < target.position.x)
        {
            rotation.y = 180;
            facingRight = true;
        }

        else
        {
            rotation.y = 0;
            facingRight = false;
        }

        transform.eulerAngles = rotation;
    }

    //If Player enter the trgger where enemy can attack set bool to true;
    public void OnTriggerEnter2D (Collider2D collision)
    {
        if (collision.gameObject.tag.Equals("Player"))
        {
            playerInRange = true;
        }
    }

    //If Player leave the trigger where enemy can attack set bool back to false;
    public void OnTriggerExit2D (Collider2D collision)
    {
        if (collision.gameObject.tag.Equals("Player"))
        {
            playerInRange = false;
        }
    }

    // Player will take damage from enemy if the player is in Range of enemy for attack;
    public void PlayerTakeDamage ()
    {
        if (playerInRange == true)
        {
            player.TakeDamage();
        }

        else if (playerInRange == false)
        {
            Debug.Log("Player not in Range!");
        }
    }
}

```

Because the script is done this way, when I go to attack the second enemy, I can't kill him anymore If help I can make a video to show the entire script bcs its a big one and to show exactly the problem

# Answer
The problem is actually in the `Player_Combat.cs` script which isn't in the question and only visible shortly in the linked video at 3:20.

It has a variable `private Enemy enemy` which it obtains once in `Start` and then never changes. That makes the player unable to interact with any other enemy except the one it found at the beginning of the game.

Instead of having the concept of a "current enemy", I would recommend to rather check what's in front of the player the moment when they attack, see if any of those objects are still living enemies, and then damage them.

One method you can use to detect colliders which overlap a given area is `Physics2D.OverlapAreaAll` (or perhaps another of the Overlap\* methods of class `Physics2D`). This method returns an array of all colliders which overlap a rectangular area. But keep in mind that not all of these colliders might be enemies, and not all of these enemies might still be alive.

Untested code:

```
Collider[] detectedColliders = Physics2D.OverlapAreaAll(/* A box in front of the current player position*/);
foreach (Collider detectedCollider in detectedColliders) {
    Enemy detectedEnemy = detectedCollider.GetComponent<Enemy>();
    if(detectedEnemy != null && detectedEnemy.currentHealth > 0) {
          detectedEnemy.TakeDamage(damage);
    }
}

```

Alternatively, if you don't want the player to be able to engage more than one enemy at a time and keep the concept of a single "current enemy", then you need to implement the code for changing that variable to a different enemy when appropriate and also need to handle the case that there might be times when there isn't any enemy at all in the game.
> 1 votes

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


# Question
Title: How to update rule tile (brush) from Unity's 2D grid tile map palette?
I have created a Palette in Unity and created a map using that rule

Now, I want to replace the current rule with another one, without having to draw everything once more. I tried to drag and drop the new rule on the same position in the palette, but the drawn map was not updated.

I am a little anxious about creating a (large) map unless I know of a way to update a brush without having to redraw everything.

# Answer
> 2 votes
I came up with a solution that I am using for the time being. I can add the new rule to the palette, and use the "fill" tool to change all of the tiles I want to replace. It is not optimal, but it was the best I could do. Since a rule (brush) will be used in large clusters, I figured this method could get the job done in a somewhat timely manner. I am still looking for better alternatives

---
Tags: unity
---


# Question
Title: How to Call a function from another script?
I just learned in a C# tutorial that we can declare `var name = new ClassNameOfOtherScript();` to create a new class object, then use the object to call the function in that class, but it doesn't seem to be working in Unity.

Am I understanding it wrong or does it work differently in Unity?

I have a class `Cube1` this is attached to an object with `SpriteRenderer` enabled. Then I have another script `ClockController` which is not attach to any object. When I run it, the color of cube does not change to red?

```
public class Cube1 : MonoBehaviour
{

    public void Rectangle()
    {
        GetComponent<SpriteRenderer>().color = Color.red;
    }

}

```

```
public class ClockController : MonoBehaviour
{

    void Start()
    {
        var cube1 = new Cube1();
        cube1.Rectangle();
    }
}

```

# Answer
Well you are doing `var cube1 = new Cube1();` which is how you would make an object in C#, but since it is Unity, and this is a MonoBehaviour, you are not supposed to make it like that.

Instead, make a new `GameObject` and attach the `Cube1` script to it.

```

void Start()
{
    // make a new gameobject.
    GameObject gameObject = new GameObject();

    // adding a SpriteRenderer as your `Cube1` will try to access it.
    // -- please also see the bottom note of the answer. --
    gameObject.AddComponent<SpriteRenderer>();

    // attach a Cube1 script to it and store the reference to it in a var.
    Cube1 cube = gameObject.AddComponent<Cube1>();

    // call the function on that cube.
    cube.Rectangle();
}

```

Sidenote, if you don't make an object in the scene that holds the ClockController, it won't execute the `Start()` method.

---

When you already have an existing `GameObject` (instead of making a new one) that has a script you want to access, you can use `gameObject.GetComponent<Cube1>()` , store it in a variable (if necessary) and access it that way. You just need to get that specific `GameObject` to begin with.

---

Extra info on component dependencies:

As pointed out by @DMGregory, `cube.Rectangle()` will try to find/access a `SpriteRenderer` on the `cube` object, which would have to be added first. You could add `[RequireComponent(typeof(SpriteRenderer))]` which means that whenever you add a `Cube1` script to a `GameObject`, the *required component is added aswell if it is not already there*.

I'd suggest to take a look at the docs: https://docs.unity3d.com/ScriptReference/RequireComponent.html

Alternatives would probably be making sure in your Cube1 script that at some point a SpriteRenderer is attached, but that's all going off-topic I think.
> 1 votes

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


title: Unity UI Buttons Not Functioning

text:
# Question
Title: Unity UI Buttons Not Functioning
I have been working on a UI Inventory System for my Unity game and for some reason, none of my buttons work in my game. All the buttons have the ‘interact-able’ box ticked and an *EventSystem* which is in the scene. In my scene, I have an image, which is holding two buttons, in a canvas. The buttons are supposed initiate a function called UseItem when clicked, but they don't respond to anything. I have tested them using **Debug.Log**, but I don't get any messages back in the Console. I also don't get any errors or warnings. I am using Unity 2019.4.17f1 LTS. The pictures below show my UI.

Here's a picture of my game scene:

Here's the complete hierarchy:

These are the EventSystem's configurations:

These are my canvas settings:

And these are use and drop button settings:

# Answer
> 0 votes
Ok, I fixed my problem. All I had to do was turn off **Raycast Target** for all my other inventory UI elements.

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


# Question
Title: How can I prevent cheating in my collecting and trading game?
I develop and manage an online game where users collect and trade virtual pets (it is entirely online). It's a simple game, we periodically release new pets, users collect them and get random ones, then they trade for the ones they want, and some are rare. We also do holiday events.

The problem is, there's nothing preventing people from creating new accounts, collecting a bunch of free pets, and then trading them all to their main account, or at least the rare ones. They could also trade them all to other users in exchange for things on other sites. This is against our rules, but enforcing it is subjective and difficult.

Historically, we've fought this by manually catching these users and banning them, looking at ip addresses, messages, trading patterns, etc. The common defense is usually "that's just my friend/sibling and they don't play as seriously as I do". And that may be true, I have no way to prove it, I just have to determine myself if they've gone too far or are abusing the system. This type of cheating can be bad for our economy as it hurts rarity values, and gives cheaters an unfair advantage in the market.

I believe this is a fundamentally flawed system and am trying to figure out how to fix it so cheating is not possible, or at least very difficult. I've seen other similar games force users to play mini-games to earn currency to get things, whereas we just give away free stuff periodically. I don't like this approach because 1.programming mini-games is a lot of extra work and 2.we're known for being a casual game, I don't think users would like playing tedious mini-games over and over to collect pets.

The solution I've been considering would be implementing a currency, say gold, that you get periodically for logging in and "being active" on the site. Gold would be required to collect the free pets, and to trade them. So even if you create a new account, you can't just trade away everything you just collected. In order to do big trades where you give away large amounts of stuff, you would have to accumulate lots of gold. Pokemon Go used this approach with stardust, but then again, there's a lot more to do in that game to earn it, and perhaps that's my problem. This has always been a simple, free to play game, and that's why people like it. Also, it's just me working on this, and my skill set is mostly web development.

Can anyone offer advice? I would really appreciate any feedback.

EDIT: Thanks for all the great suggestions, the answers and discussion this generated helped me a lot.

# Answer
> 19 votes
The canonical solution to handling the type of cheating you describe (which I mostly hear called ‘account farming’ in the context of other games) is to de-incentivize having multiple accounts. Obviously make sure your ToS calls it out as bannable, but you also need other things to make it less attractive to do this.

Possible approaches I’ve actually seen other games take to combat this and other types of trading abuse include:

* Require some degree of account verification above and beyond what is needed to play the game to be able to trade. The de-facto standard here seems to be having 2FA enabled on the account, but other approaches work too. Essentially, you want to make it such that the player has to prove they are a real person before they can trade, and also ideally limit duplicate verification methods (so, for example, you can only have one account associated with a given phone number used for 2FA).
* Set a minimum account age or level for trading, as suggested in KI.’s answer.
* Disallow trading of truly ‘free’ items, as also suggested in KI.’s answer.
* Limit the frequency at which players are allowed to trade. The norm here is a daily limit that resets at midnight server time (it must *not* be client time, otherwise you run the risk of exploits). The rationale here is that ‘normal’ game-play is not usually just trading, so there’s no reason that any given player needs to be able to trade hundreds of times a day. This also has the advantage that it will help stabilize the in-game economy (slower trading translates to slower shifts in the market).
* Force direct trades between players to be synchronous. That is, make it so both players have to meet up in-game to be able to trade. This makes life more difficult for anybody trying to shuffle items between accounts (make sure if you have a PC version to code it so it will not let users run more than one instance at a time on a given system to help enforce this), but is generally not a significant burden for *most* legitimate trades. Coincidentally, this also makes managing what items an account has a bit easier, because both accounts by definition have to be online and active to conduct the trade.
* Similarly to what you suggest, tax trades using a currency that must be earned by actually playing the game. Sounds stupid, but it’s another easy way to slow down trading and make it less attractive to trade constantly. There are two general approaches here, one is to have the player who is gaining greater value make up the difference in effective value, the other is to simply apply a flat tax to all received items based on a percentage of their effective value. This mostly acts as a deterrent to newer players grabbing super-powerful stuff in trades, but also helps make people think twice about high-volume trading because it forces them to actively play the game if they want to trade a lot. In general, the currency should probably have other uses beyond just trading (in your case, I would probably add a (small) cost in this currency to any guaranteed pet that is not a giveaway, and possibly also to random pulls as well).
* If you have an in-game auction house (that is, people can buy and sell items to other players without both people having to sync up to conduct the transaction) or trad-escrow system (same concept, just with direct transfer of items instead of involving currency), place limits on the number of outstanding buy and sell orders a player can have. This will not help directly deal with the cheating you are trying to combat (unless you remove other trading mechanisms), but it will help stabilize the in-game economy by preventing truly high-volume trading.
* Require some degree of matching of relative value between the two sides of a trade, as in David Mulder’s answer.

Most games use some combination of these. For example, Warframe actually uses all of these except the last two. They require you to reach a specific account level before you can trade, PC players are required to have 2FA enabled to be able to trade (and the console versions are tied to hardware just like the required console accounts), then you are limited to a number of trades per day equal to your account level (capped at 30), all trades are taxed based on effective received value using a currency that is largely only obtained by actually playing the game, you cannot use the starting currency in trades, and all trades are synchronous.

The idea here is to make trading burdensome enough that it requires significant dedication to actually pull off any type of account farming, without making it a burden to actually trade (because, from what you’ve said, trading is an important part of the game due to the collection aspect).

---

As a slight aside, try not to discourage people from buying premium stuff and then trading it to other players. This does not hurt your sales (the item still gets purchased), and it helps keep players who *can’t* afford to spend money on the game involved in the game (and higher player counts are almost always a good thing, because even if they are not earning you money directly, they are providing more potential friends/rivals for people who are, which in turn helps keep those people involved in the game).

# Answer
> 27 votes
I think I can offer a few solutions.

1. Set a minimum level to trade. This would essentially prevent players from making accounts just to collect the free stuff, as players will have to put in effort into the account to trade. I'm not sure how your game is set up, but this can be implemented though setting a level cap to build the "trading market building", or unlock the trading area.
2. Limit what can be traded from/to low level and/or new accounts. I believe Pokemon Go has a system like this, where there is a cap on the strength of the Pokemon that can be traded to (and possibly from) a lower level player. This would prevent new players from trading the rare pets to their main account, and also prevent new players from receiving very powerful pets from high level friends.
3. Disable trading for the free items. This would be the most direct (and personally, my least favorite) way. Essentially, the free pets would be locked from trading.

As Philipp stated, how the new player get the free pets is fairly important, and that may influence what option would be best for you, but at this moment, these are the solutions I can think of.

**Edits**

Adding on to my answer what I said in the comments, you can also include some account activation, as Bernhard Barker mentioned. However, it is worth noting that there are sites such as 10 minute mail that can be used to generate valid emails, which in turn can be used to mass activate accounts.

Also, it is in general a good idea to disable trading of premium pets, or at least limit the trading of premium pets to trades with other premium pets. This maintains the exclusivity of the premium pets, which are the income source for you game. You can also implement a trading system so that only pets of the same rarity can be traded.

You can also limit trading to pets that you have duplicates of (assuming your game allows for players to have multiple copies of the same pet), if the objective of the game is just to have and collect pets.

# Answer
> 7 votes
# Equal value trade system

Every item (pet) has a value. Each trade needs both parties to offer similar value.

Let's say we have three items: A (worth atm 500), B (worth atm 400) and C (worth atm 60). And let's say that trades are allowed up to a 100 'value mismatch' (this could also be a percentage). This means that A can be traded for B, but C can not be traded for A or B (but 5x C could be traded for B).

## Value calculation methodologies

### By hand

Just assign the items a value based on your best guess. The main two factors to account for are 'effort' (/chance) to get and age.

### Derived

Calculate the value dynamically based on factors such as:

* Number of players that have the item
* Date the item could be acquired for the last time
* Cost of the item (or chance if it's a grind based item)

### Dynamic

First get some starting point (see above), but during each trade observe to which side the trades lean. At the end of a period (e.g. each week) observe all trades. If most trades are of the type A for B t means B is undervalued and A is overvalued. If most trades are of the type B+C+C for A it means B and C are overvalued and A is undervalued. Over time such periodic calculations will allow the trade value to follow the actual market value.

# Answer
> 6 votes
Looks like you have a "nice problem", one that comes with a game getting fame.

> The solution I've been considering would be implementing a currency, say gold, that you get periodically for logging in and "being active" on the site.

If you're currently having issues with users creating "fake" accounts just to get more loot, the next step for them could bet to create a fake account then use a bot-like software on your site to make it look like they're active on the site.

One option would be to change the way you get your money. Instead of offering premium packs, you could instead charge a monthly fee (i.e. subscription based), where the premium users are allowed to obtain, use and trade premium and free pets, while the free users are only allowed to get, use and trade the free pets. You'd probably need to change how the rare pets are obtained as well (e.g. put more effort or time in the game).

By hiding the rarer stuff behind a paywall, you deter most of those users abusing the multi-account flaw.

# Answer
> 3 votes
@KI has a lot of good suggestions. To add a couple more:

You could have a time cool down after an item is received before you can trade it, steam market does something similar. You've unlocked a new item, you can trade it in two weeks time.

You could also give items out more slowly over time. Instead of of giving a "pack" of items right at the start, you could give 1 a week as a log in bonus and only have the possibility of getting the rare ones down the line. Similar to how starter Pokemon there are only a couple of options.

# Answer
> 3 votes
A common solution is not to reward this kind of behavior in the first place.

For example in Runescape there used to be drops like this, but then they swapped to having you complete challenges. You can complete them as many times as you like, thus gaining more drops. There's no advantages to using multiple accounts to do them, so people don't.

In World of Warcraft most event items bind to your account when you acquire them, and there is also usually a level requirement to do at least some of the events. This means that if alt accounts are made to acquire the loot, they can't trade them off - assuming they can even do the event at all.

Guildwars has events that are open to all and don't bind items to your character (or account), but you need to use tokens to participate. Acquiring the tokens is the main challenge, it's something anyone can do but it's best to get a lot as a high level character rather than trying to grind many different accounts.

Next time you see people cheating, try to figure out what about the system is rewarding them, and try to nip that in the bud. I think this is the most efficient approach.

Note: I haven't played these games in a long time so their approaches may have changed.

# Answer
> 2 votes
About 24 years ago I was a designer/engineer at a company making virtual collecting & trading games (and came in 2nd in our bid to make MTG online). There's a lot of intervening history that I haven't been part of. But here's the one thing that we did that I don't see in the existing answers:

Simple don't give out rare, valuable items for free. Our game came with a standard starter pack that was the same for everyone; presumably those cards didn't have any after-market trading value. That's fine. Any added packs that had randomized rare/valuable items had to be purchased.

There were occasionally free prizes given out: Maybe for participating in a seasonal competition, or some holiday promotion. These would be one single card, done maybe a few times a year (2 or 3 or 4). I think generally only accounts with some level of significant activity would get them.

So, to my perspective, the thing that jumped out in the OP's system as obviously broken was regularly giving out full packs including randomized items for free. In summary, my stab at fixing it would be one of the following menu:

* Just stop giving away so much for free
* Remove the randomized rare items from the free packs
* Create explicit common items for free giveaways, that will presumably have negligible trading value.
* Give away free items only to accounts that have some minimal play/activity level.

# Answer
> 1 votes
Fundamentally, if free accounts generate trade-able value, people will always find a way to exploit it. Some other good suggestions like requiring a minimum level to trade will discourage some number of casual exploiters, but if it's to the level where people are writing bots to do this for them, you'll only going to slow them down, and possibly only temporarily. The loophole remains. You will still always be playing whack-a-mole, just on a different level. Be really careful about whether you want to get into a technology arms race with exploiters before you start down that road.

If you want to stomp this problem out completely, you must be willing to change the gameplay.

In my opinion the most elegant way to shut this down completely is to fundamentally rethink "trading." What is trading? It's a way to make weak or duplicate pets not feel useless, and a way to obtain rare pets that would be prohibitively expensive to obtain by simply "rolling the dice" enough times. You can also fill that same need with a crafting system. Hearthstone is a great example of this, where you can disenchant extra cards to dust, and use that to craft rares you didn't open randomly. The best solution might be to remove trading completely.

If you're not willing to go that far, I'm also a fan of the previous suggestion that free loots are flagged as such, and simply cannot be traded. This may also be pushing the problem off to later--if your game gets popular enough, people will develop bots that play the game "properly" and get loot that isn't just free hand outs. But if trading has already become a core part of your users' community, this may be a compromise that you have to make at this point.

If you go that route you can think about dressing it up in ways that may foster interesting community behavior. Have rare pets keep track of the number of different previous owners? Make the flags public and let people brag about the method by which they obtained pets?

# Answer
> 1 votes
The symptom:

* Players create new Account to get free pets.
* Players trade free pets to their main account.
* "Value" of rarer pets degrades.

The cause:

* You are giving away free pets.
* You are not limiting elegibility.

So my proclaimed solution would be limit who can obtain free pets.

* Require an account to be created x amount of time before event
* Require an account to be active for x amount of time before event

Figuring out what counts as active is up to you though as that requires deeper knowledge of the game.

That way you will drastically reduce the amount of people who go through the hassle of maintaining activity on multiple accounts just to have them ready when there is an event.

You can still look for patterns like if accounts become active x amount of time before an event and then trade away all pets for example.

You may want to create some form of logic to enable free items for returning players that where once highly active and then stopped and are now interested because of an event.

You may also want to combine this with other solutions like make new accounts able to participate but unable to trade obtained pets. But let them trade pets obtained in other ways.

As trading seems to a big part of your game I would not block trading in general or block it completely for new players because:

* Limiting tradeability in general is a bad pattern in my opinion and will create much frustration for your players.
* Limiting trading by equal value or some other kind of assigned "worth" is a bad pattern too as its subjetive. If one player really wants one pet that is more common but the player is really unlucky and never gets it why prevent the player from "paying" more for it to finally have it?

The stance on blocking trading is only my opinion thoug.

# Answer
> 0 votes
Instead of free, new accounts have to cost something. The simplest thing is money, but if you don't want charge money, then charge time. Make the initial batch of free pets a separate class, that can only be traded with and for other pets in the same class. Activity in the game earns credit for the "real" pets, which can be traded more generally. Same game, just (in effect) different currencies for beginners and established players.

This scheme is transitive - you could have more than 2 classes of pets, and more than 2 classes of players.

# Answer
> -1 votes
*There is always a way to cheat...* No matter the game, people will always find a way to cheat the system. Having said that, the idea is to make cheating as hard and cumbersome as possible. You could, for instance, implement a block chain (like bitcoin) that keeps track of who owns what along the list of previous owners.

Let's assume you can add to your structure a unique identifier with the timsetamp of the asset creation. This way you can recognize originals from bootleg copies. Now add a linked list with the id of the previous and current owner, and update it as it is traded. Since the blockchain is shared, the only way to have bootlegs is if more than 50% of your players are into piracy.

---
Tags: game-design, game-mechanics, web, anti-cheat
---


title: Aseprite "Duration" vs Unity "Samples"

text:
# Question
Title: Aseprite "Duration" vs Unity "Samples"
When creating a sprite animation in Aseprite, we can set the "Duration (milliseconds)", as show here:

But when setting up the animation in Unity, we have to specify "Samples" as shown here:

How can we convert from "Duration" to "Samples"?

# Answer
The "Samples" field is short for "Samples per Second"

It is not measuring a duration or length of an animation or frame like your Aseprite example. It's a sampling frequency, determining how close together or far apart the snapping "ticks" on the timeline should be.

So if you've set your "Samples" to the default 60, then each tick on the animation timeline represents one sixtieth of a second, or about 16.6667 milliseconds.

A 110 millisecond duration would then be 110 ÷ 16.6667 = 6.666 ≈ 7 ticks long on the timeline.

To make your life simple, you could set your "Samples" to 1000, then each tick is exactly one millisecond, and you can copy over your keyframe positions unchanged from a program that presents them in millisecond timings. So a 110 ms duration would be 110 timeline ticks.

If all of your frames have a 110 ms duration, and you want each one to be a single tick on the timeline, you can divide:

$$1000 \frac {\text{ms}} {\text{second}} \div 110 \frac {\text{ms}} {\text{sample}} = 9.090909... \frac {\text{samples}} {\text{second}}$$

So you can approximate this by putting a 9 in the "Samples" field.
> 10 votes

---
Tags: unity, animation, pixel-art
---


title: Combining Quaternion Rotations

text:
# Question
Title: Combining Quaternion Rotations
I'm trying to understand Quaternions in relation to rotation and orientation.

As an example in learning, I'm trying to rotate a point (e.g. at \[0.7071, 0, -0.7071\], on the unit sphere) about the line x=z (or the vector \[0.7071, 0, 0.7071\] for a unit vector pointing in x/z direction. It should rotate around the unit sphere, passing through \[0,1,0\]

I've read that "multiple rotations are just multiplication", but if that's the case, why are the following are not equivalent?

```
# This version does what I want, rotates a point about the line x=z
val q = Quaternion().setAngleAxis(toRadians(45), 0.7071, 0, 0.7071)

# neither of the following multiplications produce the equivalent to the above q
val qx = Quaternion().setAngleAxis(toRadians(45), 1, 0, 0)
val qy = Quaternion().setAngleAxis(toRadians(45), 0, 1, 0)
val q1 = qx.mul(qy)
val q2 = qy.mul(qx)

```

(My reasoning is like looking at a unit vector starting in the x direction, which if I rotate 45 degrees in the y axis would give me a vector pointing in the z=x direction, but this is clearly naive as it doesn't work)

An example plot of qx * qy (but using 5 degree rotations instead of 45) is:

The q rotation I want gives me:

My understanding is qx and qy represent rotations about the given axis, or indeed also represent orientations, and if I use these independently and plot them, I get what I would expect, a point being rotated as required.

But if I start from either one of these, why doesn't the multiplication of the other (which represents an initial orientation multiplied by a rotation) result in a rotation that would rotate a point by both the x and the y axis?

Which leads me to the question, what does qx * qy (or vica verca) represent here? (I think this is the key bit I'm not understanding.)

Is it possible to apply something to qx or qy to get the original q directly?

# Answer
Multiplying two quaternions gives you a quaternion equivalent to performing the two rotations they represent *in sequence*.

```
q3 = q1 * q2
q3 * object = q1 * (q2 * object)
// "Perform rotation q2 with respect to the world axes, then q1"
// Or equivalently: "Perform rotation q1 about your local axes, then q2"

q4 = q2 * q1
q4 * object = q2 * (q1 * object)
// "Perform rotation q1 with respect to the world axes, then q2"
// Or equivalently: "Perform rotation q2 about your local axes, then q1"

```

(Notice that rotating around the object's local axes - ones that spin with the object - means applying the rotations in the opposite order than if we consider our axes fixed in the world reference frame)

These two possible sequences will generally give different results from one another, and different results from a single rotation along an axis intermediate between the axes of `q1` and `q2`, because 3D rotation is extremely order-dependent.

This isn't just a quirk of quaternions, but something true of orientations in three-dimensional space themselves.

Our experience from translation might mislead us. With a translation like (+1, +2, +3), we can separate it into...

* a translation by 1 unit along the x axis
* a translation by 2 units along the y axis
* and a translation by 3 units along the z axis

...and perform the three axis-aligned translations one at a time, in any order, and still get the same result of applying the composed translation all at once.

Rotation does not work that way, so an intuition calibrated on translation can easily lead us to false conclusions.

You can verify this for yourself with the axes in your example. Grab an object with an identifiable top/right/front, and mentally map its sides to axes.

* Place it on a table, and find an axis 45 degrees between the x and z axes you picked. Twist the object 45 degrees about that axis, and remember what that orientation looks like.
* Now repeat the experiment, but this time rotate 45 degrees around just the x axis first, then 45 degrees about the z axis, wherever it ends up.

You'll observe that the orientation you get at the end is different between the two experiments.

Rotation is not simply separable into axis-aligned components.

Or to be more precise: there will be *many* possible trios of axis-aligned rotations that give the same resulting orientation as any orientation you formed some other way (that's how Euler angles / Tait-Bryan angles work), but there's not such a simple mapping between the combined and separated forms like there is for translation. You can't just take the same angle and repeat it/split it proportionally between the components of its axis and get the same result. The trigonometry of the conversion is messy and has lots of counter-intuitive edge cases. As shown in the link above, sometimes applying a rotation about x and y gives you a rotation about the z!

So, to recap: it is true that to combine rotations expressed as quaternions, all you have to do is multiply those quaternions. But that represents a specific *kind* of combination, which is composition: applying one rotation, then the other, in *sequence*.

Our intuition about what this composition *should* do may depart significantly from the reality, unless we spend a lot of time turning mugs around in our hands. (Just remember to finish your coffee or tea first!)
> 6 votes

# Answer
> Is it possible to apply something to qx or qy to get the original q directly?

Yes it is! The transformation you're looking for is \\$qy^{-1} * qx * qy\\$

> (My reasoning is like looking at a unit vector starting in the x direction, which if I rotate 45 degrees in the y axis would give me a vector pointing in the z=x direction, but this is clearly naive as it doesn't work)

This will give you a rotation that turns the vector \\$(\sqrt{2}/2,0,\sqrt{2}/2)\\$ into \\$(1,0,0)\\$ -- either \\$q1\\$ or \\$q2\\$, depending on what order you apply the rotations. That's not what you're looking for, though. The rotation you want, \\$q\\$, should turn the vector \\$(\sqrt{2}/2,0,\sqrt{2}/2)\\$ into itself, and rotates the rest of the world 45° around it. (It doesn't send the x unit vector anywhere very interesting.)

\\$qx\\$ turns \\$(1,0,0)\\$ into itself, and rotates the rest of the world 45° around it.

\\$qy\\$ turns \\$(\sqrt{2}/2,0,\sqrt{2}/2)\\$ into \\$(1,0,0)\\$.

So, the step-by-step process is:

* \[\\$qy\\$\] Move your desired axis from \\$(\sqrt{2}/2,0,\sqrt{2}/2)\\$ to \\$(1,0,0)\\$
* \[\\$qx\\$\] Rotate everything around your axis (now at \\$(1,0,0)\\$)
* \[\\$qy^{-1}\\$\] Move your axis back to \\$(\sqrt{2}/2,0,\sqrt{2}/2)\\$

Composition like this reads right-to-left, so the end-result is \\$qy^{-1} * qx * qy\\$.
> 2 votes

# Answer
In a sense it is true that multiple rotations are just multiplication. However, multiplying rotations is not commutative (a*b != b*a).

To see this, take an irregular rectangular object like a book. Rotate 90 degrees around the x axis followed by a rotation of 90 degrees around the y axis. Now try again with the y axis first, followed by the x axis.

This is important because when you apply multiple rotations, they will be applied in sequence. That is, it will rotate from the position it was left in from the previous rotation.

Because of this it is not the same to make a rotation around the (x=z)-axis compared to the x followed by z axis.
> 0 votes

---
Tags: 3d, rotation, quaternion
---


# Question
Title: Why light baking has too many big blocks
I'm baking an `indirect lightmap`, but the result is terrible (as you can see on the ground). There are big white blocks, and one area on my object is missing, so you can see the inside of the object.

What could be the reason? I've tried to change some values in the inspector, to no avail. The current object is about `10 * 15` units.

# Answer
After a little digging and trying, I found that it was caused by the plane being too large (about `300 * 300` units), which means a resolution of `2048 * 2048` will be stretched out along the whole mesh.

Let's do the math. I set the texel to be 64, then `64 * 64` will be the total amount of blocks inside one unit. The size of my light map (`2048 * 2048`), can only accommodate `2048 / 64 = 32` units long. Then the 32 units will wrap the 300 units mesh, thus resulting in a bad look.
> 1 votes

---
Tags: unity
---


# Question
Title: How can I get/find all the UI texts and TextMesh Pro in the hierarchy?
When pausing/resuming the game, I want to disable/enable all UI texts.

The following code works for finding UI texts, but I also want it to find TextMesh Pro text.

How can I do this?

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

public class BackToMainMenu : MonoBehaviour
{
    [ContextMenuItem("Fetch", nameof(FetchAllTexts))]
    public Text[] uiTexts;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            if (Time.timeScale == 0)
            {
                SceneManager.UnloadSceneAsync(0);
                DisableEnableUiTexts(false);
                Cursor.visible = false;
                Time.timeScale = 1;
            }
            else
            {
                Time.timeScale = 0;
                MenuController.LoadSceneForSavedGame = false;
                DisableEnableUiTexts(true);
                SceneManager.LoadScene(0, LoadSceneMode.Additive);
                Cursor.visible = true;
            }
        }
    }

    private void FetchAllTexts()
    {
        var tmp = new List<Text>();
        foreach (var root in SceneManager.GetSceneAt(0).GetRootGameObjects())
        {
            tmp.AddRange(root.GetComponentsInChildren<Text>(true));
        }
        Text[] texts = tmp.ToArray();

        uiTexts = texts;
    }

    private void DisableEnableUiTexts(bool uiTextEnabled)
    {
        if (uiTexts.Length > 0)
        {
            foreach (Text ui in uiTexts)
            {
                ui.enabled = uiTextEnabled;
            }
        }
    }
}

```

# Answer
> 1 votes
According to your comment you are using as well TextMeshPro. You are already iterating over all elements in the root loop. You might want to have a second list for all TextMeshPro elements to not always cast between them.

```
 var textMeshProList = new List<TextMeshProUGUI>();
 foreach (var root in SceneManager.GetSceneAt(0).GetRootGameObjects())
 {
    tmp.AddRange(root.GetComponentsInChildren<Text>(true));
    textMeshProList.AddRange(root.GetComponentsInChildren<TextMeshProUGUI>(true));
 }

```

There are two different TextMeshPro Ui Text elements

* TextMeshProUGUI
* TextMeshPro

Depending which one you used you need to change the type. Or add both if you used both.

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


# Question
Title: TextField Add in Editor does not display when put under if statement
I've been trying to make a custom editor window in Unity and I needed to make an "add TextField" button. When I add a `TextField` directly (without requiring a button), it works. When I put it under `if(GUI.Button())` it does not show up. Here's my code:

```
private static List<string> s = new List<string>();
private void OnGUI()
{

    if (GUI.Button("+");)
    {
        s.Add(GUI.TextField(new Rect(0,50,Screen.width,20),"field"));
    }
}

```

# Answer
Unity’s IMGUI is a really strange beast, and you seem to have a basic misunderstanding of how it works. This is a method that basically gets called over and over and over, and each control you want to appear needs to be called every time. However, GUI.Button only returns true once, when clicked. So you need to display the text fields outside the if statement, and inside the if statement is just where you “remember” to show it.

From what I can see, it seems like you want the plus button to add a new text box with the contents set to “field” each time it’s clicked, so here’s my attempt at that:

```
private static List<string> s = new List<string>();
private void OnGUI()
{
    if (GUILayout.Button("+"))
    {
        s.Add("field");
    }
    for (int i = 0; i < s.Count; i++) {
        s[i] = GUILayout.TextField(s[i]);
    }
}

```

(From memory; pardon any compiler errors)

Note how I also used GUILayout instead of just GUI so I don’t need to specify the rect of each control.
> 1 votes

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


# Question
Title: How to stop objects pushing each other away on collision?
I'm creating something along the lines of Super Smash Brothers. There's a problem with the collision between the two players and projectiles.

We have rigid body on the characters and projectiles and every time they collide they push one another back, I know that is how it operates but is there a way to stop that from happening?

# Answer
Set the mass of your projectiles to be very low, and the mass of your characters to be higher until they are no longer affected by the collision of the projectile (mass is a variable on rigidbody component).

The reason your rigidbody's push each other away is because this is what physical objects do in real life and rigidbody simulates this as accurately as possible. You throw a light ball at a heavier ball, both balls react. The heavier ball moves less than the lighter ball. If it was a really heavy ball, or a rock I guess, the really heavy ball/rock wouldn't move noticeably.

This will work if you're expecting your projectile to be destroyed on hit like Mario's fireball. If you want to use a beam or something like some of the final smashes, you'd make the beams "hitbox" (http://en.wikipedia.org/wiki/Hitbox) a trigger that exists for one FixedUpdate frame and deals its damage/applies its forces and then goes away the next frame.

Also, when moving rigidbody's, do so via rigidbody.AddForce or add to its velocity yourself, as setting the transforms bypass the physics simulation and can easily result in you moving your objects into one another and cause them to become stuck. AddForce is more realistic at times, and just adding to the velocity can be easier to use at sometimes.

This is easy for a platformer, example in FixedUpdate:

```
if(rigidbody.velocity.x < maxMoveSpeed) { //and pressing right
    //apply force right
}
if(rigidbody.velocity.x > -maxMoveSpeed) { //and pressing left
    //apply force left
}

```
> 4 votes

# Answer
you can create two GameObjects one with a collider and one with a Rigidbody. link the position of the one with a collider with that of the one with a Rigidbody. Now both can move with physics without interacting with other gameObjects. Use the one with a collider for collision detection and such.
> 1 votes

# Answer
In your comment you mentioned that you are setting the game objects positions instead of relying on forces or velocity. If I had to take a guess, the problem you are facing is having two rigidbodies colliding together, which in turn is affecting other rigid bodies. You have two options in this case

1. Remove the rigidbodies altogether. If you are not using velocity or forces to move your bodies, why attach a rigid body?
2. Set your rigidbodies to kinematic. This way you'll leave your options open in case you do decide to have objects in your scene that can be affected by physics

**Further Information on Kinematic Rigidbodies**

To enable kinematics on a rigidbody all you have to do is click on the checkbox labelled "isKinematic". Kinematic rigidbodies are not affected by forces, gravity or collisions. They are explicitly set by setting the position and the rotation of the game object, however they can interact with other non-kinematic bodies.
> 0 votes

---
Tags: c#, unity, collision-detection
---


# Question
Title: Control how quickly 2D vehicle straightens out
I'm implementing vehicle movement in a 2D environment, where a vehicle consists of a front and a back "axle", both represented as 2D points. When the front axle moves, the back axle should follow in that direction, mimicking the way vehicles move. The way I have it right now looks like this:

After moving the front point A (white), I place B on the line between A and B such that a constant distance (the vehicle length) is kept. More accurately, I use the vector from A to B, normalize it, multiply it with the vehicle length, and add it to A, to get the new B. When searching for similar issues, I found this question's answer to come to the same technique.

As you can see, the resulting movement is quite recognizable as vehicle movement. The front also does not need to move as smoothly. Below I moved the front manually by dragging it around. As you can see, backwards movement also works perfectly:

I want to use this movement system as the back bone of a puzzle game, so its stiffness is actually an asset, since it is also quite predictable.

The only issue that I have is that it takes a good while for the vehicle to straighten out, by which I mean have the back come in line with the travel direction of the front. I'm looking for a way to control how quick this happens.

I have already played around with biasing/weighing the back point onto the line on which the front appears to be traveling, but that resulted in weird moving behavior for any other scenario than moving in a perfectly straight line. I also haven't been able to think of a different system that would inherently straighten out quicker.

So... I'm happy to try out any ideas that you might have!

Thanks!

Update 1: I've implemented the idea from @GaleRazorwind. This results in the back point moving away from the front point:

# Answer
> 1 votes
Ok, I put in a bit of thought on how to increase the speed of straightening out. Let's start with a basic image showing what you have right now:

The car starts with its front at A1 and its rear at B1. During the update, the front moves to A2, so you calculate the normal from A2 to B1 and use that to find B2.

Now, you are trying to get the vector from A2 to B2 to line up with the vector from A2 to A1 more quickly. So, take a vector from B2 to A1, normalize it, and then multiply it by a scaling value ("artist defined"). You will then offset B2 by this new scaled vector to get B3.

However, now we are no longer at the proper distance from A2, so create a vector from A2 to B3, normalize it, scale it by the vehicle length, and add it to A2 to get B4, which is the final position.

Notes: This will cause issues as you approach moving in a straight line, so you can check the Dot Product between A2A1 and A2B2 before performing these extra steps. If the dot product is close to 1/-1, don't do the extra steps. You could also multiply your scaling factor by the inverse of the dot product (1 - Dot). This will make your scaling more aggressive at sharper angles and less aggressive at shallow angles.

---
Tags: 2d, movement, vehicle
---


# Question
Title: How can I obtain the file size of a Unity build at runtime?
I'm wondering if it is possible to obtain the filesize of a game's build at runtime.

Searching this topic only yields results for *reducing* the build size, which is not at all what I'm looking for.

# Answer
If you are using a **Mac**:

After it's built by Xcode, in the "Unity Player/build" directory there will be the app. In Finder use Get Info to see the size.

Or in Xcode, find the Products group and within that .app item and do Reveal in Finder, then Get Info.

If you want to know the size for the App Store, ZIP compress the app first.

If you are using **Windows**:

Right click the Unity build you have just created and right click it. Then, click properties, then general, and check the size field.

I hope this is answers your question.
> -1 votes

---
Tags: unity, c#, android, ios, build-process
---


# Question
Title: How to efficiently implement a 7-segment display?
I want to construct a `7 segment` display (as shown below). When you input a number, the script will read the input number and light up the respective segment (change the spriterenderer color to red) to display the number.

But I think the code has become too long, since there is 0-9 digit to display, I need 10 `if statements`, 8 `scripts` and the function of each statement is to light up the respective segment so it displays the number correctly.

Is there any better way to make the code shorter?

```
using UnityEngine;

public class ClockController :  MonoBehaviour
{
    Rect1 rect1;
    Rect2 rect2;
    Rect3 rect3;
    public GameObject othergameobjectrect2;
    public GameObject othergameobjectrect3;

    void Start()
    {
        int x = 1;
        if (x == 1)
        {
            rect1 = GetComponent<Rect1>();
            rect1.Rectangle1();

            rect2 = othergameobjectrect2.GetComponent<Rect2>();
            rect2.Rectangle2();

            rect3 = othergameobjectrect3.GetComponent<Rect3>();
            rect3.Rectangle3();

        }
    }
}

```

```
using UnityEngine;

public class Rect3 : MonoBehaviour
{
    public void Rectangle3()
    {
        GetComponent<SpriteRenderer>().color = Color.red;

    }
}

```

```
using UnityEngine;

public class Rect2 : MonoBehaviour
{
    public void Rectangle2()
    {
         GetComponent<SpriteRenderer>().color = Color.red;
    }
}

```

```
using UnityEngine;

public class Rect1 : MonoBehaviour
{
    public void Rectangle1()
    {
        GetComponent<SpriteRenderer>().color = Color.red;
    }
}

```

# Answer
I'd attack it something like this...

Have one script that represents the digit as a whole, and assign to that script in the Inspector an array of `SpriteRenderers` representing the seven segments. They don't need their own custom scripts, since the only functionality we need from them is setting the colour, which the built-in `SpriteRenderer` component has already.

Then store a lookup table that encodes which segments should be on for each digit value.

When we set the clock digit to a new number, we can loop over all our segments, and set them to the corresponding state from the lookup table for that value.

The one tricky part here is that you need to assign your segment references to the correct array slots so they get the right value from the lookup table, but that should be easy enough to do with a little care.

```
public class ClockDigit : MonoBehaviour {

    //  Assuming you number your segments as follows:
    //   -- 0 --
    //  |       |
    //  5       1
    //  |       |
    //   -- 6 --
    //  |       |
    //  4       2
    //  |       |
    //   -- 3 --

    // Store a lookup table for which segments
    // should be active when displaying each digit.
    static readonly bool[,] SEGMENT_IS_ACTIVE = new bool[,] {

        {true,  true,  true,  true,  true,  true,  false}, // 0
        {false, true,  true,  false, false, false, false}, // 1
        {true,  true,  false, true,  true,  false, true }, // 2
        {true,  true,  true,  true,  false, false, true }, // 3
        {false, true,  true,  false, false, true,  true }, // 4
        {true,  false, true,  true,  false, true,  true }, // 5
        {true,  false, true,  true,  true,  true,  true }, // 6
        {true,  true,  true,  false, false, false, false}, // 7
        {true,  true,  true,  true,  true,  true,  true }, // 8
        {true,  true,  true,  true,  false, true,  true }  // 9
    };

    public Color32 activeColour = Color.red;
    public Color32 inactiveColour = Color.black;

    public SpriteRenderer[] segments = new SpriteRenderer[7];

    public void Display(int number) {
        var digit = number % 10;
        if (digit < 0) digit *= -1;

        for (int i = 0; i < 7; i++) {
            if (SEGMENT_IS_ACTIVE[digit, i]) {
                segments[i].color = activeColour;
            } else {
                segments[i].color = inactiveColour;
            }
        }
    }
}

```
> 4 votes

# Answer
As mentioned by @D.Kallan stack exchanges are not normally a good place to ask about making things run more efficiently so much as about how to make them run (for example "How to I make my 7-segment display code run faster?" vs. "How do I make a 7-segment display?"). That being said your problem is pretty simple and easy to clean up.

```
public class SevenSegmentNumber : MonoBehaviour
{
    // Segment layout
    //  0   --
    // 1 2 |  |
    //  3   --
    // 4 5 |  |
    //  6   --
    public List<SpriteRenderer> segments = new List<SpriteRenderer>();
    public Color onColor = Color.red;
    public COlor offColor = Color.black;

    public void SetDisplayValue(int digit)
    {
        int value = digit % 10;

        switch (value)
        {
           case 0:
               segments[0].color = onColor;
               segments[1].color = onColor;
               segments[2].color = onColor;
               segments[3].color = offColor;
               segments[4].color = onColor;
               segments[5].color = onColor;
               segments[6].color = onColor;
               break;
            case 1:
               segments[0].color = offColor;
               segments[1].color = offColor;
               segments[2].color = onColor;
               segments[3].color = offColor;
               segments[4].color = offColor;
               segments[5].color = onColor;
               segments[6].color = offColor;
               break;
            // Fill in the rest here
        }
    }
}

public class SevenSegmentDisplay : MonoBehaviour
{
    public List<SevenSegmentNumber> digitDisplays = new List<SevenSegmentNumber>();

    private void Awake()
    {
        SetDisplayValue(0);
    }

    public void SetDisplayValue(int value)
    {
        int remainder = value;

        for (int digitId = 0; digitId < digitDisplays.Count; digitId++)
        {
            digitDisplays[digitId].SetDisplayValue(remainder % 10);
            remainder = remainder / 10;
        }
    }
}

```

Basically your problem is coming from the fact that you are writing unique scripts for every single game object rather than just one for each type (ex. "NpcBob", "NpcJim", "NpcJoe" scripts vs a single "Npc" script). I would suggest you check out some doing tutorials to learn a bit more about how to make generic scripts that can help you prevent this kind of scripting issue from coming up again. This will be especially helpful if you need to change your seven-segment display to show letters/strings, binary numbers, hex numbers, or punctuation.
> 2 votes

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


# Question
Title: Domain distortion on a spherical texture (planetary surface)
I am experimenting with procedural techniques to generate planetary terrain. I have close to zero knowledge so I started with something simple, using perlin noise and domain distortion. My goal is to wrap these textures on a sphere model (using openGL) so I tried to use spherical coordinates and it was partially successful (I learned from https://ronvalstar.nl/creating-tileable-noise-maps).

As long as I don't apply domain distortion I obtain the expected result with no discontinuity at the poles or anywhere:

But when I do apply the domain distortion, I get this:

You can see there are discontinuities at the poles, and also at a meridian.

I'm not sure to understand why the domain distortion is breaking my spherical mapping, I tried to apply a modified formula from here: https://iquilezles.org/www/articles/warp/warp.htm but it looks like the way I define the position vector is wrong in this case.

I do not know if spherical coordinates are adapted to this kind of problem. Can you please confirm this is the most efficient way to go?

If you have something else to suggest, please share. I have been reading a lot of things about cubemaps, (u, v) texture mapping, procedural texturing etc but did not really understand everything and how it might help me, also for the most part it looked quite sophisticated (intimidating for me).

**Here is my code (the buggy part I guess is under the "# --- WARP (domain distortion) ---" line:**

```
import numpy as np
from noise import pnoise3 as perlin3
from noise import pnoise2 as perlin2
import matplotlib.pyplot as plt
import noise
from PIL import Image
import time

# --- transformation X, Y (cartesian) -> a, b, c (spherical) ---
def spherical(x, y, naxis):

  fNx = (x + 0.5) / naxis
  fNy = (y + 0.5) / naxis

  fRdx= fNx * 2 * np.pi
  fRdy = fNy * np.pi
  fYsin = np.sin(fRdy + np.pi)

  a = naxis * np.sin(fRdx) * fYsin
  b = naxis * np.cos(fRdx) * fYsin
  c = naxis * np.cos(fRdy)

  return a, b, c

# --- MAIN ---
def procedural(naxis, WARP, octaves, persistence, lacunarity):

  t0 = time.time()
  M = []

  for i in range(len(WARP) + 1):
    M.append(np.zeros((naxis, naxis)))
  M = np.array(M)

  # --- perlin noise on spherical coordinates ---
  M[0] = np.array([[perlin3(float((spherical(i, j, naxis)[0]) / naxis),
                            float((spherical(i, j, naxis)[1]) / naxis),
                            float((spherical(i, j, naxis)[2]) / naxis),
                            persistence = persistence, lacunarity = lacunarity, octaves = octaves)
                            for i in range(naxis)] for j in range(naxis)])

  # --- WARP (domain distortion) ---
  # f( p + f(p) )
  # p: spherical(i, j) -> a, b, c
  # components:  f( a + M[w-1] )
  #              f( b + M[w-1] )
  #              f( c + M[w-1] )

  for w in range(1, len(WARP) + 1):
    M[w] += np.array([[perlin3(float((M[w-1][i, j] * naxis * WARP[w-1] + spherical(i, j, naxis)[0]) / naxis),
                               float((M[w-1][i, j] * naxis * WARP[w-1] + spherical(i, j, naxis)[1]) / naxis),
                               float((M[w-1][i, j] * naxis * WARP[w-1] + spherical(i, j, naxis)[2]) / naxis),
                               persistence = persistence, lacunarity = lacunarity, octaves = octaves)
                               for i in range(naxis)] for j in range(naxis)])

  # --- normalization [0, 1] ---
  for n in range(len(WARP) + 1):
    M[n] = (M[n] - np.min(M[n])) / (np.max(M[n]) - np.min(M[n]))

  return M

cm = 'coolwarm'

naxis = 1024
WARP = [0.5, 1, 0.5]
#WARP = []
octaves = 24
persistence = 0.5
lacunarity = 2

R = procedural(naxis, WARP, octaves, persistence, lacunarity)

# --- save jpeg ---

im = Image.fromarray(R[-1] * 255)
im = im.convert('RGB')
im.save("your_file.jpeg")

fig = plt.figure()
ax = fig.add_subplot(111)
ax.imshow(R[-1], cmap = cm)
plt.show()

```

# Answer
When applying the warp, do it on the 3D coordinates while you're performing the initial noise evaluation in the first place. I am not super familiar with the Numpy syntax here, but basically you would want to redefine your lambda function so that instead of generating `noise(<x, y, z>)` or `noiseA(<x, y, z> + noiseB(<x, y, z>))` at a particular point, where `<x, y, z>` is converted from spherical coordinates, you want to go ahead and generate `noise(warp(<x, y, z>))`. Then perhaps `warp(<x, y, z>) = warp(<x + noiseWarpX(<x, y, z>), y + noiseWarpY(<x, y, z>), z + noiseWarpZ(<x, y, z>)>)`. Adding noise to each individual coordinate is slightly biased, but it's a lot less biased than adding it to all three coordinates at once.

Speaking of bias, be wary of tutorials that recommend you to use "Perlin" noise. Actual Perlin noise, which you're using here, is an old function which produces a lot of 45 and 90 degree bias. Good simplex type noises are a newer approach, which typically produce less directionally aligned results. I would consider tutorials which discuss Perlin without at least any caveats or clarification on this matter, to be recirculating outdated information. IMO there's almost no reason to use actual Perlin noise nowadays unless you're doing something to address its grid bias.

I suggest using PyFastNoiseLite, with the OpenSimplex2 noise option and the FBm fractal option. For domain warping, FastNoiseLite has a dedicated, more efficient (and further bias reducing) domain warping function implemented. However it is not mirrored in PyFastNoiseLite, so you might either have to implement the wrapper yourself, or just use the three-noises technique.
> 1 votes

---
Tags: procedural-generation, python, perlin-noise, sphere, planet
---


# Question
Title: Saving player's progress in a Unity game
I am making a game using the Unity game engine. I want to save the player's progress including level, experience points, chosen character, etc. Presently I am using *playerprefs* but I want to know whether this will work for gamers who will run this game on their mobile devices (Android/iOS) as well as desktops (OSX/PCs)? If not, then how should I save this information? I want to auto-save player progress after clearing each stage.

# Answer
> 30 votes
PlayerPrefs will work cross-platform, but it's ***not* recommended for gameplay progress save files** because it's insecure. As a plaintext file, a player can easily open it up and change the contents to cheat, or make your game behave unpredictably. It's also not guaranteed to stay around.

PlayerPrefs is intended for non-essential preference information, like control mapping or music/sfx settings - things the player can freely change anyway, and wouldn't miss terribly if they were to (on Windows for example) use a system restore point and lose some of their registry information. If this lost their high scores or campaign progress, players would be justifiably upset!

Instead, it's recommended to save gameplay progress in your own file (usually binary, possibly encrypted or signed if you want to make it harder to modify, but see Philipp's comment below on this).

You can use Application.persistentDataPath to get a reliable save location on each platform. This is typically in a user data folder that won't be wiped out in cases like the example above.

Once you have a path to save to, you can use the regular C# IO methods to create, write, and read your file. The details will vary a lot depending on your save file format and structure, so if you run into trouble, it's best to ask a new question detailing what you're trying to do and where you're stuck.

# Answer
> 4 votes
On the Unity site, there is a video that goes over the two main options for saving (PlayerPrefs and creating your own save file). The video can be found here: http://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/persistence-data-saving-loading?playlist=17117

# Answer
> 1 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
* One of the many save systems you can find on the asset store, which will likely use one or a combination of these techniques.

# Answer
> -1 votes
PlayerPrefs is a K/V store designed to "just work" no matter what platform you build for. I say just keep using it unless you have a compelling reason not to.

---
Tags: android, unity
---