0
\$\begingroup\$

I am trying to make a game where upon the player stepping on a block, the block will change color. I am doing this by using transform.position with the player character being recognized as 1 above in the position.y component.

When the player moves, my debug.log is telling me that the function is being called. However, my secondary debug which should go off whenever the player is above the block is not going off. I am completely stuck on what is causing this problem.

Here is my player code

public class Player : MonoBehaviour
{
    //singleton
    private static Player _player;
    public static Player Instance { get { return _player; } }
    private void Awake()
    {
        if (_player != null && _player != this)
            Destroy(this.gameObject);
        else
            _player = this;
    }

    public static Vector3 playerPos;

    public void IsMoving()
    {
        if (Input.GetKeyDown(KeyCode.D) == true)
        {
            transform.position = transform.position + new Vector3(1f, 0, 0);
            CubeScript.ColorChanger();
        }
        else if (Input.GetKeyDown(KeyCode.A) == true)
        {
            transform.position = transform.position + new Vector3(-1f, 0, 0);
            CubeScript.ColorChanger();
        }
        else if (Input.GetKeyDown(KeyCode.W) == true)
        {
            transform.position = transform.position + new Vector3(0.5f, 1f, 1f);
            CubeScript.ColorChanger();
        }
        else if (Input.GetKeyDown(KeyCode.S) == true)
        {
            transform.position = transform.position + new Vector3(-0.5f, -1f, -1f);
            CubeScript.ColorChanger();
        }

    }

    void Update()
    {
        playerPos = transform.position;
        IsMoving();
    }
}

Here is my Cube code

public class CubeScript : MonoBehaviour
{

    public static bool isSteppedOnOnce = false;
     public static bool isSteppedOnTwice = false;

     public static Vector3 cubePos;
     public GameObject thisCube;


     public void Awake()
     {
         cubePos = thisCube.transform.position;
         rend = GetComponent<Renderer>();
     }

    //color manager
    public Material green;
    public Material blue;
    public Material red;
    public static Renderer rend;
    public static void ColorChanger()
    {
         Debug.Log("Called");
         if (isSteppedOnOnce == false &&
             Player.playerPos.x == cubePos.x &&
             Player.playerPos.y == cubePos.y + 1 &&
             Player.playerPos.z == cubePos.z)
         {
             Debug.Log("Stepped On");
            // isSteppedOnOnce = true;
            // GetComponent<Renderer>().material = green;
         }
     }

     // Update is called once per frame
     void Update()
     {

     }
}
```
\$\endgroup\$
0
\$\begingroup\$

My first instinct says the issue is with your floating point comparisons using the equality operator. Specifically, this:

Player.playerPos.x == cubePos.x &&
Player.playerPos.y == cubePos.y + 1 &&
Player.playerPos.z == cubePos.z

I would recommend putting in a debut log statement showing the exact position of the player and cube:

public static void ColorChanger()
{
     Debug.Log("Called");
     var p = Player.playerPos;
     Debug.Log("player pos: " + p.x + "," + p.y + "," + p.z);
     p = cubePos;
     Debug.Log("cube pos: " + p.x + "," + p.y + "," + p.z);
 }

Then compare the output when the player steps in the cube. Are the values of playerPos and cubePos both exactly what you expect them to be? Note that there is a difference between 5 and 5.000000000001 that might occur due to rounding errors during floating point math.

It also might be the case that your cube and player are simply not equally aligned to a grid. This would also be evident with those logs.

In the general case, without knowing the output of those log statements, I can still give s as general suggestion, which is to do invaders comparison, eg.

Mathf.roundToInt(Player.playerPos.x) == Mathf.roundToInt(cubePos.x) &&
Mathf.roundToInt(Player.playerPos.y) == Mathf.roundToInt(cubePos.y + 1) &&
Mathf.roundToInt(Player.playerPos.z) == Mathf.roundToInt(cubePos.z)

It is also possible that “1” is not how far apart the transforms are when they appear to be next to each other. Maybe the box’s center is at the bottom of the model or something. This would also be made apparent by the added logging.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ It appears that my code is calling the player's position BEFORE the movement, as opposed to where the player is arriving. The cube is also being located as a single position each time. This value does not appear to be based off the prefab I am generating it from. Instead it is appearing on one specific block of the 28 I have on the screen imgur.com/a/P8Xm6HH \$\endgroup\$ – Tyler Apr 12 at 14:03
  • \$\begingroup\$ I am trying to use 1 prefab that will relay its GameObject information to each respective iteration of the prefab (Cube 1 has Cube 1 as thisCube, Cube 2 has Cube 2 as thisCube, etc.) and that seem on the surface to work \$\endgroup\$ – Tyler Apr 12 at 14:10
  • 1
    \$\begingroup\$ The problem then is that ColorChanger is a static method, which means it exists once globally, not once for each cube. The same is true of cubePos. Then when all of the cubes wake up, they each set the same cubePos variable to its own position. I assume what you want is to call a non-static ColorChanger method in each cube individually. That’s going to require some redesign in your part so that they can all get notified. There are many ways to do it. \$\endgroup\$ – Ed Marty Apr 13 at 1:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.