title: Magic Number Difficulty Balancing

text:
# Question
Title: Magic Number Difficulty Balancing
So I've been working on my game for roughly two years now and although it's significantly more balanced than it was a year ago, I still feel like it's too easy, or rather, doesn't really have any sort of difficulty curve over time. It's a top-down shooter, and more enemies appear as you get to later waves, but the bosses are all a joke in terms of difficulty and some of the weapons can easily obliterate large groups of enemies if you know how to use them properly.

So how do I know what "magic numbers" to pick to have a consistent difficulty to my game, and is there a good way to determine a formula to increase that difficulty in later waves? Should I be increasing health of enemies over time? Or would that not make sense since they're the same enemies? I increase number of enemies over time by having a "spawning pool" which is just an integer that increases on a logarithmic scale according to a formula I just came up with and plotted a while ago. Each enemy has a "cost" to spawn and at the beginning of each wave, random enemies are chosen and their cost deducted until the spawning pool is depleted for that wave.

The enemies' damage and health are calculated randomly using a sort of D20 system like Dungeons & Dragons where, for example, the very first enemy you encounter in the game's health is calculated by rolling 2d8+12 (roll two 8-sided die and add 12), so the range of health values they can have is 14-28. All enemies' health is calculated this way. The enemies' attacks and damage over time effects, as well as the player's weapons all use this method to generate numbers.

Is there a good way to decide on good numbers short of just playing over and over again until it feels right? Would it be bad to increase their health and damage over time since they're still the same enemies? Or maybe I should get rid of them in later waves and replace them with an upgraded basic enemy that's identical (maybe a color swap) but with better stats?

Examples would be awesome.

# Answer
> 7 votes
**Your problem isn't in finding the magic numbers or magic formula that makes your game feel "good"**

**Your problem is that you haven't adequately defined what "good" is in your game.** (In your question, at least)

Different games will use wildly different health & damage numbers and progression curves, because they're targeting different ideas of what the ideal experience is for that game.

**So, your first step is to establish concrete goals** (or anti-targets you want to avoid):

* What does your observed eperience say?

+ Think about the best run you've gotten from the RNG so far. What made that satisfying?
    + Think about a frustrating or underwhelming run you got from your RNG. What made that unsatisfying or painful?
* Try experimenting with different game scenarios, trying out different parameter ranges:

+ How many enemies on screen feels dull? How many is insurmountable? How many sits at the sweet spot in between, where it looks overwhelming, but you can pull through?
    + How much health feels "puny"? How much health feels "tough"? How much feels "bullet sponge"?
* Visualize your ideal:

+ What does your dream playthrough look like? Try writing it out as a short story from the player's eye view - what do they do, what challenges do they overcome?

Once you've done this, you can start to extract concrete criteria for what sorts of situations are enjoyable in the game you've built, or create your desired level of gameplay intensity & problem-solving.

You might find for instance...

* "A good early game challenge is to have 1-3 enemies on screen, where each one dies after 3-5 seconds of focus from the player"
* "It's good when there are short periods where there are are 5-8 enemies on screen, and they take 7 seconds to defeat. But if that lasts for more than a minute the player always loses, so these challenges should come in short bursts"

You can then work out a range of health numbers and spawning rate variations that create scenarios aligned with these patterns you've identified as desirable. That step can be a "magic formula," but the magic is in the way you've crafted the formula to suit your personal goals for your specific game. Then the numbers are just the concrete consequence of those articulated goals.

# Answer
> 3 votes
Your game sounds fairly similar to Killing Floor 2, as in it's a wave-based shooter game with scaling difficulties. From being a part of the KF2 community for a while, I'll some concerns/praises about difficulty that many people shared. I may not agree with them all but there are some valid points.

**Damage sponge enemies are not fun**. Increasing the numbers or damage is usually a better choice over increasing the health. Players feel more satisfying feedback in killing hordes of enemies vs killing stronger smaller numbers of enemies. This was also a complaint about the console versions of Diablo 3, as people suspected they cut down on enemy numbers for performance reasons. Of course, there is a caveat to this - damage sponge enemies are awesome when they're rare and truly scary. Fleshpounds in Killing Floor 2 not only do a TON of damage but they also take a TON of damage. It feels very rewarding when the team comes together to even take down one of these. But not *every* enemy is a damage sponge, just the really strong ones which show up sparsely.

Upping the damage they can take can help add difficulty, but you need to walk a fine line before you accidentally get into bullet sponge territory.

**Reward players for skillful strategies**. The Fleshpounds can be a cakewalk for skilled players who know strategies for handling them. However, higher difficulties have balanced this a bit by providing a higher spawnrate of Fleshpounds, making players deal with several at once. The number is manageable to a team of skilled players but would obliterate anyone without higher knowledge of game mechanics.

**On the contrary, do not punish players for skillful strategies.** Let them break your game and make it dirt easy with their crazy good skills. Enemies called EDARs were added to KF2 and people had a big complaint - headshots *didn't* kill them. Their weakest spot was their chest. You were forced to body shot this enemy type to kill it most of the time. This feels counter productive and less rewarding than landing a clean headshot. People with good headshot accuracy were now forced to awkwardly aim for the body rather than use their aiming skill to land oh-so-satisfying headshots. EDARs are still pretty heavily disliked additions to the game.

**Give enemies new movesets at higher difficulties**. A lot of enemies on the higher difficulties in KF2 have completely new moves which add a lot of danger. They also move faster and more erratically, making them harder to headshot. This feels like a much more "natural" increase in difficulty.

Off the top of my head, those were some of the biggest discussion points in the community to come to mind. I will add more later if more come to me. As a summary, I'd say give enemies new moves at a higher scaling, make them do more damage, make them move faster, and maybe give them *slightly* more health.

# Answer
> 1 votes
An example of a unity build, albeit different from your project, is called "Clone Drone in the Danger Zone" - It is an indie game that takes advantage of exactly color swapping and improved stats (AI) on enemy models encountered later in the game.

An early side scrolling example of the same color swap idea for enemies is found in the Sega Genesis classic "Teenage Mutant Ninja Turtles".

Overall - I completely agree with DMGregory's response. Take time to read his words! I know I sure did.

My comment is strictly added to provide you some very basic examples of enemy creation in published games and to address your final thoughts.

You can definitely choose to make enemy health a function of time - but I think your second idea of replacing your enemies altogether with a different color is a *tried and true* method that we all can probably think of many examples of. I believe that it is a great way to tailor your player experience - which as your question suggests is a very daunting task at times, especially if your current user experience is somewhat governed by random number generation.

If you are determined to use random number generation, maybe decreasing your output range for certain parameters would help you further tailor the player experience. Instead of 2d8 + 12 for your first enemies' HP , why not 2d4 + 20? that yields you a bit more stable output range of 22-28 as opposed to 14-28.. These are just some ideas to hopefully push you in the right direction friend!

EDIT : RNG is a very deep topic.

Look into the well known game DOOM and the RNG algorithm/methods used by designers. Although there is no "Magic" per se, there are some very provoking discussions on randomness and the use of code to tune the human experience of randomness in the greater field of user experience design.

I had to take a look for myself at some discussions on DOOM RNG

Eventually finding myself in the Deeper Rabbit Hole of RNG

I truly hope this helps you on your quest to conquer practical RNG in game design.

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


title: Wind in video game project

text:
# Question
Title: Wind in video game project
How to make the wind blow with randomized patterns? Like for storms and calm breezes?

# Answer
> 0 votes
Your question is quite broad, but I think I can point you in the right direction. You have two approaches each with its pros and cons.

1.) Simulate real physics

Pros: the most close to reality.

Cons: computationally expensive, hard to program.

2.) Use noise

Pros: faster to implement and runs fast also.

Cons: not so close to reality

If you go with the first one you have to implement 3/2 dimensional Computational Fluid Dynamics CFD, I would go with a shader approach. GPU Gems is an excellent source. If you go for the second option I recommend Curl Noise for nice swirly patterns. I think that you better implement either of the approaches on the GPU for performance.

---
Tags: physics
---


# Question
Title: TBN matrix for normal and parallax mapping
I'd like to refer to this question because I didn't completely answer to my problem.

I've implemented normal and parallax mapping but because of some assumptions I have to use two different TBN matrices for each effect.

One of the most important assumptions is that I have deferred renderer with normals encoding and light calculations in view space.

This implies that I have to convert data from normal maps (which are in tangent space) to view space using below TBN matrix:

```
mat3 NormalMatrix = transpose(inverse(mat3(ModelViewMatrix)));
vec3 T = normalize(NormalMatrix * Tangent);
vec3 N = normalize(NormalMatrix * Normal);
vec3 B = normalize(NormalMatrix * Bitangent);

mat3 TBN = mat3(T, B, N);

```

On the other hand parallax mapping required view direction vector in tangent space. To compute that I use camera position and fragment position (in world space) multiplied by following TBN matrix to move this vectors from world space to tangent space:

```
T = normalize(mat3(ModelMatrix) * Tangent);
N = normalize(mat3(ModelMatrix) * Normal);
B = normalize(mat3(ModelMatrix) * Bitangent);

mat3 TBN = transpose(mat3(T, B, N));

```

I'm looking for a way to optimize that. Is it possible to make it better?

# Answer
> 0 votes
Do your normal mapping in world-space instead of view-space then you'd only have your second matrix.

---
Tags: opengl, glsl, normals, normal-mapping
---


# Question
Title: OpenGL ES, object intersection artifacts
I was developing a C++ implementation of OpenGL for Android and I noticed those weird artifacts that formed between 2 intersecting objects (or triangles) :

**\[Here are the artifacts on Android\]**

The weird thing is that exactly the same library, running on my windows machine, with exactly the same shaders is not giving the same results (sorry for the bad image resolution) :

**\[No artifacts on windows\]**

I know about the existence of Z-fighting, but wouldn't that issue persist on Windows as well? I am using a 16 bit depth buffer resolution on Android (which seems to be the maximum here).

Is there something I could be missing or doing wrong?

Thank you!

# Answer
> 1 votes
Well, I was wrong, the maximum depth precision is 24 bits, and setting it this way completely eliminated the problem.

Before, on Android, my EGL configurations were `setEGLConfigChooser(8, 8, 8, 0, 16, 0)`.

With `setEGLConfigChooser(8, 8, 8, 0, 24, 0)` everything works great.

---
Tags: android, opengl-es, jni
---


# Question
Title: Unity 2019 build for Oculus Go not appearing on device
My project was building fine in 2018 and showing up on my Go under "unknown sources".

My project builds fine in 2019 and it says it gets installed but it no longer shows up under "unknown sources" or anywhere else that I can see.

I can uninstall using adb - so it's there apparently, but where, and how can I launch it?

thanks

# Answer
> 1 votes
I got it. VR was enabled, Oculus was listed in the dropdown. I needed to unload Oculus and reload it, now it works! Thanks.

# Answer
> 0 votes
For me that sounds a lot like trying to sideload an Android-App (without oculus sdk) to Oculus Go. It's on there but there is no way to open it.

For troubleshooting: Could check XRSettings and such, to see if Oculus SDK was deactivated when upgrading your project to 2019?

What happens if you create a new Project in 2019, integrate Oculus SDK and load it onto the GO?

