- Home /
How to move enemy with physics based movement?
Fairly new to Unity/C#. I'm doing an FPS. I've gotten all the animations down, but when it comes to actually having the enemy move, I'm having some issues. I'd like a physics based locomotion so the creature doesn't just clip through walls. I'm aware of Rigidbody,AddForce and CharacterController.Move but I have no idea how to "phrase" them given my current setup or what values to put where.
I've tried the AddForce page, but again, I'm unsure how to phrase it in a way, so that when the Walking animation starts, and the enemy has spotted the player, that it moves toward them.
public class WastrelChase : MonoBehaviour {
public Transform player;
static Animator anim;
// Use this for initialization
void Start ()
{
anim = GetComponent<Animator>();
}
// Update is called once per frame
void Update () {
if (Vector3.Distance(player.position, this.transform.position) < 5)
{
Vector3 direction = player.position - this.transform.position;
direction.y = 0;
this.transform.rotation = Quaternion.Slerp(this.transform.rotation,
Quaternion.LookRotation(direction), 0.1f);
anim.SetBool("IsIdle", false);
if (direction.magnitude > .8)
{
anim.SetBool("IsWalking", true);
anim.SetBool("IsStriking", false);
}
else
{
anim.SetBool("IsStriking", true);
anim.SetBool("IsWalking", false);
}
}
else
{
anim.SetBool("IsIdle", true);
anim.SetBool("IsWalking", false);
anim.SetBool("IsStriking", false);
}
}
}
Answer by bobisgod234 · Jun 19, 2017 at 03:22 AM
Is there a reason your anim variable is static? This means that all instances of "WastrelChase" will share the same Animator component, which surely won't end well. I would recommend removing the static. keyword and replacing it with private, so it becomes
private Animator anim;
Back to the question, you need a reference to your Rigidbody. You can add it to the top of the script and assign it just like your anim component:
private Rigidbody myRigidbody;
// Use this for initialization
void Start ()
{
myRigidbody = GetComponent<Rigidbody >();
}
Next, make sure your object has some collider attached to it.
Depending on your enemy type, it may be a good idea to lock the X and Z rotation of the Rigidbody component, to prevent it from rolling around.
Next is to apply the force to the rigidbody. AddForce should be used in the FixedUpdate function, so what we will do is create a new Vector3 variable in our MonoBehaviour called "moveDirection", which we will use in the Fixed update function.
The top of your class should now look something like:
public Transform player;
private Animator anim;
private Rigidbody myRigidbody;
private Vector3 moveDirection;
Set it to be zero at the very start of your Update function:
void Update () {
moveDirection = Vector3.zero;
if (Vector3.Distance(player.position, this.transform.position) < 5)
{
And assign it the direction you wish your object to move in, where you set IsWalking to true:
if (direction.magnitude > .8)
{
moveDirection = direction.normalized;
anim.SetBool("IsWalking", true);
anim.SetBool("IsStriking", false);
}
Then, add your FixedUpdate function:
void FixedUpdate()
{
myRigidbody.AddForce(myDirection * 50f);
}
the 50f is the movement force. You will need to adjust it to get movement working right. If it doesn't appear to be moving, try increasing this to very large numbers (e.g. 50000f) to see if its just due to the force being to low.
The finished script will look something like:
public class WastrelChase : MonoBehaviour {
public Transform player;
private Animator anim;
private Rigidbody myRigidbody;
private Vector3 moveDirection;
// Use this for initialization
void Start ()
{
anim = GetComponent<Animator>();
myRigidbody = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update () {
moveDirection = Vector3.zero;
if (Vector3.Distance(player.position, this.transform.position) < 5)
{
Vector3 direction = player.position - this.transform.position;
direction.y = 0;
this.transform.rotation = Quaternion.Slerp(this.transform.rotation,
Quaternion.LookRotation(direction), 0.1f);
anim.SetBool("IsIdle", false);
if (direction.magnitude > .8)
{
moveDirection = direction.normalized;
anim.SetBool("IsWalking", true);
anim.SetBool("IsStriking", false);
}
else
{
anim.SetBool("IsStriking", true);
anim.SetBool("IsWalking", false);
}
}
else
{
anim.SetBool("IsIdle", true);
anim.SetBool("IsWalking", false);
anim.SetBool("IsStriking", false);
}
}
void FixedUpdate()
{
myRigidbody.AddForce(moveDirection * 50f);
}
}
thanks for your help, but the enemy is still shuffling in place, even with the force at 500000, is there something i should set my rigidbody / collider as in Unity? it doesn't appear to be affected by gravity either.
never$$anonymous$$d actually! turns out i just had to turn off kinematic for rigidbody in unity! well, looks like i can't use a mesh collider but oh well, not too big of a deal, thanks for your help!
Your answer
Follow this Question
Related Questions
Enemy Rigidbody Not Responding to Gravity 1 Answer
Why do the AI get caught on trees? 0 Answers
Simple AI Error 8025 Parrsing error. 2 Answers
AI passes through walls and flies 2 Answers
My Eneny AI Script Wont Work? 2 Answers