Script works strange

Hello everyone. I have a very basic script of keeping the player near an object. Sometimes it works fine, sometimes it shows debug messages and does nothing. Also I noticed that when I change anything in the script file (literally just by adding comments) it works as intended. What I made wrong?

Here’s a code:

public bool isFightOn = false;
   
    public GameObject player;
    public GameObject encounter;
    public float radius = 2f;

    public void Update()
    {
        if (isFightOn)
        {
            var localEncounterVector3 = encounter.transform.position;

            var distance = Vector3.Distance(player.transform.position, localEncounterVector3);

            if (distance >= radius)
            {
                var newPosition = player.transform.position - localEncounterVector3;
                Debug.Log("text1");

                newPosition *= radius / distance;
                player.transform.position = localEncounterVector3 + newPosition;
            }
        }
    }

    public void CreateBondary(GameObject player, GameObject encounter, float radius)
    {
        var localEncounterVector3 = encounter.transform.position;

        var distance = Vector3.Distance(player.transform.position, localEncounterVector3);

        if (distance > radius)
        {
            var newPosition = player.transform.position - localEncounterVector3;
            Debug.Log("text1");

            newPosition *= radius / distance;
            player.transform.position = localEncounterVector3 + newPosition;
        }
    }

    public override void Interact()
    {
        isFightOn = true;
    }

What went wrong?

Hello.

Unfortunately, it’s a bit hard to tell what is going on without a little more context. What debug messages are showing?

One thing I did notice in your script is you have a duplicate algorithm happening in both your update and in the CreateBondary() method. Is your intention to run this method when the “isFightOn” variable is true?

It seems you may be confusing yourself by changing one algorithm in the CreateBondary() method and not seeing the effect because only the update version of the algorithm is being run.

Also, when is Interact called? it may not be called sometimes due to another script resulting in the issues you are seeing.

Let me know if this helps at all, or if there is more context to the situation.

I’m sorry for inconvenience. I forgot to sanitize a code for a show. Actually what I have:

public class CallableBoundary : InteractableModule
{
    public bool isFightOn = false;
   
    public GameObject player;
    public GameObject encounter;
    public float radius = 2f;

    public void Update()
    {
        if (isFightOn)
        {
            var localEncounterVector3 = encounter.transform.position;

            var distance = Vector3.Distance(player.transform.position, localEncounterVector3);

            if (distance >= radius)
            {
                var newPosition = player.transform.position - localEncounterVector3;
                Debug.Log("text1");

                newPosition *= radius / distance;
                player.transform.position = localEncounterVector3 + newPosition;
            }
        }
    }

    public override void Interact()
    {
        isFightOn = true;
    }
}

And this is parent class. It works.

abstract public class InteractableModule : MonoBehaviour
{
    public abstract void Interact();

    // Start is called before the first frame update
    void Start()
    {
        var interactable = GetComponent<Interactable>();

        if (interactable == null)
        {
            Debug.LogError("No Interactable");
            return;
        }

        interactable.OnInteract += Interact;
    }
}

When I said debug message, I meant my Debug.Log(“text1”);. Player keeps moving away from my object and nothing holds him. But sometimes it fires up and ties the player to itself.

In your update function:

public void Update()
    {
        if (isFightOn)
        {
            var localEncounterVector3 = encounter.transform.position;
            var distance = Vector3.Distance(player.transform.position, localEncounterVector3);
            if (distance >= radius)
            {
                var newPosition = player.transform.position - localEncounterVector3;
                Debug.Log("text1");
                newPosition *= radius / distance;
                player.transform.position = localEncounterVector3 + newPosition;
            }
        }
    }

it’s unclear to me what your are trying to do to the new position variable. If you want to lock into the appropriate position, why alter the new position by dividing the radius by the distance?

If you want to snap directly to a position around the location you can do the following:

public void Update()
    {
        if (isFightOn)
        {
            var localEncounterVector3 = encounter.transform.position;
            player.transform.position = localEncounterVector3 + (player.transform.position - localEncounterVector3);
        }
    }

this will situate the player in the right location without doing unnecessary checks. I’m thinking that your check if (distance >= radius) is the main issue and sometimes it’s not returning the appropriate value, as well the newPosition *= radius / distance; doesn’t make sense in my mind as to it’s purpose in positioning the player correctly.

I think this is what your are looking for, let me know if your intentions are different. Perhaps a visual drawing would help?

I want to let player move within the round with an object as a center. So I calculate distance between him and the object. If player tries to escape “the circle” then he’s stumbles upon an “invisible wall”.

I tried your solution and still I can move freely. Maybe something is wrong with my usage of transform?

Then maybe you don’t need to lock the player into position, you could use the transform.RotateAround() method with input that you specify to move around the encounter position: Unity - Scripting API: Transform.RotateAround (unity3d.com) When the encounter occurs (as I understand it) you can switch to using this as the movement.

I found the culprit. It was a character controller on my capsule. It was simply overwriting my changes. So if my code is called from the LateUpdate then everything works fine.

Oh perfect, glad you found the issue! Gotta love things overriding other things. Makes game dev fun! :stuck_out_tongue:

1 Like