title: Command pattern for network games

text:
# Question
Title: Command pattern for network games
I am currently programming a multiplayer game. The basic idea is that the game uses Command Pattern for any actions that happens in the game. If the player right clicks to move then a command is issued to the selected object to move to the location.

I implemented gRPC to include multiplayer. Here is my problem, when the player right clicks on the ground I send a gRPC call with that command then the server acknowledges the commands and sends it back to all the clients, the client then processes the command and everything goes well. Now if the player enters the game while a command is underway the client never received that command so its never process on the client.

What would be a good way to fix this problem without sending the info of all the actors (x,y,z) and what they are doing at each server ticks?

Thanks!

# Answer
> 1 votes
The way I'm handling this in the server I'm writing at the moment is to have the server keep track of the current game state after applying each command. The commands are instantaneous transactions that modify that state.

That doesn't mean we teleport the unit all the way to the destination. Rather, it means we instantaneously set them into a "moving" state, with state information about their destination or path.

That means there's never a command "underway" or "in progress". Any command whose ultimate result takes time to execute has an immediate result, putting the game entities into a persistent executing state. Now the command can be forgotten, and the state carries on the work.

When a new player joins, the server sends them a complete dump of the world state as of all the commands and game simulation ticks it's processed at that time. So they have the net result of all past commands, giving them the same starting point for any future commands.

As an example: if you told a unit to move from 0 to 10, and I log on when the server's copy of the unit has reached 5, my state dump says "Unit at {position 5}, in state {moving to {position 10}}"

Now I can continue to apply command deltas on top of that state, in the same order they were processed on the server, to obtain a state consistent with the consensus.

---
Tags: unity, multiplayer
---


title: UIButton fails to play sound

text:
# Question
Title: UIButton fails to play sound
I'm doing this game where with cards you assign different beats to different channels. You drag and drop the beat to a channel and it gets added to the mixer. What I'm having trouble with is when i try to play each channel individually with an UI Button. This is the script attached to the channels:

```
public class ManageChannel : MonoBehaviour
{
    public AudioSource thisAudioSource;
    bool chequeo;
    string Nombre;

    public AudioMixer audioMixer;

    public void AsignaCanal (){
        Nombre = this.name; // tomo el nombre del canal actual
        thisAudioSource = this.GetComponent<AudioSource>();

        var carta = this.transform.GetChild(0); // llamo a la carta hija de este objeto
        thisAudioSource.clip = carta.GetComponent<AudioSource>().clip;
        thisAudioSource.outputAudioMixerGroup = audioMixer.FindMatchingGroups(Nombre)[0]; // asigno al AudioSource el grupo correspondiente

    }

    public void comienzaAudio (){
        if (!thisAudioSource.isPlaying){
            thisAudioSource.Play();
        }
        else {
            thisAudioSource.Stop();
        }
    }

    // Start is called before the first frame update
    void Start()
    {
        chequeo = true;

    }

    // Update is called once per frame
    void Update()
    {
        if (this.transform.childCount != 0 && chequeo) {
                AsignaCanal();
                chequeo = false;
                thisAudioSource.Play();

        }

    }
}

```

What the script does is when a card is dropped, it takes the clip of the card and get its into the `AudioSource` of the channel, and that `AudioSource` gets outputted to its respective channel (for example, the `GameObject` "Channel 1" goes to the mixer group "Channel 1" and so on). Then i've tried to build the buttons to reproduce the track of each channel individually, but using `AudioSource.Play()` since I believe I cannot do it with the AudioMixer directly. What i did is create a UIButton and then assign the respective `GameObject` Channel to the `OnClick()` section on the inspector, and then i choose the following function on the script that i showed before

```
public void comienzaAudio (){
        if (!thisAudioSource.isPlaying){
            thisAudioSource.Play();
        }
        else {
            thisAudioSource.Stop();
        }
    }

```

Then, every time i press the button, that function should be called. The problem is nothing happens. I'm positive the button is working because i tested with a `bool` value and a `Debug.Log()` to see if it changes values with every click, and it does. So, i honestly have no clue what the issue is. Any help would be appreciated. Thanks!

# Answer
> 0 votes
I'm not spotting any immediate issue with your code. Here are some easy things to try:

* Make sure your mixer is not muted or set at too low of a volume (try playing audio through the mixer using some other approach, e.g. "play on awake").
* Make sure the AudioSource volume is not set too low, and that the spread/spatial settings are correct
* Add logging code to ensure everything is set up correctly (this should usually be your first step in debugging):

```
public void comienzaAudio (){

    print("Clip: " + thisAudioSource.clip);
    print("Mixer: " + thisAudioSource.outputAudioMixerGroup);
    print("isPlaying: " + thisAudioSource.isPlaying);
    print("Volume: " + thisAudioSource.volume);
    print("Max distance: " + thisAudioSource.maxDistance);

    if (!thisAudioSource.isPlaying){
        thisAudioSource.Play();
    } else {
        thisAudioSource.Stop();
    }
}

```

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


# Question
Title: Change rigidbodys default height from floor?
I am new to unity and I have a few questions:

There is a mesh that has a rigidbody and a box collider that I placed on the scene.
I also added a generic terrain to the scene from the 3D objects menu.
When I put the mesh at a certain height and it drops I notice that it always stops at **Y = 0.500000**.
How do I change this default value? What controls this? For example, does unity have it so that when any other type of collider hits the **terraincollider** the **other collider** automatically updates the rigidbody to be 0.50000 above it and this only happens when it hits a terrain collider?
If this is the case, Is this **causing a collision every frame** and **adjusting it to 0.50000 every frame** so it doesnt fall through?

Finally, assuming that the **Y = 0.50000** value above the ground cannot be changed, if I wanted something to "hoover" above the ground, would I always need to take that the maximum amount that I can get to the ground is **Y = 0.500000**?

# Answer
> How do I change this default value? What controls this?

As DMGregory was hinting, a 1 meter box has a center at 0.5m. So if the bottom of the box is touching the ground, the center of the box will be 0.5 meters above the ground.

> Is this causing a collision every frame and adjusting it to 0.50000 every frame so it doesnt fall through?

No, when a Rigidbody comes to a resting position it starts "sleeping", meaning that the physics engine recognizes that it's at rest and stops processing its physics until something moves it. See the Rigidbody documentation:

> When a Rigidbody is moving slower than a defined minimum linear or rotational speed, the physics engine assumes it has come to a halt. When this happens, the GameObject does not move again until it receives a collision or force, and so it is set to “sleeping” mode. This optimisation means that no processor time is spent updating the Rigidbody until the next time it is “awoken” (that is, set in motion again).

Although the description from Unity's ancient history may be easier to digest at first glance:

> When Rigidbodies fall to rest - a box landing on the floor - they will start sleeping. Sleeping is an optimization which allows the Physics Engine to stop processing those rigidbodies.
> 1 votes

---
Tags: unity, physics
---


# Question
Title: Random 100x100 map using all levels from 1 to 100
I'm developing a game where players walk though a 100x100 grid of different rooms. Each room has a level associated with it starting from lvl 1 to lvl 100.

The map is divided into 10x10 areas and in the middle of each area there's a 2x2 "castle" which players must conquer in order to access next levels castles (so if players start off at lvl 1 they need to conquer the lvl 1 castle before being able to enter lvl 2 castles).

Each room in a castle (2x2 area in the middle of each 10x10 area) has the same level and there must be a castle for each level from 1 to 100.

As for now I was generating the whole map "statically" and use the matrix blur to interpolate room levels between castles.

What I would like to achieve is having a seeded function `f(x,y)` that returns the level of the room at position `(x,y)` without pre-defining the matrix.

I checked out Perlin Noise functions, but it doesn't guarantee each level between 1 and 100 is taken nor the right position of the "castles".

The image above is the starting point of the game map, lower levels of green represent lower room levels, the blue squares in the center are the castles. This image is then blurred preserving just the castles level.

Players can move around the map and will meet harder challenges in higher level rooms. The goal is reaching level 100 by spotting and conquering each castle in sequence.

# Answer
> 2 votes
To ensure all castles 1-100 are present, simply shuffle an array containing all the numbers 1-100. You can either do this once when you first generate the map and then hold onto it, or you can use a seeded random number generator to assist with the shuffle so that you get consistent results each time. Here is an example in Python. If you're using another language, there may or may not be an equivalent, but it's a simple enough process that you could write your own shuffler.

The following example (pseudo-code) assumes you'll generate it once and re-use it; if you really want to re-generate it each time, just use a seeded shuffle to ensure consistency.

```
    world_map = generate_world_map(10)

    def generate_world_map(size):
        castles = range(1, size*size)
        shuffle castles
        split castles into array[size][size]
        return castles

    def get_room_level(x, y):
        map_x = floor(x/10)
        map_y = floor(y/10)
        castle_level = world_map[map_x][map_y] # Replace this with func call if re-generating every time
        adjacent_catles = world_map[map_x +/-1][map_y +/-1] (up to 4 - or 8 if diagonals included - other castles; fewer if at an edge)
        do blurring thing

```

It sounds like you've got the blurring bit right and are just concerned about castle consistency. This approach should handle that. Just remember to look out for edges.

---
Tags: matrix, maps, levels, noise
---


# Question
Title: Two Colliders on the same GameObject for different purposes
I'm somewhat new to Unity and am trying to build a battle system. Right now, I have an attack that checks collisions with enemy objects like this:

```
private void OnTriggerEnter2D(Collider2D other) {
  if (other.gameObject.layer != LayerMask.NameToLayer(_hurtboxLayer))
    return;

  var enemyHealth = other.GetComponent<Health>();
  enemyHealth.TakeDamage(_damagePoints);
}

```

My game also uses Rigidbody2D objects to let the player and enemies bump into each other. Because I want the "bumping" Collider2D be different from the hitbox Collider2D, I made a child GameObject called Hurtbox for each enemy. The Hurtbox objects have a Health behaviour which handles the HP and death of an enemy:

```
public class Health : MonoBehaviour {

  [SerializeField] private int _initialHealthPoints;
  private int _healthPoints;

  public void TakeDamage(int damagePoints) {
    _healthPoints -= damagePoints;

    if (_healthPoints <= 0) {
      Die();
    }
  }

  private void Die() {
    Destroy(gameObject);
  }

  private void Start() {
    _healthPoints = _initialHealthPoints;
  }

}

```

The `Die` method only destroys the hurtbox object and is not allowed to destroy the enemy object, which is its parent. Is there any way I can put both Collider2Ds and the Health behaviour on the same GameObject and only check a specific Collider in the `OnTriggerEnter2D` method?

# Answer
As DMGregory pointed out, my solution was on the right track. What I do differently now, is that now the Health behaviour detroys its parent. I had an exception when I tried this the first time, but that might have been because I put the code in the wrong behaviour. Also, I made sure to check the Physics 2D settings to make sure, the Hurtbox objects wouldn't collide with any other objects.

My game objects:

* Character/Enemy (Rigidbody2D, Box Collider 2D)
    + Hurtbox (Box Collider 2D, Health)
* Projectile (Box Collider 2D, Projectile behaviour) -\> instantiated by character/enemy

**Projectile Code**

