Trying to Limit player movement when button is pressed

Hi,
I am making a game where you have the ability to become non solid and when in this state i want it to be so that the player can only move within a fixed area, preferably a half dome
any ideas for the code???

6 Answers

6

There’s multiple ways this could be achieved:

  1. One solution is to have a special Tag for the walkable floor areas. Say you have a floor that the player is allowed to walk on. Give it a tag named “Walkable”.
    Then your script is generating Raycasts downward to detect the tag of the current floor. If the floor below the player does not contain the tag “Walkable”, then the player is not allowed to move there, If the floor below the player does contain “Walkable”, then the player can move to that location.

  2. You could use a bounds check (if using square shaped area). Add a collider set to trigger in the scene as the bounds area.
    Figure out where the player would be if it moved. Then do

if (boundsCollider.bounds.Contains(newPlayerPosition))
{
    //ok to move player
}
  1. Or if using a circle area, you could calculate the the distance from the center of the circle to the player. The player would not be allowed to move if the distance is greater than the radius of the circle.
var dist = Vector3.Distance(circleArea.transform.position, newPlayerPosition));
if (dist  < circleArea.radius)
{
   //ok to move player
}

Hello @FreshWind1020,

You can clamp the position to a circle:

void Update() {
    // Calculate the direction from the center point to the current position
    Vector3 direction = this.transform.position - this.centerPoint.position;

    // Clamp the distance to the maximum radius of the circle
    float distance = direction.magnitude;
    float clampedDistance = Mathf.Clamp(distance, 0f, this.maxDistance);

    // Calculate the new position limited to the circular boundaries
    Vector3 newPosition = this.centerPoint.position + direction.normalized * clampedDistance;

    // Update the position of the object or player or whatever
    this.transform.position = newPosition;
}

p.s what would be the best way to show this boundary to the player???

a dotted circle on the floor to limit the area, or if you use shader graph you can check Brackey on youtube and make the force field, so when your player get's near the limit the force field appears slightly

Can you send me a link to that video? I could not find it.

Dear Cyber_Cats I tryed your code and a few things are confusing to me about it, The first thing i would like to address it the variable "this" in this.transform.position, I am assuming this is the player????? also in the code Vector3 direction = this.transform.position - this.centerPoint.position; The location of this.centerPoint.position is not defined All in all i do not truly understand your code and would love to have some more feed back Sincerely FreshWind1020

Hello, "this" is just a keyword, it's a reference on the current class, it helps me know if i'm using a class variable or a local variable but you can remove it. the "centerPoint" is a transform that you place in the center of the circle where you want your player to be stuck, nothing fancy

Thank you so much for all the great advice
Ill be shure to try your suggestions I am new to unity and the C# language
so I am so glad to have such a great community

cheers:
FreshWind1020


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

public class Disperse : MonoBehaviour
{
    public Transform centerPoint;
    public float maxDistance;
    public float targetTime = 30.0f;
    // Start is called before the first frame update
    void Start()
    {
        maxDistance = 5;    
    }

    // Update is called once per frame
    void Update()
    {
        
        targetTime -= Time.deltaTime;
        if (targetTime <= 0.0f)
        {
            timerEnded();
        }
        if (Input.GetKeyDown(KeyCode.Return) && targetTime > 0.0f)
        {

            Debug.Log("maxdis = true");
            // Calculate the direction from the center point to the current position
            Vector3 direction = this.transform.position - this.centerPoint.position;

            // Clamp the distance to the maximum radius of the circle
            float distance = direction.magnitude;
            float clampedDistance = Mathf.Clamp(distance, 0f, this.maxDistance);

            // Calculate the new position limited to the circular boundaries
            Vector3 newPosition = this.centerPoint.position + direction.normalized * clampedDistance;

            //Update the position of the object or player or whatever
            this.transform.position = newPosition;
        }
        void timerEnded()
        {
            targetTime = 30.0f;
        }
    }
}


You coded everything in a condition that makes it execute only once

right but even that one time when i press enter it does not seem to limit movement

I see the problem now and i fixed it!

thank you for all the help!

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

public class Disperse : MonoBehaviour {

    private static float MAX_DISTANCE = 5;

    public Transform centerPoint;
    public float targetTime = 30.0f;

    private bool _isASlime;

    private void Update() {
        
        if (Input.GetKeyDown(KeyCode.Return) && this._isASlime == false) {
            this.TransformToSlime();
        }

        if (this._isASlime == false) {
            return; // not executing the code under this if it's not a slime 
        }

        targetTime -= Time.deltaTime;
        if (targetTime <= 0.0f) {
            this.BackToNormal();
            return;
        }

        // Calculate the direction from the center point to the current position
        Vector3 direction = (this.transform.position - this.centerPoint.position);

        // Clamp the distance to the maximum radius of the circle
        float distance = direction.magnitude;
        float clampedDistance = Mathf.Clamp(distance, 0f, MAX_DISTANCE);

        // Calculate the new position limited to the circular boundaries
        Vector3 newPosition = this.centerPoint.position + direction.normalized * clampedDistance;

        //Update the position of the slime
        this.transform.position = newPosition;
    }

    private void TransformToSlime() {
        this._isASlime = true;
        targetTime = 30.0f;
    }

    private void BackToNormal() {
        this._isASlime = false;
        targetTime = 30.0f;
    }

}

@FreshWind1020 I forgot something: when you turn to a slime you have to reset the position of the centerPoint to where you are:

private void TransformToSlime() {
    this.centerPoint.Position = this.transform.position
    this._isASlime = true;
    targetTime = 30.0f;
}

Ok would i put that at the end?

also thank you so much for all of the help!

In my previous reply I recoded your script, you can change the TransformToSlime function by this one. You are welcome :)

ummm i ran into a problem

Assets\Poof.cs(51,26): error CS1061: 'Transform' does not contain a definition for 'Position' and no accessible extension method 'Position' accepting a first argument of type 'Transform' could be found (are you missing a using directive or an assembly reference?)