title: Preload scene in unity

text:
# Question
Title: Preload scene in unity
I have a game with two scenes, menu and maingame. I have uploaded the game to googleplay. However when I open the game and click on the play button in the menu scene, the next scene (maingame) takes about 4-5 seconds to load. Is there any way to load the maingame along with the menu so that there is no delay in loading?

**EDIT**

I have added code to the MainMenu.cs file so that when the game starts the LoadSceneAsync function is called and allowSceneActivation is set to false. Once the "play" button is pressed, the activation is set to true. The first time the game loads, there is still a bit of delay however if the player dies and I go the main menu and press play again, there is no delay.

```
AsyncOperation async;

void Start()
{
    async = SceneManager.LoadSceneAsync(1);
    async.allowSceneActivation = false;
}

public void PlayBtnPressed()
{
   async.allowSceneActivation = true;
   AudioManager.audiomanager.Play("PlayButton");
}

```

# Answer
> 2 votes
# Scene Loading

### Basic

Tested this in a new project. The idea is to start scene preloading when `Return` button is pressed and save `AsyncOperation` that is doing it, disallow scene activation for it and allow it when you need the scene to be loaded as soon as it's ready.

I would expect it to be loaded into memory, be careful if you are RAM-bounded because both scenes will take up memory space until one is unloaded.

Reproduce:

1. Create a new project.
2. Create 2 scenes:
    * "menu"
    * "maingame"
3. Add both scenes to `Build Settings`.
4. Open "menu" scene.
5. Create `GameObject` and add `PreloadSceneInUnity` component to it.
6. Enter playmode.
7. Press `Return` and see "maingame (is loading)" in Hierarchy window.
8. Press `Space` \- "maingame" scene will open.

## Code

**Git:** Preload scene in unity

```
using System.Collections;

using UnityEngine;
using UnityEngine.SceneManagement;

public class PreloadSceneInUnity : MonoBehaviour
{
    [SerializeField] private string _sceneName = "maingame";
    public string _SceneName => this._sceneName;

    private AsyncOperation _asyncOperation;

    private IEnumerator LoadSceneAsyncProcess(string sceneName)
    {
        // Begin to load the Scene you have specified.
        this._asyncOperation = SceneManager.LoadSceneAsync(sceneName);

        // Don't let the Scene activate until you allow it to.
        this._asyncOperation.allowSceneActivation = false;

        while (!this._asyncOperation.isDone)
        {
            Debug.Log($"[scene]:{sceneName} [load progress]: {this._asyncOperation.progress}");

            yield return null;
        }
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Return) && this._asyncOperation == null)
        {
            Debug.Log("Started Scene Preloading");

            // Start scene preloading.
            this.StartCoroutine(this.LoadSceneAsyncProcess(sceneName: this._sceneName));
        }

        // Press the space key to activate the Scene.
        if (Input.GetKeyDown(KeyCode.Space) && this._asyncOperation != null)
        {
            Debug.Log("Allowed Scene Activation");

            this._asyncOperation.allowSceneActivation = true;
        }
    }
}

```

---

### Advanced

If you are not satisfied with how scene loading works in `UnityEngine.SceneManagement` \- I suggest you take a look at `Addressables` package that Unity provides, it has support for scene loading as well, but be aware that it's a lot more complicated to get into and there is a learning curve that requires to learn quite a few more things before scene loading.

# Answer
> 1 votes
You can load the next scene asynchronously using SceneManager.LoadSceneAsync() using coroutines. You can use this strategy on a splash / loading screen if you're wanting to see it load before showing the menu.

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

public class Example : MonoBehaviour
{
    void Update()
    {
        // Press the space key to start coroutine
        if (Input.GetKeyDown(KeyCode.Space))
        {
            // Use a coroutine to load the Scene in the background
            StartCoroutine(LoadYourAsyncScene());
        }
    }

    IEnumerator LoadYourAsyncScene()
    {

        AsyncOperation asyncLoad = SceneManager.LoadSceneAsync("Scene2");

        // yield to other processes until the scene is loaded
        while (!asyncLoad.isDone)
        {
            yield return null;
        }

        // Do something here like enabling the play button or closing the splash/loading screen
    }
}

```

Code example from: https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager.LoadSceneAsync.html

EDIT: As has been indicated in the comments, if you want to control when the scene loads, you can use the allowSceneActivation flag on the above AsyncOperation object. asyncLoad.allowSceneActivation = false; When you want it to load the next scene: asyncLoad.allowSceneActivation = true;

---
Tags: unity, preload
---


# Question
Title: In Unity, what's a better solution than having a bunch of singleton static managers? (SceneManager, UIManager, SfxManager, PfxManager)
I always hand a bunch of public static manager classes in my game:

* GameManager (singleton) for reading and writing persistent data and gamestate across scenes
* SceneManager for holding scene data (coins picked up, score, are we in a cutscene)
* UIManager for dealing with HUD stuff
* SfxManager for sound effects
* PfxManager for particle effects

On the gameobject that holds these manager classes, there are also subordinate classes (e.g. HUDManager, a smaller class that managers tasks specific to HUD, and then delegate those tasks into other smaller scripts) in order to avoid monolithic manager classes.

Is this method frowned upon in Unity game development and if so, what are some better solutions than this approach?

# Answer
> 2 votes
My usual approach is to minimize managers by creating smarter gameObjects which have their own controllers.

* "coins picked up" and "score" are properties of the player, so they should be on the player game object.
* Instead of an UI Manager, I create controllers for individual UI elements. When they show information about a gameObject (like `player.score`), they reference a gameObject in the scene.
* Instead of an Sfx Manager, I use objects with audio sources which might or might not have controllers which control that one audio source.

But if the manager-pattern feels natural to you, then you might feel right at home with the new DOTS architecture, where all the game logic is in managers (called "Systems").

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


title: How does Unity's execution order work?

text:
# Question
Title: How does Unity's execution order work?
I wonder how Unity's execution order really works. There's an ordered list at https://docs.unity3d.com/Manual/ExecutionOrder.html, but how does this work when there are different gameobjects involved? Will Unity first run the specific function for all the monobehaviours in the scene before it proceeds to the next function? Or will each monobehaviour go through that specific order of functions before Unity goes to the next monobehaviour? Or is it more complex? It isn't really clear to me from the documentation.

For example, normally Start() gets called before Update(), however when I was debugging, Update() on my Avatar prefab got called before Start() of my Camera child object. Is this supposed to happen?

# Answer
> 3 votes
As I mentioned in the comments, a simple way to investigate execution order in Unity is to add a debug log to each method you're interested in, something like...

```
Debug.LogFormat("{0}: [Event] called on {1}'s {2} at {3}",
                 Time.frameCount,
                 name,
                 this.GetType().Name,
                 Time.time);

```

Then you can read the sequence of messages and frame time stamps in the log to find out exactly what order each method was called in.

You'll find that this varies between objects that already existed, enabled in your scene from the beginning of the frame, and new objects that get created or enabled midway through the frame.

**For script instances already present in your scene**, at load:

1. Each script instance gets its `Awake` method called, then its `OnEnable` method, if enabled, back-to-back. Then then the next script instance gets its `Awake` called, so you'll see an alternating pattern of `Awake` `OnOnable` `Awake` `OnEnable` if you log it as I recommended.

This is why these two methods are shown bundled together as "Initialization" in the Unity execution order diagram.
2. Then all the `Start` methods are called, on all script instances.
3. Then all the `FixedUpdate` methods for the first physics step.
4. Then all the `Update` methods for the variable time step.
5. Then all the `LateUpdate` methods.

**For subsequent frames**, this process repeats for all enabled objects remaining from previous frames, starting from step 3 if there's one or more physics steps to evaluate this frame, and otherwise skipping ahead to step 4.

In my tests, the order in which particular script instances get their message method called within any given step appears to be the reverse order of creation, with the components I added last getting their method called first. I wouldn't count on this level of micro-ordering for your scripts though, as it's something the engine could be expected to change when optimizing a build.

This means the order can hop back-and-forth between GameObjects in the hierarchy, and **does not necessarily process all script instances on a single object consecutively**, before scripts on its child objects, etc. (This is to be expected, since we can override the order of executing particular script classes independent of how they're arranged on objects in the scene).

**If a new script instance is spawned mid-frame**, with `Instantiate` or `AddComponent`:

1. Its `Awake` and `OnEnable` (if enabled) methods get called back-to-back.
2. The `Instantiate` or `AddComponent` call returns, and control flow resumes on the next statement of the method that spawned the script, and the engine continues processing whatever message it was processing at the time.
3. The engine moves on to the *next* update step (`FixedUpdate`, `Update`, `LateUpdate`, etc.)

That means the new script instance has "missed the bus" for the current processing step, but can still catch the next one after this. If it was spawned during `Update`, it doesn't get an `Update` call this frame. But it could still get a `LateUpdate`.
4. When the new script instance's turn comes in the next processing step (ie. `FixedUpdate`/`Update`/`LateUpdate`), Unity checks to see if it's been started yet. If not, it calls `Start` on this instance "just in time," then proceeds with processing its message method call.
5. Just before rendering, if any newly-spawned scripts still haven't started (eg. they were spawned in `LateUpdate`), Unity calls `Start` on those stragglers.

So, these newly-created or newly-enabled objects could be the reason you're observing `Start` or other messages sometimes getting called in the middle of some other phase of processing. It's the engine playing catch-up to get the newly-added or -awoken instance up to speed for wherever the rest of the scene objects have advanced to in the update order.

---
Tags: unity
---


# Question
Title: Unity - Transforming horizontal distance between two spriteRenderers to set UnityEngine.UI.Button width to this distance
In my Unity scene, I have a couple of `spriteRenderers` and a `UnityEngine.UI.Button` called `thisButton`. The spriteRenderers are spread horizontally across my scene. I want to change the button width to span from the leftmost spriteRenderer to the rightmost spriteRenderer.

To do this, I have subtracted the x-Coordinate of the rightmost spriteRenderer (`fRightEndingPosition`) from the x-Coordinate of the leftmost spriteRenderer (`fLeftStartingPosition`).

```
float fLeftStartingPosition = leftmostSpriteRenderer.transform.position.x;
float fRightEndingPosition = rightmostSpriteRenderer.transform.position.x;
float fButtonTargetWidth = fRightEndingPosition - fLeftStartingPosition;

```

Then, I try to set the width of `thisButton` to the value of `fButtonTargetWidth` by doing

```
RectTransform buttonSize = thisButton.GetComponent<RectTransform>();
buttonSize.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, fButtonTargetWidth);

```

However, when I try to use this as the width of my button, the result is not correct. I am pretty sure this has something to do with different types of coordinates being used for the spriteRenderers and the button (world, screen, viewport, etc.), but I haven't been able to figure this out on my own.

In one specific example `fLeftStartingPosition` is `-1.1`, and `fRightEndingPosition` is `1.1`. In my scene, a button that spans this distance has a width of roundabout 40 on its RectTransform. So clearly, setting the width of this RectTransform (`buttonSize`) to `fButtonTargetWidth` (`2.2`) in code results in a button that is way to narrow. In fact, after setting it's width to 2.2, it is not visible at all.

How do I transform this distance of 2.2 to the desired width of roundabout 40, in a way that this distance would be transformed correctly, no matter what the actual value of fButtonTargetWidth is?

# Answer
> 1 votes
Your solution might work with a world-space canvas, but I don't recommend using world-space canvases for most situations because it's difficult to make them adapt to different screen aspect ratios/resolutions.

If you're using a Screen Space canvas, you need to convert the world coordinates of the sprite renderers into screen space, then convert that into canvas space.

This solution works for cameras set to "Screen Space - Overlay" or "Screen Space - Canvas":

```
//This solution does NOT work for world-space canvases!
Assert.IsFalse(canvas.renderMode == RenderMode.WorldSpace);
Canvas canvas = thisButton.GetComponentInParent<Canvas>();
Vector3 leftScreen = Camera.main.WorldToScreenPoint(leftmostSpriteRenderer.transform.position);
Vector3 rightScreen = Camera.main.WorldToScreenPoint(rightmostSpriteRenderer.transform.position);

RectTransform buttonRT = thisButton.GetComponent<RectTransform>();
var sizeDelta = buttonRT.sizeDelta;
sizeDelta.x = (rightScreen.x - leftScreen.x) / canvas.scaleFactor;
buttonRT.sizeDelta = sizeDelta;

```

What we do here is convert the positions of the two sprite renderers into screen coordinates (which are in pixels), then convert the screen coordinates into canvas dimensions by dividing by the canvas scale factor (since the canvas scale factor is a ratio of canvas coordinates to screen coordinates).

---
Tags: unity, sprites, transformation, coordinates, unity-ui
---


title: Tile Palette problem in Unity

text:
# Question
Title: Tile Palette problem in Unity
I am working on isometric tilemap in Unity 2019.4.8f1.

In the Tile Palette panel, the selection is always 1 block away. Please see this screenshot:

In the screenshot, apparently I selected an empty tile, but in fact I am select the green tile with flowers. How come? Every selection is one tile away. The same issue happens in the Tilemap selection mode too. I have to select the adjacent tile in order to select the tile I want.

How do I fix it? It's quite annoying.

*UPDATE* I have added the settings of Grid, Tilemap as well as the import settings of the tile sprite sheet below.

---

*UPDATE 2* Changed the Pivot in Sprite Editor to **Bottom Center**

Recreated the Tile Palette, and it looks like hovering 0.5 unit up.

# Answer
> 1 votes
Thanks to @DMGregory, the problem is resolved. The root cause of the problem is the Pivot configured in the Sprite Editor is incorrect.

After setting the Pivot to "Center", regenerate the tiles and reset the Tilemap pivot points to X=0.5, Y=0.5, Z=0, the selection in the Tile Palette panel becomes normal again.

---
Tags: unity, tilemap, isometric
---


# Question
Title: How to detect Tilemap collisions with monogame extended?
So,I kind of figured out how to detect the collisions when the chracter hits a certain tilelayer(such as a wall).Right now it just just the tiles which should have collision and prints out "collision" on the game screen(As shown in the video below). But now I have two problems

1. The collision is not being detected in the correct place in the bottom and left walls(as shown in the video below,the collision is not detected as soon as the player touches the wall but a little while later)
2. How do I actually implement the collsions(as in stopping the player when he collides)?

The Video https://youtu.be/0E1UXms4AXQ

Here's the code below

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using MonoGame.Extended;

using MonoGame.Extended.Tiled;
using MonoGame.Extended.Tiled.Renderers;
using MonoGame.Extended.ViewportAdapters;

namespace Dungeon
{
    public class Game1 : Game
    {
        private GraphicsDeviceManager _graphics;
        private SpriteBatch _spriteBatch;
        private TiledMap map;
        private TiledMapRenderer mapRenderer;
        private OrthographicCamera cam;
        private Texture2D player;
        private Vector2 playerPos;
        private InputManager manager;
        private SpriteEffects effect;
        private TiledMapTileLayer mapLayer;
        private SpriteFont font;
        private string s;
        public Game1()
        {
            _graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            IsMouseVisible = true;
        }

        protected override void Initialize()
        {
            effect = SpriteEffects.FlipHorizontally;
            // TODO: Add your initialization logic here
            s = " ";
            manager = new InputManager();
            playerPos = new Vector2(100,100);
            mapRenderer = new TiledMapRenderer(GraphicsDevice);
            var viewportAdapter = new BoxingViewportAdapter(Window,GraphicsDevice,800,400);
            cam = new OrthographicCamera(viewportAdapter);
            base.Initialize();
        }

        protected override void LoadContent()
        {
            _spriteBatch = new SpriteBatch(GraphicsDevice);
            map = Content.Load<TiledMap>("Dungeon");
            mapRenderer.LoadMap(map);
            player = Content.Load<Texture2D>("player");
            mapLayer = map.GetLayer<TiledMapTileLayer>("walls");
            font = Content.Load<SpriteFont>("Debug");
            // TODO: use this.Content to load your game content here
        }

        protected override void Update(GameTime gameTime)
        {

            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();
            mapRenderer.Update(gameTime);
            // TODO: Add your update logic here
            KeyboardState state = Keyboard.GetState();
            if(state.IsKeyDown(Keys.A)||state.IsKeyDown(Keys.Left))
            {
                effect = SpriteEffects.FlipHorizontally;

            }
            else if(state.IsKeyDown(Keys.D)||state.IsKeyDown(Keys.Right))
            {
                effect = SpriteEffects.None;

            }
            float move = 2;

                playerPos =manager.moveVertical(playerPos,move);
            playerPos = manager.moveHorizontal(playerPos,move);
            ushort tx = (ushort)(playerPos.X / map.TileWidth);
            ushort ty = (ushort)(playerPos.Y / map.TileHeight);
            TiledMapTile? tile;
            if (mapLayer.TryGetTile(tx, ty, out tile))
            {
                if(!tile.Value.IsBlank)
                {
                    s = "collision";
                }
                else
                {
                    s = "none";
                }
            }
                base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);
            mapRenderer.Draw();
            var transformMatrix = cam.GetViewMatrix();

            _spriteBatch.Begin(transformMatrix:transformMatrix);
            _spriteBatch.DrawString(font,s,new Vector2(0,0),Color.White);
            _spriteBatch.Draw(player,new Rectangle((int)playerPos.X, (int)playerPos.Y,16,16),null,Color.White, 0f, new Vector2(16,16),effect,1);
            _spriteBatch.End();
            // TODO: Add your drawing code here

            base.Draw(gameTime);
        }
    }
}```

</code></pre>

# Answer
After some searching I finally figured out the 2nd problem all I needed to do was make a Vector2 variable and store the intial position of the player(before updating it) into it When collision was detected the player position is set to the initial value

```
            var pos = playerPos;
            playerPos =manager.moveVertical(playerPos,move);
            playerPos = manager.moveHorizontal(playerPos,move);
            ushort tx = (ushort)(playerPos.X / map.TileWidth);
            ushort ty = (ushort)(playerPos.Y / map.TileHeight);
            TiledMapTile? tile;
            if (mapLayer.TryGetTile(tx, ty, out tile))
            {
                if(!tile.Value.IsBlank)
                {
                    s = "collision";
                    playerPos = pos;
                }
                else
                {
                    s = "none";
                }
            }

```

Which leaves us with the first problem only.
> 0 votes

---
Tags: monogame, monogame-extended
---


# Question
Title: How to restrict the players movement win relation to screen bounds in Unity? (Without colliders)
I am really enjoying making the switch to Unity. But here I have found one of those rare moments where it appears to make things more difficult (at least it is for me as I am crap at understanding the actual manual)

Basically my 'player' is a space ship. It starts life at 0,0,0 world coordinates and I have been doing all the movement based off of that. (ie. Add force X to move left or right, and there is a constant Z speed which is done via rb.transform.Translate().)

I want to restrict the movement on the X Axis, so in Libgdx id use something like:

```
if (player.position.x <= 0){ player.position.x = 0;}
if (player.position.x >= viewport.getX()){ player.position.x = viewport.getX();}

```

The thing is that wont work for me in Unity for several reasons (1. I dont know much about the viewport as I didnt create it. 2. the player.position is being affected by the rigidbody forces. AND i am working in world coordinates with the players position).

As I said, the player is constantly moving forward on Z axis, so making colliders doesnt seem like the right choice for me.

I'm pretty sure Unity devs would of put this in Unity v0.001 but I just cannot for the life of me find how to actually do it. (Any info I can find seems from like 2011 and also is pretty badly written code making this simple matter takes dozens of lines of code and some methods - I'm hoping there is a Unity method already made, like player.transform.ScreenPosition or something but yeah I cannot find it!?

Any help would be massively appreciated as always.

# Answer
> 2 votes
You can restrict the player position to the viewport like this:

```
void Update() {
    Vector3 pos = Camera.main.WorldToViewportPoint(transform.position);
    pos.x = Mathf.Clamp01(pos.x);
    transform.position = Camera.main.ViewportToWorldPoint(pos);
}

```

That converts the position of the player (assuming or any object this script is attached to) into viewport coordinates, which range from 0 to 1. Then clamps the position between 0 and 1. Finally converting back to world space. So, if the object is outside of the screen, its position will convert to something less than 0 or greater than 1, which this script will correct. Otherwise, it'll leave the position where it is.

# Answer
> 2 votes
A slightly different approach to the one given by Michael, which I am using on my project, if you are using crossplatform input axis and convert it to vector3 for movement;

```
     public float h;                            //input axix x
     public float v;                            //input axis y

     private void FixedUpdate()
     {
             h = CrossPlatformInputManager.GetAxis(axisX);
             v = CrossPlatformInputManager.GetAxis(axisY);

        Vector3 viewPos = cam.WorldToViewportPoint(transform.position);

         if (viewPos.y < 0.02f)
         {
             v = 1;
         }
        else if (viewPos.y > 0.99f)
        {
             v= -1;
        }

         if (viewPos.x < 0.01f)
         {
             h = 1;
         }
         else if (viewPos.x > 0.98f)
         {
             h = -1;
         }

         m_Move = v * Vector3.forward + h * Vector3.right;

 }

```

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


# Question
Title: Orthographic Camera Movement inside Rotated Boundary Rectangle Weird Behaviour [Unity3d]
Basically I have an orthographic camera that is looking at a simple square. The camera is sitting above the square and tilted by x: 45° and y: 45°, so the camera sees the square as a rhombus / diamond shape.

I want the camera to be moveable within a rectangular boundary that appears to be leveled with the camera, so it would need to be rotated by 45° around the y-axis (up-vector in Unity) in World-coordinates. I already figured out the math to constrain the camera to this shape, but there is a *weird thing going on* when the movement gets clipped: The camera doesn't follow the outline perfectly, but in a rounded shape (see screenshot). Could this be due to a rounding error? Code snipped below.

```
using System;
using UnityEngine;
using static UnityEngine.Mathf;

public class InputController : MonoBehaviour
{
    private const float CamHeight = 10f;
    [SerializeField] private GameObject gameBoard;
    [SerializeField] private GameObject camBounds;
    [SerializeField] private float camBoundRadius = 5f;
    private Vector3 _camOrigin;
    private MeshCollider _collider;
    private Vector3 _difference; // Change in position of mouse relative to origin
    private Camera _mainCamera;
    private Vector3 _origin; // Place where mouse is first pressed
    private Plane _worldPlane;

    private void Start()
    {
        _mainCamera = Camera.main;
        if (_mainCamera is null) throw new Exception("No main camera could be found!");
        // Set the camera so that the board is always in the center
        _camOrigin = new Vector3(
            -CamHeight / Sqrt(2f),
            CamHeight,
            -CamHeight / Sqrt(2f));
        _mainCamera.transform.position = _camOrigin;
        _collider = gameBoard.GetComponent<MeshCollider>();
        _worldPlane = new Plane(Vector3.up, 0); // For dragging the camera around
    }

    private void LateUpdate()
    {
        if (Input.GetMouseButtonDown(0)) _origin = MouseWorldPosition();
        if (Input.GetMouseButton(0))
        {
            _difference = MouseWorldPosition() - transform.position;
            var newPos = _origin - _difference;
            var absDiff = newPos - _camOrigin;

            var angle = Angle2Pi(Vector3.right, absDiff);
            var constraint = SawTooth(angle);

            if (absDiff.magnitude < constraint)
                transform.position = newPos;
            else
                transform.position = _camOrigin + absDiff.normalized * constraint;
        }
    }

    private Vector3 MouseWorldPosition()
    {
        var clickedPoint = Input.mousePosition;
        var ray = _mainCamera.ScreenPointToRay(clickedPoint);
        var worldPos = Vector3.zero;

        if (_worldPlane.Raycast(ray, out var raycastHit)) worldPos = ray.GetPoint(raycastHit);

        return worldPos;
    }

    private float SawTooth(float theta)
    {
        var x = 4f / PI * camBoundRadius * (1f - 1f / Sqrt(2f));
        x *= Abs(theta % (PI / 2f) - PI / 4f);
        x += camBoundRadius / Sqrt(2f);
        return x;
    }

    private static float Angle2Pi(Vector3 from, Vector3 to, Vector3 normal = default)
    {
        if (normal == default) normal = Vector3.up;

        var angle = Vector3.Angle(from, to) * (PI / 180f);
        var sign = Sign(Vector3.Dot(normal, Vector3.Cross(from, to)));
        angle = 2f * PI - angle * sign;

        return angle;
    }
}

```

# Answer
Well I took a different approach that works perfectly and actually makes use of the bounding box shown in the screenshot. Here the code:

```
private void LateUpdate()
{
    if (Input.GetMouseButtonDown(0)) _origin = MouseWorldPosition();
    if (Input.GetMouseButton(0))
    {
        _difference = MouseWorldPosition() - transform.position;
        var newPos = _origin - _difference;
        var absDiff = newPos - _camOrigin;

        if (absDiff == Vector3.zero) return;

        // Check if newPos is outside the bounding box, i.e. if a raycast hits the bounding box
        var ray = new Ray(newPos, -absDiff.normalized);
        if (_camBounds.Raycast(ray, out var raycastHit, absDiff.magnitude))
            transform.position = ray.GetPoint(raycastHit.distance);
        else
            transform.position = newPos;
    }
}

```
> 1 votes

---
Tags: unity, c#, camera, movement
---


# Question
Title: How to make player seem bigger / world smaller, without changing world coordinates
I am making a voxel game with OpenGl, I've got the major parts working, except the camera seems small compared to the the blocks. How do I make the camera bigger?
Do I do a scaling on the model matrix for each chunk? Or do I do something with the view matrix of the camera? When i tried these things, it messed up the coordinate system of my game, the blocks were not where they really were. I just want the player to be visually 2x bigger.

```
// the view matrix
glm::mat4 Camera::GetViewMatrix()
{
    glm::mat4 view = glm::lookAt(position, position + target, up);
    return view;
}

    // Where i do the chunk rendering
void WorldRenderer::RenderChunck(Chunk *c)
{
    glActiveTexture(GL_TEXTURE0);
    worldTexture->BindTexture();
    worldShader->Bind();
    worldVertexBuffer->BindVertexArrayBuffer();
    worldVertexBuffer->PutVertexData(c->meshData.verts, c->meshData.indices, c->meshData.textureCoords);

    glm::mat4 model = glm::mat4(1.0f); // model = local space to world space
    model = glm::translate(model, vec3(c->pos.x * Chunk::CHUNCK_SIZE, c->pos.y * Chunk::CHUNCK_SIZE, c->pos.z * Chunk::CHUNCK_SIZE));

    worldShader->setMat4f("model", model);
    glDrawElements(GL_TRIANGLES, c->meshData.indices.size(), GL_UNSIGNED_INT, 0);
}
void WorldRenderer::Render(glm::mat4 projectionMatrix, glm::mat4 viewMatrix)
{
    worldShader->setMat4f("view", viewMatrix);
    worldShader->setMat4f("projection", projectionMatrix);

    for (Chunk *c : renderedChunks)
    {
        this->RenderChunck(c);
    }
}

```

# Answer
> 3 votes
Move the camera higher up. The human brain expects to see things from the normal human eye height above the ground, about 150-170 cm. So your walls look about 4-6 metres high. Make the camera 10 times as high, and now they're 0.4-0.6 metres high.

Your current perspective is appropriate for a dungeon crawler where each wall is a voxel and the walls have traps and doors in them and so on. It's not appropriate for a Minecraft-style game. Minecraft intends to have 1-metre cubes, so it places the camera 1.6 cubes above the ground.

As HolyBlackCat said, don't forget to choose an appropriate movement speed as well.

# Answer
> 1 votes
There's no such thing as "camera size". If you have a free-moving camera, the perceived "camera size" depends solely on the camera movement speed.

If you make your world N times larger and increase the movement speed N times, those two actions will cancel each other out, and the end result will be the same.

So instead of making the world larger, make the camera move faster. There's nothing more to it (except maybe changing the initial camera position to be higher above the ground).

---
Tags: opengl, 3d, rendering, graphics, voxels
---


# Question
Title: how to set volume of sound depending on the impulse a body receives in Libgdx / Box2d?
I am trying to set the volume of a bouncing sound of a ball depending on how hard the ball hits something. so the harder the ball hits a wall or a ground the more loud the bounce sound.

I couldn't find anyway to get the impulse of a body other than the `postSolve(Contact contact, ContactImpulse impulse)`  method in`ContactListner` class.

But i then realized that unlike the `beginContact(Contact contact)` method, `postSolve(Contact contact, ContactImpulse impulse)`  gets called repeatedly until the contact ends. so it repeatedly plays the bouncing sound making it sound stalked and buggy.

I cant use the `beginContact(Contact contact)` method because there is no way to get the impulse that the ball is receiving from this method. I tried to to use the velocity of the ball instead of impulse inside `beginContact(Contact contact)`but that didnt yield good results and found it very complicated as i had to consider both horizontal and vertical speeds.

so my question is how can I make the sound play only once if i am using the `postSolve(Contact contact, ContactImpulse impulse)`  method or is there any other solution to achieve what i am trying to do here?

