locations being stored in map manager are inaccurate and ruining overlap validation.

I don’t understand why sometimes the sections are deactivating like they should… and sometimes they are not. All I’m trying to do is make sure the maze pieces can’t be placed on top of each other (unless I want them too… users will get a power up where their tiles “crush” underlying tiles, so I have to be mindful of that feature now.

MazeManger.cs

  public static void SectionPlaced(GameObject mazeTile)
    {
        SectionValidation[] children;
        children = mazeTile.GetComponentsInChildren<SectionValidation>();
        foreach (SectionValidation sectionValidation in children)
        {
            
            if (instance.placedSections.Contains(sectionValidation.gameObject.transform.position))
            {
                Debug.LogError("placed two sections in same spot");
            }
            else
            {                
                instance.placedSections.Add(sectionValidation.gameObject.transform.position);
            }
        }
        EventManager.TriggerEvent("OnPlaceTile");
    }
}

BuildController.cs

  private void RotateGhost()
    {
        ghost.transform.Rotate(Vector3.up * 90.0f);
        currentRoty += 90.0f;
        if (currentRoty >= 360) currentRoty = 0.0f;
        
        SectionValidation[] children;
        children = ghost.GetComponentsInChildren<SectionValidation>(true);
        foreach (SectionValidation section in children)
        {
            section.gameObject.SetActive(true);
        }
        EventManager.TriggerEvent("OnMoveGhost");
    }

    private void PlaceMazeTile()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out RaycastHit hitInfo, 300f, mask))
        {
            if (!equippedTile) return;
            targetNode = hitInfo.transform.gameObject;

            GameObject placed = Instantiate(ghost, new Vector3(targetNode.transform.position.x, 0, targetNode.transform.position.z), Quaternion.Euler(0, currentRoty, 0));
            
            MazeManager.SectionPlaced(placed);

            if (ghost) Destroy(ghost);
        }
    }

    public void MoveGhost()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray, out RaycastHit hitInfo, 300f, mask))
        {
            if (!equippedTile) return;
            //only run the first time we hit a new node
            if (hitInfo.transform.gameObject == targetNode) return;
            targetNode = hitInfo.transform.gameObject;

            if (ghost) Destroy(ghost);
            ghost = Instantiate(equippedTile, new Vector3(hitInfo.transform.position.x, 0, hitInfo.transform.position.z), Quaternion.Euler(0, currentRoty, 0));
            EventManager.TriggerEvent("OnMoveGhost");
                     
        }

    }

SectionValidation.cs This is placed on every 1x1 square section of the tile… like minos making up a tetromino

 private void OnMoveGhost()
    {
        if (!isGhost) return;

        if(MazeManager.instance.placedSections.Contains(this.gameObject.transform.position))
        {
            this.gameObject.SetActive(false);
        }
    }

2 Answers

2

@Astrydax you are almost certainly dealing with floating point precision errors. This is a well documented problem in computing and is not limited to Unity. Doing some google searches on it will show you many people experiencing this issue.

A quick search found this on Unity forums which has an answer from a user called lordofduct that you should probably review.

If you refactor your code to add integers instead of floats, and then cast them to floats it might solve or reduce your issue

So change this bit:

 ghost.transform.Rotate(Vector3.up * 90.0f);
         currentRoty += 90.0f;
         if (currentRoty >= 360) currentRoty = 0.0f;

To something like this:

     ghost.transform.Rotate(Vector3.up * 90);
        currentRoty += 90;
        if (currentRoty >= 360) currentRoty = 0;

that line was originally that. I changed it to a float to see if it made a difference.

In your SectonValidation script, you could make a Vector3Int property, and use that instead of transform.position, this way you won’t suffer from floating-point inaccuracy.