---
Tags: unity, android, oculus
---


# Question
Title: Webgl page heap size increasing in each page load then crash
I am getting aw snap or sometime not enough memory problem when I reload my webgl page. I have a webgl project which is empty (just a camera + light), developed in **unity3d**. I am reloading it, and profile its memory.

As you can see that its load 1.2MB in the first load than 1281 MB in second then 1574 then 2160 and then get crash. I am amazed that why it is happening?

> Another source of memory-related problems is the IndexedDB filesystem used by Unity. Any time you cache an asset bundle or use any filesystem-related methods, they are stored in a virtual filesystem backed by IndexedDB.
>
> What you might not realize is that this virtual filesystem is loaded into and persisted in memory as soon as your Unity application starts. This means that if you are using the default Unity caching mechanism for Asset Bundles, you are adding the size of all of those bundles to the memory requirements for your game, even **if they are not being loaded.**

but the problem is I didn't load anything from this build yet.

Even when I try to refresh my empty project several time in chrome I get this error:

For Mozilla, there is an error log which states failed to asynchronously prepare wasm: out of memory

# Answer
I have **resolved this error**, thanks to unity. It was related to web browser console open. When the dev tools are open, chrome keep increment the memory on page reload. While the problem is still persist with firefox. I found that FireFox has default behaviou that it increment the memory when you page reload.
> 0 votes

# Answer
It would help if you added a link to a git repository, or some code samples.

Without seeing your code or project, check what packages, plugins and other imports have been added to your project. Verify that your project's assets only contains things that you need, and remove everything that is unnecessary.
> 0 votes

---
Tags: unity, webgl
---


# Question
Title: How can spotlights be implemented with a perspective projection?
I was reading Shadow Mapping with Directional Lights and noted that spotlights are implemented by rendering with the perspective projection, stating that the spotlight worked just like the camera. However, I don't see how this could be, as the cross section of a spotlight is a circle, but cross section of the perspective projection frustum is really a rectangle, so wont there either be extra information or too little? Or am I missing something. If you have any questions please feel free to ask I will try to respond as quickly as possible. Thanks a lot for your time!

# Answer
Yes, there can be extra shadow information outside the actual cone of light. Since ultimately you mask this area anyway with an angular falloff formula or light cookie, it doesn't impact that final image observed by the player's camera.

If you want to prevent rendering of scene geometry in these areas of the shadow map, you can first render a circular cut-out of the appropriate radius positioned at the near plane. That way any fragments of scene geometry that fall in the corners of the square will fail the early depth test and get skipped.
> 0 votes

---
Tags: 3d, mathematics, shadows, projection
---


# Question
Title: Multiplayer first person camera gone after restart
I have a main camera in a multiplayer scene and when a player joins he owns that camera so there is always a single camera.

Now when i click "disconnect" and connect again, there is no camera left in the scene because it gets "destroyed" with the players prefab.

How can i catch the "client disconnect" on client side to clear the cameras parent so that it still remains in the scene?

# Answer
Instead of having the player own the camera you can make the player own a camera position and have the main camera follow its position and orientation. Then when the player is destroyed only his cameraPosition is destroyed and the main camera can then fall back to another position and orientation.
> 0 votes

---
Tags: unity
---


# Question
Title: How to apply code of certain script to another?
I have a code in my "OnCollider" script to respawn whenever the player dies and has taken an object containing tag 'Respawn'. 1st script: OnCollider ;

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

    public class OnColllider : MonoBehaviour {
        public GameObject Doorfinder;
        public GameObject Door2;
        public Transform Camera;
        public Transform target;
        public GameObject Coin;
        public bool collided;
        public GameObject Playee;
        public GameObject currentRespawn;
        void Start(){
            Door2 = GameObject.Find ("Door0.2");
            Playee = GameObject.Find ("Player");
        }
        public void OnCollisionEnter2D(Collision2D collision){

            if (collision.gameObject.name ==

"scroll") {
            Destroy (collision.gameObject);
            Destroy (Doorfinder);
        }
        if (collision.gameObject.tag == "Fire" ) {
            Playee.SetActive (false);
        }

        if (collision.gameObject.name == "PathFinder") {
            Destroy (collision.gameObject);
            Destroy (Door2);
        }

        if (collision.gameObject.tag == "Coin") {
            Destroy (collision.gameObject);
        }

        if (collision.gameObject.tag == "subVillains") {
            Playee.SetActive (false);
        }
        if (collision.gameObject.tag == "Bramble") {

            Playee.SetActive (false);
        }

        Respawnable (collision);
    }
    public void Respawnable (Collision2D collision){
        if (collision.gameObject.tag == "Respawn") {
            collided = true;
            collision.gameObject.SetActive (false);

        }
        if (collided = true && Playee.activeInHierarchy == false) {
            transform.position = currentRespawn.transform.position;
            Playee.SetActive (true);
            collided = false;
        }
        if (currentRespawn.activeInHierarchy == false && collision.gameObject.tag == "Respawn") {
            currentRespawn = collision.gameObject;

        }

    }

}

```

2nd Script: Enemy;

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

public class MaxyMory: MonoBehaviour {
    public Vector2 origin;
    public float distance;
    public int layerMask;
    public float sider;
    public Vector2 secondorigin;
    public float bringer;
    public float lesngther;
    public GameObject destroy;
    public Vector2 origination;
    public float middle;
    public float lengther;
    // Use this for initialization
    void Start () {
        origin = new Vector2 (transform.position.x + bringer, transform.position.y + sider);
        origination = new Vector2 (transform.position.x + bringer, transform.position.y + middle);
        secondorigin = new Vector2 (transform.position.x + bringer, transform.position.y + lengther);
    }

    // Update is called once per frame
    public void Update(GameObject Playee){
        Debug.DrawRay (origin, Vector2.right*distance,  Color.red);
        Debug.DrawRay (secondorigin, Vector2.right * distance, Color.cyan);
        Debug.DrawRay (origination, Vector2.right * (distance + 30f), Color.gray);
        RaycastHit2D hit = Physics2D.Raycast (origin, Vector2.right, distance);
        RaycastHit2D anotherhit = Physics2D.Raycast (secondorigin, Vector2.right, distance);
        RaycastHit2D checker = Physics2D.Raycast (origination, Vector2.right, distance + 2f);
        if (hit.collider.tag == "Player" || anotherhit.collider.tag == "Player") {
            Playee.SetActive (false);
        }

    }

}

```

OnCollider is attached to the player while the enemy script is attached to the enemy itself.

# Answer
It looks to me like you might want something more like a Respawnable component that exposes a respawning method that other scripts can call when they want to kill/respawn the player avatar:

```
public class Respawnable : MonoBehaviour {

    public GameObject currentRespawnPoint;
    bool hasUnusedRespawnPoint;

    public bool TryRespawn() {
        if (hasUnusedRespawnPoint == false) {
            gameObject.SetActive(false);
            return false;
        }

        transform.position = currentRespawnPoint.transform.position;
        gameObject.SetActive(true);
        hasUnusedRespawnPoint = false;

        return true;
    }

    void OnCollisionEnter(Collision collision) {
        if (collision.gameObject.CompareTag("Respawn") == false)
            return;

        collision.gameObject.SetActive(false);
        hasUnusedRespawnPoint = true;

        // It's unclear whether you need this.
        // Generally, if the game object is disabled,
        // its collision methods won't even fire.
        // I've kept it to match your existing script.
        if(gameObject.activeInHierarchy == false)
            TryRespawn();

        currentRespawnPoint = collision.gameObject;
    }

}

```

Your enemy script can then invoke just the respawn logic when it needs to, by calling the public`TryRespawn` method directly :

```
var respawnable = playerObject.GetComponent<Respawnable>();
respawnable.TryRespawn();

```
> 0 votes

# Answer
The original answer is a good answer and works but to me it sounds like you just want to fully understand calling some logic in script2 from script1.

one way to handle that without one script being a 'singleton' or using 'static' is to simply just add the reference to the other script.

```
public class Script1 : MonoBehaviour
{
    //reference script2
    //make it public and add the script or set the reference with code in awake or start
   //in your case can even set it in the collision itself (not recommended).

    Script2 otherScript;

    void OnCollisionEnter2D(Collision2D collision)
    {
        /// Your stuff on script 1

        //call something you want handled in script2
        otherScript.OtherStuffOnScript2();
    }

}

public class Script2 : MonoBehaviour
{

    public void OtherStuffOnScript2()
    {
        //Script 2 stuff
    }
}

```

To better understand doing the same as above with a parameter or even multiple parameters ie.(GameObject go, Vector3 position, ect..)

```
public class Script1 : MonoBehaviour
{
    //reference script2
    //make it public and add the script or set the reference with code in awake or start.
    Script2 otherScript;

    void OnCollisionEnter2D(Collision2D collision)
    {
        /// Your stuff on script 1

        //call something you want handled in script2
        //passing the gameobject to script 2 with the parameter.
        otherScript.OtherStuffOnScript2(gameObject);
    }

}

public class Script2 : MonoBehaviour
{

    public void OtherStuffOnScript2(GameObject go)
    {
        //Script 2 stuff
        //go is the GameObject you sent with call from script1
    }
}

```
> 0 votes

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


# Question
Title: Why aren't my walls moving, and how do I make them move?
Here is my all GameControl script:

```
static GameObject HexGrey;
static GameObject HexPurple;
static GameObject HexBlue;
static GameObject HexGreen;
static GameObject HexTurq;
static GameObject HexRed;
static GameObject HexYellow;

Vector3 GreyVec;
Vector3 PurpleVec;
Vector3 BlueVec;
Vector3 GreenVec;
Vector3 TurqVec;
Vector3 RedVec;
Vector3 YellowVec;
Vector3 GreyVecOrigin;
Vector3 PurpleVecOrigin;
Vector3 BlueVecOrigin;
Vector3 GreenVecOrigin;
Vector3 TurqVecOrigin;
Vector3 RedVecOrigin;
Vector3 YellowVecOrigin;

public Button button;                       // DeathCanvas
public Text text;

public Material wallMat;

float t;

public static int a = 0;
public static int b = 0;
float wallMoveT = 0.7f;

private IEnumerator coroutine;

void Start()
{
    button.gameObject.SetActive(false);         // DeathCanvas
    text.enabled = false;
    coroutine = enumerator(3);
    StartCoroutine(coroutine);
    ObjectAssignment();
    VecAssignment();
}

void Update()
{
    WallControl();
}

void ObjectAssignment()
{
    HexGrey = GameObject.FindGameObjectWithTag("HexGrey");
    HexPurple = GameObject.FindGameObjectWithTag("HexPurple");
    HexBlue = GameObject.FindGameObjectWithTag("HexBlue");
    HexGreen = GameObject.FindGameObjectWithTag("HexGreen");
    HexTurq = GameObject.FindGameObjectWithTag("HexLBlue");
    HexRed = GameObject.FindGameObjectWithTag("HexRed");
    HexYellow = GameObject.FindGameObjectWithTag("HexYellow");
}

void VecAssignment()
{
    t += Time.deltaTime / wallMoveT;

    GreyVecOrigin = new Vector3(HexGrey.transform.position.x, 0, HexGrey.transform.position.z);
    PurpleVecOrigin = new Vector3(HexPurple.transform.position.x, 0, HexPurple.transform.position.z);
    BlueVecOrigin = new Vector3(HexBlue.transform.position.x, 0, HexBlue.transform.position.z);
    GreenVecOrigin = new Vector3(HexGreen.transform.position.x, 0, HexGreen.transform.position.z);
    TurqVecOrigin = new Vector3(HexTurq.transform.position.x, 0, HexTurq.transform.position.z);
    RedVecOrigin = new Vector3(HexRed.transform.position.x, 0, HexRed.transform.position.z);
    YellowVecOrigin = new Vector3(HexYellow.transform.position.x, 0, HexYellow.transform.position.z);

    GreyVec = new Vector3(HexGrey.transform.position.x, -4, HexGrey.transform.position.z);
    PurpleVec = new Vector3(HexPurple.transform.position.x, -4, HexPurple.transform.position.z);
    BlueVec = new Vector3(HexBlue.transform.position.x, -4, HexBlue.transform.position.z);
    GreenVec = new Vector3(HexGreen.transform.position.x, -4, HexGreen.transform.position.z);
    TurqVec = new Vector3(HexTurq.transform.position.x, -4, HexTurq.transform.position.z);
    RedVec = new Vector3(HexRed.transform.position.x, -4, HexRed.transform.position.z);
    YellowVec = new Vector3(HexYellow.transform.position.x, -4, HexYellow.transform.position.z);
}

void WallControl()
{
    if (a == 1)
    {
        wallMat.color = Color.grey;
        if (b == 1)
        {
            HexPurple.transform.position = Vector3.Lerp((HexPurple.transform.position), (PurpleVec), t);
            HexBlue.transform.position = Vector3.Lerp((HexBlue.transform.position), (BlueVec), t);
            HexGreen.transform.position = Vector3.Lerp((HexGreen.transform.position), (GreenVec), t);
            HexTurq.transform.position = Vector3.Lerp((HexTurq.transform.position), (TurqVec), t);
            HexRed.transform.position = Vector3.Lerp((HexRed.transform.position), (RedVec), t);
            HexYellow.transform.position = Vector3.Lerp((HexYellow.transform.position), (YellowVec), t);
            Debug.Log("GREY");
        }
    }
    else if (a == 2)
    {
        wallMat.color = Color.magenta;
        if (b == 2)
        {
            HexGrey.transform.position = Vector3.Lerp((HexGrey.transform.position), (GreyVec), t);
            HexBlue.transform.position = Vector3.Lerp((HexBlue.transform.position), (BlueVec), t);
            HexGreen.transform.position = Vector3.Lerp((HexGreen.transform.position), (GreenVec), t);
            HexTurq.transform.position = Vector3.Lerp((HexTurq.transform.position), (TurqVec), t);
            HexRed.transform.position = Vector3.Lerp((HexRed.transform.position), (RedVec), t);
            HexYellow.transform.position = Vector3.Lerp((HexYellow.transform.position), (YellowVec), t);
            Debug.Log("MAGENTA");
        }
    }
    else if (a == 3)
    {
        wallMat.color = Color.blue;
        if (b == 3)
        {
            HexPurple.transform.position = Vector3.Lerp((HexPurple.transform.position), (PurpleVec), t);
            HexGrey.transform.position = Vector3.Lerp((HexGrey.transform.position), (GreyVec), t);
            HexGreen.transform.position = Vector3.Lerp((HexGreen.transform.position), (GreenVec), t);
            HexTurq.transform.position = Vector3.Lerp((HexTurq.transform.position), (TurqVec), t);
            HexRed.transform.position = Vector3.Lerp((HexRed.transform.position), (RedVec), t);
            HexYellow.transform.position = Vector3.Lerp((HexYellow.transform.position), (YellowVec), t);
            Debug.Log("BLUE");
        }
    }
    else if (a == 4)
    {
        wallMat.color = Color.green;
        if (b == 4)
        {
            HexPurple.transform.position = Vector3.Lerp((HexPurple.transform.position), (PurpleVec), t);
            HexBlue.transform.position = Vector3.Lerp((HexBlue.transform.position), (BlueVec), t);
            HexGrey.transform.position = Vector3.Lerp((HexGrey.transform.position), (GreyVec), t);
            HexTurq.transform.position = Vector3.Lerp((HexTurq.transform.position), (TurqVec), t);
            HexRed.transform.position = Vector3.Lerp((HexRed.transform.position), (RedVec), t);
            HexYellow.transform.position = Vector3.Lerp((HexYellow.transform.position), (YellowVec), t);
            Debug.Log("GREEN");
        }
    }
    else if (a == 5)
    {
        wallMat.color = Color.cyan;
        if (b == 5)
        {
            HexPurple.transform.position = Vector3.Lerp((HexPurple.transform.position), (PurpleVec), t);
            HexBlue.transform.position = Vector3.Lerp((HexBlue.transform.position), (BlueVec), t);
            HexGreen.transform.position = Vector3.Lerp((HexGreen.transform.position), (GreenVec), t);
            HexGrey.transform.position = Vector3.Lerp((HexGrey.transform.position), (GreyVec), t);
            HexRed.transform.position = Vector3.Lerp((HexRed.transform.position), (RedVec), t);
            HexYellow.transform.position = Vector3.Lerp((HexYellow.transform.position), (YellowVec), t);
            Debug.Log("CYAN");
        }
    }
    else if (a == 6)
    {
        wallMat.color = Color.red;
        if (b == 6)
        {
            HexPurple.transform.position = Vector3.Lerp((HexPurple.transform.position), (PurpleVec), t);
            HexBlue.transform.position = Vector3.Lerp((HexBlue.transform.position), (BlueVec), t);
            HexGreen.transform.position = Vector3.Lerp((HexGreen.transform.position), (GreenVec), t);
            HexTurq.transform.position = Vector3.Lerp((HexTurq.transform.position), (TurqVec), t);
            HexGrey.transform.position = Vector3.Lerp((HexGrey.transform.position), (GreyVec), t);
            HexYellow.transform.position = Vector3.Lerp((HexYellow.transform.position), (YellowVec), t);
            Debug.Log("RED");
        }
    }
    else if (a == 7)
    {
        wallMat.color = Color.yellow;
        if (b == 7)
        {
            HexPurple.transform.position = Vector3.Lerp((HexPurple.transform.position), (PurpleVec), t);
            HexBlue.transform.position = Vector3.Lerp((HexBlue.transform.position), (BlueVec), t);
            HexGreen.transform.position = Vector3.Lerp((HexGreen.transform.position), (GreenVec), t);
            HexTurq.transform.position = Vector3.Lerp((HexTurq.transform.position), (TurqVec), t);
            HexRed.transform.position = Vector3.Lerp((HexRed.transform.position), (RedVec), t);
            HexGrey.transform.position = Vector3.Lerp((HexGrey.transform.position), (GreyVec), t);
            Debug.Log("YELLOW");
        }
    }
    else if (a == 8)
    {
        wallMat.color = Color.black;
        HexGrey.transform.position = Vector3.Lerp((HexGrey.transform.position), (GreyVecOrigin), t);
        HexPurple.transform.position = Vector3.Lerp((HexPurple.transform.position), (PurpleVecOrigin), t);
        HexBlue.transform.position = Vector3.Lerp((HexBlue.transform.position), (BlueVecOrigin), t);
        HexGreen.transform.position = Vector3.Lerp((HexGreen.transform.position), (GreenVecOrigin), t);
        HexTurq.transform.position = Vector3.Lerp((HexTurq.transform.position), (TurqVecOrigin), t);
        HexRed.transform.position = Vector3.Lerp((HexRed.transform.position), (RedVecOrigin), t);
        HexYellow.transform.position = Vector3.Lerp((HexYellow.transform.position), (YellowVecOrigin), t);
        Debug.Log("BLACK");
    }
    else
    {
        wallMat.color = Color.black;
    }
}

private IEnumerator enumerator(int waitTime)
{
    while (true)
    {
        yield return new WaitForSeconds(waitTime);
        a = Random.Range(1, 8);
        yield return new WaitForSeconds(1.5f);
        b = a;
        yield return new WaitForSeconds(waitTime);
        a = 8;
        b = 0;
    }
}

public void GoToMainMenu()
{
    SceneManager.LoadScene("MainMenu");
}

```

I know using integers named "a" and "b" looks like complicated, but infact it's not. First a pick random int inRange 1-8 (and color of the walls changes), then waits for 1.5f seconds and i say "b = a" (hexs' transform.position changes).

I've checked the a and b integers but the values are right.

What I want: first change the color of the walls randomly. Then wait 1.5f seconds and transform the objects according to walls' color. And loop this cycle.

Problem is: Color of the walls changes but objects positions never change.

# Answer
> 1 votes
It looks like you forgot to update your `t` variable.

From what I understand of your code, you'll want to reset it in your `IEnumerator enumerator(int waitTime)` function:

```
private IEnumerator enumerator(int waitTime)
{
    while (true)
    {
        yield return new WaitForSeconds(waitTime);
        a = Random.Range(1, 8);
        yield return new WaitForSeconds(1.5f);
        b = a;
        t = 0;  // <--- reset t timer here
        t += Time.deltaTime / wallMoveT;  // <--- update it here
        yield return new WaitForSeconds(waitTime);
        ...

```

---

There are still two issues I see with this code, and I'll tackle them separately.

---

Once your walls will be moving, you'll most likely see that they're not moving as you expect, linearly: they'll be moving with a "curved" speed. This is because you use the current location as one of the parameters for your lerp.

You are very close to get this working: you have kept your "original" and you "target" positions separately, you just need to use these for the lerp instead of using the current object position:

```
if (b == 1)
{
    HexPurple.transform.position = Vector3.Lerp(HexPurpleOrigin, PurpleVec, t);
    HexBlue.transform.position = Vector3.Lerp(HexBlueOrigin, BlueVec, t);
    HexGreen.transform.position = Vector3.Lerp(HexGreenOrigin, GreenVec, t);

```

---

All of this code repetition seems a bit error prone. I'm not too familiar with c# but I would try to build `array`s of things based on `enum`s and act upon them.

This is all untested code, but that would give you an idea:

```
// First, you need your enum:
enum HexColors {
  Grey,
  Purple,
  Blue,
  Green,
  Turq,
  Red,
  Yellow,
  Count
};

static GameObject[] gameObjects = new GameObject[(int)HexColors.Count];
Vector3[] vec = new Vector3[(int)HexColors.Count];
Vector3[] vecOrigin = new Vector3[(int)HexColors.Count];

public Button button;                       // DeathCanvas
public Text text;

public Material wallMat;

float t;

public static int a = 0;
public static int b = 0;
float wallMoveT = 0.7f;

private IEnumerator coroutine;

void Start()
{
    button.gameObject.SetActive(false);         // DeathCanvas
    text.enabled = false;
    coroutine = enumerator(3);
    StartCoroutine(coroutine);
    ObjectAssignment();
    VecAssignment();
}

void Update()
{
    WallControl();
}

void ObjectAssignment()
{
    gameObjects[(int)HexColors.Grey  ] = GameObject.FindGameObjectWithTag("HexGrey");
    gameObjects[(int)HexColors.Purple] = GameObject.FindGameObjectWithTag("HexPurple");
    gameObjects[(int)HexColors.Blue  ] = GameObject.FindGameObjectWithTag("HexBlue");
    gameObjects[(int)HexColors.Green ] = GameObject.FindGameObjectWithTag("HexGreen");
    gameObjects[(int)HexColors.Turq  ] = GameObject.FindGameObjectWithTag("HexLBlue");
    gameObjects[(int)HexColors.Red   ] = GameObject.FindGameObjectWithTag("HexRed");
    gameObjects[(int)HexColors.Yellow] = GameObject.FindGameObjectWithTag("HexYellow");
}

void VecAssignment()
{
    for (int i = 0; i < (int)HexColors.Count; i++)
    {
        vecOrigin[i] = new Vector3( gameObjects[i].transform.position.x,  0, gameObjects[i].transform.position.z);
        vec      [i] = new Vector3( gameObjects[i].transform.position.x, -4, gameObjects[i].transform.position.z);
    }
}

void WallControl()
{
    if (a == b)
    {
        for (int i = 0; i < (int)HexColors.Count; i++)
        {
            if (i+1 != a)
                gameObjects[i].transform.position = Vector3.Lerp((gameObjects[i].transform.position), (vec[i]), t);
        }
    }

    if (a == 1)
    {
        wallMat.color = Color.grey;
        if (b == 1)
            Debug.Log("GREY");
    }
    else if (a == 2)
    {
        wallMat.color = Color.magenta;
        if (b == 2)
            Debug.Log("MAGENTA");
    }
    else if (a == 3)
    {
        wallMat.color = Color.blue;
        if (b == 3)
            Debug.Log("BLUE");
    }
    else if (a == 4)
    {
        wallMat.color = Color.green;
        if (b == 4)
            Debug.Log("GREEN");
    }
    else if (a == 5)
    {
        wallMat.color = Color.cyan;
        if (b == 5)
            Debug.Log("CYAN");
    }
    else if (a == 6)
    {
        wallMat.color = Color.red;
        if (b == 6)
            Debug.Log("RED");
    }
    else if (a == 7)
    {
        wallMat.color = Color.yellow;
        if (b == 7)
            Debug.Log("YELLOW");
    }
    else if (a == 8)
    {
        wallMat.color = Color.black;
        for (int i = 0; i < (int)HexColors.Count; i++)
            gameObjects[i].transform.position = Vector3.Lerp((gameObjects[i].transform.position), (vecOrigin[i]), t);
        Debug.Log("BLACK");
    }
    else
    {
        wallMat.color = Color.black;
    }
}

private IEnumerator enumerator(int waitTime)
{
    while (true)
    {
        yield return new WaitForSeconds(waitTime);
        a = Random.Range(1, 8);
        yield return new WaitForSeconds(1.5f);
        b = a;
        yield return new WaitForSeconds(waitTime);
        a = 8;
        b = 0;
    }
}

public void GoToMainMenu()
{
    SceneManager.LoadScene("MainMenu");
}

```

Someone better with c# than I am could comment, but that's a basis. This would save you a lot of repeating code and make the code a bit easier to read and to understand.

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


# Question
Title: Are unity games as performant as Unreal's?
TLDR: I make both RPG and MMORPG, 3D, heavy games with big landscape. Both engines are very good, but which one produces games with more FPS assuming the quality was the same?

I've been using RPGmaker and Gamemaker a lot in the past.

Recently I've kept switching from UE4 to Unity and vice versa. I can't decide which one is better. Unity is more popular so its a huge + for unity.

However some people claim Unreal games are much faster because unreal codes in c++.

However, Unity now created something called DOTS thats supposed to be faster than c++

For example, this site says that Unity is better than ue4 especially for rpg, which is one of my fav genres

What are your thoughts? I need to know this to not spend months and years in wrong engine.

# Answer
Both Unity and Unreal are capable of producing AAA quality games with high, stable framerates. How do we know? Because both have been used to make AAA quality games with high, stable framerates. This means that whatever performance differences there are are unlikely to form a sensible basis for deciding between engines, and remember that the time available to optimise performance is about as important for final performance as any underlying difference in the engine used.

That said, if you really, *really* care, Unreal gives you the source and Unity doesn't which means that you are able to boost the performance more in Unreal than in Unity because only one of them lets you tune the underlying engine to your specific game.
> 2 votes

---
Tags: unity, unreal-4, unreal
---


title: Limit Color Pallete Using Shader

text:
# Question
Title: Limit Color Pallete Using Shader
Basically, what I want to do is take a primary input image texture (which is a render texture in-game) and a secondary pallete texture (contains X number of colors, and is X by 1 pixels in size). What I want to do is replace all of the pixels in the image with the most similar color in the color pallete texture. I made a stab at producing the effect, but at the moment, it only seems to return the first color in the pallete. Below is my (nonfunctional) version. I'm new to shaders, so sorry for the potentially very sloppy/basic shader code.

```
Shader "Custom/Limiter" {
Properties
{
    _MainTex ("Texture", 2D) = "white" {}
    _PalTex ("Pallete", 2D) = "white" {}
}
SubShader
{
    // No culling or depth
    Cull Off ZWrite Off ZTest Always

    Pass
    {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag

        #include "UnityCG.cginc"

        struct appdata
        {
            float4 vertex : POSITION;
            float2 uv : TEXCOORD0;
        };

        struct v2f
        {
            float2 uv : TEXCOORD0;
            float4 vertex : SV_POSITION;
        };

        v2f vert (appdata v)
        {
            v2f o;
            o.vertex = UnityObjectToClipPos(v.vertex);
            o.uv = v.uv;
            return o;
        }

        sampler2D _MainTex;
        sampler2D _PalTex;

        fixed4 frag (v2f i) : SV_Target
        {
            float4 baseCol = tex2D(_MainTex, i.uv);
            float4 palCol = tex2D(_PalTex, 0);
            float palDiff = 1000;

            for (int p = 0; p < 37; p++) {
                float baseColDiff = abs(tex2D(_PalTex, p).r - baseCol.r) + abs(tex2D(_PalTex, p).g - baseCol.g) + abs(tex2D(_PalTex, p).b - baseCol.b);
                palDiff = min(palDiff, baseColDiff);
                palCol = (abs(palDiff - baseColDiff) < 0.001) ? tex2D(_PalTex, p) : palCol;
            }

            return palCol;
        }
        ENDCG
    }
}
}

```

Any help would be greatly appreciated! I feel like it's a relatively simple problem to solve, but I couldn't find any examples of existing shaders like it, or any resources describing it.

Edit: This shader works... sort of. It has been picking the nearest color, but it has only been picking two yellow colors out of the pallete. I tried removing those colors, and it then chose to use only an orange. I don't know if this will help anyone, but I thought it was at least mildly interesting.

# Answer
> 0 votes
What I would do is loop through each palette color, looking for the closest one to the base color. Something like:

```
float4 bestColor = float4(0, 0, 0, 0);
float3 bestDiff = float3(1000, 1000, 1000);
for (float i = 0; i < X /*number of colors in palette*/; ++i) {
    float4 palCol = tex2D(_PalText, float2(i, 0));
    float3 diff = abs(baseCol.rgb, palCol.rgb);
    if (length(diff) < length(bestDiff)) {
        bestDiff = diff;
        bestColor = palCol;
    }
}
return bestColor;

```

(Apologies for any typos)

# Answer
> 0 votes
Ok, so I ended up getting the answer anyway. Here's a GitHub repository that does the effect by using lists of colors. Not sure why it works when this shader doesn't, but it works. https://github.com/oxysoft/RetroSuite3D

And here's the shader in that repository doing the job. Don't directly copy-paste it, as it has to use a script to assign the colors to it. https://github.com/oxysoft/RetroSuite3D/blob/master/Assets/Shaders/Custom/RetroPixelMax.shader

---
Tags: unity, shaders, textures
---


title: "Overloading" GameObject?

text:
# Question
Title: "Overloading" GameObject?
I would like to show weapons and health items in an inventory grid.

The item can be rotated in the grid, and it occupies a certain region in the grid.

Currently I store this information (where the item is located, if it is rotated, etc.) in an additional array. However, this is not elegant and error prone.

I would therefore like to ask if it is possible to somehow store this additional information directly in the weapon or health GameObject.

Ideally I would like to be able to do something like this:

```
Pistol.GridProps.Rotation = 90
Pistol.GridProps.Row = 5
Pistol.GridProps.Col = 3

```

Is it possible to add something like "GridProps" to all my game objects?

Thank you!

# Answer
You can use `GameObject.AddComponent` to add a script with any variables you want.
> 1 votes

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


# Question
Title: Is unzipping SDL2 necessary to set it up on a Visual Studio project?
Some tutorials, such as the one on WikiHow.com, suggest to download SDL and use it without unzipping it. The instructions there read as such:

> Download the version for Visual C++. It is SDL2-devel-2.0.9-VC.zip (Visual C++ 32/64-bit).
>
> 1. In downloading window you have the zip folder SDL2-devel-2.0.9-VC.zip, and inside the folder SDL2-2.0.9. Click it \> right click \> select Copy.
> 2. Navigate to C:\SDL. Inside SDL, right click \> select Paste. Click on name SDL2-2.0.9 and rename to SDL2. Now in folder SDL you have folder SDL2.

I'm wondering if it would be better to unzip the library instead, something that would be instructed like this instead:

> Download the version for Visual C++. It is SDL2-devel-2.0.9-VC.zip (Visual C++ 32/64-bit).
>
> 1. In downloading window you have the zip folder SDL2-devel-2.0.9-VC.zip, right-click on the zip file and select Extract everything...
> 2. In the window that opened up, type C:\SDL, then click Extract.

# Answer
> 2 votes
It looks like Windows is playing tricks on you.

With the first set of instructions, you *are* actually unzipping the files. For a while now (I think it started with Windows XP, Windows users no longer need to use a third party tool to extract zipped files: Windows has the tool built in the Windows/File Explorer, and it allows to seamlessly browse the archive and extract files from it: if you double-click on this zip file, Windows *opens* it for you and lets you *browse* through it. **If you *Copy* something from within, and *Paste* it somewhere else (e.g. in the `C:\SDL` directory), Windows will extract/decompress the content *at that moment***. This is what happens with the first set of instructions, making the set of proposed instructions not required.

So yes, it is necessary to unzip the library, but the way you do it does not matter, as long as the files are where you tell Visual Studio to expect them. Both these methods accomplish the same thing:

* right clicking the archive \> selecting *Extract all*
* double-clicking the archive \> copying its contents \> pasting the contents outside the archive

---

On a side note, Visual Studio and its linker and compiler need access to actual files to compile, link and run projects. They are not made to open `.zip` archives and look for `.h`, `.lib` and `.dll` files within. The order of the locations where the compiler looks for things is very clear when reading the documentation, and in no case there is mention of a zip file.

---
Tags: c++, sdl2, visual-studio
---


# Question
Title: Unity - Set/Manipulate Render-Buffer for "Render Overlay Effects"
**Note**

This is more of a question on how/where to do furhter research into this topic becasue I do not know anything about it yet. If anyone has answers on how to accomplish this goal, I'd very much welcome it, too!

**Background**

I've been working on my own game (**2D Arcade**, **Android**) for quite a while and I'm currently adding "Sequences" which take controll of modular gameplay functionality and add some special behaviour as well as extra "challenges". To make the transitions more interesting - especcially transitions to bossfights and/or dramatic scenes

**What I want to do**

I want to perform some sort of render overlay: basically manipulating the render buffer to either

* Draw full colors (e.g. complete screen white PLUS fade out of white overlay)

and/or

* Manipulate - "mix" - all pixels colors with a specific color to achieve a color mix effect (as shown below, which is just some example)

I have no idea at all on how to do this. I could write a shader, but that would have to be applied to every single object in the scene (?). The white overlay effect could be done with a simple white sprite, but I'd find it more interesing to create an overlay effect which can accomplish tasks such as 'color mixing'

**Edit**

I'm currently looking into CommandBuffers which have a very sparse documentation on how to actually use them but they seem to be intended for things that are way more complicated than what I intend to do.

What I'd ideally imagine is a way to get the current render buffer as some sort of array, matrix or whatnot, containing information of each individual fragment (as some brief research turned up it's not actually pixels), copy it, make some operations on it and return it to the target renderer. Is there a way to do anything alike?