```
private void OnTriggerEnter2D(Collider2D other) {
  if (other.gameObject.layer != _hurtboxLayerMask)
    return;

  var enemyHealth = other.GetComponent<Health>();
  enemyHealth.TakeDamage(damagePoints);
  Destroy(gameObject);
}

```

**Health behaviour**

```
public class Health : MonoBehaviour {
  [SerializeField] private int initialHealthPoints;
  private int _healthPoints;

  public void TakeDamage(int damagePoints) {
    HealthPoints -= damagePoints;

    if (HealthPoints <= 0) {
      Die();
    }
  }

  private void Die() {
    Destroy(transform.parent.gameObject);
  }

  private void Start() {
    HealthPoints = TotalHealthPoints = initialHealthPoints;
  }

  public int TotalHealthPoints { get; private set; }
  public int HealthPoints { get; private set; }
}

```
> 1 votes

---
Tags: unity, collision-detection, component-based, collider, monobehaviour
---


title: glDrawArrays draws nothing

text:
# Question
Title: glDrawArrays draws nothing
I am trying to draw a triangle using shaders in LWJGL, but nothing is being drawn on the screen, and no error is being produces. I can't figure out what I'm doing wrong.

To create a vao, I use:

```
int buffer = glGenBuffers();
int vertexArray = glGenVertexArrays();

ByteBuffer data = ByteBuffer.allocateDirect(6 * 8).order(ByteOrder.nativeOrder());
data.putFloat(-0.5f);
data.putFloat(0.5f);

data.putFloat(-0.5f);
data.putFloat(-0.5f);

data.putFloat(0.5f);
data.putFloat(-0.5f);

glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, data, GL_STATIC_DRAW);

glBindVertexArray(vertexArray);
int positionAttributeLocation = glGetAttribLocation(program, "position");
glEnableVertexAttribArray(positionAttributeLocation);
glVertexAttribPointer(positionAttributeLocation, 2, GL_FLOAT, false, 8, 0);

```

and then I draw using:

```
glUseProgram(program);
glDrawArrays(GL_TRIANGLES, 0, 3);

```

Here's my vertex shader:

```
#version 110

in vec2 position;

void main(void) {
  gl_Position = vec4(position.xy, 1, 1.0);
}

```

and fragment shader:

```
#version 110

void main(void) {
  gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
}

```

# Answer
I finally figured it out. The `ByteBuffer` needs to be reset to position 0 before passing it to `glBufferData`, by using `data.position(0)`...
> 2 votes

# Answer
```
gl_Position = vec4(position.xy, 1, 1.0);

```

This is drawing with a Z of 1, which, depending on how you have your projection matrix set up, is almost certainly not what you want. Try using a Z of 0 instead:

```
gl_Position = vec4(position.xy, 0, 1.0);

```

Also cross-check this with how you create your depth buffer, your current depth write and test state, and how you're clearing it each frame.
> 0 votes

---
Tags: shaders, lwjgl
---


# Question
Title: How do I modify the coordinates of an object from a script?
I want it to be teleported to a place when it collides with an object and I already have the if the only thing I am missing is a command to modify the coordinates

# Answer
You should be able to find something like this in very nearly every Unity tutorial ever written, so please be sure to search for existing documentation and guides before asking here.

```
void MoveObjectTo(GameObject mover, Vector3 position) {
    mover.transform.position = position;
}

```
> 1 votes

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


# Question
Title: Pygame.display.set_icon unable to show transparecy
On Python 3.2.5 32 bit, I installed pygame. I made some code with it. It included `pygame.display.set_icon(image)`. The image file is .png and I loaded it by using `image = pygame.image.load("clockico.png").convert_alpha()` The transparent pixels on the .png file showed up as black. I tried using a `.ico` file instead of a `.png` file, but the output was the same. Is there a way to fix this?

# Answer
> 0 votes
You should change the `convert_alpha()` part to just `convert()`, as the `convert_alpha()` changes the transparent pixels.

# Answer
> 0 votes
On Windows 10, using Pygame 1.9.6, I have found that all I need to do is to scale my PNG image to match an allowed Windows icon size. For example, with my 80x80 image, I do:

```
icon = pygame.image.load(ICON_FILENAME)
icon = pygame.transform.smoothscale(icon, (96, 96))
pygame.display.set_icon(icon)

```

If you're only using the image as an icon (and not planning to reuse the image object), you do not need to call `image.convert()` or `image.convert_alpha()`. In fact, I would recommend setting your icon as early as possible, even before you call `pygame.display.set_mode()`, and `convert()` or `convert_alpha()` will fail if you call them that early.

---
Tags: python, pygame, file-format, png
---


# Question
Title: How can I fix the player suspension in the air?
I'm making a 2D platformer with Unity. I used this video to write the code but with some little changes. I want to support both keyboard and gamepad, so I use the new Input System. I defined three variables called `GroundedRememeber`, `JumpPressedRemember` and `JumpPressedRememberTime` and basically they work like timers and check if the player leaves the ground and if so, then the player can jump when it is near the ground without the need to touch it. These timers weren't working, so I added a new method called `TryJump` and deleted some lines and now, the player is suspended in the air and moving upwards.

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

public class PlayerController : MonoBehaviour, PlayerInputActions.IPlayerActions
 {
   private PlayerInputActions controls;
   [SerializeField] LayerMask groundLayers;
   private Rigidbody2D rb;
   private Animator anim;
   private bool facingRight = true;
   private Vector2 moveInput;
  [SerializeField] private float jumpForce;
    float JumpPressedRemember = 0;

   [SerializeField] float JumpPressedRememberTime = 0.2f;
    float GroundedRemember = 0;

   [SerializeField]  float GroundedRememberTime = 0.25f;
   [SerializeField]  float HorizontalAcceleration = 1;
   [SerializeField] [Range(0, 1)] float HorizontalDampingBasic = 0.5f;
   [SerializeField] [Range(0, 1)] float HorizontalDampingWhenStopping = 0.5f;
   [SerializeField] [Range(0, 1)] float HorizontalDampingWhenTurning = 0.5f;
   [SerializeField] [Range(0, 1)] float JumpHeight = 0.5f;

   private void Awake()
   {
      controls = new PlayerInputActions();

      controls.Player.SetCallbacks(this);
    }
     void Start()
    {
      rb = GetComponent<Rigidbody2D>();
      anim = GetComponent<Animator>();
}
   void PlayerInputActions.IPlayerActions.OnMove(InputAction.CallbackContext context)
   {
      moveInput = context.ReadValue<Vector2>();
   }

     bool TryJump() {
    if (GroundedRemember > 0) {
        Jump();
        return true;
    } else {
        JumpPressedRemember = JumpPressedRememberTime;
        return false;
    }
}
     void PlayerInputActions.IPlayerActions.OnJump(InputAction.CallbackContext context)
   {
       jumpForce = context.ReadValue<float>();
       switch (context.phase) {
            case InputActionPhase.Performed:
               TryJump();
               break;
       }
   }
    void Jump() {
     rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Force);
     GroundedRemember = 0;
     JumpPressedRemember = 0;
   }

  void FixedUpdate()
  {

   if(facingRight == false && moveInput.x > 0){

    Flip();

   }else if (facingRight == true && moveInput.x < 0){

    Flip();

   }
 }
    void Flip(){

    facingRight = !facingRight;
    Vector3 Scaler = transform.localScale;
    Scaler.x *= -1;
    transform.localScale = Scaler;

 }
 void OnEnable()
 {
     controls.Enable();
 }

 void OnDisable()
{
    controls.Disable();
}
 void Update()
  {

   Vector2 GroundedBoxCheckPosition = (Vector2)transform.position + new Vector2(0, -0.01f);
   Vector2  GroundedBoxCheckScale = (Vector2)transform.localScale + new Vector2(-0.02f, 0);
   bool Grounded = Physics2D.OverlapBox(GroundedBoxCheckPosition, transform.localScale, 0, groundLayers);

    JumpPressedRemember -= Time.deltaTime;

    GroundedRemember -= Time.deltaTime;

    if (Grounded)  {
      GroundedRemember = GroundedRememberTime;
       }

    if ((JumpPressedRemember > 0)) {
      TryJump();

     float HorizontalVelocity = rb.velocity.x;
      HorizontalVelocity += moveInput.x;

     if (Mathf.Abs(moveInput.x) < 0.01f)
            HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingWhenStopping, Time.deltaTime * 10f);
     else if (Mathf.Sign(moveInput.x) != Mathf.Sign(HorizontalVelocity))
           HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingWhenTurning, Time.deltaTime * 10f);
     else
            HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingBasic, Time.deltaTime * 10f);

        rb.velocity = new Vector2(HorizontalVelocity, rb.velocity.y);
  }
}
 }

```

# Answer
> 2 votes
Did you meant to execute this line every frame?

```
rb.velocity = new Vector2(rb.velocity.x, jumpForce);

```

If `jumpForce` is zero, this slows the player's fall by preventing gravity from accelerating them, since your zero-out their vertical velocity every frame. If jumpForce is greater than zero, it could cause the player to rise.

I don't see any useful function this line serves other than giving you problems to bring to StackExchange, so I'd say delete it.

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


title: POST HttpRequest doesn't send any data

text:
# Question
Title: POST HttpRequest doesn't send any data
I've some trouble for sending a post request to my nodejs server.

I can receive data from the server with GET method, but when I try to send data with POST, I've an empty bracket on return on this function:

```
func _on_request_completed(result, response_code, headers, body):
    var json = JSON.parse(body.get_string_from_utf8())
    print(json.result)
    print(response_code)

```

And empty bracket on my JSON console.log on the server too.

My code:

```
extends CanvasLayer

func _ready():
    $HTTPRequest.connect("request_completed", self, "_on_request_completed")

func _on_Button_pressed():
    var data = {"name": "Godette"}
    _make_post_request("http://localhost:8080/", data, false)

func _on_request_completed(result, response_code, headers, body):
    var json = JSON.parse(body.get_string_from_utf8())
    print(json.result)
    print(response_code)

func _on_HTTPRequest_request_completed():
    pass

func _make_post_request(url, data_to_send, use_ssl):
    # Convert data to json string:
    var query = JSON.print(data_to_send)
    # Add 'Content-Type' header:
    var headers = ["Content-Type: application/json"]
    $HTTPRequest.request(url, headers, false, HTTPClient.METHOD_POST, query)

```

And this code return this in my console:

```
{}
200
```

Thanks for help :)

# Answer
I find nothing wrong with your code. I suppose the wrong code might be your server code. My GDScript code as you can see is similar to yours:

```
extends Control

func _ready():
    $HTTPRequest.connect("request_completed", self, "_on_request_completed")

func _on_request_completed(result, response_code, headers, body):
    var json = JSON.parse(body.get_string_from_utf8())
    print(json.result)

func _make_post_request(url, data_to_send, use_ssl):
    var query = JSON.print(data_to_send)
    var headers = ["Content-Type: application/json"]
    $HTTPRequest.request(url, headers, use_ssl, HTTPClient.METHOD_POST, query)

func _on_Send_pressed():
    _make_post_request("http://127.0.0.1:3200/hello/",
        {"name":"godot"}, false)

```

My server code looks like this:

```
const express = require('express');

const app = express();
const bodyparser = require('body-parser');

const port = process.env.PORT || 3200;

// middleware

app.use(bodyparser.json());
app.use(bodyparser.urlencoded({ extended: false }));

app.post('/hello', (req, res) => {
  const resp = req.body;

  console.log(resp.name);

  res.status(200).json({
     name: resp.name,
     message: 'hello stranger',
  });
});

app.listen(port, () => {
  console.log(`running at port ${port}`);
});

```

And when I click on the `Send` Button I get this output:
`{message:hello stranger, name:godot}`
> 1 votes

---
Tags: networking, godot, gdscript
---


title: How to fix stuck between sprite shape

text:
# Question
Title: How to fix stuck between sprite shape
I'm making hill climb racing type game but I have an issue here when climbing the car is so slow also there will be stuck between sprite shape like that

* I've tried configuring `hingejoint` 2d but it's not working and still stuck
* Making value some `MotorPower` bigger but its still slow when climbing

here my car controller script:

```
JointMotor2D motorBack;
public WheelJoint2D motorWheel;

public Rigidbody2D carRigidbody;

public M_GameManager _GameManager;

public float speed;
float currentSpeed;
public bool isGrounded;
public float groundDistance = 2.1f;

[Header("Power")]
public float motorPower = 1400f, brakePower = 14f, declarationSpeed = .3f;

public float carMaxSpeed = 14f;
float motorTemp;
float powerTemp;
public bool isMobile;

public bool isGas;
public bool isRealesed;

[Header("Particle")]
public ParticleSystem wheelParticle;
ParticleSystem.EmissionModule em;
public Transform particlePosition;

[Header("Fuel")]
public float fuel = 100f;
public float fuelconsumption = 5f;

// Can rotate option. be true value when car is on the fly
bool canRotate = false;

// Rotate force on the  fly
public float RotateForce = 140f;

void Start()
{
    Application.targetFrameRate = -1;

    _GameManager = FindObjectOfType<M_GameManager>();

    // Set car rigidbody's COM
    carRigidbody = gameObject.GetComponent<Rigidbody2D>();

    // Starting with WheelJoint2D motor
    motorBack = motorWheel.motor;
    //motorFront = motorWheel1.motor;

    // Cast a ray to find isGrounded
    StartCoroutine(RaycCast());

    //EngineSoundS = GetComponent<AudioSource>();

    powerTemp = motorPower;

    em = wheelParticle.emission;
    em.enabled = false;
}
//float maxspeed = 300f;

void FixedUpdate()
{

    // speed limiter based on max speed limit value
    if (speed > carMaxSpeed)
        motorPower = 0;
    else
        motorPower = powerTemp;

    // Moving forward
    if (Input.GetAxis("Horizontal") > 0 || HoriTemp > 0)
    {

        // Add force to car back wheel
        if (isGrounded)
        {
            motorBack.motorSpeed = Mathf.Lerp(motorBack.motorSpeed, -motorPower, Time.deltaTime * 1.4f);
            fuel -= fuelconsumption * Time.fixedDeltaTime;

            if (fuel < 0)
            {
                _GameManager.isTimerunning = false;
                _GameManager.fuelFinished = true;
                _GameManager.StartFuelFinish();
            }

            if (fuel > 100f)
            {
                fuel = 100;
            }
            //motorFront.motorSpeed = Mathf.Lerp(motorFront.motorSpeed, -motorPower, Time.deltaTime * 1.4f);
        }

        // Wheel particles
        if (isGrounded)
        {
            if (speed < 2f || speed < -2f)
            {
                wheelParticle.transform.position = particlePosition.position;

                em.enabled = true;

            }
            else
                em.enabled = false;
        }
        else
            em.enabled = false;

    }
    else
    {// Moving backward
        if (Input.GetAxis("Horizontal") < 0 || HoriTemp < 0)
        {
            if (speed < -carMaxSpeed)
            {
                if (isGrounded)
                {
                    motorBack.motorSpeed = Mathf.Lerp(motorBack.motorSpeed, 0, Time.deltaTime * 3f);
                    //motorFront.motorSpeed = Mathf.Lerp(motorFront.motorSpeed, 0, Time.deltaTime * 3f);
                }
            }
            else
            {
                if (isGrounded)
                {
                    motorBack.motorSpeed = Mathf.Lerp(motorBack.motorSpeed, motorPower, Time.deltaTime * 1.4f);
                    //motorFront.motorSpeed = Mathf.Lerp(motorFront.motorSpeed, motorPower, Time.deltaTime * 1.4f);
                }

            }

        }
        else
        {
            // Releasing car throttle and brake
            if (isGrounded)
            {
                motorBack.motorSpeed = Mathf.Lerp(motorBack.motorSpeed, 0, Time.deltaTime * declarationSpeed);
                //motorFront.motorSpeed = Mathf.Lerp(motorFront.motorSpeed, 0, Time.deltaTime * declarationSpeed);
            }
        }

    }

    motorWheel.motor = motorBack;
    //motorWheel1.motor = motorFront;

    if (canRotate)
    {
        Rotate();
    }

    if (!isMobile)
        HoriTemp = Input.GetAxis("Horizontal");
}

public float HoriTemp;
void LateUpdate()
{

    // Get car speed
    speed = GetComponent<Rigidbody2D>().velocity.magnitude;
    if (Input.GetAxis("Horizontal") < 0 || HoriTemp < 0)
        speed = -speed;
}

```

# Answer
> 0 votes
I found the answer but maybe bad because I didn't find any the good one,

so basically add 2d physics material to the body of the car collider and set the friction to 0 and make the wheel bigger to get easy when the vehicle climbing, for the slow, just add `wheelJoint2d` and make new variable `front tires` so `frontTires.motor=motor`.

---
Tags: unity, game-mechanics, joints, hinge-joint
---


# Question
Title: Implementing GDPR compliance for multiple different ad networks
I'm creating a Unity game that uses admob mediation to show rewarded ads. I'm using about 5-10 different ad networks.

How do I implement GDPR compliance for EU users?

I tried following some online tutorials, but none of them had content showing getting GDPR consent for multiple networks.

How can I modify this script to correctly get compliance where needed for all of my ad networks?

```
public class Mediation : MonoBehaviour
{
 string Video_Ad_Id = "ca-app-pub-3940256099942544/5224354917";
 private RewardedAd rewardedAd;
 public Button reviveBtn;

