Gameobject to "run" away from another on collide trigger

So… I have a gameobject with a collider trigger setup. I want it to detect while another specific gameobject (tag “player”) is within the collider, to turn and run away.

I have the movement working, however the rotation is not working. It appears to “flicker”, I believe because it is continuously recalculating the angle of transform.forward back and forth.

Note, that I want the gameobject to continue running away, until the player is out of the sphere collider (like it is “escapaing”).

Here is my code currently:

    void OnTriggerStay(Collider CollisionObject)
    {

        if (CollisionObject.tag == "Player")
        {

        // Rotate gameobject to face "away" from the player who entered the collider
            Vector3 targetDirection = CollisionObject.transform.position - transform.position;
            Vector3 newDirection = Vector3.RotateTowards(transform.forward, targetDirection, -180, 10);
            Debug.DrawRay(transform.position, newDirection, Color.red);
            transform.rotation = Quaternion.LookRotation(newDirection);

        // (This section works as expected) script to move gameobject away from player.
            transform.position = Vector3.MoveTowards(transform.position, CollisionObject.transform.position, -1 * walkSpeed * Time.deltaTime);
        }
    }

Appreciate any advice on what I am doing wrong…

Which object is the player and which is the running object?

One thing I see that is weird is your 3rd argument to Vector3.RotateTowards: -180

Vector3.RotateTowards takes an angle in radians. 180 radians is almost 29 full rotations! You probably want to use -Mathf.PI as your argument, which is equal to 180 degrees of rotation. Why did Unity use radians for Vector3.RotateTowards? Beats me!

Sorry, the collision object with tag player, is player. The script is attached to the running object.

Thanks for the comment regarding radians, I will have a play with that also.

A question regarding RotateTowards though, how can I tell it to rotatetowards away from the player? I guess I need to calculate the direction between the two objects to determine the angle?

SO if CollisionObject is the player and transform is the “runner”, then accoding to this:Vector3 targetDirection = CollisionObject.transform.position - transform.position; “targetDirection” will be a Vector pointing from the runner towards the player.

But then you’re using a negative value in RotateTowards so this should cancel out to rotating away from the player. However it would be simpler if you got rid of the double negative:

    void OnTriggerStay(Collider CollisionObject)
    {
        if (CollisionObject.tag == "Player")
        {
            // Rotate gameobject to face "away" from the player who entered the collider
            Vector3 targetDirection = transform.position - CollisionObject.transform.position;
            Vector3 newDirection = Vector3.RotateTowards(transform.forward, targetDirection, Mathf.PI, 10);
            Debug.DrawRay(transform.position, newDirection, Color.red);
            transform.rotation = Quaternion.LookRotation(newDirection);
            // (This section works as expected) script to move gameobject away from player.
            transform.position = Vector3.MoveTowards(transform.position, CollisionObject.transform.position, -1 * walkSpeed * Time.deltaTime);
        }
    }

I’m not sure that will fix your problem though… The cheaty way would be this:

    void OnTriggerStay(Collider CollisionObject)
    {
        if (CollisionObject.tag == "Player")
        {
            // Rotate gameobject to face "away" from the player who entered the collider
            Vector3 targetDirection = transform.position - CollisionObject.transform.position;
            Debug.DrawRay(transform.position, targetDirection, Color.red);
            transform.rotation = Quaternion.LookRotation(targetDirection);
            // (This section works as expected) script to move gameobject away from player.
            transform.position = Vector3.MoveTowards(transform.position, CollisionObject.transform.position, -1 * walkSpeed * Time.deltaTime);
        }
    }