# Answer
Have you looked into `Camera.OnRenderImage()`? It lets you write a shader to do post-processing effects, which is what it sounds like you want.
> 0 votes

---
Tags: unity, 2d, rendering, graphic-effects
---


# Question
Title: Is it possible to customize the Scriptableobject inspector for Simple level data, without the use of PropertyDrawers?
I've invented an innovative, new game mechanic for Bricker Breaker Quest and want to create a quick prototype to recruit a game development team. After wasting a week researching the best way to easily represent the simple level data, I reluctantly started using Scriptableobjects. Each level is defined as a `List<Block>`, where :

```
public class Block : MonoBehaviour, IComparer<Block>
{
    public int x;
    public int y;

    public int lives = 0;
    private int pastLife = 0;

    private SpriteRenderer spriteRenderer;
    private TextMeshPro text;

    private void OnCollisionEnter2D(Collision2D collision)
    {
        lives--;

        if (lives > 0)
            UpdateVisualState();
        else
        {
            gameObject.SetActive(false);
        }
    }

    private void Awake()...

    public void AddLives(int life)...
}

```

How do I properly serialize the Block object so that I can enter the X, Y, and Lives integers directly in the Inspector? As a quick hack, I created a `List<Vector3Int>` instead of the Block List and use the Z input field to enter the lives. Seems like overkill to create a PropertyDrawer just to relabel one field.

Any other advice is appreciated.

# Answer
Do you need the Block class to be a MonoBehaviour? if not, then why not making it a class with the Serializable attribute? That way it will show on the inspector, because otherwise by making a list of MonoBehaviours you will only make object fields of that class on the inspector.

```
[System.Serializable]
public class Block : IComparer<Block>
{
    public int x;
    public int y;
    public int z;

    public int Compare<Block a, Block b>
    {
        /// Do whatever evaluation you want to make.
        return 0;
    }
}

```

And if you need it to be on either a MonoBehaviour or ScriptableObject, then just make a member of Block type:

```
public class Mono : MonoBehaviour
{
    public Block block;
}

// Or...

public class ScriptableClass : ScriptableObject
{
    public Block block;
}

```
> 2 votes

---
Tags: unity, c#, gui, data-structure, level-design
---


# Question
Title: Instantiated UI element references to the same object
I'm creating UI using a prefab and move it using a coroutine, the prefab has `transform.position` of `(0,0,0)`:

```
private List<GameObject> liveBoxes = new List<GameObject>();

void Update()
{
  PopDialogBoxFixedInterval();
}

// @todo debug only
void PopDialogBoxFixedInterval()
{
  float now = Time.time;
  if (now - lastTime > delay)
  {
    lastTime = now;
    PopDialogBox();
  }
}

void PopDialogBox()
{
  Vector3 pos = new Vector3(-horzExtent + .5f, -vertExtent, 0f);
  GameObject box = Instantiate(dialogBoxPrefab, pos, Quaternion.identity, canvas.transform);

  box.name = "Box_" + Time.time;
  liveBoxes.Add(box);

  for (int i = 0; i < liveBoxes.Count; ++i)
  {
    Debug.Log("Move " + liveBoxes[i].name + ", all: " + liveBoxes.Count);
    StartCoroutine(SmoothMoveDialogBox(liveBoxes[i]));
  }
}

```

The problem is the `box` always references to the first created object. As the below:

But in fact I have more than one boxes (adding "Box\_2" is not shown in log):

---

The prefab itself is a panel with text and image:

# Answer
The problem is caused by canvas render mode which I used "screenspace - camera", so it doesn't move the elements under it.

The default configuration is "screenspace - overlap" and won't cause any trouble. This is not an optimal answer since I don't understand why. But it solved the problem I had.
> 0 votes

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


# Question
Title: OnInspectorGUI Custom properties are not displayed in the right order
I basically made a lot of research and wasn´t able to find any solution.
So my **problem**: I´ve made some variables disappear/appear depending on an enum with a custom editor script. But if they appear they do not appear at the position where the normal editor variables would appear

```
override public void OnInspectorGUI()
{
    base.OnInspectorGUI();
    GunCard myScript = target as GunCard;

    EditorGUI.indentLevel++;

    switch (myScript.aimingControlType)
    {
        case AimingControlType.Manual:
            myScript.hasAimAssistance = EditorGUILayout.Toggle("Has aim assistance", myScript.hasAimAssistance);
            break;
        case AimingControlType.AutoTargeting:
            myScript.targetPreference = (TargetTypes)EditorGUILayout.EnumPopup("Target preference", myScript.targetPreference);
            myScript.requiresLineOfSight = EditorGUILayout.Toggle("Requires line of sight", myScript.requiresLineOfSight);
            myScript.requiresPossibleTargetOnScreen = EditorGUILayout.Toggle("requires possible target on screen", myScript.requiresPossibleTargetOnScreen);
            break;
    }
    EditorGUI.indentLevel--;
}

```

Here is where they appear:

That are the raw variables in the scriptable object

```
[Header("Aiming Controls")]
public AimingControlType aimingControlType;

[HideInInspector] public bool hasAimAssistance;
[HideInInspector] public bool requiresLineOfSight;                //TODO: implement -> requires 180
[HideInInspector] public bool requiresPossibleTargetOnScreen;     //TODO: implement -> requires 180
[HideInInspector] public TargetTypes targetPreference;
[HideInInspector] public bool isAutoShootWhenAimOnTarget;

```

I know I´m basically adding new variables to the inspector in my editor Script but it would be really useful to order them. **Is there a way to do that?**

P.S sorry for the funny typo in the picture :)

# Answer
In your `OnInspectorGUI` override, you call the base first which draws the default Inspector for the scriptable object first and the custom drawer code is actually after that, so it renders afterward.

One thing you can do is calling the base at the bottom of your override, but it means you have to add a custom editor field for you `AimingControlType` enumeration.

The code would be something like this:

```
override public void OnInspectorGUI()
{
    GunCard myScript = target as GunCard;

    EditorGUI.indentLevel++;
    myScript.aimingControlType = (AimingControlType )EditorGUILayout.EnumPopup("Aiming Control Type", myScript.aimingControlType);
    switch (myScript.aimingControlType)
    {
        case AimingControlType.Manual:
            myScript.hasAimAssistance = EditorGUILayout.Toggle("Has aim assistance", myScript.hasAimAssistance);
            break;
        case AimingControlType.AutoTargeting:
            myScript.targetPreference = (TargetTypes)EditorGUILayout.EnumPopup("Target preference", myScript.targetPreference);
            myScript.requiresLineOfSight = EditorGUILayout.Toggle("Requires line of sight", myScript.requiresLineOfSight);
            myScript.requiresPossibleTargetOnScreen = EditorGUILayout.Toggle("requires possible target on screen", myScript.requiresPossibleTargetOnScreen);
            break;
    }
    EditorGUI.indentLevel--;
    base.OnInspectorGUI();
}

```

As well as this change in your scriptable class.

```
[HideInInspector]
public AimingControlType aimingControlType;

[HideInInspector] public bool hasAimAssistance;
[HideInInspector] public bool requiresLineOfSight;                //TODO: implement -> requires 180
[HideInInspector] public bool requiresPossibleTargetOnScreen;     //TODO: implement -> requires 180
[HideInInspector] public TargetTypes targetPreference;
[HideInInspector] public bool isAutoShootWhenAimOnTarget;

```
> 0 votes

---
Tags: unity, editors
---


# Question
Title: How to activate an object only when it's within the camera view
I want to toggle an object's active state using the camera view:

* when the object leaves the view it deactivates
* when the object enters the camera's view it activates

I'm using this to control the activity of objects in a carousel like this

I did this with a coroutine, but in my project the fps is falling a lot because of the coroutine.

I've already used `OnBecameVisible` and `isVisible` but that's not it since they only work with a renderer.

```
    public void next() {
        StartCoroutine(On(waitnext));
    }

    IEnumerator On(float waitnext) {
        yield return new WaitForSeconds(waitnext);
        myArray[Selecao].SetActive(false);
        Selecao++;
        if(Selecao > myArray.Length - 1) {
            Selecao = 0;
        }
        yield return new WaitForSeconds(waitnext);
        myArray[Selecao].SetActive(true);
    }

    public void previous() {
        StartCoroutine(On2(waitprevious));
    }

    IEnumerator On2(float waitprevious) {
        yield return new WaitForSeconds(waitprevious);
        myArray[Selecao].SetActive(false);
        Selecao--;
        if(Selecao < 0) {
            Selecao = myArray.Length - 1;
        }
        yield return new WaitForSeconds(waitprevious);
        myArray[Selecao].SetActive(true);
    }

```

# Answer
> 0 votes
You can achieve this by adding colliders to your object and camera.

* preferably set the camera collider `isTrigger` on if the object is a rigid body.
* You can use tags, layers and game object name to filter which object you want to operate on.

Here is the code:

```
[RequireComponent(typeof(Collider))]
public class FrustomColliderDetector : MonoBehaviour
{
    //Gets called when it enters the camera collider
    private void OnCollisionEnter(Collision other) {
        if(other.gameObject.tag == "object-tag")
            other.gameObject.SetActive(true);
    }
    //Gets called when it leaves the camera collider
    private void OnCollisionExit(Collision other) {
        if(other.gameObject.tag == "object-tag")
        other.gameObject.SetActive(false);
    }

}

```

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


# Question
Title: Using non-copyrighted music for a paid game
I'm making a game. It will be sold and not free. Am I allowed to use non-copyrighted music in it?

# Answer
There is no such thing as "non-copyrighted" music. The moment someone creates a creative work, they have a copyright on it. What you could mean is:

* Music in the public domain due to age. But that would mean that the music is at least 70 years old, in some countries longer. Remember that melody, lyrics, arrangement and performance are all separately copyrighted. When someone plays Mozart on a piano, records it and puts it on the Internet, they might not have a copyright on the melody, but they have a copyright on this specific recording. That means not just the song needs to be old enough to be in the public domain, but also the performance. Any recordings taken over 70 years ago will likely be of insufficient quality for your game, so they are likely out of discussion.
* Music where the copyright holder(s) offer(s) the work under a free license. In that case check the license conditions of the piece in question to see if you are allowed to use it for your specific purpose and if you need to fulfill any conditions in order to do that. Some musicians release their work under a license which allows non-commercial use but not commercial use (with various definitions of "commercial"). Some might allow commercial use, but only if you credit them and/or do not edit their work. A few might allow you to do anything you want. But unless you actually see a license attached to the work, you have to assume that it's an "all rights reserved" work which must not be used without permission.