 void Start()
 {
    MobileAds.Initialize((initStatus) =>
    {
        Dictionary<string, AdapterStatus> map = initStatus.getAdapterStatusMap();
        foreach (KeyValuePair<string, AdapterStatus> keyValuePair in map)
        {
            string className = keyValuePair.Key;
            AdapterStatus status = keyValuePair.Value;
            switch (status.InitializationState)
            {
                case AdapterState.NotReady:
                    // The adapter initialization did not complete.
                    MonoBehaviour.print("Adapter: " + className + " not ready.");
                    break;
                case AdapterState.Ready:
                    // The adapter was successfully initialized.
                    MonoBehaviour.print("Adapter: " + className + " is initialized.");
                    break;
            }
        }
    });

    RequestRewardBasedVideo();
}

void Update()
{
    if (rewardedAd.IsLoaded())
    {
        reviveBtn.interactable = true;
    }
}

```

I'm not sure where to ask for consent as I'm using multiple ad networks and not just admob. In the documentation, there is this line of code:

```
AdRequest request = new AdRequest.Builder().AddExtra("npa", "1") .Build();

```

Where do I add this in the script above and how do I ask for consent for multiple networks, like Chartboost, Adcolony, ironSource etc?

**EDIT**

I have added the following code to the mainmenu script which loads up when the game starts.

```
public GameObject GDPR_Popup;
void Start()
{
    Invoke("CheckForGDPR",.25f);
}

void CheckForGDPR()
{
    if (PlayerPrefs.GetInt("npa", -1) == -1)
    {
        GDPR_Popup.SetActive(true);
    }
}

public void OnUserClickAccept()
{
    PlayerPrefs.SetInt("npa", 0); //this is for google admob
    AdColonyAppOptions.SetGDPRConsentString("1");
    AppLovin.SetHasUserConsent(true);
    GDPR_Popup.SetActive(false);
}

public void OnUserClickCancel()
{
    PlayerPrefs.SetInt("npa", 1);//this is for google admob
    AdColonyAppOptions.SetGDPRConsentString("0");
    AppLovin.SetHasUserConsent(false);
    GDPR_Popup.SetActive(false);
}

```

Would something like this work as I'm not sure how to test this?

Also, how to initialize the ad networks only when the user has accepted or canceled GDPR option(this I believe was mentioned in the google admob mediation documents but there was no code sample given).

Can someone please help?

# Answer
> 1 votes
At a glance from the From the Mobile Ads SDK (Unity) documentation for Requesting Consent from European Users, this doesn't look like the sort of thing that you can do with a one line addition to a script:

> Mediation networks Google currently is unable to obtain and handle consent for mediation networks, so you'll need to obtain and handle consent for each ad network separately. We are actively working with all of our open source and versioned mediation networks to provide updated documentation with details on how to forward consent. Documentation is already live for the following mediation networks:
>
> * AppLovin
> * Chartboost
> * Facebook
> * MoPub
> * myTarget
> * Tapjoy
> * Unity Ads
> * Vungle

I randomly looked at a few of these & they each seem to have their own unique instructions. As far as I can tell, you'll need to follow up on each network individually.

---
Tags: unity, c#, advertisements, admob
---


title: Ways to draw tracks on 4-connected grid

text:
# Question
Title: Ways to draw tracks on 4-connected grid
I'm working on a grid based puzzle game involving tracks, and I'm having trouble finding a nice way to have users draw those tracks on the grid in a way is easily understood. For simplicity I had the idea to make the user draw tracks by dragging/drawing on the grid. I thought this was a nice way to do things, since both mouse and touch inputs could be handled in the same way.

As how I have designed the game right now, the only tracks that are possible are straight and 90 degree turns, which I believe is also referred to as a 4-connected grid. I have a limit of two track pieces that can exist on one tile. This way the game supports junctions and crossings, which are an important part of the puzzle design, but things remain relatively clear.

I have looked at other grid based games that involve tracks or track-like connections, but many do not support junctions and crossings (Like the awesome Cosmic Express, and in some capacity Flow Free by Big Duck Games).

A game I know of that does support this is Trainyard by Matt Rix. There, when your dragged path connects three (adjacent) grid cells, a track on cell number 2 is created that connects cell 1 with cell 3. I personally find this method quite clear, and this is the system that is in my game right now, but prototype play testers found it quite difficult to draw the shapes they wanted and they made a lot of errors in the process, which became frustrating.

I can't really think of any other way than how Trainyard does it, at least at the technical level. In the end to build a track you need to know which sides to connect, so by dragging you have to touch at least three cells. Perhaps you can make assumptions at certain points to make things more streamlined? Or perhaps it is just a matter of better visualization? If anyone has thoughts on the matter, I would be very interested to talk about it! :) If you know of other games that have players draw tracks that support junctions and crossings, I would be very interested to see how they are doing it.

I do recognize the fact that you might need to have had some experience playing games with this system, so for what it's worth: The free version of Trainyard called Trainyard Express is still available on Google Play. The iOS version is gone unfortunately. It's quite an old game and hasn't been updated very regularly.

Edit 1: Currently track build logic is as follows: When dragging starts (mouse down on area where grid is shown), I start keeping a list of tile coordinates that the mouse is touching. When, while dragging, a new cell is reached, that new cell coordinate is added to the list. When the list length is 3 or higher, the last three coordinates in the list are used to create a track. So, for example, when the list is ((0,0), (1,0), (1,1)), a track on (1,0) is created with a turn that connects (0,0) with (1,1). Then, when (1,2) is reached, a straight track on (1,1) is added that connects (1,0) with (1,2). Hope this clarifies, else I could add a graphic representation.

Edit 2: Some issues that arise when using pure Trainyard drawing system:

* Wanting to draw a straight line going right, starting at (1,1), accidentally grazing over the edge entering (2,2) below, resulting in a turn from (1,1) to (2,2) on (2,1). Then correcting back onto the correct row, and reaching to (3,1), resulting in turn on (2,1) from (2,2) to (3,1).

* While wanting to make a turn to connect (1,1) with (2,2) via (2,1), users often start drawing **on** (2,1), resulting in no track being drawn.

# Answer
This is Matt, the creator of Trainyard. @DMGregory summoned me here! :)

It sounds like you're working through the same issues I had to deal with. It's a tricky problem where there isn't necessarily a perfect solution.

One thing to consider is the constraints of the problem. I was targeting a 50mm wide screen on the early iPhones, and Apple's recommendation was that touch areas should be at least 7mm wide, which led to Trainyard's grid having 7 columns. This is also why Trainyard's touch system is based almost entirely on the grid tiles themselves and not any kind of sub-regions. This also meant that any visual indicators on the tiles themselves were entirely hidden by the player's finger. Since you're targeting modern devices and mouse-based interfaces, that may open up some new options to you.

I knew Trainyard's system would be counterintuitive at first, but it also allowed for extremely quick and reliable inputs for players who understood the system. I put a lot of effort into making sure the tutorials were very clear about dragging across tiles. Players still got confused by it occassionally, but I had many thousands of "casual" players who were able to get very proficient with it, so it served its purpose. I did try adding "edge touches", but at least on those early devices, it led to more instances of unexpected behaviour, and it was also harder to explain to players.

You clearly already know this, but the key with this drawing system is that you are really defining track between edges and not tiles. The reason each track piece requires three tiles is because when drawing track in tile B of ABC, you need the edge from A-\>B and the edge from B-\>C. For that reason, if I were to revisit Trainyard today on modern devices I would try doing edge touches again. I'd hope that the new larger screens would make it work better, or that maybe I could figure out the right amounts of tolerance to make it work predictably.

A few other features of Trainyard's system:

* I show little arrow indicators on the edges the moment they've been drawn across to make them clear to the player. I'm not sure how much this helps since they're mostly covered by the player's finger, but in theory it helps with the latency problem that @DMGregory mentioned. I do keep them visible for a second after the track has been drawn, so the player does get to see them and start to develop an intuition about how the track drawing works. In a modern implemenation I might try showing a "ghost" version of the track as the player got close to a second edge.
* If you return to a tile right away, I ignore the first time you entered it. So for example if you have tiles ABC and you drag from B-\>A-\>B-\>C, I'll treat it as if you did A-\>B-\>C so you'll just get a horizontal track through B. This is pretty obvious but I'm just making it clear it's a bit more complex than taking groups of every 3 tiles.
* If you draw over a tile with existing track, I make that new track the the "active" (top layer) of the two tracks. On the other hand, if there are already two tracks on the tile and the exact same track path is already active, I destroy the other track on the tile.
* If the touch moves more than the size of a tile in a single frame, I act as if there have been multiple touches along the path. This allows players to draw long vertical and horizontal lines very quickly without worrying about "skipping" a tile.

So in summary, you should go with the things @DMGregory suggested in this answer, but I'm just trying to provide a bit of insight into the decisions I made. Also I apologize for the game not being available anymore. It was written in 32-bit pre-ARC Objective-C with a modified beta version of Cocos2D, so it's been a bit of a nightmare to modernize ;)

Hope that helps!
> 27 votes

# Answer
I think you can solve the two pain points you indicated with a few heuristics.

One is a little hysteresis: once the player is drawing in a particular row/column, keep their drawing cursor locked in that row/column until their mouse/touch point strays more than ~30% of the way into the next row/column.

That gives more tolerance for error, so the player has some wiggle room to draw less than perfectly straight across a row and still get a straight line result.

The other is to detect invalid commands and try to infer the player's intent. In this example...

Once the track from (1, 1) to (3, 1) has been drawn, we can fairly assume that an input that starts in (2, 1) and touches or crosses this middle line is intended to connect to or modify the existing track. Based on which half of the tile the player started on, we can add the entrance from (1, 1) or (3, 1) as an extra "first point" of the path.

The other issue may be that you require the player to swipe between three tiles in order to draw on one. That adds a latency between when the player *thinks* their input should be clear to when the game recognizes it, which can be frustrating or add uncertainty into the player's mental model of how the mechanic works.

You might want to consider counting "edge touches" as points for your drawing. So if I swipe from the left edge of (4, 1) to the bottom edge, without ever touching (3, 1) or (4, 2), that's still counted as a valid corner. That lets you start showing track drawing feedback earlier in the gesture, helping the game feel more responsive, and showing the player their mistakes closer to when they made them, so they can understand how their input caused it and can adapt their play, rather than blame it on a "bad recognizer".
> 6 votes

# Answer
I would suggest that if your testers found it difficult to draw track shapes they wanted, this may have to do specifically with your using a 4-connected grid (of a certain coarseness of resolution).

Have you considered:

* increasing the resolution of the grid, a finer grid giving the player more control over how the track is drawn, while keeping the tracks created ON that grid still large enough to be easily visible
* allowing diagonal tracks (8-connected grid)
* A 4-connected grid with tracks angled at multiples of 22.5 degrees (16 directions) which can span multiple tiles
* A non-grid based system where tracks can be drawn freely by the user, then reduced in complexity to just a few segments, once they release the drag?

Amongst these, I'm sure you'll find your answer.
> 1 votes

---
Tags: 2d, input, grid, user-experience
---


# Question
Title: Problem when importing color in hexadecimal format from an ini file
In my game I can import a color correctly when it is in the "engine format".

**Example ("color.ini"):**

```
[color]
color1="c_black"
color2="c_green"
color3="c_navy"

```

**These colors were seen in this link:**

https://docs2.yoyogames.com/source/\_build/3\_scripting/4\_gml\_reference/drawing/colour/index.html

It turns out that I can't import the color when I use its hexadecimal code (only the colors from the previous link don't supply me).

**Example ("color.ini"):**

```
[color]
color1="#FA8072"
color2="#FAEBD7"
color3="#E0FFFF"

```

**Codes taken from this link:**

https://celke.com.br/artigo/tabela-de-cores-html-nome-hexadecimal-rgb

* I tried lowercase variations, with $ instead of # and nothing worked.
* It is not even a case of seeing the wrong color, but of changing nothing (it always turns white).
* I am using the function (asset\_get\_index) to apply the color.

**Link where I looked for a solution before coming here:**

https://www.reddit.com/r/gamemaker/comments/cc0dk6/saving\_a\_colour\_to\_an\_ini\_file/?ref=readnext

---

**Code in my game (works in all colors that don't come as hexadecimal):**

```
color[i]=ini_read_string("color","color"+string(i),"");

```

**Draw:**

```
draw_sprite_ext(spr_Barra,0,290,97+25*(i-1),1,1,0,asset_get_index(color[i]),1);

```

---

**Code I tried, based on one of the comments, from the question:**

```
result=0;

zero=ord("0");
nine=ord("9");
a=ord("A");
f=ord("F");

for(var i=1;i<=string_length(color1);i++){
    c=ord(string_char_at(string_upper(color1),i));
    result=result<<4;

    if (c>=zero && c<=nine){
        result=result+(c-zero);
    }else if(c>=A && c<=f){
        result=result+(c-a+10);
    }
}

```

**I used the function (show\_debug\_message) to see the result of the code and got nonsense results:**

* 1024, 2048

**Link to see the code base I tried:**

https://www.reddit.com/r/gamemaker/comments/9nyjbu/hexstringtonumber\_script/

# Answer
I read this article to jog my memory about HEX colour indexing, which is basically a base-16 that can be converted easily to decimal values, used in GMS to create colour values with the `make_colour_rgb(r, g, b)` function.

The paragraph "Converting Hex to RGB Color Codes" was my main guide through the implementation, as it explains crystal clear how to convert values from hexadecimal to decimal values, grouping them for red, green, and blue values:

> * Take the first digit, D, and convert it into decimal. The result is 13.
> * Multiply 13 by 16. 13 (16) = 208. This is the partial value.
> * Take the second digit, A, and convert it into decimal. The result is 10.
> * Add the partial value to the second digit. 208 + 10 = 218.

And so on for all the remaining values. Then I came up with quite a simple implementation:

```
// Converts a HEX colour value in an RGB map
// INPUT:   string
// OUTPUT:  ds_map["red", "green", "blue"] OR noone
var hex_code = string_upper(string_lettersdigits(argument0));
var rgb_map = ds_map_create();
ds_map_add( rgb_map, "red",
    16 * hex_to_dec(string_char_at(hex_code, 1)) +
    hex_to_dec(string_char_at(hex_code, 2)) );
ds_map_add( rgb_map, "green",
    16 * hex_to_dec(string_char_at(hex_code, 3)) +
    hex_to_dec(string_char_at(hex_code, 4)) );
ds_map_add( rgb_map, "blue",
    16 * hex_to_dec(string_char_at(hex_code, 5)) +
    hex_to_dec(string_char_at(hex_code, 6)) );
return rgb_map;

```

This function takes a string in the format `#000000` (including the hash character) and converts it to RGB values stored in a `ds_map`, and accepts both uppercase and lowercase letters.

The support function `hex_to_dec()` is used to convert individual HEX values into their decimal counterparts by checking against their ASCII values:

```
// Converts a HEX value in a decimal number
// INPUT:   string
// OUTPUT:  real
if ( ord(argument0) >= 48 && ord(argument0) <= 57 ) return real(argument0);
if ( ord(argument0) >= 65 && ord(argument0) <= 90 ) return ((ord(argument0) - 65) mod 6) + 10;

```

This function takes a 1-char string and returns its value in the decimal system, it does the same for letters A-F and loops back (thanks to `mod`) for other letters (which is a nicer alternative to throwing an exception, in my opinion, despite harder debugging).

There's so much to do to improve this code, but it works fine as a starting point. It's up to you to deal with wrong or missing input, according to your needs.
> 1 votes

---
Tags: game-maker, color, game-maker-studio-2
---


# Question
Title: How can I detect a Gameobject touching another gameObject without using collider2D's?
I have fish gameObjects that have colliders2D so that I can click and move them. I added fish food with Collider2D's but it was hard for me to click on the fish. After I disabled the fish food collider2D it was easier to click on the fish. Is there an alternative when detecting two gameObjeccts without colliders?

# Answer
> 0 votes
Don't use `OnMouseDown`. Having this in your project forces Unity to cast rays for you in the most generic way, which is often less efficient and less precise than casting them yourself.

Make your own script that can filter to the physics layer you care about.

```
public class FishClicker : MonoBehaviour {

    public LayerMask whatIsFish;

    public float clickRadius = 0.1f;

    void Update() {

        if (Input.GetMouseButtonDown(0)) {
            var mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            var hit = Physics2D.OverlapCircle(mousePos, clickRadius, whatIsFish);

            if (hit != null) {
                var fish = hit.GetComponentInParent<Fish>();

                if (fish != null) { fish.DoClickThing(); }
            }
        }
    }
}

```

---
Tags: unity, 2d, collision-detection
---


# Question
Title: Getting data from the backbuffer D3D11 using Map
I'm having some trouble using ID3D11DeviceContext::Map() correctly.

Here's the whole function so far:

```
 Color Graphics::GetPixel(int x, int y) const
{
    //Temp frame buffer descriptor;
    CD3D11_TEXTURE2D_DESC pFrameDesc;
    pFrameDesc.Width = WindowWidth;
    pFrameDesc.Height = WindowHeight;
    pFrameDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
    pFrameDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
    pFrameDesc.MipLevels = 1u;
    pFrameDesc.ArraySize = 1u;
    pFrameDesc.SampleDesc.Count = 1u;
    pFrameDesc.SampleDesc.Quality = 0u;
    pFrameDesc.Usage = D3D11_USAGE_DEFAULT;
    pFrameDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS;
    pFrameDesc.MiscFlags = 0u;

    // Create temp frame buffer(2d texture)
    wrl::ComPtr<ID3D11Texture2D>pFrame = nullptr;
    HRESULT hr = pDevice->CreateTexture2D(&pFrameDesc, nullptr, &pFrame);
    GFX_THROW_INFO(hr);

    hr = pSwapChain->GetBuffer(0, __uuidof(pFrame), &pFrame);
    GFX_THROW_INFO(hr);

    D3D11_MAPPED_SUBRESOURCE map;
    map.RowPitch = WindowWidth * 4;
    map.DepthPitch = WindowHeight * 4;

    //Throwing here, CPU access flags problem.
    hr = pContext->Map(pFrame.Get(), 0u, D3D11_MAP_READ, 0u, &map);
    GFX_THROW_INFO(hr);

    pContext->Unmap(pFrame.Get(), 0u);

    return { 0.0f, 0.4f, 0.0f, 0.0f };
}

```

I'm getting an exception thrown at pContext-\>Map()

"Map cannot be called with MAP\_READ access, because the Resource was not created with the D3D11\_CPU\_ACCESS\_READ flag. "

Which is confusing as the newly created resource has the D3D11\_CPU\_ACCESS\_READ flag enabled. This is also true If I try MAP\_WRITE and change the access flags to match. I've also tried ORing the flags together with no luck.

The ultimate use of this function is to be able to create a CPU side array of Color objects (Colors are currently a struct of four floats) Which I can then send onto the NewTek NDI sdk. But I feel it would also be useful for saving screen shots, creating colour pickers etc.

Any ideas welcome!

# Answer
> 5 votes
Your code doesn't use your created texture with `D3D11_CPU_ACCESS_READ`.

It creates a texture:

```
// Create temp frame buffer(2d texture)
wrl::ComPtr<ID3D11Texture2D>pFrame = nullptr;
HRESULT hr = pDevice->CreateTexture2D(&pFrameDesc, nullptr, &pFrame);
GFX_THROW_INFO(hr);

```

Then it releases that texture and takes a reference to one from the swapchain (which is *never* set for CPU READ):

```
hr = pSwapChain->GetBuffer(0, __uuidof(pFrame), &pFrame);
GFX_THROW_INFO(hr);

```

Then you try to map the swapchain buffer:

```
hr = pContext->Map(pFrame.Get(), 0u, D3D11_MAP_READ, 0u, &map);
GFX_THROW_INFO(hr);

```

# Answer
> 1 votes
Chuck Walbourn's answer is correct, but to give you a bit more context, the texture you're creating with `pDevice->CreateTexture2D` is not the same as what you're getting with `pSwapChain->GetBuffer`.

With `pDevice->CreateTexture2D`, you are creating a **brand new** on-memory texture (which is indeed set to be read from the CPU). The new texture is stored in `pFrame`.

Then, with `pSwapChain->GetBuffer`, you are getting the **existing** back buffer from the swap chain (which was not created with CPU read access). This is stored in `pFrame`, effectively discarding the previous value.

You have two choices here (I haven't touched D3D11 in years. This is based on my D3D12, Vulkan and current-gen console knowledge)

**Option A** is to ditch the new on-memory texture, and instead set the back buffer in the swap chain for CPU access. I don't recommend you do this, since textures meant for CPU readback won't necessarily perform as well as those which are created without CPU access.

Also, while you have mapped memory, the GPU will have to flush the contents of the texture, and cease all GPU operations on it until you unmap the memory. Depending on where in your drawing process you're doing this, this operation will be a huge bottleneck.

By the way, I'm not even sure if Direct3D will allow you to create a swap chain with CPU read access, so you probably won't even be able to try it out.

**Option B** is to make a draw operation with a full screen textured quad, where the texture is the back buffer, and the render target is your CPU-readable texture. This is generally the preferred method, as it resolves all the problems Option A had, at the expense of one full screen draw operation.

Keep in mind that it is possible (I don't remember with D3D11) that you won't be able to set the back buffer as a texture for drawing. In that case, instead of making your game's draw calls directly to the back buffer, you might have to create yet another render target, draw everything to it, and then make two copies: one to the swap chain back buffer, and another one to your CPU-readable texture.

This method is a bit more complex, but is guaranteed to work on D3D12, as well as most likely every other modern platform.

---
Tags: c++, graphics, directx11
---


# Question
Title: Calculating probabilities for a custom drop table system
I have a "drop table" / "loot table" / "item table" / "whatever you want to call it" system and I need to solve two Problems. Apologies in advance for the text wall :/

The Problems:

1. Calculate the probability of pulling a specific item from a table
2. Calculate the probability of pulling ANY item from a table with a specific tag (such as "Epic", "Rare", "Weapon", "Sword", "Currency", etc)

A few details about the system:

1. Tables are setup with a certain number of 'Slots' and 'Rolls'
2. **Slots** determines the total number of *unique* items that can be dropped from the table
3. **Rolls** determines how many times we 'pull' an item out of the table
4. Each row within a table will drop one of a pre-calculated set of items
5. Each row can be marked as 'Guaranteed', 'Random' or both (more on that in a bit)
6. Rows have a 'MaxRollsToConsume' field (0 == infinite rolls), and a Weight field (used for weighted randomness, 0 Weight = never pulled)

And a bit of pseudo code for how we actually pull items out of the table

```
create a guaranteed set of rows
create a random pool of rows
create a result with a set number of slots available to fill

(note: adding an item to the result will only fill a slot if that item does not already exist in the result)

foreach row in table
   if row is guaranteed, then add to guaranteed set
   if row is random, then add to random pool

foreach row in guaranteed set
   pull item out of row and add it to result
   consume a roll

while there are rolls remaining and empty slots in the result
   select a row from the random set using weighted randomness and respecting the MaxRollsToConsume field
   pull item out of row and add it to result
   consume a roll
   if this row has reached its max rolls then remove it from the random pool

while there are rolls remaining
   select an item from the current result using weighted randomness and respecting the MaxRollsToConsume field
   add the item to the result
   consume a roll

return the result

```

I understand how to calculate the probabilities for the 'Guaranteed' rows because, well, they are events that are guaranteed to happen so it's pretty easy to calculate.

Where I'm falling short is on how to calculate the 'Random' rows (especially with respect to the MaxRollsToConsume field) and only pulling a certain number of times. For example, I have 5 random rows, but only 2 Rolls to consume. How do I calculate the probability of an item being pulled from one of the those 2 Rolls while also taking into account how many Rolls are allowed per row?

I'm fairly confident that if I can solve Problem 1 with some help then I'll be able to solve Problem 2 on my own. Any help is appreciated and thanks in advance! If anything is unclear or more info is needed please let me know! :)

# Answer
> 0 votes
I devised an answer based on my understanding here it is.

slots: total number of unique items in a table
rolls: maximum pull count from a table

```
rows = [[row1], [row2], ...]
# row 1
rows[0] = [g_or_r, MaxRollsToConsume, weight_change, weight_constant, items...]

# rows[0][0] = 0 => guaranteed
# rows[0][0] = 1 => random
# rows[0][0] = 2 => (not random and not guaranteed)

MaxRollsToConsume = 3 #if it's 0, you can't pull from the row

result = [ ] #where the pulled items will be at the end.
slot = 4 #how many items should result have

for i in rows.length:
    #you have rolls, available slot, rolls to consume
    #and this is a guaranteed row.
    if(rolls > 0 and slot > 0 and rows[i][1] > 0 and rows[i][0] == 0):
        #append a random item from the row
        result.append(rows[i][random(4, rows[0].length)])
        rolls -= 1
        slot -= 1
        rows[i][1] -= 1 # row can consume n-1 roll

    # same but this row is random
    elif(rolls > 0 and slot > 0 and rows[i][1] > 0 and rows[i][0] = 1):

        #decrease weight. If the decreased weight is smaller than 5,
        #choose an item from the row randomly
        #and increase weight to its initial state.
        row[i][2] -= random(1,5)
        if(row[i][2]<5):
            result.append(rows[i][random(4, rows[0].length)])
            row[i][2] = row[i][3] #change the weight to its initial state
            rolls -= 1
            slot -= 1
            rows[i][1] -= 0
            if(rows[i][1] == 0):
                rows[i][0] = 3 #removed from the random rows
    else:
        #you don't have rolls, available slot.
        #you have consumed the rolls.
        break;

```

About weighting system: let's say a row has 20 weight it's going to take minimum 4 and maximum 20 hits before an item can be selected from that row. so adjust the weight and/or decreasing factor(5, in this case) accordingly.

---
Tags: mathematics, probability
---


# Question
Title: How do I set decimal values in 1D blend tree?
I have created a 1D blend tree. It is being used for a 3rd Person Controller.

The blend tree consists of 3 animations:

1. aim pistol down to the floor
2. aim pistol at middle of the screen (straight forward)
3. aim pistol up in the sky

To determine the blend value (which animation should be played), I inspect the current mouse position and convert it a value between 0 (aim low) and 1 (aim high). The middle position would be 0.5. Here is my code:

```
float f = Input.mousePosition.y / Screen.height;

Debug.Log("Blendval " + f.ToString());//
_animator.SetFloat("BlendVal", f);

```

I tried to insert these decimal values in the blend tree like this:

However, this doesn't work. Unity converts my "0.5" to 0. I don't see why.

I can instead use integers like this:

Why doesn't Unity allow me to use 0, 0.5 and 1? Why do I have to use "other" values like -1, 0 and 1?

Thank you!

Edit:

I don't understand what is going on. I have just typed 0.5 here instead of 0:

And then suddenly I could enter the values as desired, and even "Automate Threshold" would do what I expected:

But now it won't accept negative values anymore.

Strange.

# Answer
There is a bug in Unity:

If you type the decimal separator as ".", it works.

But not if you use ",".

You can use "," anywhere else in Unity, and it will automatically be converted to ".", but not in the Blend Tree.

I have filed a bug report.

I will remove this question once Unity fixed it.
> 1 votes

---
Tags: animator, animation-controller
---


# Question
Title: How do I calculate/weight a diminishing damage formula based on N targets?
I'm making a game and had a look at the questions about calculating damage/diminishing returns here and here but I haven't quite been able to come up with a logarithmic function that satisfies this goal - which is probably super obvious to those mathematically minded of you (apologies if it is!).

The goal is:

* deal half of the damage total to the first target
* deal a diminishing amount of damage for each target beyond the first
* do not deal more damage than is input into the function
* bonus: create a linear downward curve

An example (what I've got so far):

```
fn = (amount, count) => {
 let d = amount;
 let r = 0.5;
 let a = [];

 for (i = 0; i < count; i++) {
   a.push(d * r);
   r -= r/(count-i);
 }

 a.push(a.reduce((acc, cur) => acc + cur)); //push the total combined damage output as last result of array
 return a;
}

```

You can probably spot the problem! Given 300 damage and 3 targets (`fn(300, 3)`), this outputs the following: `[150, 100, 50, 300]` \- which is great. The last number is just the total amount of damage being dealt, which with these inputs matches the amount fed into the function.

Given 4 targets and 400 damage, the problem is exposed with the output being: `[200, 150, 100, 50, 500]` \- the damage output is 100 more than the input amount.

This is not a game breaking problem for me and it's also not that important that the downward curve be linear, but if there is a way to achieve that result that would be awesome and I would greatly appreciate any input!

Thanks for your time!

# Answer
If you want a linear decrease in damage, then the *total* damage can be described as the area of a right triangle formed by a sloped line graph: the height is the max damage, the length is the number of targets, and the hypotenuse corresponds to the sequence of damage numbers seen.

The area of a right triangle is *w* × *h* / 2. So solving that gives our first intermediate result: *h* = 2 × *totalDamage* / *numberOfTargets*. Then, we can pick damages evenly along that sequence (just a linear interpolation from zero):

*damageToTarget*\[*i*\] = *h* × ((*i* \+ 0.5) / *numberOfTargets*)

The "+ 0.5" is needed in order to sample the line at the right points to sum up to exactly the total and not get any of the real-number-math equivalent of off-by-one errors.

Test program, in Python, and its output:

```
from __future__ import division

def damages(total, count):
    scale = 2.0 * total / count
    return [scale * (i + 0.5) / count for i in range(0, count)]

def test_case(total, count):
    d = damages(total, count)
    print(total, d, sum(d))

test_case(300, 3)
test_case(400, 4)
test_case(10, 10)
test_case(65, 1)

```

```
(300, [33.333333333333336, 100.0, 166.66666666666666], 300.0)
(400, [25.0, 75.0, 125.0, 175.0], 400.0)
(10, [0.1, 0.3, 0.5, 0.7, 0.9, 1.1, 1.3, 1.5, 1.7, 1.9], 10.0)
(65, [65.0], 65.0)

```

---

A completely different strategy, which works for *arbitrary* damage curves, is this:

1. Pick some numbers that make a curve you like the shape of.
2. Sum them up.
3. Multiply each of them by *totalDamage* / *sum*.

That is, just “correct the error so it adds up right”. Note that this means that you don't have to pick the numbers based on the total damage: they can have any scale at all, or even be a handmade list of constants, and they will be adjusted to fit.

---

All of the above strategies will sometimes give you fractions. If that's a problem, I suggest the strategy of, for each target's damage value:

1. Round it up or down as you see fit.
2. Subtract the rounded value from the old value; this gives you the "leftover" damage.
3. Add the leftover to the next target's damage value, before you perform step 1 for it.

This should always end up with zero leftover on the last item (approximately, due to floating point error) so the damage total will still be correct.
> 2 votes

# Answer
This is the working/final method in JS just in case future eyeballs. Please see/upvote the accepted answer (which this is based on) accordingly :)

fn = (amount, count) => {
 // ensure full damage is dealt if only one target
 if (count <= 1) return [amount];

 count--;
 let h = 2 * (amount / 2) / count;
 let a = [];

 for (i = 0; i < count; i++) {
   a.unshift(h * (i + 0.5) / count);
 }

 // using unshift to populate array from beginning to avoid reversing/remembering to traverse it backwards later on
 a.unshift(amount/2);

 a.push(a.reduce((acc, cur) => acc + cur));

 return a;
}
```

> 0 votes

---
Tags: mathematics, game-design, algorithm, game-mechanics
---


# Question
Title: How to convert from frag position to UV coordinates when my viewport doesn't cover the screen?
So, I'm implementing SSAO as part of my rendering pipeline using OpenGL/GLSL. It works pretty well when I have a camera that takes up the entire screen. However, when my camera is smaller than the full screen size, the SSAO texture doesn't get sampled correctly. Here is the relevant GLSL shader code:

```
// Convert from clip-space
vec2 fragCoords = (fragPos.xy/ fragPos.w); // fragPos is MVP * worldPosition
vec2 screenCoords = fragCoords * 0.5 + 0.5; // Convert from [-1, 1] to [0, 1] to sample UV coordinates

// Sample texture
float ssaoFactor = texture2D(ssaoTexture, screenCoords).r;

```

I know that there is some funkiness going on with the viewport, but the fixes that I've tried haven't worked. My first thought was to scale fragCoords by normalized size of my viewport (e.g. vec2(0.5, 0.5) for a viewport with half of the width and height of the screen), but that just produced a very strange result. Any thoughts?

# Answer
Figured this out a while ago. My shader math was fine, but I wasn't setting my viewport size correctly before drawing into my buffer.
> 1 votes

---
Tags: shaders, glsl, projection, viewport, ssao
---


# Question
Title: Displaying sprites in a 2.5D raycasting engine
I'm developing a raycasting engine like the one used in DOOM, Wolfenstein 3D, etc.

My engine is capable of correctly displaying walls and textures on walls, but I'm stuck at sprites rendering.

Given that my engine is based on lines and angles only (just trigonometry), is there a way to render sprites without going for matrices? And if so, which technique should I use?

# Answer
> 3 votes
In order for the correct parts of the sprite to be obscured by walls and other sprites, you need to create a plane in the rendering space upon which you can blit the sprite.

The plane itself should be the size of the interactable you want to draw, and its normal should be facing the camera, essentially a moving wall perpendicular to the view angle.

Once that is in place, you can just use the same techniques you've used to draw textures on walls.

# Answer
> 0 votes
There are two problems in using billboard sprites in these kind of engines.

First, determine the view, if there is more than one, that you should display given the orientation of both the object and the player.

Second, drawing the billboard itself.

Assuming that your sprite has only one image, you can choose to render it at the same time you render your level, by considering it as part of the general geometry of the level, represented by a quad, a movable wall as @William Totland has explained.

Another option would be to fill a z-buffer while you render and rendering the sprite against it.

All in all, it's very dependant on your rendering algorithm.

# Answer
> 0 votes
Well I would give the sprite a line (defined by two x,y coords) and then check for an intersection with the ray line (from player to wall) and use the distance from the collision for the height of the sprite. If there's a sprite that should rotate around the player I would do the player angle - \\$\pi/2\\$, and then get the line for the intersection using that angle and the sprites radius.

---
Tags: sprites, rendering, raycasting, 2.5d
---


# Question
Title: Connecting clients with UDP and WebSocket connections
I'm in the process of making a physics intensive multiplayer game. Naturally I use a UDP to transfer packets regarding rigidbodies between client and an authoritative server.

However non-essential packets I'd prefer to use a more reliable connection like WebSockets. This would be for things like voice chat, text chat, scoreboard, etc. It also seems the be a nice approach to checking if the client is still connected and if not, stop sending it UDP packets.

I'm actually unable to find use cases of this dual connection approach online and I was wondering how this is typically handled in similar games. Is it very far fetched or unconventional?

Another question would be how far do I take relying on the WebSocket connection? Lets say for managing remaining bullets in a guns magazine, would it be better over UDP or WebSocket?

I feel like WebSockets would be best in this case because if the bullet was successfully spawned and the server needs to remove a bullet from the client's gun's magazine, if that packet doesn't arrive at the client, then they shot a free bullet...

The UDP equivalent for this scenario would be to always send the client's magazine state as packets and the client just updates it's magazine whenever the packets get to them. My concern here is overloading the network traffic data that might not have even changed...

# Answer
> 0 votes
In 2020 having two connections for different tasks - it's not a problem at all. But managing a game state with two different protocols and connections - is not a very good practice.

UDP will clearly work faster. If you will manage game state with UDP and WS - you can quickly get in some situations like "Player shoot before you get any message about its magazine state".

I'd recommend using UDP for all gameplay relates when speed is most important. Reload, move, physics, shoot, player positions.

And use WebSocket for side information. Like chant message, ranking, menus.

---
Tags: networking, multiplayer, websocket, udp
---


# Question
Title: ScreenToWorldPoint: How much depth has to be added to screen point?
I am developing a 3rd Person Controller.

The hero's chest should be rotated towards a point on the screen.

To determine the point, I use the following code:

```
var mousePos = Input.mousePosition;
mousePos.z = 10; // Make sure to add some "depth" to the screen point

var aim = Camera.main.ScreenToWorldPoint(mousePos);

```

Then I rotate the chest like this:

```
Vector3 v = new Vector3(0, aim.x, 0);
Chest.Rotate(v);

```

It does work, but it rotates only minimally, and the the direction is inverted: If the mouse is on the right of the screen, the chest rotates to the left and vice versa.

Also, I'm not sure how to include the model's overall rotation (but I don't know yet if that is necessary).

Does anybody have any idea what I'm doing wrong?

Edit: When I add more depth to it, it rotates much more:

```
var mousePos = Input.mousePosition;
mousePos.z = 100; // Make sure to add some "depth" to the screen point

var aim = Camera.main.ScreenToWorldPoint(mousePos);

```

But I have no idea how much depth is actually needed. If I add 1000, it rotates like crazy.

So I would like to know how to calculate the amount of depth that should actually be added to the screen point.

# Answer
> 1 votes
The Z you are assigning is taken as the distance of the point along the ray produced in the viewport; which corresponds to all the world points stacked on that screen point. The higher the Z, the farther it is from the camera.

That being said, based on the information you provided, I suspect you want to use `ScreenPointToRay` here, perform a raycast, then rotate the chest towards the hit point of the raycast. If the ray doesn't hit anything, then you can use your current method and assign a very high Z value to simulate infinity along the ray.

I'm also not sure what the purpose of just taking the x axis of your `aim` vector is. Don't you want to use the `aim` vector you already have? Why discard other axes? Also why are you assigning the x of aim to the y of your rotation vector? Maybe you want LookAt instead.

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


# Question
Title: 8-way 2D top down movement (diagonal) idle animation issues
**Background**

I am working on animations for 8-way movement for my character and have done the 8 directional running animations using a blend tree.

Now I need to do the same for the idle animations.

When the player stops moving, the correct idle animation should play.

For example, if they move right and let go of the 'A' button, then the idle animation of the player facing right is played.

---

**Problem**

I have done 4/8 directions (Up, Left, Right & Down), my problem is with the diagonals.

e.g if the player lets go of the 'W' and 'D' keys then the idle animation of the player facing the Upper Right corner should be played.

I can't get this to work though.

My blend tree for the animations:

I realize that it's because the two keys (Whether W+D, S+D, A+S, or W+A) are let go at different times, and with the system I have currently, the player has to let go of any of those two key combinations at exactly the same time to successfully play the right diagonal animation.

---

**Tl;Dr:**

How do I accomplish these post-movement idle animations when my current system relies on the player releasing the correct keys simultaneously?

Is there a system for this, add a tiny bit of input lag or map keys to something?

Code:

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

public class PlayerMovement : MonoBehaviour
{
    [SerializeField] private Transform pfDashEffect;

    public Animator animator;

    public LayerMask layerMask;

    Vector2 movement;

    public float speed = 10f;
    public float dashDistance = 100f;
    private Vector3 lastMoveDir;

    private float MoveX;
    private float MoveY;

    private void Update()
    {
        // Input
        movement.x = Input.GetAxisRaw("Horizontal");
        movement.y = Input.GetAxisRaw("Vertical");

        animator.SetFloat("Horizontal", movement.x);
        animator.SetFloat("Vertical", movement.y);
        animator.SetFloat("Speed", movement.sqrMagnitude);

        Move();
        Dash();

    }

    private void FixedUpdate()
    {
        PlayerAbilities.Dash();
    }

    private void Move()
    {
        MoveX = 0f;
        MoveY = 0f;

        if (Input.GetKey(KeyCode.W))
        {
            MoveY = +1f;
        }
        if (Input.GetKey(KeyCode.A))
        {
            MoveX = -1f;
        }
        if (Input.GetKey(KeyCode.S))
        {
            MoveY = -1f;
        }
        if (Input.GetKey(KeyCode.D))
        {
            MoveX = +1f;
        }

        bool isIdle = MoveX == 0 && MoveY == 0;
        if (isIdle)
        {
            // Play idle animation with the lastMoveDir so that the idle animation plays in the right rotation (left, right, up, down)
        }
        else
        {
            Vector3 moveDir = new Vector3(MoveX, MoveY).normalized;

            if (TryMove(moveDir, speed * Time.deltaTime))
            {
                // Play walking
                animator.SetFloat("Horizontal", movement.x);
                animator.SetFloat("Vertical", movement.y);
                animator.SetFloat("Speed", movement.sqrMagnitude);
            }
            else
            {
                // Play idle
                animator.SetFloat("Speed", 0);
            }
        }
    }

    private bool CanMove(Vector3 dir, float distance)
    {
        return Physics2D.Raycast(transform.position, dir, distance, layerMask).collider == null;
    }

    private bool TryMove(Vector3 baseMoveDir, float distance)
    {
        Vector3 moveDir = baseMoveDir;

        bool canMove = CanMove(moveDir, distance);
        if (!canMove)
        {
            // Cannot move diagonally
            moveDir = new Vector3(baseMoveDir.x, 0f).normalized;
            canMove = moveDir.x != 0f && CanMove(moveDir, distance);
            if (!canMove)
            {
                // Cannot move horizontally
                moveDir = new Vector3(0f, baseMoveDir.y).normalized;
                canMove = moveDir.y != 0f && CanMove(moveDir, distance);
            }
        }

        if (canMove)
        {
            lastMoveDir = moveDir;
            // Play walking animation with the moveDir so that the idle animation plays in the right rotation (left, right, up, down)
           // storeLastDirection(new Vector3(MoveX, MoveY));

            animator.SetFloat("LastMoveVertical", lastMoveDir.y);
            animator.SetFloat("LastMoveHorizontal", lastMoveDir.x);
            transform.position += moveDir * distance;
            return true;
        }
        else
        {
            return fase;
        }
    }

    private void Dash()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Vector3 beforeDashPosition = transform.position;
            if(TryMove(lastMoveDir, dashDistance))
            {
                Transform dashEffectTransform = Instantiate(pfDashEffect, beforeDashPosition, Quaternion.identity);
                dashEffectTransform.eulerAngles = new Vector3(0, 0, GetAngleFromVectorFloat(lastMoveDir));
                float dashEffectWidth = 5;
                dashEffectTransform.localScale = new Vector3(dashDistance / dashEffectWidth, 1f, 1f);
            }
        }
    }

    public static float GetAngleFromVectorFloat(Vector3 dir)
    {
        dir = dir.normalized;
        float n = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
        if (n < 0) n += 360;

        return n;
    }
}

```

At the moment I'm just storing the two x and y coordinates for my blend tree like this:

```
animator.SetFloat("LastMoveVertical", lastMoveDir.y);
animator.SetFloat("LastMoveHorizontal", lastMoveDir.x);

```

Which works well for the simple directions (North, East, South, West), just not the diagonal ones as the X/Y values change when each button is released. So if the player lets go of the W and 5 milliseconds later lets go of the D key, that's enough for the value to change which then in turn doesn't show the correct animation.

# Answer
I have found that a cheap lerp can do the trick. Try using a different variable to store the anim parameters, and lerp them to the target values over time.

```
private Vect3 animParam;

void UpdateAnimDir(Vector3 movementDir) {
    animParam = Lerp(animParm, movementDir, Time.deltaTime * 0.1);

    animator.SetFloat("Horizontal", animParam.x);
    animator.SetFloat("Vertical", animParam.y);
}

```

You can adjust the factor, or do something more complex to smooth out the value so you don't read the immediate value and react.
> 1 votes

# Answer
I didn't opt for the solutions mentioned since I wanted the character movement to be as snappy as possible. I chose to animate my player using a script based state machine, but the same logic should apply.

I got this to work by using GetAxis (not raw) as an indication for what buttons were previously pressed.

For example, assume WASD are used for controls. If W and D were held down and W was released 1 frame before D, that would cause the animation to default to Idle looking up. If Input.GetAxis("Horizontal") is slightly less than 1, then it had been pressed very recently. Knowing this, we set the animation to idle looking in the north east direction.
> 1 votes

# Answer
The best way to solve this problem would be to have a separate vector holding the direction that was just being moved in, and when a key is released to start a coroutine that will update this value after a couple of milliseconds

```
Vector3 heldDirection; // update this each time there is a new key down event, with all held keys

// for each of your directions
if(Input.GetKeyUp(direction){
    BlendToIdleFromDirection(heldDirection); // use the heldDirection to blend into your correct idleAnimation
    StartCorutine(ReleaseDirection(direction));
}

// will update the held direction after a small delay
ReleaseDirection(direction){
    yield return new WaitForSeconds(0.2f);
    if(Vector2.dot(direction,heldDirection) > 0) { // check in case this has been updated by another coroutine
        heldDirection -= direction;
    }
}

```
> 0 votes

---
Tags: unity, c#, 2d, animation, movement
---


# Question
Title: Why does the player cling to the ground and cannot jump?
I'm making a 2D platformer with Unity. I used this tutorial to write the code but with some changes like using the new Input System. Like the tutorial, I've defined three variables called `GroundedRememeber`, `JumpPressedRemember` and `JumpPressedRememberTime` and basically they work like timers and check if the player leaves the ground and if so, then the player can jump when it is near the ground without the need to touch it. The problem is that these timers are not working and the player can't jump, just clings to the ground. My player controller has no errors but the jumping is not working.

Here's my Player Controller script:

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

public class PlayerController : MonoBehaviour, PlayerInputActions.IPlayerActions
{
   private PlayerInputActions controls;
   [SerializeField] LayerMask groundLayers;
   private Rigidbody2D rb;
   private Animator anim;
   private bool facingRight = true;
   private Vector2 moveInput;
   private Vector2 playerSize;
   private float JumpPressedRemember = 0;

   [SerializeField] float JumpPressedRememberTime = 0.2f;
   private float GroundedRemember = 0;

   [SerializeField]  float GroundedRememberTime = 0.25f;
   [SerializeField]  float HorizontalAcceleration = 1;
   [SerializeField] [Range(0, 1)] float HorizontalDampingBasic = 0.5f;
   [SerializeField] [Range(0, 1)] float HorizontalDampingWhenStopping = 0.5f;
   [SerializeField] [Range(0, 1)] float HorizontalDampingWhenTurning = 0.5f;
   [SerializeField] [Range(0, 10)] float JumpHeight = 5f;

   private void Awake()
   {
      controls = new PlayerInputActions();
      controls.Player.SetCallbacks(this);
      controls.Enable();
   }
   void Start()
   {
      rb = GetComponent<Rigidbody2D>();
      anim = GetComponent<Animator>();
      playerSize = (Vector2) GetComponent<CapsuleCollider2D>().bounds.size + new Vector2(-0.02f, 0);
   }
   void PlayerInputActions.IPlayerActions.OnMove(InputAction.CallbackContext context)
   {
      moveInput = context.ReadValue<Vector2>();

   }

   void PlayerInputActions.IPlayerActions.OnJump(InputAction.CallbackContext context) {
       switch (context.phase) {
            case InputActionPhase.Performed:
            JumpPressedRemember = JumpPressedRememberTime;
               break;
       }
   }

   void FixedUpdate()
   {
       if(facingRight == false && moveInput.x > 0){
           Flip();
       } else if (facingRight == true && moveInput.x < 0){
           Flip();
       }
   }
   void Flip(){
        facingRight = !facingRight;
        Vector3 Scaler = transform.localScale;
        Scaler.x *= -1;
        transform.localScale = Scaler;

   void Update()
   {
       Vector2 GroundedBoxCheckPosition = (Vector2)transform.position + new Vector2(0, -0.01f);
       bool Grounded = Physics2D.OverlapBox(GroundedBoxCheckPosition, playerSize, 0, groundLayers);

       GroundedRemember -= Time.deltaTime;
       if (Grounded)
       {
           GroundedRemember = GroundedRememberTime;
       }

       JumpPressedRemember -= Time.deltaTime;

       if ((JumpPressedRemember > 0) && (GroundedRemember > 0)) {
            rb.AddForce(Vector2.up * JumpHeight, ForceMode2D.Impulse);
            GroundedRemember = 0;
            JumpPressedRemember = 0;
       }

       float HorizontalVelocity = rb.velocity.x;
       HorizontalVelocity += moveInput.x;

       if (Mathf.Abs(moveInput.x) < 0.01f)
            HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingWhenStopping, Time.deltaTime * 10f);
       else if (Mathf.Sign(moveInput.x) != Mathf.Sign(HorizontalVelocity))
           HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingWhenTurning, Time.deltaTime * 10f);
       else
            HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingBasic, Time.deltaTime * 10f);

       rb.velocity = new Vector2(HorizontalVelocity, rb.velocity.y);
   }
}

