How to refine the enemy moving towards me?

I know the answer is really simple, but i just can’t seem to put a finger on it. Here is my code:

void Update () {
		
		float Speed = Random.Range(1.0F,10.0F);
		Vector3 direction_to_player = (Player.transform.position - transform.position);
		rigidbody.AddForce(direction_to_player);
		
		}

So this causes the enemy to move towards me, but the problem is the enemy doesn’t head straight at me. Even if the enemy is right in front of me, it moves in a circular orbit around the player, slowly getting closer and closer. And if u try to increase the speed, the orbit just becomes more elliptical. How can i make the enemy come straight at me, instead of circling me?

This sounds like the enemy is hitting a collider so it can't get to the location it wants; watch it in scene view and see if there's something like that? In your code above, you have "Player" in uppercase, is that right?

The thing is, it moves towards the player, but if it misses once, it can't compensate and it will overshoot, and then come back and overshoot again. How do i make it so that it doesn't overshoot?

Add some logic to stop adding force when the enemy nears the player; also check out MoveTowards

Do you want to do it in realistic physics? Or you just want to make a simple game?

I want to make it simple, and have some way for it to stop, and then head straight at the player, instead of the enemy remaining in motion and slowly turning around. The enemy should be like a bull, where it stops, and then turns around for another charge.

4 Answers

4

rigidbody.rotation = Quaternion.LookRotation(direction_to_player);

rigidbody.velocity = direction_to_player;

this works, but when an explosion occurs, the enemies aren't pushed back like they originally were. How can i make it so that they will get pushed back from the explosion force?

The code I posted I found in the AngryBots enemy AI movement motor. Download and have a look at the code.

It sounds like you not setting the angular velocity… Here’s a typical rigidbody movement motor… Assuming you have 2 vectors, point a the position of the game object, b the position of the target to move to…

First calculate the force -

Vector3 nextDirection = (b - a).normalized;                       
Vector3 targetVelocity = nextDirection * speed;
Vector3 deltaVelocity = targetVelocity - thisRigidbody.velocity;
                                 if (thisRigidbody.useGravity)
                                        deltaVelocity.y = 0;
                                
                                force = deltaVelocity * accelerationRate;

Then we can calculate the angular velocity

                // Make the character rotate towards the target rotation
                var turnDir = nextDirection;
                if (turnDir == Vector3.zero) 
                {
                        angularVelocity = Vector3.zero;
                }
                else 
                {
                        var rotationAngle = AngleAroundAxis (transform.forward, turnDir, Vector3.up);
                        angularVelocity = (Vector3.up * rotationAngle * turningSmoothing);
                }

Then you can set the rigidbody –

thisRigidbody.AddForce (force, ForceMode.Acceleration);
thisRigidbody.angularVelocity = angularVelocity;

Here is how to calculate the angle around an axis (make it turn around its head y axis)

public static float AngleAroundAxis (Vector3 dirA, Vector3 dirB, Vector3 axis) 
                {
                    // Project A and B onto the plane orthogonal target axis
                    dirA = dirA - Vector3.Project (dirA, axis);
                    dirB = dirB - Vector3.Project (dirB, axis);
                   
                    // Find (positive) angle between A and B
                    float angle = Vector3.Angle (dirA, dirB);
                   
                        // Return angle multiplied with 1 or -1
                    return angle * (Vector3.Dot (axis, Vector3.Cross (dirA, dirB)) < 0 ? -1 : 1);
                }

    
To make sure it doesn't overshoot make use of a in range calculation and the adjust the speed for the component above. You can do this with ( b - a).magnitude or Vector3.Distance. The trick is to calculate the gradual deceleration or you can just make it stop with a speed = 0. Let me know if you need more help.

It is giving me a bunch of errors, probably because it is in js. My code is in c#.

I just gave you snippets of code, you need to put this into a component,, I'm illustrating what you should do not giving you a complete solution. You need to declare "speed" as public fields for example...

That is C#........... Notice the lack of the word function

it also has the word var spread thorughout

Cool kids use var, it means you don't have to spell out your intent twice ;)

you may want to try


edit … avoid from falling through floor added …

    GameObject Player;
	public float speed;
	public float rotationSpeed=3f;
	public float howCloseToPlayer=3f;//Adjust here to stop enemy in a safe distance from Player to avoid moves in a circular orbit around the player
	
	//set the position Y to be stable
	public float minY = 0f, maxY = 0.01f;// keep position Y (avoid fall through)
	public Vector3 currentPosition ;
	
	void Start () {
		Player=GameObject.Find("Player");
		speed = Random.Range(3.0f,10.0f);
		rotationSpeed=3f;
	}
	
	void Update () {
	
		// get the position to a variable
		currentPosition = transform.position;
    	// modify the variable to keep y within minY to maxY
		currentPosition.y = Mathf.Clamp( currentPosition.y, minY, maxY);
   		// and now set the transform position to our modified vector
		transform.position = currentPosition;
	
		
		//rotate to look at the player
		transform.rotation = Quaternion.Slerp(transform.rotation,Quaternion.LookRotation(Player.transform.position - transform.position), rotationSpeed*Time.deltaTime);
		
		//move towards the player
	    transform.position += transform.forward * speed * Time.deltaTime;
		
		if (Vector3.Distance(Player.transform.position,transform.position)<=howCloseToPlayer){
			rotationSpeed=0;
			speed=0;
			//Do Damage or whatever you want in here
		}
	}

I will up vote this as soon as i can

@pulkit8.mahajan - if this is the answer you consider best/correct, click on the checkmark at the top left of this answer.

If your terrain has height variance, beware of using transform.position to move things in this manner, they will fall through

as @getyour411 said and propably is true , edit up the above script for position.y

use this: rigidbody.MovePosition(newPosition) if you arrange position though transform, the physics system doesn't know you moved the objects and won't help you to check the collision

Add to Update (JS)

// add outside functions
var Player : Transform;
var MoveSpeed = 4;
var MaxDist = 10;
var MinDist = 5;
// add to Update
transform.LookAt(Player);
    if(Vector3.Distance(transform.position,Player.position) >= MinDist){
    transform.position += transform.forward*MoveSpeed*Time.deltaTime;
    if(Vector3.Distance(transform.position,Player.position) <= MaxDist)
    {
    //Here Call any function U want Like Shoot at here or something
    
    }
    }