And by the way: Whether or not your derived work is paid, unpaid, for-profit or non-profit is largely irrelevant for what you can and can not do under the copyright laws of most countries.
> 12 votes

# Answer
I don't understand what you mean to say "non-copyrighted". Mayhap, you were trying to say royalty free music. If yes, then you should try to get royalty free music from CreativeCommons but keep in mind that you are using it for a commercial purpose that's why you would definitely need the CreativeCommons license before using this royalty free music.

On the other hand, you can search the web for royalty free music composers. However, you would again need a pro license with the permission of musician to use it for commercial purpose as royalty free music sites only offer music without having the license to students to use it for non-commercial purpose.
> 0 votes

---
Tags: copyright, music
---


# Question
Title: How would I rotate my billboards parallel to the camera view?
I'm trying to make my own space-sim in Godot and I'm stuck trying to get the visuals of the "starfield"-effect that is a staple of the genre. I'm using a Particle system with billboards that would be parallel to the camera's view (creating something like a cylinder).

I'm struggling with the math involved in the Vertex shader to transform those billboards. Can anyone help me?

# Answer
> 2 votes
You can just set the top 3x3 part of the model matrix to an identity matrix, since that part stores the rotation. One caveat is that it will override any scaling you do, so make sure to store that matrix separately and apply later.

---
Tags: mathematics, shaders, glsl, godot
---


# Question
Title: Why is searching through 3D neighbours given certain parameters in my pathfinding algorithm slow?
I'm currently new to the whole pathfinding thing (and coding in general thing), but I seem to have figured it out. It is 3D pathfinding, working on a 3d array of nodes. Everything works, but my problem is the way I check neighbours is very very slow. My game is a grid based, turn based game so while the pauses aren't the worst, it's still a bit noticable. My math skills are pretty much 0, so when coming up with this way to check neighbours based on the parameters/"rules" I want, I pretty much brute forced it. Here are the rules:

Everyone can move north,south,east,west If you can fly, in addition to NSEW, you can also move Up, Down, U+N, U+S, U+E U+W, D+N, D+S, D+E, D+W If you can fall, in addition to NSEW, you can also move D+N, D+S, D+E, D+W If you can climb ladders, you can also go U+N, U+S, U+E U+W, D+N, D+S, D+E, D+W at ladders.

I haven't put in the down portion of the ladders yet as this is already slowing down and I wanted to figure it out before I go ahead and do that.

Anyways, if anyone cares to take a look at this monster block of code and give me some advice/lend a hand I'd truly appreciate it \<3

```
    /// <summary>
    /// Return a list of neighbours to specified Node
    /// </summary>
    /// <param name="node">Node to check</param>

    /// <param name="canClimbLadders"></param>
    /// <param name="canFall"></param>
    /// <param name="canFly"></param>
    /// <returns></returns>
    private List<Node> ScanNeighbours(Node node, bool canClimbLadders, bool canFall, bool canFly)
    {
        List<Node> list = new List<Node>();

        #region NSEW regular checks

        //North
        Vector3 west = node.pos;
        west.x -= 1;
        Node westNode = gridManager.GetNodePos(west);
        if (westNode != null && westNode.isEmpty)
        {
            list.Add(westNode);
        }

        //South
        Vector3 east = node.pos;
        east.x += 1;
        Node eastNode = gridManager.GetNodePos(east);
        if (eastNode != null && eastNode.isEmpty)
        {
            list.Add(eastNode);
        }

        //East
        Vector3 north = node.pos;
        north.z += 1;
        Node northNode = gridManager.GetNodePos(north);
        if (northNode != null && northNode.isEmpty)
        {
            list.Add(northNode);
        }

        //West
        Vector3 south = node.pos;
        south.z -= 1;
        Node southNode = gridManager.GetNodePos(south);
        if (southNode != null && southNode.isEmpty)
        {
            list.Add(southNode);
        }

        #endregion

        //Flying can check up down and all directions except for diags
        if (canFly)
        {
            //Up
            Vector3 up = node.pos;
            up.y += 1;
            Node upNode = gridManager.GetNodePos(up);
            if (upNode != null && upNode.isEmpty)
            {
                list.Add(upNode);
            }

            //Down
            Vector3 down = node.pos;
            down.y -= 1;
            Node downNode = gridManager.GetNodePos(down);
            if (downNode != null && downNode.isEmpty)
            {
                list.Add(downNode);
            }

            //UpWest
            Vector3 upWest = node.pos;
            upWest.y += 1;
            upWest.x -= 1;
            Node upWestNode = gridManager.GetNodePos(upWest);
            if (upWestNode != null && upWestNode.isEmpty)
            {
                list.Add(upWestNode);
            }

            //UpEast
            Vector3 upEast = node.pos;
            upEast.y += 1;
            upEast.x += 1;
            Node upEastNode = gridManager.GetNodePos(upEast);
            if (upEastNode != null && upEastNode.isEmpty)
            {
                list.Add(upEastNode);
            }

            //UpNorth
            Vector3 upNorth = node.pos;
            upNorth.y += 1;
            upNorth.z += 1;
            Node upNorthNode = gridManager.GetNodePos(upNorth);
            if (upNorthNode != null && upNorthNode.isEmpty)
            {
                list.Add(upNorthNode);
            }

            //UpSouth
            Vector3 upSouth = node.pos;
            upSouth.y += 1;
            upSouth.z -= 1;
            Node upSouthNode = gridManager.GetNodePos(upSouth);
            if (upSouthNode != null && upSouthNode.isEmpty)
            {
                list.Add(upSouthNode);
            }
        }

        //Flying can jump down ledges as well so check
        if (canFall || canFly)
        {
            Vector3 downWest = node.pos;
            downWest.y -= 1;
            downWest.x -= 1;
            Node downWestNode = gridManager.GetNodePos(downWest);
            if (downWestNode != null && downWestNode.isEmpty)
            {
                list.Add(downWestNode);
            }

            Vector3 downEast = node.pos;
            downEast.y -= 1;
            downEast.x += 1;
            Node downEastNode = gridManager.GetNodePos(downEast);
            if (downEastNode != null && downEastNode.isEmpty)
            {
                list.Add(downEastNode);
            }

            Vector3 downNorth = node.pos;
            downNorth.y -= 1;
            downNorth.z += 1;
            Node downNorthNode = gridManager.GetNodePos(downNorth);
            if (downNorthNode != null && downNorthNode.isEmpty)
            {
                list.Add(downNorthNode);
            }

            Vector3 downSouth = node.pos;
            downSouth.y -= 1;
            downSouth.z -= 1;
            Node downSouthNode = gridManager.GetNodePos(downSouth);
            if (downSouthNode != null && downSouthNode.isEmpty)
            {
                list.Add(downSouthNode);
            }

        }

        //Flying doesnt need to climb ladders, so don't check again
        if (canClimbLadders && !canFly)
        {
            if (node.nodeType == NodeType.ladder)
            {
                switch(node.ladderDirection)
                {
                    case Direction.west:
                        Vector3 upWest = node.pos;
                        upWest.y += 1;
                        upWest.x -= 1;
                        Node upWestNode = gridManager.GetNodePos(upWest);
                        if (upWestNode != null && upWestNode.isEmpty)
                        {
                            list.Add(upWestNode);
                        }

                        break;

                    case Direction.east:
                        Vector3 upEast = node.pos;
                        upEast.y += 1;
                        upEast.x += 1;
                        Node upEastNode = gridManager.GetNodePos(upEast);
                        if (upEastNode != null && upEastNode.isEmpty)
                        {
                            list.Add(upEastNode);
                        }
                        break;

                    case Direction.north:
                        Vector3 upNorth = node.pos;
                        upNorth.y += 1;
                        upNorth.z += 1;
                        Node upNorthNode = gridManager.GetNodePos(upNorth);
                        if (upNorthNode != null && upNorthNode.isEmpty)
                        {
                            list.Add(upNorthNode);
                        }
                        break;

                    case Direction.south:
                        Vector3 upSouth = node.pos;
                        upSouth.y += 1;
                        upSouth.z -= 1;
                        Node upSouthNode = gridManager.GetNodePos(upSouth);
                        if (upSouthNode != null && upSouthNode.isEmpty)
                        {
                            list.Add(upSouthNode);
                        }
                        break;
                }
            }
        }
    }
    return list;

}

```

# Answer
> 1 votes
Two major improvements you can make here:

**1: Do not construct a new List object every time you scan for neighbours**

```
List<Node> list = new List<Node>();

```

This line needs to allocate memory to hold the list, and update the garbage collector to keep track of it so it can clean it up later. This is expensive.

Instead, either keep one list around as a member variable that you can re-use for every call (clearing it once you've used its benefits), or create one list at the start of the pathfinding query and pass it into the neighbour-finding subroutine as an argument.

**2: Check to see if you've already explored this cell before you add it to the list**

Basically, whenever you can exclude a cell from consideration, do so. You may already be doing this elsewhere in your code, and the exact logic depends on the type of search you're doing (eg. for Breadth-First Search if you've seen this cell already, it's safe to ignore it entirely, while for Djikstra's algorithm or A\* you might have discovered a shorter route to a cell in the open set, so it's only safe to ignore if it's in the closed set).

---

The other thing you can do to simplify your code is to add the concept of neighbourhoods. Add a few "constant" arrays to define your neighbourhoods up top:

```
static readonly Vector3Int[] groundNeighbours = new Vector3Int[]{
    new Vector3Int(1, 0, 0), new Vector3Int(0, 0, 1),
    new Vector3Int(-1, 0, 0), new Vector3Int(0, 0, -1)
}

static readonly Vector3Int[] groundNeighboursWithFall = new Vector3Int[]{
    new Vector3Int(1, 0, 0), new Vector3Int(0, 0, 1),
    new Vector3Int(-1, 0, 0), new Vector3Int(0, 0, -1),
    new Vector3Int(1, -1, 0), new Vector3Int(0, -1, 1),
    new Vector3Int(-1, -1, 0), new Vector3Int(0, -1, -1)
}

static readonly Vector3Int[] airNeighbours = new Vector3Int[]{
    new Vector3Int(1, 0, 0), new Vector3Int(0, 0, 1),
    new Vector3Int(-1, 0, 0), new Vector3Int(0, 0, -1),
    new Vector3Int(1, 1, 0), new Vector3Int(0, 1, 1),
    new Vector3Int(-1, 1, 0), new Vector3Int(0, 1, -1),
    new Vector3Int(1, -1, 0), new Vector3Int(0, -1, 1),
    new Vector3Int(-1, -1, 0), new Vector3Int(0, -1, -1)
}

```

Then your giant collection of `if` statements can get much more concise - just select your neighbourhood then iterate over it:

```
Vector3Int[] neighbourhood = groundNeighbours;

if(canFly)
    neighbourhood = airNeighbours;
else if (canFall)
    neighbourhood = groundNeighboursWithFall;

foreach(var offset in neighbourhood) {
    var site = node.pos + offset;
    var neighbour = gridManager.GetNodePos(site);
    if(neighbour != null && neighbour.isEmpty)
        list.Add(neighbour);
}

```

It's up to you whether you want to handle each directional ladder case as another neighbourhood, or just cover ladders as a special-case addition at the end.

Here we're spending a little extra on the additions, since we're adding a vector instead of a single component (not sure if this gets vectorized under the hood on some platforms - that would certainly be nice!), but since we're running the same code over and over again in a tight loop, the instruction cache and branch predictor may be able to do a little better for us. So, you might or might not see a performance difference from this code change, but at the very least, it's a lot fewer lines to maintain!

# Answer
> 0 votes
You are working on a grid, which means that it should be easy to achieve fast path finding.

With A\*, it is important to get O(1) tests for checking if a node is in CLOSED or OPEN set.

You do *not* want to iterate these OPEN and CLOSED sets to see if it contains an entry.

Instead, you store OPEN/CLOSED bits on the grid itself. That way, the test and also moving a node in or out of a set is then a simple O(1) operation.

Since you indicated that scanning for neighbours is your bottleneck, and not the testing of the sets, I will assume you already have this covered.

Now on to scanning neighbours:

It would help if you precompute the neighbours for each grid node. That way, you don't have to scan for them on the fly while doing the A\* search.

I would also drop the use of dynamic data structures for storing neighbours. You already know the limit of how many neighbours a node can have. Say 20, then just store a fixed sized C array with 20 slots, and a counter in each of your grid node. That way you have very fast access to all your neighbours. A dynamic C++ list just gets in the way: it is slower, and I doubt it is much smaller that a statically sized (for worst case) C array.

---
Tags: c#, path-finding
---


# Question
Title: Is it possible to apply a texture to a 2D-sprite in unity 2-d?
I want to take an (animated) 2-d sprite and apply a texture to it. Basically, I want every non-transparent pixel to be covered by the texture (color is disregarded). I understand I can probably accomplish this using masks but I am worried that may not be the most performant solution. I know you can put textures onto 3-d models, so I was wondering if there was a similar process for 2d sprites. Below I have a graphic demonstrating what I want.

**What I have tried so far**

I see there is an option to add a material to a sprite, so I tried creating various materials.

**1. Default material**

When I tried applying this material to my sprite, the sprite disappeared entirely. I suspect because this default material type only works on 3D objects

**2. Sprite Material**

I figured sprites probably expect sprite materials, so I tried creating one. However, there does not appear to be anywhere to upload an image to use as a texture. This appears to only be useful for adding tints to sprites.

# Answer
> 6 votes
You need to create a custom shader. The following examples are made in Unity's node based shader creation tool called Shader Graph.

You need to multiply the alpha output of your character texture (you need only to where it is) with your desired material. If you'd like to understand the operations with texture this site cover some material which is applicable in Unity too.
.

> However, there does not appear to be anywhere to upload an image to use as a texture. This appears to only be useful for adding tints to sprites.

