0
\$\begingroup\$

I'm making a game where you have a friend follow you. I have a script that partly works, but when the friend exits the trigger, it won't follow the player.

How do I get the friend to follow the player once indefinitely, or until it hits the trigger again?

Here is the script:

public Transform friend;
private int movespeed;

public int speed;
public Rigidbody rb;

// Use this for initialization
void Start()
{
    speedup();
}

// Update is called once per frame
void Update()
{

    transform.LookAt(freind);
    Vector3 eulerAngles = transform.rotation.eulerAngles;
    eulerAngles.x = 0;
    eulerAngles.z = 0;
    transform.rotation = Quaternion.Euler(eulerAngles);

    rb.AddRelativeForce(0, 0, movespeed);

}

public void OnTriggerStay(Collider other)
{

    if (other.tag == "Player")
    {
        movespeed = 0;
    }
    else
    {
        speedup();
    }
}

public void speedup()
{
    movespeed = speed;
}
\$\endgroup\$
1
  • \$\begingroup\$ make sure your player is marked with the tag Player in the inspector, also keep the on trigger stay function \$\endgroup\$
    – Indiepixel
    Commented Feb 8, 2019 at 2:07

2 Answers 2

3
\$\begingroup\$

This code says:

"As long as I'm still in trigger contact with something...

...if that thing is tagged 'Player', set move speed to zero

...otherwise (ie. if that thing is tagged anything else), set move speed to speed"

It looks like you mean that last clause to say "if I'm no longer in trigger contact..." but if we weren't in trigger contact anymore, OnTriggerStay wouldn't even be called.

It looks like what you want is something more like:

bool isNearPlayer;

void OnTriggerEnter(Collider other) {
    if(other.gameObject.CompareTag("Player"))
        isNearPlayer = true;
}

void OnTriggerExit(Collider other) {
    if(other.gameObject.CompareTag("Player"))
         isNearPlayer = false;
}

This toggles a mode flag on & off when we enter & exit trigger range around the player. (Also note that using CompareTag is more efficient than comparing strings with ==)

Then you can use that mode flag in your FixedUpdate method:

if(isNearPlayer == false)
    rb.AddRelativeForce...

(Even better, since you already have a reference to the player object, you can check its range directly, without waiting to detect trigger contact: isNearPlayer = (transform.position - friend.Position).sqrMagnitude < stopRange * stopRange); )

\$\endgroup\$
5
  • \$\begingroup\$ +1 The distance check at the end could be simplified with isNearPlayer = (Vector3.Distance(transform.position, friend.position) < stopRange) \$\endgroup\$
    – BrianH
    Commented Feb 8, 2019 at 14:59
  • \$\begingroup\$ @BrianH that is indeed shorter, though it does entail an unnecessary square root. ;) \$\endgroup\$
    – DMGregory
    Commented Feb 8, 2019 at 15:00
  • \$\begingroup\$ Really? Neet trick - TIL! \$\endgroup\$
    – BrianH
    Commented Feb 8, 2019 at 15:02
  • 1
    \$\begingroup\$ @BrianH Vector3.Distance(transform.position, friend.position) < stopRange == (transform.position - friend.position).magnitude < stopRange. You can see native code for Vector3.Distance here: github.com/Unity-Technologies/UnityCsReference/blob/master/… \$\endgroup\$ Commented Feb 8, 2019 at 19:49
  • \$\begingroup\$ @CandidMoon Great resource, hadn't realized they provided the source for the native implementations as well - thanks! \$\endgroup\$
    – BrianH
    Commented Feb 8, 2019 at 19:51
0
\$\begingroup\$

I've found the answer! I just had to add an on Trigger exit statement with the speed up function inside:

public Transform freind;
private int movespeed;

public int speed;
public Rigidbody rb;
// Use this for initialization
void Start()
{
    speedup();
}

// Update is called once per frame
void Update()
{

    transform.LookAt(freind);
    Vector3 eulerAngles = transform.rotation.eulerAngles;
    eulerAngles.x = 0;
    eulerAngles.z = 0;
    transform.rotation = Quaternion.Euler(eulerAngles);

    rb.AddRelativeForce(0, 0, movespeed);

}

public void OnTriggerStay(Collider other)
{


    if (other.tag == "Player")
    {
        movespeed = 0;
    }

}
public void OnTriggerExit(Collider other)
{
    speedup();
}

public void speedup()
{
    movespeed = speed;
}
\$\endgroup\$

You must log in to answer this question.

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