```

This is the original code from the tutorial which is using the old Input System:

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

public class PlayerMovement : MonoBehaviour
{
    [SerializeField]
    LayerMask lmWalls;

    [SerializeField]
    float fJumpVelocity = 5;

    Rigidbody2D rigid;

    float fJumpPressedRemember = 0;
    [SerializeField]
    float fJumpPressedRememberTime = 0.2f;

    float fGroundedRemember = 0;
    [SerializeField]
    float fGroundedRememberTime = 0.25f;

    [SerializeField]
    float fHorizontalAcceleration = 1;
    [SerializeField]
    [Range(0, 1)]
    float fHorizontalDampingBasic = 0.5f;
    [SerializeField]
    [Range(0, 1)]
    float fHorizontalDampingWhenStopping = 0.5f;
    [SerializeField]
    [Range(0, 1)]
    float fHorizontalDampingWhenTurning = 0.5f;

    [SerializeField]
    [Range(0, 1)]
    float fCutJumpHeight = 0.5f;

    void Start ()
    {
        rigid = GetComponent<Rigidbody2D>();
    }

    void Update ()
    {
        Vector2 v2GroundedBoxCheckPosition = (Vector2)transform.position + new Vector2(0, -0.01f);
        Vector2 v2GroundedBoxCheckScale = (Vector2)transform.localScale + new Vector2(-0.02f, 0);
        bool bGrounded = Physics2D.OverlapBox(v2GroundedBoxCheckPosition, v2GroundedBoxCheckScale, 0, lmWalls);

        fGroundedRemember -= Time.deltaTime;
        if (bGrounded)
        {
            fGroundedRemember = fGroundedRememberTime;
        }

        fJumpPressedRemember -= Time.deltaTime;
        if (Input.GetButtonDown("Jump"))
        {
            fJumpPressedRemember = fJumpPressedRememberTime;
        }

        if (Input.GetButtonUp("Jump"))
        {
            if (rigid.velocity.y > 0)
            {
                rigid.velocity = new Vector2(rigid.velocity.x, rigid.velocity.y * fCutJumpHeight);
            }
        }

        if ((fJumpPressedRemember > 0) && (fGroundedRemember > 0))
        {
            fJumpPressedRemember = 0;
            fGroundedRemember = 0;
            rigid.velocity = new Vector2(rigid.velocity.x, fJumpVelocity);
        }

        float fHorizontalVelocity = rigid.velocity.x;
        fHorizontalVelocity += Input.GetAxisRaw("Horizontal");

        if (Mathf.Abs(Input.GetAxisRaw("Horizontal")) < 0.01f)
            fHorizontalVelocity *= Mathf.Pow(1f - fHorizontalDampingWhenStopping, Time.deltaTime * 10f);
        else if (Mathf.Sign(Input.GetAxisRaw("Horizontal")) != Mathf.Sign(fHorizontalVelocity))
            fHorizontalVelocity *= Mathf.Pow(1f - fHorizontalDampingWhenTurning, Time.deltaTime * 10f);
        else
            fHorizontalVelocity *= Mathf.Pow(1f - fHorizontalDampingBasic, Time.deltaTime * 10f);

        rigid.velocity = new Vector2(fHorizontalVelocity, rigid.velocity.y);
    }
}

```

