- Home /
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 $$anonymous$$oveTowards
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, ins$$anonymous$$d 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.
Answer by SunnyChow · Jan 13, 2014 at 06:02 AM
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.
Answer by morbidcamel · Jan 13, 2014 at 05:25 AM
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. $$anonymous$$y 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
Cool kids use var, it means you don't have to spell out your intent twice ;)
Answer by sath · Jan 13, 2014 at 06:30 AM
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
}
}
@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.$$anonymous$$ovePosition(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
Answer by Nirav-Madhani · Nov 30, 2014 at 09:28 AM
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
}
}