You can have properties in the shader and exposed to the inspector and edit the via script(s). In ShaderGraph you can convert variables to properties, which you can see in the "Blackboard" and assign default values as well as expose them to the editor.
TL;DR
I decided to give a basic example of the shader, created in the Shader Graph tool created by Unity.
The source project is the official ShaderGraph Example Library published by Unity Technologies on their Github repository. The sprite I applied the shader on is the "ELLEN\_RUN\_NoGun\_01\_5x5\_0" asset. The grass texture sample is a random seamless texture found on google (I don't own any rights for it).

The properties on the Blackboard and wich can be controlled over a C# script are:

1. The target sprite (collection) from the official assets provided with the project (size: 1975x2260) .
2. The overlay texture (your custom material) (size: (1975/(number of "Ellens" we have on the X axis)\*(2260/number of "Ellens" we have on the Y axis)
3. A custom Vector2 "Tiling", which holds the information how many times the texture should be repeated on the corresponding (x and y) axis as we don't want the texture to stretch. (Assuming you'd like to use the same texture on every animated part.) The Blackboard should look like this:
After we imported these assets it's time to created the graph. First we need to sample both sprites (passed in as properties). To our custom material we add the tiling and offset we think it is the best. Then we multiply it with the alpha of our character (we only need the pixels we can see) and put the result into the Albedo channel of the PBR Master Node.
We leave the rest of the values on their defaults (\*change the "Surface" property in the PBR settings to Opaque) except the Alpha which is going to be "0", because we don't want to see any pixel that is clipped, if the alpha is "1", every "clipped" pixel is just black.
The Aplha clip treshold gets the inversed "pixels" of the aplha value, because we'd like to define the area the should be clipped (every pixel with the value of 1 or below should be cliped, but with an alpha value of 0, we tell that anyhing with that value shoud not be clipped).
Here is the graph:
The generated code is a bit too long to post it here (123659 lines according to VS Code), but here is the final result of the game view:

# Answer
> 0 votes
Before I even saw S4NNY1's updated answer (which seems to work perfectly!) I was able to create my own shader code by modifying the default sprite shader code (I followed this youtube video to figure out what to do).

First I looked up the default shader code (couldn't find it in my unity project, so I just googled it)

I added a '\_SubTex' property to access the second texture object

```
Properties
{
    [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    _SubTex ("Sub Texture", 2D) = "white" {} //  This is the new property
    _Color ("Tint", Color) = (1,1,1,1)
    [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
}

```

Then I modified the SampleSpriteTexture function to basically overlay the second texture on top of the first, using the lerp function.

```
        fixed4 SampleSpriteTexture (float2 uv)
        {
            fixed4 color1 = tex2D (_MainTex, uv);
            fixed4 color2 = tex2D (_SubTex, uv)

            fixed4 lerped_color = lerp(color1, color2, ceil(color1.a));

#if UNITY_TEXTURE_ALPHASPLIT_ALLOWED
            if (_AlphaSplitEnabled)
                lerped_color.a = tex2D (_AlphaTex, uv).r;
#endif //UNITY_TEXTURE_ALPHASPLIT_ALLOWED

            return lerped_color;
        }

```

And that's all it took!

---
Tags: unity, textures, sprites, graphics
---


# Question
Title: Null Reference Exception while getting Components
I'm trying to access my enemy and spawning values from two different classes into a class that is trying to change them both. Although when I do this I keep getting a Null Reference Exception error. The error is where `spawnManager` first gets called.

This is the code that is trying to get the two values. (And just to note I am trying to access these two values from my Welcome scene and these two values are in my Game scene but I do not know if this is affecting anything):

```
private EnemyAI enemy;
private SpawnManager spawnManager;

void Start() {
    spawnManager = GetComponent<SpawnManager>();
    enemy = GetComponent<EnemyAI>();
}

public void onEasy() {
    spawnManager.enemyShipWait = Random.Range(1f, 3f); <-- This line has the error
    spawnManager.randomPowerupWait = Random.Range(7f, 12f);
    enemy.speed = 2.75f;
}

```

These are the two pictures of my scenes: Game Scene:

Welcome Scene:

# Answer
# You can't reference across a scene boundary

If you have two scenes, nothing in scene 1 can reference things in scene 2 and vice versa. When you are in scene 1, scene 2 *does not exist* and vice versa. You cannot reference things that don't exist and the whole point of scenes is to separate out groups of things that don't need to exist at the same time.

(Or, as I used to say during the Flash Era: "Don't use scenes" but Flash's scene boundaries were much, *much* harder to pass any data across than Unity's: even the `global` keyword didn't work!)

* You can *load scenes (combine)* when you load a scene, but this just creates a virtual scene with the contents of both (as if you'd only ever had the one scene) and often not what you want (I have seen it used once and that was to separate out a global UI so that two different people could work on separate things without causing merge conflicts).
* You can call *`DontDestroyOnLoad()`* on an object which will cause it to persist across scene loading boundaries, but will cause issues if you return to the scene it originated from (you will get duplicates), but this still doesn't let you reference things that don't exist yet, you'll have to wait for the new scene to be loaded.
* You can put these values in a globally accessible location (e.g. a static class), but this may create issues as well, but may be what you are looking for in this situation. Remember to make both scripts look at the global values in order to perform their logic.
> 3 votes

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


# Question
Title: Is there an algorithm to move vertices along a planar mesh to give an area more vertex without destroying the shape too much?
Currently, I am playing around with a terrain technique called Vector-Field terrain as created and used for the game Halo Wars. I have successfully recreated the technique. However, I'm having difficulty with trying to figure out how to adjust the vertex density for the overhangs in the terrain.

Vector-Field Terrains still suffer similar problems to height map terrains. Where any time there is a vertex with a vertical scalar that is too different from it's neighbor will have UV stretching.

The way that Vector-Field terrains eliminates this, is that you can pull surrounding vertexes to give the area more resolution by giving it more density without changing the topology.

I can not for the life of me come up with a way to do this in a none destructive manner and in an automated way. I'd like to be able to keep the final shape as close as possible to the source. And only pull in as many vertexes as needed to correct this.

Does anyone know of any algorithms to solve this problem?

# Answer
> 1 votes
Some kind of optimization algorithm should do the trick.

I assume that this is not a time critical task, rather done during development or initialization, not during game play. Furthermore, that you know if a given distribution of vertices keeps the final shape close to the source.

Ideally, you will have a function that assigns a number to each configuration of vertices and estimates how close the final shape is to the source. Let's call this function figure of merit (FOM). You want to optimize the FOM with a side-condition that the number of vertices stays constant.

I can imagine two methods, a directed, gradient-based approach and a randomized, Monte-Carlo approach.

1. Directed, gradient-based approach

The position coordinates of each vertex of the Vector-Field terrain are the parameters. Try to compute the derivatives of the FOM with respect to these parameters. One can approximate the derivative numerically by changing the positions only slightly and computing corresponding differences in the FOM (finite differences).

Then move a bit along this gradient direction (i.e. apply gradient times a suitable stepsize to update the positions). Choose the step size so, so that the FOM is best. Some vertices might get very close, meaning that they can be substituted by a fewer number of vertices.

Repeat the computation of the gradient at the new positions and repeat the movement along the new gradient direction. (See also gradient descent.)

This is suitable of you are already close to the desired solution and want to refine it. The movement of vertices from/to close-by regions to neighboring regions needing them should be included here.

2. Randomized, Monte-Carlo approach

Method 1 only performs a local optimization. However, for a global optimization random changes in the vertices might be more suitable. For every iteration, induce more drastic, random changes. For example, one could completely re-distribute 10% of the vertices to other random positions.

The trick is: only accept these changes if they improve the FOM, do accept them only with a very small probability if they make the FOM worse. (Typically one uses Exponential(-Constant * FOM-change) as acceptance probability (here FOM should be minimized)).

Then repeat this for a long time keep track of the best intermediate result (configuration with the best FOM). In the end, choose it. (See also Monte Carlo methods.)

If you want you could combine both, for example apply method 1 on the result of method 2.

---
Tags: algorithm, terrain, computational-geometry
---


title: Pygame Collision Bug

text:
# Question
Title: Pygame Collision Bug
I'm trying to add collisions to my first game, and it has a bug.

My code is:

```
import pygame
from pygame.locals import *
import sys
import os
import time
width = 950
height = 500

screen = pygame.display.set_mode((width, height))
Game = False
pygame.init()
icon = pygame.image.load(os.path.join("Images", "icon.png")).convert_alpha()
pygame.display.set_icon(icon)
pygame.display.set_caption('Flappy Dog')

def game():
    Game = True
    background = pygame.image.load(os.path.join("Images", "Background_00.png")).convert()
    Dog1 = pygame.image.load(os.path.join("Images", "Dog1.png")).convert_alpha()
    SpikeUp0 = pygame.image.load(os.path.join("Images", "SpikeUp0.png")).convert_alpha()
    SpikeDown0 = pygame.image.load(os.path.join("Images", "SpikeDown0.png")).convert_alpha()
    Bone = pygame.image.load(os.path.join("Images", "Bone.png")).convert_alpha()

    boneSprite = pygame.sprite.Sprite()
    boneSprite.image = Bone
    boneSprite.rect = boneSprite.image.get_rect()
    spikeUpSprite = pygame.sprite.Sprite()
    spikeUpSprite.image = SpikeUp0
    spikeUpSprite.rect = spikeUpSprite.image.get_rect()
    spikeDownSprite = pygame.sprite.Sprite()
    spikeDownSprite.image = SpikeDown0
    spikeDownSprite.rect = spikeDownSprite.image.get_rect()
    dogSprite = pygame.sprite.Sprite()
    dogSprite.image = Dog1
    dogSprite.rect = dogSprite.image.get_rect()
    bones = pygame.sprite.Group()
    bones.add(boneSprite)
    dog = pygame.sprite.Group()
    dog.add(dogSprite)
    spikes = pygame.sprite.Group()
    spikes.add(spikeUpSprite)
    spikes.add(spikeDownSprite)
    pygame.display.update()

    Dog1_pos_y = 100
    Dog1_pos_x = 30

    while Game == True:
        pygame.event.pump()
        if pygame.key.get_pressed()[K_UP]: # Up
            Dog1_pos_y -= 1
            screen.blit(background, (0, 0))
            screen.blit(Dog1, (Dog1_pos_x, Dog1_pos_y))
            screen.blit(SpikeDown0, (0, 436))
            screen.blit(SpikeUp0, (0, 0))
            pygame.display.update()
            pygame.time.delay(1)
        else: # Down
            Dog1_pos_y = Dog1_pos_y +0.875
            screen.blit(background, (0, 0))
            screen.blit(Dog1, (Dog1_pos_x, Dog1_pos_y))
            screen.blit(SpikeDown0, (0, 436))
            screen.blit(SpikeUp0, (0, 0))
            pygame.display.update()
            pygame.time.delay(1)
        if pygame.key.get_pressed() [K_LEFT]:
            Dog1_pos_x -= 1.5
            screen.blit(background, (0, 0))
            screen.blit(Dog1, (Dog1_pos_x, Dog1_pos_y))
            screen.blit(SpikeDown0, (0, 436))
            screen.blit(SpikeUp0, (0, 0))
            pygame.display.update()
            pygame.time.delay(1)
        if pygame.key.get_pressed() [K_RIGHT]:
            Dog1_pos_x += 1.5
            screen.blit(background, (0, 0))
            screen.blit(Dog1, (Dog1_pos_x, Dog1_pos_y))
            screen.blit(SpikeDown0, (0, 436))
            screen.blit(SpikeUp0, (0, 0))
            pygame.display.update()
            pygame.time.delay(1)

        if pygame.sprite.spritecollideany(dogSprite, spikes):
            print ("GAME OVER")
        for event in pygame.event.get():
             if event.type == pygame.QUIT:
                 pygame.quit()
                 sys.exit()
                 pygame.display.update()

def gameOver():
    background = pygame.image.load(os.path.join("Images", "Background_00.png")).convert()
    GameOver = pygame.image.load(os.path.join("Images", "Game-Over.png")).convert_alpha()
    replay = pygame.image.load(os.path.join("Images", "Replay.png")).convert_alpha()
    Dog0 = pygame.image.load(os.path.join("Images", "Dog0.png")).convert_alpha()
    Bone = pygame.image.load(os.path.join("Images", "Bone.png")).convert_alpha()

    screen.blit(background, (0, 0))
    screen.blit(GameOver, (0, 0))
    screen.blit(replay, (600, 375))
    screen.blit(Dog0, (10, 250))
    pygame.display.flip()

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
                pygame.display.update()
            if event.type == pygame.MOUSEBUTTONDOWN:
                x_mouse, y_mouse = pygame.mouse.get_pos()
                if x_mouse >= 600 and y_mouse >= 375:
                    game()

def mainScreen():
    background = pygame.image.load(os.path.join("Images", "Background_00.png")).convert()
    FlappyDog = pygame.image.load(os.path.join("Images", "Flappy.png")).convert_alpha()
    Play = pygame.image.load(os.path.join("Images", "Play.png")).convert_alpha()
    Dog = pygame.image.load(os.path.join("Images", "Dog0.png")).convert_alpha()
    SpikeUp0 = pygame.image.load(os.path.join("Images", "SpikeUp0.png")).convert_alpha()
    SpikeUp1 = pygame.image.load(os.path.join("Images", "SpikeUp1.png")).convert_alpha()
    SpikeDown0 = pygame.image.load(os.path.join("Images", "SpikeDown0.png")).convert_alpha()
    SpikeDown1 = pygame.image.load(os.path.join("Images", "SpikeDown1.png")).convert_alpha()
    Bone = pygame.image.load(os.path.join("Images", "Bone.png")).convert_alpha()

    screen.blit(background, (0, 0))
    screen.blit(SpikeUp0, (0, 0))
    screen.blit(SpikeDown0, (0, 450))
    screen.blit(FlappyDog, (0, 0))
    screen.blit(Dog, (10, 250))
    screen.blit(Bone, (150, -300))
    screen.blit(Bone, (150, 400))
    screen.blit(Play, (650, 370))
    pygame.display.flip()

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
                pygame.display.update()
            if event.type == MOUSEBUTTONDOWN:
                x_mouse, y_mouse = pygame.mouse.get_pos()
                if x_mouse >= 650 and y_mouse >= 370:
                    game()

mainScreen()

```

I don't know why, when I press the play button I go to the game screen for a second (I'm not touching the spikes) and I go to the game over screen.

There is no error message

Thanks in advantage.

# Answer
`pygame.sprite.groupcollide` returns a dictionary that always includes the sprites in the first group. Therefore, the `if` test you have written will always return true.

You should re-write the function to check whether or not there are sprites in the list for every sprite in the `dog` group.
> 1 votes

# Answer
Ok, I found the solution.

Change the way to make images sprites, like this:

```
Dog = pygame.sprite.Sprite()
Dog.rect = pygame.Rect(0, 100, 270, 256)
Bone = pygame.sprite.Sprite()
Bone.rect = pygame.Rect(850, 0, 87, 498)
Dog.image = pygame.image.load("Dog1.png").convert_alpha()
Bone.image = pygame.image.load("Bone.png").convert_alpha()

```

And don't use `pygame.sprite.groupcollide`, use `pygame.sprite.collide_rect(Dog, Bone)`

When blit the image replace the x and y pos. and use `Dog.rect.topleft` and `Bone.rect.topleft`. This will work.
> 0 votes

---
Tags: collision-detection, python, pygame
---


# Question
Title: How to align FixedUpdate variable change with user input
I'm creating a small endless runner where the player has to swipe up and down on the screen to move a fish. Imagine Subway Surfers where you travel smoothly as opposed to just jumping a foot to the left or right. Anyway, I am trying to make the fish rotate in the approximate direction of the player's finger and gradually rotate back when the player lets go of the screen. The program was working almost smoothly -- except for the fact that the fish was rotating back to the default position constantly, so it looked really glitchy.

The way this script works is that it takes in two Vector2 variables - the current and previous positions of the fish. It then subtracts these to get a Vector2 denoting the change in position since the last frame. I then feed it into `Mathf.Atan` to get the direction of this motion. Finally, I rotate the fish by this new amount - minus its current rotation - to get it going in the right direction. I'll show the code down below. Upon investigating why this was causing the fish to consistently rotate back to 0 degrees for a couple frames, over and over, I learned that the Unity thought that the change in y position was the thing switching to zero every other frame. All of my code is operating on FixedUpdate and I don't use Update anywhere, so I have no idea why it is switching so erratically. If user touch input is measured during Update, that might be the source of the problem, but it would be nice if I could find a solution. I'm just kind of confused, and would love if someone could clear this up for me as soon as possible.

Now here's my code for the class "RotateByTouch":

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

public class RotateByTouch : MonoBehaviour
{
    public TrackObjectMotion trackObjectMotion;
    public GameObject thisObject;

    public float rotationValue;

    void FixedUpdate()
    {

        rotationValue = Mathf.Atan(trackObjectMotion.DeltaY / trackObjectMotion.DeltaX) * Mathf.Rad2Deg;

        thisObject.transform.Rotate(Vector3.forward, rotationValue - thisObject.transform.rotation.eulerAngles.z);

    }

}

```

And here's my code for the class "TrackObjectMotion":

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

public class TrackObjectMotion : MonoBehaviour
{

    public Vector3 CurrentPosition;
    public Vector3 PreviousPosition;

    public float DeltaX;
    public float DeltaY;

    // Update is called once per frame
    void FixedUpdate()
    {
        PreviousPosition = CurrentPosition;
        CurrentPosition = this.gameObject.transform.position;

        DeltaX = CurrentPosition.x - PreviousPosition.x;
        DeltaY = CurrentPosition.y - PreviousPosition.y;
    }
}

```

And finally, here's the code I used for the actual moving of the fish:

```
public void FixedUpdate(){
    foreach(Touch touch in Input.touches){
        if(touch.Phase == TouchPhase.Moved){
            this.transform.Translate(0, touch.deltaPosition.y, 0);
        }
    }
}

```

That last bit is just leaving out a little bit about multiplying by constants to get the desired result, but that's not important.

Thanks in advance!

# Answer
Whenever you have an actual target you want to eventually rotate towards, my suggestion would be to use either `transform.LookAt(Transform target, Vector3 worldUp = Vector3.up)` or `Quaternion.LookRotation(Vector3 forward, Vector3 upwards = Vector3.up)`.

Meanwhile if you wouldn't know the exact rotation angle that you want your object to be rotated towards, just the angular speed (like if you'd move your characters by arrows, or D-pad), then I suggest you'd use transform.Rotate.

Since in your case you want the rotation to happen overtime, `Quaternion.LookRotation` would be the choice to get the desired final direction, and `Quaternion.Lerp(currentAngle, targetAngle, step/totalsteps)` to set the current rotation. Here `OnTouch` you'd set `Quaternion targetAngle = Quaternion.LookRotation(touch.position, Vector3.Up)`, then Lerp towards that rotation via some speed.

In your actual code, I see that you use delta position for setting up the rotation. Remember, that you calculate your delta as `previous` vs `current` frame, therefore, right when the finger stops moving, or moves slower than frames register the delta, it becomes zero.
> 2 votes

---
Tags: unity
---