This is the `PlayerInputActions` window.

*The action type of Move is set to Pass Through and control type is Vector2*

# Answer
First thing make sure that the original script is working. In a simple test scene even the original script has bugs and the grounded check is not working correctly when your player gets scaled.

```
Vector2 v2GroundedBoxCheckScale = (Vector2)transform.localScale + new Vector2(-0.02f, 0);

```

If my player is for example has a sprite that is 0.25 units big and I scale it to 4x via the transform to make it 1, the original script assumes now that the player is grounded even if he is 4 units away from the ground. And he can do as many jumps in the air as he wants until he is really high.

You don't need to calculate the v2GroundedBoxCheckScale every update, you can do it once in Start and save the value since the scale of your player should not change anymore. To get the actual size, the easiest would be to grab it from the bounds of your renderer.

A simplified version for buffering the jump:

```
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerController : MonoBehaviour, PlayerInputActions.IPlayerActions
{

   [SerializeField] LayerMask groundLayers;
   [SerializeField] float jumpPressedRememberTime = 0.2f;
   [SerializeField] float groundedRememberTime = 0.25f;
   [SerializeField] [Range(0, 10)] float jumpHeight = 5f;

   private Rigidbody2D _rb;
   private PlayerInputActions _controls;
   private Vector2 _playerSize;
   private float _jumpPressedRemember = 0;
   private float _groundedRemember = 0;

   private void Awake()
   {
       _controls = new PlayerInputActions();
       _controls.Player.SetCallbacks(this);
       _controls.Enable();
   }

   void Start()
   {
      _rb = GetComponent<Rigidbody2D>();
      _playerSize = (Vector2) GetComponent<SpriteRenderer>().bounds.size + new Vector2(-0.02f, 0);
   }

   void PlayerInputActions.IPlayerActions.OnJump(InputAction.CallbackContext context){
       switch (context.phase) {
           case InputActionPhase.Performed:
               _jumpPressedRemember = jumpPressedRememberTime;
               break;
       }
   }

   void Update(){
       Vector2 groundedBoxCheckPosition = (Vector2)transform.position + new Vector2(0, -0.01f);
       bool grounded = Physics2D.OverlapBox(groundedBoxCheckPosition, _playerSize, 0, groundLayers);
       _groundedRemember -= Time.deltaTime;
       if (grounded)
       {
           _groundedRemember = groundedRememberTime;
       }
       _jumpPressedRemember -= Time.deltaTime;
       if ((_jumpPressedRemember > 0) && (_groundedRemember > 0))
       {
           _rb.velocity = Vector3.zero;
           _rb.AddForce(Vector2.up * jumpHeight, ForceMode2D.Impulse);
           _groundedRemember = 0;
           _jumpPressedRemember = 0;
       }
   }
}

```

