0
\$\begingroup\$

This is my logic :

When the player is moving I'm getting the distance from another object.

When the player is at distance for example 61 slow down the player moving "Forward" until the player stop and can't move any further forward.

The same logic should be applied for any direction the player is moving from the object not only from the object front or the sides 360 degrees no matter where the player is moving to when the distance is 61 start slow down the player to stop.

The next logic/rule is one of my biggest problem :

When the player is rotating by me and facing the other direction the give the player to option to move again this time make the player start moving again from slowdown to the regular walking speed. but only if the player is facing the other direction.

Now the problems I'm facing :

When the player moved forward reached distance 61 then start slow down and then stop, if the player is rotating facing the other direction and start moving back even a bit for a millisecond then if I rotate the player to the forward direction again he can move again and pass the distance 61. This way even if the player stopped already I can cheat the block by rotating facing the player the other direction moving only a bit then rotating back again and move much more. I need some how to make that if the player stopped then rotating the other direction start walking again only if he reach some distance like 50 or 40 then he can rotate back and move forward again and slow down and stop at distance 61.

The second problem is when I'm moving far away from the object but in another place from the side or from the back then the player is walking/running automatic and everything get messed. The play not stopping not slow down.

I can record a very short and small video clip to show what I mean, What it's doing so far and what are the problems if the video clip maybe will be more help to understand what I'm trying to do.

This is a short video clip I recorded showing the problem/s.

The problem/s I shot it starting from second 37 : in this case the distance is checked from the big space ship behind the player.

https://www.youtube.com/watch?v=Rrw_swX5Q8A&feature=emb_logo

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityStandardAssets.Characters.ThirdPerson;

public class DistanceCheck : MonoBehaviour
{
    public GameObject distanceTarget;
    public GameObject longDistanceDescriptionTextImage;
    public TextMeshProUGUI text;

    private Animator anim;

    float timeElapsed = 0;
    float lerpDuration = 3;
    float startValue = 1;
    float endValue = 0;
    float valueToLerp = 0;

    // Opposite Direction
    float timeElapsedOpposite = 0;
    float lerpDurationOpposite = 3;
    float startValueForOpposite = 0;
    float endValueForOpposite = 1;
    float valueToLerpOpposite = 0;

    float angle;

    // Start is called before the first frame update
    void Start()
    {
        angle = transform.eulerAngles.y;
        anim = transform.GetComponent<Animator>();
    }

    // Update is called once per frame
    void Update()
    {
        var distance = Vector3.Distance(transform.position, distanceTarget.transform.position);
        angle = transform.eulerAngles.y;
        if (distance > 61f && angle < 180)
        {
            if (timeElapsed < lerpDuration)
            {
                valueToLerp = Mathf.Lerp(startValue, endValue, timeElapsed / lerpDuration);
                anim.SetFloat("Forward", valueToLerp);
                timeElapsed += Time.deltaTime;
            }
            anim.SetFloat("Forward", valueToLerp);
            timeElapsedOpposite = 0;
            longDistanceDescriptionTextImage.SetActive(true);
            text.text = "I can't move that far by foot. I need to find some transportation to move any further.";
        }

        // Get the angle:

        if (angle > 180f && distance > 61f)
        {
            text.text = "";
            longDistanceDescriptionTextImage.SetActive(false);

            if (timeElapsedOpposite < lerpDurationOpposite)
            {
                valueToLerpOpposite = Mathf.Lerp(startValueForOpposite, endValueForOpposite, timeElapsedOpposite / lerpDurationOpposite);
                anim.SetFloat("Forward", valueToLerpOpposite);
                timeElapsedOpposite += Time.deltaTime;
            }
            anim.SetFloat("Forward", valueToLerpOpposite);

            timeElapsed = 0;
        }

        if (distance > 61f && Mathf.Abs(anim.GetFloat("Forward")) < 0.003943384f)
        {
            anim.SetBool("Idle", true);
        }
        else
        {
            anim.SetBool("Idle", false);
        }
    }
}
\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

There’s a million ways to do this, here’s a few easy ways off the top of my head:

  1. You could make a distance joint with unity’s configurable joint pretty easily using linear limits. Make sure to use the spring dampener as mentioned, it will make your character softly bump the edge of the boundary.
  2. Instead of constraints, you could simply attach 4 objects with no renderer, only a box collider. Make the boxes very tall and box your player in. Super simple. Disable the objects when the character has a vehicle.
  3. This one is a bit odd, but you could create an object with no renderer and make one big inverted box or sphere collider. It would (in theory) keep your character from passing outside.
\$\endgroup\$
2
  • \$\begingroup\$ On number 2 when you wrote attach 4 objects you meant to create 4 empty objects like in 4 corners with colliders creating a huge box as a blocker ? \$\endgroup\$
    – Daniel Lip
    Commented Jan 2, 2021 at 7:39
  • \$\begingroup\$ Yeah basically 4 invisible walls attached to your object that you can disable as needed \$\endgroup\$
    – Jon
    Commented Jan 2, 2021 at 7:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .