How can I improve and fix this code?

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

public class DirtBlockHover : MonoBehaviour {


    // Setting up
    public GameObject Selection;
    public float Axisz = (float)15.92; // Offset
    public float Axisy = (float)24.1; // Y Value
    public float Axisx = (float)-17.13; // Offset
    public float MarkY = (float)4.5; // For the Marker
    public AudioSource Dig; // Sound
    public GameObject Mark; // Marker
    public Vector3 spawnPos; // CheckSphere() position
    public float radius; // CheckSphere() radius
    private GameObject MarkObject; // Marker Instantiated Clone

    private void OnMouseEnter() // Upon entering the dirtblock, gold, or Gems object which this script is attached to
    {
        RaycastHit hit = new RaycastHit(); // Raycasting!!
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // SPTR = ScreenPointToRay
        if (Physics.Raycast(ray, out hit, 1000)) // Set the ray to 'ray' and it's length to 1000 units.
        {
            print("YAY! IT SHOULD WORK!"); // debugging tool!
            Selection.SetActive(true); // Turning the SelectionBox on
            Selection.transform.position = new Vector3(gameObject.transform.position.x + Axisx, Axisy, gameObject.transform.position.z + Axisz); // Set selection box to current objects position and add some
            if (Input.GetMouseButtonDown(0)) // When my mouse clicks
            {
                if (Physics.CheckSphere(spawnPos, radius, 20)) // Check if there is already a marker above the object, Layer 20 is the Marker Layer
                {
                    print("Destroying Mark"); // more debugging
                    Dig.Play(); // Play a dig sound
                    Destroy(Mark); // DESTROY IT
                }
                else
                {
                    print("Adding Mark"); // another debugging thingy
                    Dig.Play(); // Play a dig sound
                    MarkObject = Instantiate(Mark, new Vector3(gameObject.transform.position.x, gameObject.transform.position.y + MarkY, gameObject.transform.position.z), transform.rotation); // add the Marker to the world.
                }
            }
        }
        /* if (hit.transform.tag == "Land")
        {
        print("IS IT WORKING?");
        Selection.SetActive(false);
        }
        GameObject[] childObjects = Selection.GetComponentsInChildren<GameObject>();
        */
        // Up above used to play a previous role. Now I am just keeping it just incase I change my mind on some feature.

        if (hit.transform.tag == "Bedrock") // If it hits bedrock
        {
            Selection.SetActive(false);
            // Like I said, just incase I want to change it. 
        }


    }

    private void OnMouseExit()
    {
        Selection.SetActive(false);
    }
}

This is used for a game I am creating that is similar to Dungeon Keeper, where you dig out your own Dungeon. These are assigned to diggable blocks. Clicking on the diggable blocks make it marked. The problem is, this isn’t exactly marking every single one you click. It instead acts like you aren’t clicking sometimes when you are. So, sometimes is works, sometimes it doesn’t.

I was hoping someone would point me in the right direction or help me out here as to why this isn’t working as intended. If you could explain, that would be great! I put comments in the script to help understand.

All transform and rotations calculations should be used in Fixed Update. Put the vectors and quaternions calcs inside Fixed Update. Use a method(); inside FixedUpdate also. Link it like the example above, because i think that to your code Works better, just need organize it:

//Try this pseudo code

float force = 0f;

void FixedUpdate()
    {

        Method1();
        Method2();
         
        Rigdibody.AddForce(Vector3.up * force);
        Rigidbody.rotation = Quaternion.Euler(new Vector3(0, force, 0));
        
    }

void method1()
{ 
   if(Input.GetAxis("Horizontal") > 0{force = 50f;}
}

void method2()
{
    if(Input.GetAxis("Horizontal") < 0{force = -50f;}
}

The first problem I see is setting up your variables. You create float variables, then cast them as floats, that’s unnecessary. You were likely getting an error because you left out the “f” after each value; all float values must have an “f” after the number.

public float Axisz = (float)15.92;

should be this:

public float Axisz = 15.92f;

Next, I placed your GameObject and component variables at the top because they’re easier to see and grab references as needed. I also changed how some variables were named Axisz to axisZ will read easier in the inspector and in code.

Initializing RaycastHit is unnecessary. Doing RaycastHit hit; is fine.

Don’t extend a ray’s length more than it needs to. The greater the ray, the more objects you have to check against it, so using 1000 is overkill.

Print() is a wrapper for Debug.Log() and easier to type but only works on classes derived from MonoBehaviour. Because of this it’s simpler to use Debug.Log() so you don’t mix-and-match them depending on your class inheritance.

It’s more optimal to cache your gameobject’s position if used multiple times.

private Transform  t;            // This gameobject's transform

void Awake()
{
    t = transform;
}

// Set to current position with offset
selection.transform.position.Set( t.position.x + axisX, axisY, t.position.z + axisZ );

The int value in CheckSphere() is not the layer id but a bitmask. If you want to hit an object on layer id 20, you must specify 1 << 20, not 20.

if ( Physics.CheckSphere( spawnPos, radius, 20 ) )

needs to be

if ( Physics.CheckSphere( spawnPos, radius, 1 << 20 ) )

Even easier, you can create a LayerMask variable and use that instead.

public LayerMask  markerLayer;    // Marker layer

if ( Physics.CheckSphere( spawnPos, radius, markerLayer ) )

You should not constantly Destroy and Instantiate game objects. That’ll ruin your performance. If you’re only using one maker, simply activate and deactivate the game object.

// Hit marker?
if ( Physics.CheckSphere( spawnPos, radius, 1 << 20 ) )
{
    Debug.Log( "Clearing marker..." );
    Dig.Play();
    markerObject.SetActive( false );
}
else
{
    Debug.Log( "Placing marker..." );
    Dig.Play();

    // Reposition marker
    markerObject.SetActive( true );
    markerObject.transform.position.Set( t.position.x, t.position.y + markY, t.position.z );
}

Always use CompareTag(), it does not allocate garbage.

// Hit bedrock?
if ( hit.transform.tag == "Bedrock" )
{
    selection.SetActive( false );
}

into

// Hit bedrock?
if ( hit.collider.CompareTag( "Bedrock" ) )
{
    selection.SetActive( false );
}

Here is the final code refactored:

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

public class DirtBlockHover : MonoBehaviour
{
    public GameObject  selection;
    public AudioSource dig;           // Sound
                                      
    [Header("Positions")]             
    public float axisX = -17.13f;     // X Offset
    public float axisY = 24.1f;       // Y Value
    public float axisZ = 15.92f;      // Z Offset
    public float markY = 4.5f;        // For the marker
                                      
    [Header("Marker Detection")]      
    public GameObject marker;         // Marker
    public LayerMask  markerLayer;    // Marker layer
    public float      markerRadius;   // Radius of sphere
    public Vector3    markerPosition; // Center of sphere
                                      
    private Transform  t;             // This gameobject's transform
    private GameObject markerObject;  // Marker instantiated clone

    void Awake()
    {
        t = transform;
    }

    // Upon entering the dirtblock, gold, or Gems object which this script is attached to
    private void OnMouseEnter()
    {
        RaycastHit hit;
        Ray ray = Camera.main.ScreenPointToRay( Input.mousePosition );

        // Hit something?
        if ( Physics.Raycast( ray, out hit, 100 ) )
        {
            Debug.Log( "You hit something!" );
            selection.SetActive( true );

            // Set to current position with offset
            selection.transform.position.Set( t.position.x + axisX, axisY, t.position.z + axisZ );

            // Left click?
            if ( Input.GetMouseButtonDown( 0 ) )
            {
                // Hit marker?
                if ( Physics.CheckSphere( markerPosition, markerRadius, markerLayer ) )
                {
                    Debug.Log( "Clearing marker..." );
                    dig.Play();
                    markerObject.SetActive( false );
                }
                else
                {
                    Debug.Log( "Placing marker..." );
                    dig.Play();

                    // Reposition marker
                    markerObject.SetActive( true );
                    markerObject.transform.position.Set( t.position.x, t.position.y + markY, t.position.z );
                }
            }
        }

        // Hit bedrock?
        if ( hit.collider.CompareTag( "Bedrock" ) )
        {
            selection.SetActive( false );
        }
    }

    private void OnMouseExit()
    {
        selection.SetActive( false );
    }
}

You don’t have to comment every line of code. It’s good so you don’t forget what you did but naming variables and methods properly will help your code read itself. Playing an audio sound or debug.log doesn’t need a comment. For code that merits commenting, make sure to say in as few words what the following code/line does…