I changed the JumpHeight to around 5 to see the actual jump.

Example project can be downloaded from https://github.com/Zibelas/DelayJump \- the scene DemoJumo.
> -1 votes

# Answer
When a player GameObject does not jump when you expect it too, sometimes the issue is related to having both a `Rigidbody` component with gravity enabled while also somehow constraining it's y-value to keep it from falling through the ground plane.

The constraint keeps the object from falling, yet its Rigidbody's velocity is being continually accelerated by gravity every frame.

To determine if this is the case, try resetting the GameObject's velocity before jumping:

### This will reset a GameObject's velocity and then jump:

```
rb.velocity = Vector3.zero;
rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Force);

```

where `rb` is a reference to the object's RigidBody component.
> 0 votes

---
Tags: unity, c#, input, jumping
---


# Question
Title: How to calculate best move in Match-3 game?
I am having a hard time identifying how to approach this problem.

If you have a match 3 game and the objects can only be swapped horizontally and vertically, and only swapped if it will result in a match of 3 or more jewels, which will be removed, with each removed jewel adding +1 to the score.

How would I find the best possible move? I'm confused at where to start and been searching for a while now and getting nowhere.

* Board 6x6 or 8x8
* Matches = 3 or more of same kind
* write function to find best swap for maximum score.

Any help would be greatly appreciated !