# Answer
Playing sounds from the `beginContact`, `endContact`, `preSolve` and `postSolve` methods is not a good idea (as you've identified) as the methods may be called many times per `World` step depending on the number of collisions that occurred.

What you can do in these methods is to collect information so that you can use it later when the **Box2D** `World` step is done.

One way to achieve what you're trying to do would be to

1. Capture the collision event in `postSolve` and if the involved `Body` or `Fixture` is something that have special collision handling then notify the `userObject` that the collision has occured and with which force.
2. In the `userObject`, store the information of all such notifications.
3. In an `update` method that runs once per game-loop tick figure out if a sounds needs to be played and play it.
4. Clear the stored information about collisions.

The above approach limits the number of sounds that is being requested to play to one per object per game-loop tick, rather than one per recorded collision.

If one sound per game-loop tick is too many sound you can easily add a counter for the number of currently playing sounds for each object and cap it.

I can't easily demonstrate it with actual audio here, but here's an example where I draw red circles with a radius that represents the volume of the sound:

The full source code for the above:

```
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.*;

public class BouncingSounds extends Game {

    private OrthographicCamera camera;
    private World world;
    private Box2DDebugRenderer renderer;
    private Ball[] balls;
    private ShapeRenderer soundRenderer;

    public interface ForceListener {
        void forceImpact(float force);
    }

    public static class Ball implements ForceListener {
        private static final float MIN_FORCE = 200.0f;
        private static final float MAX_FORCE = 8000.0f;
        private Body body;
        private float impactForce = 0.0f;
        private float soundVolume = 0.0f;

        public Ball(World world, float x, float y) {
            CircleShape ballShape = new CircleShape();
            ballShape.setRadius(4.0f);

            FixtureDef ballFixtureDef = new FixtureDef();
            ballFixtureDef.shape = ballShape;
            ballFixtureDef.friction = 0.2f;
            ballFixtureDef.density = 1.0f;
            ballFixtureDef.restitution = 0.65f;

            BodyDef ballBodyDef = new BodyDef();
            ballBodyDef.type = BodyDef.BodyType.DynamicBody;

            body = world.createBody(ballBodyDef);
            Fixture ballFixture = body.createFixture(ballFixtureDef);
            ballFixture.setUserData(this);
            body.setTransform(x, y, 0);
        }

        public void update(float deltaTime) {
            soundVolume -= 8.0f * deltaTime;
            if (impactForce > MIN_FORCE) {
                float relativeForce = (Math.min(impactForce, MAX_FORCE) - MIN_FORCE) / (MAX_FORCE - MIN_FORCE);
                soundVolume = relativeForce * 4;
            }
            impactForce = 0.0f;
        }

        public void render(ShapeRenderer soundRenderer) {
            if (soundVolume > 0.0f) {
                soundRenderer.setColor(Color.RED);
                soundRenderer.circle(body.getPosition().x, body.getPosition().y, soundVolume, 16);
            }
        }

        @Override
        public void forceImpact(float force) {
            impactForce += force;
        }
    }

    private void buildGroundBlock(float x, float y) {
        PolygonShape groundShape = new PolygonShape();
        groundShape.setAsBox(5, 2);

        FixtureDef groundFixtureDef = new FixtureDef();
        groundFixtureDef.shape = groundShape;
        groundFixtureDef.friction = 0.2f;
        groundFixtureDef.density = 1.0f;
        groundFixtureDef.restitution = 0.2f;

        BodyDef groundBodyDef = new BodyDef();
        groundBodyDef.type = BodyDef.BodyType.StaticBody;

        Body ground = world.createBody(groundBodyDef);
        ground.createFixture(groundFixtureDef);
        ground.setTransform(x, y, 0);
    }

    @Override
    public void create() {
        float aspectRatio = (float) Gdx.graphics.getHeight() / (float) Gdx.graphics.getWidth();
        camera = new OrthographicCamera(100.0f, 100.0f * aspectRatio);
        camera.position.set(0.0f, 25.0f, 1.0f);
        camera.update();

        world = new World(new Vector2(0, -50), false);

        buildGroundBlock(-40.0f, 0.0f);
        buildGroundBlock(-25.0f, 0.0f);
        buildGroundBlock(25.0f, 0.0f);

        Ball ballA = new Ball(world, -32.5f, 50.0f);
        Ball ballB = new Ball(world, 25.0f, 75.0f);
        balls = new Ball[]{ballA, ballB};

        world.setContactListener(new ContactListener() {
            @Override
            public void beginContact(Contact contact) {
            }

            @Override
            public void endContact(Contact contact) {
            }

            @Override
            public void preSolve(Contact contact, Manifold oldManifold) {
            }

            @Override
            public void postSolve(Contact contact, ContactImpulse impulse) {
                Fixture fixtureA = contact.getFixtureA();
                Fixture fixtureB = contact.getFixtureB();

                Object userObjectA = fixtureA.getUserData();
                Object userObjectB = fixtureB.getUserData();

                int count = impulse.getCount();
                float totalForce = 0.0f;
                for (int i = 0; i < count; ++i) {
                    float fx = impulse.getNormalImpulses()[i * 2 + 0];
                    float fy = impulse.getNormalImpulses()[i * 2 + 1];
                    float force = (float) Math.sqrt(fx * fx + fy * fy);
                    totalForce += force;
                }

                if (userObjectA instanceof ForceListener)
                    ((ForceListener) userObjectA).forceImpact(totalForce);

                if (userObjectB instanceof ForceListener)
                    ((ForceListener) userObjectB).forceImpact(totalForce);
            }
        });

        soundRenderer = new ShapeRenderer();
        renderer = new Box2DDebugRenderer();
    }

    @Override
    public void render() {
        Gdx.gl.glClearColor(0, 0, 0, 0);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        world.step(Gdx.graphics.getDeltaTime(), 4, 6);

        for (Ball ball : balls)
            ball.update(Gdx.graphics.getDeltaTime());
        renderer.render(world, camera.combined);

        soundRenderer.setProjectionMatrix(camera.combined);
        soundRenderer.begin(ShapeRenderer.ShapeType.Filled);
        for (Ball ball : balls)
            ball.render(soundRenderer);

        soundRenderer.end();
    }
}

```
> 1 votes

---
Tags: libgdx, box2d
---


# Question
Title: How to check if two normals/directions "look at" each other?
I need to flip polygons in my application. How do I determine if two vectors face each other, like in the second image below? Note that the origin of the vectors is also important, in addition to the direction.

# Answer
> 2 votes
Given points `P0` and `P1` with normals `N1` and `N2`...

* Compute delta vector: `delta = P1 - P0`
* Compute dot product with normal: `dp0 = dot(delta, N0)`
* Compute dot product with normal: `dp1 = dot(delta, N1)`
* If `dp0` is positive, and `dp1` is negative then they see each other.

But frankly, this can be expressed even simpler:

***They both look at each other if each normal looks at the other point.***

`N0` looks at `P1` if `dot( P1-P0, N0 )` is positive.

`N1` looks at `P0` if `dot( P0-P1, N1 )` is positive.(\*)

or `dot (P1-P0, N1 )` is negative, as you already computed that vector for the first test.

# Answer
> 1 votes
Well, you can compare the distances between origins (`d1`) and points offset by the normals (`d2`) (scaled by fraction of the distance, to avoid overshoots). If the distance is smaller than between origins - normals are facing each other.

I'm not sure if you expect normals (-1;2 at 0;0) and (-2;2 at 2;0) to face each other or not though.

---
Tags: mathematics, normals, direction
---


# Question
Title: Cannot set SerializeField in Unity editor
I'm following a tutorial showing how to use the new input management system in Unity, but I'm stuck at this part:

I've created the InputSystem and a action map for my "player" object called `PlayerInputActions`, in it I defined a action called "Fire" which is bound to left mouse button and left shift (for testing). I've also added this action map to my "player" object as well as my C# script called `PlayerShooting`, it looks like this:

```
[SerializeField]
private PlayerInputActions playerInput;

private void OnEnable()
{
    Debug.Log("Enabling");
    playerInput.Player.Fire.performed += OnFire;
    playerInput.Player.Fire.Enable();
}

private void OnDisable()
{
    playerInput.Player.Fire.performed += OnFire;
    playerInput.Player.Fire.Disable();
}

private void OnFire(InputAction.CallbackContext context)
{
    Debug.Log("Fire");
}

```

Now the next step in the tutorial is running the game and looking at the output console to see if it worked or not, and of course for the guy doing the tutorial it worked, but I (expectedly) get an error in the console:

> NullReferenceException: Object reference not set to an instance of an object PlayerMovement.OnEnable () (at Assets/PlayerShooting.cs:12)
> NullReferenceException: Object reference not set to an instance of an object PlayerMovement.OnDisable () (at Assets/PlayerShooting.cs:18)
> Assets\PlayerShooting.cs(7,32): warning CS0649: Field 'PlayerMovement.playerInput' is never assigned to, and will always have its default value null

So I went back to editor to see if I can set the `playerInput` field of the `PlayerShooting` script on my "player" GameObject, but for some reason I can't see the field there.

So, how do I set the `playerInput` field on my "player" GameObject?

I reworked it a little and here is the new `PlayerInputActions`:

public class @PlayerControls : IInputActionCollection, IDisposable
{
    public InputActionAsset asset { get; }
    public @PlayerControls()
    {
        asset = InputActionAsset.FromJson(@"{
    ""name"": ""PlayerControls"",
    ""maps"": [
        {
            ""name"": ""Player"",
            ""id"": ""448d37d3-a4af-479e-8c8f-ad8fc97cb397"",
            ""actions"": [
                {
                    ""name"": ""Fire"",
                    ""type"": ""Button"",
                    ""id"": ""28cd5757-df8b-4428-85a0-c004ea56d718"",
                    ""expectedControlType"": """",
                    ""processors"": """",
                    ""interactions"": """"
                },
                {
                    ""name"": ""Jump"",
                    ""type"": ""Button"",
                    ""id"": ""ea20c10e-9876-44bf-9067-618e6fcdf724"",
                    ""expectedControlType"": """",
                    ""processors"": """",
                    ""interactions"": ""Press""
                },
                {
                    ""name"": ""Movement"",
                    ""type"": ""Button"",
                    ""id"": ""a07f2f71-ad1c-4a3b-837c-7fb5f7a3022e"",
                    ""expectedControlType"": """",
                    ""processors"": """",
                    ""interactions"": """"
                }
            ],
            ""bindings"": [
                {
                    ""name"": """",
                    ""id"": ""dec75062-6672-48d5-b1f5-ddec4799a18a"",
                    ""path"": ""<Mouse>/leftButton"",
                    ""interactions"": """",
                    ""processors"": """",
                    ""groups"": """",
                    ""action"": ""Fire"",
                    ""isComposite"": false,
                    ""isPartOfComposite"": false
                },
                {
                    ""name"": """",
                    ""id"": ""bfb9d278-bc38-4552-9d4f-7946469ddb3c"",
                    ""path"": ""<Keyboard>/space"",
                    ""interactions"": """",
                    ""processors"": """",
                    ""groups"": """",
                    ""action"": ""Jump"",
                    ""isComposite"": false,
                    ""isPartOfComposite"": false
                },
                {
                    ""name"": ""WASD"",
                    ""id"": ""0d93449f-0f8f-4d2c-baa3-89f3a45e34f8"",
                    ""path"": ""2DVector"",
                    ""interactions"": """",
                    ""processors"": """",
                    ""groups"": """",
                    ""action"": ""Movement"",
                    ""isComposite"": true,
                    ""isPartOfComposite"": false
                },
                {
                    ""name"": ""up"",
                    ""id"": ""2fe6e7ba-01af-4e5c-b061-8ed2f30331ba"",
                    ""path"": ""<Keyboard>/w"",
                    ""interactions"": """",
                    ""processors"": """",
                    ""groups"": """",
                    ""action"": ""Movement"",
                    ""isComposite"": false,
                    ""isPartOfComposite"": true
                },
                {
                    ""name"": ""down"",
                    ""id"": ""3e6c2b0b-f283-4e00-a7b6-f51b44ec6c76"",
                    ""path"": ""<Keyboard>/s"",
                    ""interactions"": """",
                    ""processors"": """",
                    ""groups"": """",
                    ""action"": ""Movement"",
                    ""isComposite"": false,
                    ""isPartOfComposite"": true
                },
                {
                    ""name"": ""left"",
                    ""id"": ""42a6d504-4650-4c5f-92ef-b58c2d9450d7"",
                    ""path"": ""<Keyboard>/a"",
                    ""interactions"": """",
                    ""processors"": """",
                    ""groups"": """",
                    ""action"": ""Movement"",
                    ""isComposite"": false,
                    ""isPartOfComposite"": true
                },
                {
                    ""name"": ""right"",
                    ""id"": ""bf4596ba-08bb-4809-92c0-90dd781463ad"",
                    ""path"": ""<Keyboard>/d"",
                    ""interactions"": """",
                    ""processors"": """",
                    ""groups"": """",
                    ""action"": ""Movement"",
                    ""isComposite"": false,
                    ""isPartOfComposite"": true
                },
                {
                    ""name"": ""Arrows"",
                    ""id"": ""a972e8d8-1528-4f42-9dc2-ec84ca3636f3"",
                    ""path"": ""2DVector"",
                    ""interactions"": """",
                    ""processors"": """",
                    ""groups"": """",
                    ""action"": ""Movement"",
                    ""isComposite"": true,
                    ""isPartOfComposite"": false
                },
                {
                    ""name"": ""up"",
                    ""id"": ""b3df1bd6-964e-400f-a847-1ecca2a2e995"",
                    ""path"": ""<Keyboard>/upArrow"",
                    ""interactions"": """",
                    ""processors"": """",
                    ""groups"": """",
                    ""action"": ""Movement"",
                    ""isComposite"": false,
                    ""isPartOfComposite"": true
                },
                {
                    ""name"": ""down"",
                    ""id"": ""c77c1ea6-b730-4600-bb1c-b156750e607d"",
                    ""path"": ""<Keyboard>/downArrow"",
                    ""interactions"": """",
                    ""processors"": """",
                    ""groups"": """",
                    ""action"": ""Movement"",
                    ""isComposite"": false,
                    ""isPartOfComposite"": true
                },
                {
                    ""name"": ""left"",
                    ""id"": ""c8ddea3a-a62c-42cc-a5e8-b8bef3737f20"",
                    ""path"": ""<Keyboard>/leftArrow"",
                    ""interactions"": """",
                    ""processors"": """",
                    ""groups"": """",
                    ""action"": ""Movement"",
                    ""isComposite"": false,
                    ""isPartOfComposite"": true
                },
                {
                    ""name"": ""right"",
                    ""id"": ""555665d5-d351-4bef-8eba-3335074297b9"",
                    ""path"": ""<Keyboard>/rightArrow"",
                    ""interactions"": """",
                    ""processors"": """",
                    ""groups"": """",
                    ""action"": ""Movement"",
                    ""isComposite"": false,
                    ""isPartOfComposite"": true
                }
            ]
        }
    ],
    ""controlSchemes"": []
}");
        // Player
        m_Player = asset.FindActionMap("Player", throwIfNotFound: true);
        m_Player_Fire = m_Player.FindAction("Fire", throwIfNotFound: true);
        m_Player_Jump = m_Player.FindAction("Jump", throwIfNotFound: true);
        m_Player_Movement = m_Player.FindAction("Movement", throwIfNotFound: true);
    }

    public void Dispose()
    {
        UnityEngine.Object.Destroy(asset);
    }

    public InputBinding? bindingMask
    {
        get => asset.bindingMask;
        set => asset.bindingMask = value;
    }

    public ReadOnlyArray<InputDevice>? devices
    {
        get => asset.devices;
        set => asset.devices = value;
    }

    public ReadOnlyArray<InputControlScheme> controlSchemes => asset.controlSchemes;

    public bool Contains(InputAction action)
    {
        return asset.Contains(action);
    }

    public IEnumerator<InputAction> GetEnumerator()
    {
        return asset.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public void Enable()
    {
        asset.Enable();
    }

    public void Disable()
    {
        asset.Disable();
    }

    // Player
    private readonly InputActionMap m_Player;
    private IPlayerActions m_PlayerActionsCallbackInterface;
    private readonly InputAction m_Player_Fire;
    private readonly InputAction m_Player_Jump;
    private readonly InputAction m_Player_Movement;
    public struct PlayerActions
    {
        private @PlayerControls m_Wrapper;
        public PlayerActions(@PlayerControls wrapper) { m_Wrapper = wrapper; }
        public InputAction @Fire => m_Wrapper.m_Player_Fire;
        public InputAction @Jump => m_Wrapper.m_Player_Jump;
        public InputAction @Movement => m_Wrapper.m_Player_Movement;
        public InputActionMap Get() { return m_Wrapper.m_Player; }
        public void Enable() { Get().Enable(); }
        public void Disable() { Get().Disable(); }
        public bool enabled => Get().enabled;
        public static implicit operator InputActionMap(PlayerActions set) { return set.Get(); }
        public void SetCallbacks(IPlayerActions instance)
        {
            if (m_Wrapper.m_PlayerActionsCallbackInterface != null)
            {
                @Fire.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnFire;
                @Fire.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnFire;
                @Fire.canceled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnFire;
                @Jump.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnJump;
                @Jump.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnJump;
                @Jump.canceled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnJump;
                @Movement.started -= m_Wrapper.m_PlayerActionsCallbackInterface.OnMovement;
                @Movement.performed -= m_Wrapper.m_PlayerActionsCallbackInterface.OnMovement;
                @Movement.canceled -= m_Wrapper.m_PlayerActionsCallbackInterface.OnMovement;
            }
            m_Wrapper.m_PlayerActionsCallbackInterface = instance;
            if (instance != null)
            {
                @Fire.started += instance.OnFire;
                @Fire.performed += instance.OnFire;
                @Fire.canceled += instance.OnFire;
                @Jump.started += instance.OnJump;
                @Jump.performed += instance.OnJump;
                @Jump.canceled += instance.OnJump;
                @Movement.started += instance.OnMovement;
                @Movement.performed += instance.OnMovement;
                @Movement.canceled += instance.OnMovement;
            }
        }
    }
    public PlayerActions @Player => new PlayerActions(this);
    public interface IPlayerActions
    {
        void OnFire(InputAction.CallbackContext context);
        void OnJump(InputAction.CallbackContext context);
        void OnMovement(InputAction.CallbackContext context);
    }
}

```
</code></pre>

# Answer
With the newer versions you need to instantiate the controls like so

```
    private void Awake() {
        playerInput = new PlayerInputActions();
    }
    private void OnEnable() {
        playerInput.Enable();
    }
    private void OnDisable() {
        playerInput.Disable();
    }
    void Start()
    {
        playerInput.Player.Fire.performed += _ => OnFire();
    }

```

I have a tutorial here for more information: Link
> 1 votes

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


# Question
Title: 2D Side-scrolling Strategy Game Pathfinding Help
Hey Guys,I am trying to implement dungeons into my 2d RTS ish game.The dungeons is made out of rooms, you start at the top, and you can unlock rooms with scouts.The picture is the unlocked version of the dungeons, except for the middle part where it says "locked".For example the long rooms in the picture are actually consists of 3-4 rooms. The dungeon is handbuilt by me, there are no obstacles except for unlocked areas and walls.No need for collision avoidance.The boxes with up and down indicates "ladders", when a unit wants to go up/down it just fades out and fades in the new layer, no moving up/down animation.You control the units by mouse.No jump mechanic etc, they just move flat on the green areas.

---

So I think I need to calculate and store which ladders(or nodes) the unit needs to take to reach the target, I need to check if ladders are connected to each other I think.But I don't know, not a great programmer.I have looked into A*star and dijkstra's algorithms but they seem complicated to implement, there is a built in A*star in gamemaker but it uses grid system and doesn't seem to fit to my problem. Do I really need to learn one of those algorithms or can I get away with a simpler approach?Any pseudo code you guide me with?I would really appreciate the help.I know a bit of c# and unity.Thanks a lot!

# Answer
> 0 votes
**For a single agent or multiple non-colliding agents**

Try hill-climbing, how a hound might follow a scent, or the game of "you're getting warmer".

The way to do this is to pick the target node you want to do to, then diffuse a (floating point) scent value outward from the target room, through it's neighbouring nodes; then their neighbouring nodes; and so on till the whole graph is covered (you will need a suitable reduction formula as the scent spreads outwards). These scent maps are also commonly known as *heat maps*. The dark blue in this image looks like your where your target room would be diffusing heat / scent outward:

(Obviously it will look a little different in your case, but the principle is the same.)

Once there is scent spread throughout the map, you walk the entity from the current room to the neighbour with higher scent, until there are no more neighbours with a higher scent, at which point you've reached the target room.

For your locked door, we lock that tile or room to a scent value of 0 - this means it is never an attractive location to walk to. Unlocking the door means that location can once again receive scent, just like any other.

**For multiple colliding agents**

Collaborative Diffusion is conceptually simpler than A\* if not as efficient in all cases (which for a simple game like yours, won't matter). It is hill-climbing, but supports having multiple (colliding) agents avoid one another.

---
Tags: 2d, game-mechanics, path-finding, platformer, side-scroller
---


title: What is root.json file in Minecraft?

text:
# Question
Title: What is root.json file in Minecraft?
I found root.json file in minecraft source code and I want to know what is root.json file in minecraft. I found minecraft source code with VS Code Decompiler extension.(For find minecraft source code, first go in the VS Code and download Decompiler extension and then open .minecraft folder and then open versions folder and then select your version folder and then decompile jar file with VS Code Decompiler extension.)

root.json file is datapack file.

# Answer
I'm not sure if this is the root.json that you're describing, since you haven't listed any identifying contents or folder paths in your question, like this:

```
data/minecraft/advancements/story/root.json

```

But if this is what you're looking at, then it looks like this file describes the start of one of the "Advancement" trees in the game. For this example, it's the first achievement in the "Minecraft" / "Story" tab (on the far left of this image):

The first part of the file covers what should be shown for this advancement in the UI, including an icon image (for the first/root node in the tree, this icon is also used for the menu tab itself), localized text IDs for its title and description, and what icon frame shape the advancement should use.

It also defines whether the advancement should show an on-screen toast or be announced to the chat upon completion.

The root (first) node in the advancement tree also defines what background texture to use for the menu tab containing its tree.

```
  "display": {
    "icon": {
      "item": "minecraft:grass_block"
    },
    "title": {
      "translate": "advancements.story.root.title"
    },
    "description": {
      "translate": "advancements.story.root.description"
    },
    "frame": "task",
    "show_toast": false,
    "announce_to_chat": false,
    "hidden": false,
    "background": "minecraft:textures/gui/advancements/backgrounds/stone.png"
  },

```

The next section defines the trigger conditions that will lead to the advancement completing - in this example, when the player gets a crafting table in their inventory:

```
  "criteria": {
    "crafting_table": {
      "trigger": "minecraft:inventory_changed",
      "conditions": {
        "items": [
          {
            "item": "minecraft:crafting_table"
          }
        ]
      }
    }
  },
  "requirements": [
    [
      "crafting_table"
    ]
  ]
}

```

Other json files in the folder look quite similar, but they'll also have an extra line at the top:

```
"parent": "minecraft:story/root",

```

...which indicates which node comes before them in the tree.
> 0 votes

---
Tags: minecraft-modding
---


# Question
Title: How do I spread a LookAt rotation over 3 bones with different percentages?
I'm trying to rebuild the RE4 controller.

At first, I thought that only the chest bone is used to rotate the pistol towards a target. I have then however found a hack to put the camera in a fixed position so that I could actually see the bone rotations.

Juding the logic that I have recorded, I believe that first a LookAt rotation is used, and then this rotation is spread over the abdomen, abdomen2 and chest bones.

Looking at the video that I have recorded, I think that the rotation is not "divided by 3", but procentually and then again changing towards the limits (for example, at the limits, the rotation is mostly done only by the chest).

Can anybody tell me if my judgement is correct, and if yes, how to split a rotation this way?

Would this be correct?

--\>

The chest bone moves the most, the abdomen2 less, and the abdomen bone moves the least. In percentages:

* chest bone: 60%
* abdomen2 bone: 30%
* abdomen bone: 10%

Let's assume a rotation of 200°.

Am I right to assume that the rotation of each bone is calculated like this?

Chest bone: Gets 60% of 200°, that is 120°

Abdomen2 bone: Gets 30% of 200°, that is 60°

Abdomen bone: Gets 10% of 200°, that is 20°.

Thank you!

ps: Here are a few screenshots, but it's much easier to estimate from the video:

# Answer
> 1 votes
You can blend between two orientations like so:

```
void PartlyRotateBone(Transform bone, Quaternion targetRotation, float strength) {
    bone.rotation = Quaternion.Slerp(bone.rotation, targetRotation, strength);
}

```

Here, `strength` gives a linear blend from the bone's existing/animated rotation when it's zero, to the target rotation when it's 1, with even steps along the way.

You could also use `Quaternion.Lerp`, which is a little cheaper, but slightly non-uniform. The rotation gets biased toward the source for `strength < 0.5f`, and toward the target for `strength > 0.5f`, for a slight "ease in-out" curve that might even be desirable for your uses.

You can then construct and apply your rotation something a bit like this:

```
Quaternion targetRotation = Quaternion.LookRotation(lookDirection, lookUp);

PartlyRotateBone(abdomen, targetRotation, 0.1f);
PartlyRotateBone(abdomen2, targetRotation, 0.3f);
PartlyRotateBone(chest, targetRotation, 0.6f);

```

Be sure to work from the root of the armature toward the leaves - because each time you apply one of these rotations, you change the rotations of all downstream bones.

You should also factor that into the percentages you choose. Let's say my three bones are all in a straight stack, facing North, and my target rotation is 90 degrees East. Even if I choose the same strength of 0.5 for each bone, the top bone will twist more, because it inherits the twist of the bones below it:

* `abdomen` rotates halfway between its current (0 degrees North) to the target (90 degrees East), to face 45 degrees North-East
* `abdomen2` rotates halfway between its current (45 degrees North-East) to the target (90 degrees East), to face 67.5 degrees East-by-North-East
* `chest` rotates halfway between its current (67.5 degrees East-by-North-East) to the target (90 degrees East), to face 78.75 degrees East-by-North-East.

You can use an AnimationCurve to choose your rotation strength values as a function of your target angle, which can help you shift which bones twist more or less aggressively at different angle ranges, in a smoothly continuous way.

---
Tags: animation, rotation
---


# Question
Title: Unity C# Invoke Function Freezes Program
```
if(Input.GetKeyDown(KeyCode.G) && ammo <= 9)
        {
            ableS = false;
            while(ammo <= 9)
            {
                Invoke("bulletplus", 0.5f);
            }
            ableS = true;
        }

```

This is the main part I am having trouble with.

Down there is ALL my code:

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

public class gun : MonoBehaviour
{
    Vector2 rotation = new Vector2 (0, 0);
    public float rot = 3;
    public Vector3 pos;
    public Rigidbody Orb;
    public Text ammoT;
    public int ammo = 10;
    bool ableS = true;

    void Update () {
        // Ammo
        if(ammo >= 7)
        {
            ammoT.GetComponent<Text>().color = Color.green;
        } else if(ammo >= 4)
        {
            ammoT.GetComponent<Text>().color = Color.yellow;
        } else {
            ammoT.GetComponent<Text>().color = Color.red;
        }

        // Rotation
        rotation.x += -Input.GetAxis ("Mouse Y");
        rotation.x = Mathf.Clamp(rotation.x, -70, 70);
        rotation.y += Input.GetAxis("Mouse X");
        transform.eulerAngles = (Vector2)rotation * rot;
        pos = new Vector3(transform.position.x, transform.position.y, transform.position.z);

        // Shoot Choklats
        if(Input.GetMouseButtonDown(0) && ammo >= 1 && ableS)
        {
            ammoT.text = "Ammo: " + ammo.ToString();
            ammo -= 1;
            Rigidbody projectile = Instantiate(Orb, pos, transform.rotation);
            projectile.velocity = transform.forward * 50f;
        }

        // Reload
        if(Input.GetKeyDown(KeyCode.G) && ammo <= 9)
        {
            ableS = false;
            while(ammo <= 9)
            {
                Invoke("bulletplus", 0.5f);
            }
            ableS = true;
        }
    }

    void bulletplus()
    {
        ammo += 1;
        ammoT.text = "Ammo: " + ammo.ToString();
    }
}

```

# Answer
> 1 votes
You seem to be under the impression that this line of code asks to do multiple things:

```
Invoke("bulletplus", 0.5f);

```
* **Schedule the method named "bulletplus" to be called 0.5 seconds from now.**
* Pause the execution of the current method we called it from, and let the rest of the engine continue running its updates and rendering for the frame.
* Don't resume this method until "bulletplus" has run to completion. After that, resume the calling method with its prior state on the next line after the `Invoke`.

In actual fact, it only does the first line, in bold. Pausing and resuming the calling method are not features it offers according to the documentation. You can verify this yourself with a simple test:

```
void Start()
{
    Debug.LogFormat("{0}: Start starts at {1}", ++callOrder, Time.time);
    Invoke("InvokeReporter", 0.5f);
    Debug.LogFormat("{0}: Start finishes at {1}", ++callOrder, Time.time);
}

void InvokeReporter() {
    Debug.LogFormat("{0}: Invoked method runs at {1}", ++callOrder, Time.time);
}

```

You can see `Invoke` does not add any delay between the first and second halves of `Start` \- they run back-to-back in the same frame.

So, as was pointed out to you in the comments, this is an infinite loop:

```
while(ammo <= 9)
{
     Invoke("bulletplus", 0.5f);
}

```

Scheduling an invocation of "bulletplus" to happen later does not increase the value of the `ammo` variable now. So if `ammo` was less than 10 when we entered the loop, it will still be less than 10 no matter how many times we repeat the loop, and we can never escape.

Apart from a coroutine hitting a `yield` statement, Unity executes each MonoBehaviour message method completely, from top to bottom or the first `return` statement, before moving on to the next object/message or proceeding with any of the other work of the frame.

So if your `Update` method gets stuck in this infinite loop and never returns, then Unity is stuck executing it endlessly, unable to move onto the next script that needs updating, or draw a new frame, or process new input. Your game hangs because the engine can't get to updating the window.

It looks like what you want is a coroutine something like this:

```
Vector2 rotation = new Vector2 (0, 0);
public float rotationSpeed = 3;
public Rigidbody projectilePrefab;

public Text ammoText;
public int ammo = 10;
bool reloadInProgress = false;

void Update () {
    // Rotation
    rotation.x += -Input.GetAxis ("Mouse Y") * rotationSpeed;
    rotation.x = Mathf.Clamp(rotation.x, -70, 70);
    rotation.y += Input.GetAxis("Mouse X") * rototationSpeed;
    rotation.y %= 360.0f;
    transform.eulerAngles = rotation;

    // Can't shoot or start another reload while already reloading.
    if(reloadInProgress)
        return;

    if(Input.GetMouseButtonDown(0) && ammo >= 1)
    {
        UpdateAmmo(-1);
        Rigidbody projectile = Instantiate(
                                 projectilePrefab,
                                 transform.position,
                                 transform.rotation);
        projectile.velocity = transform.forward * 50f;
    }

    // Reload
    if(Input.GetKeyDown(KeyCode.G) && ammo <= 9)
    {
        // Start a method that can take turns with the engine,
        // pausing for multiple frames then resuming when needed.
        StartCoroutine(Reload());
    }
}

IEnumerator Reload() {
    reloadInProgress = true;

    while(ammo <= 9) {
        // Put this coroutine on hold for a period of time,
        // while letting the rest of the game run.
        yield return new WaitForSeconds(0.5f);
        // Then resume our execution on the next line:
        UpdateAmmo(+1);
    }

    reloadInProgress = false;
}

// Let's do this update work only when the ammo changes, not every frame.
void UpdateAmmo(int ammoChange) {
    ammo += ammoChange;
    ammoText.text = "Ammo: " + ammo.ToString();

    if(ammo >= 7) {
        ammoText.color = Color.green;
    } else if(ammo >= 4) {
        ammoText.color = Color.yellow;
    } else {
        ammoText.color = Color.red;
    }
}

```

---
Tags: unity
---


# Question
Title: How can I color in only specific regions of my scene?
I am interested in having large portions of my game be grayscale, but I'd like certain parts of the scene to have full color.

Something like this:

Is this something that is possible with shaders or the like within unity? What sort of techniques would I need in order to leech color from most areas like in my screenshot above?

# Answer
One of my favourite tricks in Unity is the `OnRenderImage` method. Put this on a script on your camera, and you get to intercept the image the camera has just rendered, and change it any way you like before it gets passed along to the screen or the next rendering pass.

We'll use this to make a script that takes a material and applies it as a post-process effect to the scene:

```
[ExecuteInEditMode]
public class PostFilter : MonoBehaviour
{
    public Material filter;

    private void OnRenderImage(RenderTexture source, RenderTexture destination) {
        if (filter == null)
            Graphics.Blit(source, destination);
        else
            Graphics.Blit(source, destination, filter);
    }
}

```

Next we need a way to encode which parts of the image should stay colourful. For that, my thought is to use the alpha channel of the image. We'll make a simple shader we can slap on some spheres that will write out a radial gradient into the alpha channel, while keeping the RGB channels the same. I've set this to use Max blending, so if you have two of these gradients overlapping, you'll keep the brighter value.

```
Shader "Unlit/GlowBall"
{
    Properties
    {
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }
        LOD 100

        BlendOp Max
        ZWrite Off

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL0;
            };

            struct v2f
            {
                float3 normal : TEXCOORD0;
                float3 view : TEXCOORD1;
                float4 vertex : SV_POSITION;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.normal = mul(UNITY_MATRIX_IT_MV, v.normal);
                o.view = -UnityObjectToViewPos(v.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float fresnel = saturate(dot(normalize(i.normal), normalize(i.view)));
                return float4(0, 0, 0, fresnel * fresnel);
            }
            ENDCG
        }
    }
}

```

But we want our alpha channel to be zero before these are drawn, so we get fully desaturated colours everywhere else. So we'll write a filter we can use with our post effect script to erase the alpha channel of the rendered scene image:

```
Shader "Effect/Tint"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Color ("Tint Colour", Color) = (1, 1, 1, 0)
    }
    SubShader
    {
        // No culling or depth
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            fixed4 _Color;

            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;

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);

                return col * _Color;
            }
            ENDCG
        }
    }
}

```

Create a material with this shader, set the tint colour to (1, 1, 1, 0), and assign it as the filter on the `PostFilter` script on your main camera. Now it's outputting the scene image to the screen with the alpha channel blacked-out and ready for our next step.

Next we need to render our glow balls in a second pass, after we've erased the scene's alpha. So we'll duplicate the main camera, and make the new copy a child of the original, so they move together.

Set the clear flags on the new camera to "Don't Clear", and its Depth to 0 (after the default Main Camera's -1), so we draw over the existing scene image).

Set the culling flags so your new camera sees only the glow balls, and the main camera sees everything BUT the glow balls.

So once this camera has rendered, we'll have our scene image, with bright alpha *only* where we have our gradient spheres placed. One last post-effect filter on this child camera will then turn that alpha mask into colour saturation before presenting the image to the screen:

```
Shader "Effect/SelectiveDesaturate"
{
    Properties
    {
        _MainTex ("Texture", 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;

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);

                float desaturated = dot(col.rgb, float3(0.2126f, 0.7152f, 0.0722f));

                col = lerp(desaturated, col, col.a);

                return col;
            }
            ENDCG
        }
    }
}

```

You can see these balls will now add saturation to anything inside/behind them, but can still be occluded by desaturated objects in front of them (like the studs at the top of the image, or the grey jigsaw on the right).
> 1 votes

---
Tags: unity, shaders, graphic-effects
---


# Question
Title: How to calculate the surface area of a mesh
I am looking for a way to **calculate surface area of a 3D mesh object** and found this code from a Unity forum:

```
 public float Area(Mesh m)
 {
     Vector3[] mVertices = m.vertices;
     Vector3 result = Vector3.zero;
     for (int p = mVertices.Length - 1, q = 0; q < mVertices.Length; p = q++)
     {
         result += Vector3.Cross(mVertices[q], mVertices[p]);
     }
     Debug.Log(result);
     result *= 0.5f;
     return result.magnitude;
 }

```

But the problem is that it is not providing the correct area as I have found from testing the fbx with Revit. Revit is showing a different surface area from what this code shows.

Here is a sample mesh

**Front**

**Back**

**Top**

Its surface area as calculated by the function above is 97.4913,
while in Revit it's actually 52.811 \\$m^2\\$.

I don't know how revit calculate it but it provide area and volume information automatically (i have no idea how even revit works).

# Answer
> 9 votes
Looking at the formula you're using, it looks like it's designed to calculate the area of a planar polygon, where the vertices are all in clockwise / counterclockwise order about the perimeter.

That's not the same as a 3D mesh.

Try something like this instead:

* we'll iterate over the triangles of the mesh
* for each triangle, we'll compute vectors representing the two edges
* half the magnitude of the cross product of these edges gives us the area of the triangle
* we'll sum these triangle areas to accumulate the full surface area

Note that if your mesh has any double-sided faces or internal faces, they can bias this result.

```
float CalculateSurfaceArea(Mesh mesh) {
    var triangles = mesh.triangles;
    var vertices = mesh.vertices;

    double sum = 0.0;

    for(int i = 0; i < triangles.Length; i += 3) {
        Vector3 corner = vertices[triangles[i]];
        Vector3 a = vertices[triangles[i + 1]] - corner;
        Vector3 b = vertices[triangles[i + 2]] - corner;

        sum += Vector3.Cross(a, b).magnitude;
    }

    return (float)(sum/2.0);
}

```

Since it now looks like you want to compute just the area of the mesh facing in a particular direction, you can try this version instead. Pass the direction you want to view the mesh from and it should compute the projected surface area of the faces facing at least partially in that direction.

```
float CalculateFacingArea(Mesh mesh, Vector3 direction) {
    direction = direction.normalized;
    var triangles = mesh.triangles;
    var vertices = mesh.vertices;

    double sum = 0.0;

    for(int i = 0; i < triangles.Length; i += 3) {
        Vector3 corner = vertices[triangles[i]];
        Vector3 a = vertices[triangles[i + 1]] - corner;
        Vector3 b = vertices[triangles[i + 2]] - corner;

        float projection = Vector3.Dot(Vector3.Cross(b, a), direction);
        if (projection > 0f)
            sum += projection;
    }

    return (float)(sum/2.0);
}

```

# Answer
> 1 votes
Shamelessly building on DMGregorys answer..

You can also define this as an extension method for the `Mesh` class.

```
// Put this in some static Util class
public static float CalculateSurfaceArea(this Mesh mesh) {
    var triangles = mesh.triangles;
    var vertices = mesh.vertices;

    double sum = 0.0;

    for (int i = 0; i < triangles.Length; i += 3) {
        Vector3 corner = vertices[triangles[i]];
        Vector3 a = vertices[triangles[i + 1]] - corner;
        Vector3 b = vertices[triangles[i + 2]] - corner;

        sum += Vector3.Cross(a, b).magnitude;
    }

    return (float)(sum / 2.0);
}

```

you can now simply call

```
Mesh mesh = Surface.GetComponent<MeshFilter>().sharedMesh;
float area = mesh.CalculateSurfaceArea();

```

---
Tags: unity, c#, mathematics, geometry, computational-geometry
---


title: Plotting a pseudo 3D globe

text:
# Question
Title: Plotting a pseudo 3D globe
I would like to plot a small globe where the main character can walk, exactly like Sonic & Knukles Bonus Stage. For those who won't google it, here is a picture.

I am familiar with Raycasting, used in Wolfenstein and other games to "simulate" a 3D perspective in a 2D map.

But I could not figure how to program the globe thing, and I suppose that it was not a real 3D rendering, as Sonic was a 16 bit game.

Any idea on how to do it without any sofisticated 3D engine?

# Answer
**Overview**

* Set up an endless 1D track of 2x 2D planes. As you run forward, the plane behind you comes forward to keep you running; this keeps happening repeatedly whether you run forward or backward.
* Now do the same thing in 2D i.e with 2x2 2D planes. Wherever you go, the world continues beneath your feet.
* Transform the planes to a perspective view.
* Now create a spherical bulge effect through screen space transformation i.e. by adjusting all the ground pixels to make them appear curved, even though it's really flat, repeating surface.
* Even when the character rotates 90 degrees over a few frames, this still shows the same curved-world effect.

**3D Planes in 2D**

Let's assume you have 2x2 flat planes rendering on your screen as squares (viewed top down), and you can move around on them as described above.

We now need to transform these planes (collectively), viewed top down, to an oblique-to-ground perspective.

This is done in 2 steps:

1. squeeze the combined ground plane so that its upper half "pinches" to the width of the viewport and its lower half exceeds the width of the viewport. This is done using `yRatio` as calculated in the code section below, i.e. the closer we are to the top, the more we scale `x` in order to pinch the top of the square so it looks like a frustum or triangle.
2. Scale it down and reposition it in y so that its bottom is flush with bottom of viewport, and its top is (say) at midway down the screen - this is your horizon.

Both of these steps are dependent on where the player is currently standing.

**Curvature**

A semicircle formula is needed for the transformation of pixels, which will be displaced along screen y to achieve the bulge effect. This part is left to your research.

```
semicircleDisplace(xCurrent)
{

    //formula to calculate maximal (horizon) yDisplacement from xCurrent
    //...

    return yDisplacement;
}

pixels[xCurrent][yCurrent].y += semicircleDisplace(xCurrent);

```

The problem with this is that we bulge *all* the pixels just as much near the bottom of the screen, as near the top, leading to a sort of upside-down U look to the terrain, when what we really want near the bottom of the screen is a nearly straight line; midway, some displacement / bulge; and at the horizon, maximal displacement. We achieve this by using a (possibly linear) interpolated factor:

```
semicircleDisplace(xCurrent, yCurrent)
{

    //formula to calculate maximal (horizon) yDisplacement from xCurrent
    //...

    //linear interpolation based on where we are between bottom of screen and horizon
    yRange  = yMax - yMin
    yRatio  = yCurrent - yMin
    yFactor = yRatio / yRange

    return yDisplacement * yFactor;

}
pixels[xCurrent][yCurrent].y += semicircleDisplace(xCurrent, yCurrent);

```

`yFactor` is a value between `0.0` and `1.0` by which you multiply `yDisplacement`. If linear interpolation (which is cheap) doesn't give a great look, you can play with non-linear interpolations to achieve the right sort of ground curvature look. But my guess is linear will look just fine.
> 1 votes

---
Tags: 3d, raycasting
---


title: Json deserialize problem

text:
# Question
Title: Json deserialize problem
I made some editor window to add and edit some stuff. I decided to use Json, because I thought it would be easy.

I have some class `Card` in the Assets/Scripts folder. I have `NewCardsEditor` in the Assets/Editor folder. When I click the "Save" button, it works perfect. But when I open this window again, I receive this error message:

> ArgumentException: Cannot deserialize JSON to new instances of type 'Card.'

Code is too long, I'll only add those parts which appear relevant to me. When you need more code, please comment.

Part of `Card` class:

```
public class Card : MonoBehaviour
    {
        [SerializeField] [Tooltip("Название карты")] private string _name;
        [SerializeField] [Tooltip("Название карты для игрока")] private string _inGameName;
        [SerializeField] [Tooltip("Стоимость карты")] [Range(0, 10)] private int _cost;
        [SerializeField] [Tooltip("Uncheck, если стоимость в ОД")] private bool _manaSpell;
        [Space(10)]
        [SerializeField] [Tooltip("Вызываемое существо")] private GameObject _creature;

        #region Бонус, если он есть
        [Space(10)]
        [Header("Бонус, если его нет - не заполнять")]

        [SerializeField] [Tooltip("Название заклинания")] private string _bonusName;
        [SerializeField] [Tooltip("Тип бонуса/заклинания(Для вызова в функции)")] private string _bonusType;
        [SerializeField] [Tooltip("Полное описание бонуса")] private string _bonusFullName;
        [SerializeField] [Tooltip("Цель/цели заклинания/бонуса")] private string _bonusTarget;
        [SerializeField] [Tooltip("Значение атаки. Если оно не нужно - 0")] private int _bonusAtt;
        [SerializeField] [Tooltip("Значение HP. Если оно не нужно - 0")] private int _bonusHP;
        #endregion

        /// <summary>
        /// True если карта с вызовом существа
        /// </summary>
        private bool _isCreature;
        /// <summary>
        /// true если карта на столе, false - в руке
        /// </summary>
        private bool _isActive = false;
#region Для редактора
        /// <summary>
        /// Название карты
        /// </summary>
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
        /// <summary>
        /// Название карты для игрока
        /// </summary>
        public string InGameName
        {
            get { return _inGameName; }
            set { _inGameName = value; }
        }
        /// <summary>
        /// Стоимость карты
        /// </summary>
        public int Cost
        {
            get { return _cost; }
            set { _cost = value; }
        }
        /// <summary>
        /// Стоимость в мане?
        /// </summary>
        public bool IsManaSpell
        {
            get { return _manaSpell; }
            set { _manaSpell = value; }
        }
        /// <summary>
        /// Существо ли это?
        /// </summary>
        public bool IsCreature
        {
            get { return _isCreature; }
            set { _isCreature = value; }
        }
        /// <summary>
        /// Существо, если карта - вызов существа
        /// </summary>
        public GameObject CardsCreature
        {
            get { return _creature; }
            set { _creature = value; }
        }

        #region Бонус и вся его инфа
        /// <summary>
        /// Имя бонуса
        /// </summary>
        public string BonusName
        {
            get { return _bonusName; }
            set { _bonusName = value; }
        }
        /// <summary>
        /// Тип бонуса
        /// </summary>
        public string BonusType
        {
            get { return _bonusType; }
            set { _bonusType = value; }
        }
        /// <summary>
        /// Полное описание бонуса
        /// </summary>
        public string BonusFullName
        {
            get { return _bonusFullName; }
            set { _bonusFullName = value; }
        }
        /// <summary>
        /// Цель бонуса
        /// </summary>
        public string BonusTarget
        {
            get { return _bonusTarget; }
            set { _bonusTarget = value; }
        }
        /// <summary>
        /// Значение Attack бонуса
        /// </summary>
        public int BonusAtt
        {
            get { return _bonusAtt; }
            set { _bonusAtt = value; }
        }
        /// <summary>
        /// Значение НР бонуса
        /// </summary>
        public int BonusHP
        {
            get { return _bonusHP; }
            set { _bonusHP = value; }
        }
        #endregion

        /// <summary>
        /// Если нужно применить карту - true
        /// </summary>
        public bool Active
        {
            get { return _isActive; }
            set { _isActive = value; }
        }
        #endregion

```

Here is `NewCardsEditor` editor window(part):

```
#region Переменные

    List<Card> cardsList = new List<Card>();
    string savePath;

    //Для удобства в редакторе
    /// <summary>
    /// Типы стоимости карт
    /// </summary>
    string[] costTypes = { "action", "mana" };
    /// <summary>
    /// Типы карт
    /// </summary>
    string[] spellTypes = { "Creature", "Spell" };
    int indexCost, indexType;
    /// <summary>
    /// Все возможные цели заклинаний
    /// </summary>
    string[] targets = { "Summoner", "Enemy", "Summoner and enemy", "Elly creature", "Enemy creature",
        "All ally's creatures", "All enemy's creatures", "All creatures", "Everyone"};
    /// <summary>
    /// Выбранная цель(индекс). Для записи выбранной цели
    /// </summary>
    int indexTarget;

    //Переменные-составляющие карты
    string _name, _inGameName;
    int _cost;
    bool _isManaSpell;
    bool _isCreature;

    GameObject _creature;
    //Далее параметры бонуса
    string _bonusName, _bonusFullName;
    string _bonusType;
    string _bonusTarget;
    int _bonusAtt, _bonusHP;

    #endregion

private void OnEnable()
    {
        savePath = Application.dataPath + "/SaveData/Cards.txt";

        if (File.Exists(savePath))
        {
            if (File.ReadAllLines(savePath).Length != 0)
            {
                foreach (string s in File.ReadAllLines(savePath))
                {
                    cardsList.Add(JsonUtility.FromJson<Card>(s));
                }
            }
        }
        else
        {
            File.Create(savePath);
        }
    }

...

if (GUILayout.Button(new GUIContent("Save", "Сохраняет карту(-ы) в файл")))
        {
            var card = new Card();

            card.Name = _name;
            card.InGameName = _inGameName;
            card.Cost = _cost;
            card.IsManaSpell = _isManaSpell;
            card.IsCreature = _isCreature;
            card.CardsCreature = _creature;
            card.BonusName = _bonusName;
            card.BonusFullName = _bonusFullName;
            card.BonusType = _bonusType;
            card.BonusTarget = _bonusTarget;
            card.BonusAtt = _bonusAtt;
            card.BonusHP = _bonusHP;

            var str = JsonUtility.ToJson(card);
            using (StreamWriter sw = File.AppendText(savePath))
                sw.WriteLine(str);
        }

```

And here is saved file:

```
{
  "_name": "apple",
  "_inGameName": "Вкусное яблочко",
  "_cost": 1,
  "_manaSpell": false,
  "_creature": {
    "instanceID": 0
  },
  "_bonusName": "heal by 2",
  "_bonusType": "",
  "_bonusFullName": "Исцеляет вкусившего на 2",
  "_bonusTarget": "",
  "_bonusAtt": 0,
  "_bonusHP": 2
}

```

# Answer
IT WORKS! @DMGregory idk if that is what you meant, but I did so and it works PERFECT! I created a simple class(It's all I have in that script) for card(and the same for Bonus):

```
public class CardData
{
    public string cardName;
    public string inGameName;
    public int cost;
    public bool manaSpell;
    public string creatureName;

    public BonusData cardsBonus;
}

```

Then I use it to save/load via Json.
> 0 votes

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


# Question
Title: Render hands and gun in front of everything
I'm currently learning about Unreal Engine 4 by making an FPS game.

How can I render the player character's hands and gun on top of everything?

Currently when I walk up to a wall, the hands and gun can clip into the wall like this:

I want it to look like this, where even when the player is facing into a wall, the hands and gun stay on top:

How can I achieve this?

Update: Found this solution:

> Render the meshes at the end of the depth-only prepass with depth testing disabled and tagging those pixels in the stencil buffer. Then enable stencil test in the base pass to not touch those pixels. At the end of the base pass you turn off stencil test and render your foreground meshes with depth testing enabled to get their properties in the gbuffer."

# Answer
> 1 votes
Render the meshes at the end of the depth-only prepass with depth testing disabled and tagging those pixels in the stencil buffer. Then enable stencil test in the base pass to not touch those pixels. At the end of the base pass you turn off stencil test and render your foreground meshes with depth testing enabled to get their properties in the gbuffer.

# Answer
> 1 votes
Unfortunately I can’t answer in terms of unreal engine, as I do not have experience with it, but I’m guessing that my experience with general game development and Unity specifically may transfer in this particular case.

In Unity, I would set up the hands and weapon to be rendered separately from everything else, by setting their layer to be something other than the default.

Then, the main camera would be set up to not render things on this layer.

Finally, I would add another camera as a child of the first camera. It would need to:

* render after the main camera (done by giving it a different priority)
* clear the depth buffer (and only the depth buffer)
* and render *only* the things on the new layer.

I’m sure there are also ways to do this using a shader for more performance, but this would not be a big performance hit, and also I’m unable to give anything close to good advice on how to write unreal engine shaders.

Again, I’m not familiar enough with unreal engine, I so if this is entirely off the mark, I apologize.

---
Tags: c++, rendering, unreal-4, unreal, first-person-shooter
---


# Question
Title: Additive Scene Loading Buttons not Becoming 'Active'
I'm quite new to Unity but I'm making a game, and have created a simple Pause menu, when a key is pressed (escape), I just load a Pause scene, additively, and set that Pause scene to the active scene, however, only the buttons on the previous 'game' scene are interactive. The mouseEnter, exit etc aren't triggering on the pause menu buttons, despite the pause menu being overlayed on top of the 'game' scene; the Pause scene being the active one and the 'game' scene buttons are still the interactive ones (i.e. register clicks, mouse overs etc).

Obviously when I open the pause menu, I want the pause menu buttons to be the interactive ones (registering clicks, mouse over etc), not the previous 'game' scene buttons.

The pause menu scene interacts perfectly when loaded additively with a scene that had no buttons.

Many thanks.

# Answer
Solution was the edit the Canvas 'Order in Layer' option, with the pause menu having a higher order. Presumably this means the pause menu UI, is now properly layered over the top of the game scene UI, and so the mouse corrects hovers over the pause menu buttons, not the game buttons.
> 2 votes

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