EDIT: So I could iterate through the entire board with a nested for loop for the rows and columns, but im not sure what approach to take from here.

For example, say I start with top left which is "red" and I want to test if swapping this will result in a match. How would I go about searching and identifying all possibilities that would result in swapping this left equaling a match and score of 5.

\**If I am being really unclear I apologies and will remove my question and possible reword.

# Answer
Do you want the best move *right now*, or are you looking moves in advance?

If it's just the best move right now for the most points on this move, try every legal move and then pick the one with the highest value. Assume incoming gems during a chain reaction don't match with anything so you get the best you can calculate with no concern for what random gems might fall in to replace them.

If you want to look moves in advance, then you use the minimax algorithm on the above tactic. As you go more moves in advance, the unknown non-matching gems will take up more and more space, which mimics the inability to plan very far in advance in these games.
> 3 votes

# Answer
Another approach is to brute force it. (Basically what Almo wrote, I will just explain the steps a bit more if you want only the best single move)

1. Make a copy of your game board. You always only work with the copy, not the original board.
2. You start at the top left tile. We are iterating now over the board, always checking to the right and bottom. You don't need to compare it to the left/ top since it would be a duplicated check.
3. If your current tile is a valid move, check how many points you got for it. If it was your first valid move, save the tile and direction of your move and the score. If it is a second valid move, compare the score. If it is higher, replace your old saved tile/ direction/ score.
4. After each valid made move, you grab another copy from the board and continue from the tile you checked last.
5. You can also check multiple moves, like what is the max score you can make in 3 moves. All you need to to is change the copy you take in 1. from the result board you get after you made the move.

One thing you need to pay attention is, how are you generating new tiles. If you have some CreateRandomTile(), you should replace it by a list that gets prefilled by a few dozen tiles from your CreateRandomTile(). That way you guaranty that you always have the same board. (And it is easier compared to clone the random function). You won't be able to evaluate the absolut best for 10 moves ahead, but 3 moves ahead is all you need. When you find the best 3 next moves, just make the first of the three and reevaluate again the next 3.
> 0 votes

# Answer
I'm pretty sure this problem doesn't have a neat algorithm to it, so brute force is the way to go:

```
var optimalMove = {points: -1, x: null, y: null, direction: null}
for each (x) {
    for each (y) {
        for each (direction in [up, down, left, right]) {
            // Create identical copy of the board so we don't mess up the actual board
            var copy = realBoard.copy()
            copy.moveTile(x, y, direction)
            var points = copy.removeConnectedTiles()
            if (points > optimalMove.points)
                optimalMove = {points, x, y, direction}
        }
    }
}
realBoard.moveTile(optimalMove.x, optimalMove.y, optimalMove.direction)

```

Can be slightly optimized by not doing a move if the board would look identical, e.g:

```
if(tileAt(x, y).color == neighbor(x, y, direction).color)
    continue

```

If you're having trouble finding which tiles are connected to which other tiles (so, finding the actual score) I would (off the top of my head...) look for the biggest Flood Fill. The algorithm is quite simple:

```
function floodFill(x, y, color = null, checked = []) {
    var tile = tileAt(x, y)
    if(color is null)
        color = tile.color
    else if (tile.color is not color)
        return 0;

    var sum = 0
    if(checked does not contain {x + 1, y})
        sum += floodFill(x + 1, y, color, checked + {x + 1, y})
    if(checked does not contain {x - 1, y})
        sum += floodFill(x - 1, y, color, checked + {x - 1, y})
    if(checked does not contain {x, y + 1})
        sum += floodFill(x, y + 1, color, checked + {x, y + 1})
    if(checked does not contain {x, y - 1})
        sum += floodFill(x, y - 1, color, checked + {x, y - 1})
    return sum
}

var highest = {score: -1, x: null, y: null}
for each (x, y) {
    if (floodFill(x, y) > highest.score)
        highest = {score: floodFill(x, y), x, y}
}

```

My implementation might have some issues, check the linked wikipedia page. Can definitely be improved in performance (if a tile has already been checked, no need to check it again).
> 0 votes

---
Tags: algorithm
---