- Home /
How to make my enemy discover, chase and lose player.
I have been try to find and try the code from google and unity3d.com, but still cannot work, maybe i dun understand.
The code i using now is
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GuardMovement : MonoBehaviour
{
//public float speed;
Rigidbody2D rb;
private Animator animator;
protected Vector3 velocity;
public Transform _transform;
public float distance = 5f;
public float speed = 1f;
Vector3 _originalPosition;
bool isGoingLeft = false;
public float distFromStart;
/*private float movespd = 1.0f;
//private int dir = -1;
public const float TurnLimit = 3.5f, CheckLimit = 2.0f;
public bool detect_player = false;
public bool after_chase = false;
public bool checkplayerloc = false;
public bool dirCheck = false;
public bool chgdir = false;
public enum State{Patrol, ChasePlayer, ReturnToOriloc};
public State behaviourState;
private Rigidbody2D enemy_rb2d;
private Vector3 oriloc;
private Vector2 newposition;
//private float checktime = CheckLimit;
//turntime = TurnLimit,*/
private Transform player;
void Start ()
{
rb = GetComponent <Rigidbody2D> ();
animator = this.GetComponent<Animator> ();
_originalPosition = gameObject.transform.position;
_transform = GetComponent<Transform>();
velocity = new Vector3(speed,0,0);
_transform.Translate ( velocity.x*Time.deltaTime,0,0);
player = GameObject.FindGameObjectWithTag ("Player").transform;
//oriloc = transform.position;
//behaviourState = State.Patrol;
//enemy_rb2d = gameObject.GetComponent<Rigidbody2D> ();
}
void Update ()
{
distFromStart = transform.position.x - _originalPosition.x;
if (isGoingLeft)
{
// If gone too far, switch direction
if (distFromStart < -distance)
SwitchDirection ();
_transform.Translate (-velocity.x * Time.deltaTime, 0, 0);
if (distFromStart < 3)
{
animator.SetInteger ("Direction", 3);
}
}
else
{
// If gone too far, switch direction
if (distFromStart > distance)
SwitchDirection ();
_transform.Translate (velocity.x * Time.deltaTime, 0, 0);
if (distFromStart > -3)
{
animator.SetInteger ("Direction", 1);
}
}
}
void SwitchDirection()
{
isGoingLeft = !isGoingLeft;
//TODO: Change facing direction, animation, etc
}
}
How do i put the code inside my code that the enemy have chase my character in a certain distance, after that distance enemy will go back to it own certain area continuous walk around in that area.
$$anonymous$$ake a timer that increase while tthe enemy is chasing. If a certain time is reached, cancel the chasing behavior and switch to idling, and set the timer to 0.
Answer by BlackHack_ · Aug 29, 2017 at 03:19 PM
Sorry my answer wasn't detailed enough because I didn't understand your question clearly. I have rewritten your code with performance and readability in mind, and tried to explain everything using comments. Btw <= means less than or equal.
using UnityEngine;
public class GuardMovement : MonoBehaviour
{
public float playerDetectionRange = 50;
public float playerDeathZone = 1f;
public float patrolDistance = 5f;
public float speed = 1f;
// Using a multiplyer to avoid having another var
// for walking speed and anothor one for current speed.
public float runningSpeedMultiplyer = 1.5f;
Animator animator;
// Patroling
Vector3[] patrolPositions;
int patrolPositionsIndex;
Vector3 startPosition;
Vector3 targetPosition;
Transform player;
bool isTargetingPlayer = false;
void Start()
{
animator = GetComponent<Animator>();
startPosition = transform.position;
patrolPositions = new Vector3[] {
new Vector3(startPosition.x + patrolDistance, startPosition.y, startPosition.z),
new Vector3(startPosition.x - patrolDistance, startPosition.y, startPosition.z)
};
// To save preformance if your game has only 1 player,
// then change it in the declearation to be:
// static Transform player;
// and add that here:
// if (player == null)
player = GameObject.FindGameObjectWithTag("Player").transform;
}
void Update()
{
if (IsPlayerInDetectionRange())
{
// The player is moving so we need to update the every frame.
SetTargetPosition(player.position);
// Will only not target the player while in range
// once he enters the detection range.
if (!isTargetingPlayer)
{
isTargetingPlayer = true;
OnPlayerEnter();
}
if (IsPlayerInAttackRange())
{
// Do whatever you want in here to
// indicate that the player is dead.
// player.Kill();
}
}
// If not in range.
else
{
// will only taget the player while not in range
// once he leaves the detection range.
if (isTargetingPlayer)
{
isTargetingPlayer = false;
OnPlayerLeave();
}
// Patrol only while no player in range.
Patrol();
}
MoveToTargetPosition();
}
bool IsPlayerInDetectionRange()
{
if (Vector2.Distance(transform.position, player.position) < playerDetectionRange)
{
return true;
}
else
{
return false;
}
}
bool IsPlayerInAttackRange()
{
if (Vector2.Distance(transform.position, player.position) < playerDeathZone)
{
return true;
}
else
{
return false;
}
}
void OnPlayerEnter()
{
speed *= runningSpeedMultiplyer; // same as (speed = speed * runningSpeedMultiplyer)
}
void OnPlayerLeave()
{
speed /= runningSpeedMultiplyer; // same as (speed = speed / runningSpeedMultiplyer)
}
void Patrol()
{
// Putting it in a var just to make it easier to read.
Vector3 currentPatrolPosition = patrolPositions[patrolPositionsIndex];
// If we are not patroling (if after chasing a player)
if (targetPosition != currentPatrolPosition)
{
SetTargetPosition(currentPatrolPosition);
}
// If we have reached our target patrol, then switch to the next one.
if (transform.position == currentPatrolPosition)
{
patrolPositionsIndex++; // same as (patrolPositionsIndex = patrolPositionsIndex + 1)
// We currently have 2 patrol position stored in an array,
// if the index is bigger than or equal to the length of the array (2),
// then we will start from the beggining (index 0).
if (patrolPositionsIndex >= patrolPositions.Length)
patrolPositionsIndex = 0;
SetTargetPosition(patrolPositions[patrolPositionsIndex]);
}
}
void SetTargetPosition(Vector3 newTargetPosition)
{
targetPosition = newTargetPosition;
// if is going left
if (transform.position.x < targetPosition.x)
{
animator.SetInteger("Direction", 3);
}
// if is going right
else
{
animator.SetInteger("Direction", 1);
}
}
void MoveToTargetPosition()
{
transform.position = Vector3.MoveTowards(transform.position, targetPosition, speed * Time.deltaTime);
}
}
I have been try the code u gv me, it work very good, but my enemy dint go for patrol. i have put 3 enemy in my game, but only one of it going for patrol and other 2 just only going right, sometime will turn left than not turning right and sometime after right turn left then turn right, it will continuous in right in his patrol area.
Can i know what is the problem?
I don't understand your problem clearly, please provide me with a video (or a link to a YouTube video) so I can understand the problem better.
left btm and left top only going right only sometimr going left than wait 10 second+ then going right, after that it keep going right
Answer by donkey0t · Aug 29, 2017 at 05:03 PM
I'm a total newbie so forgive me if I'm talking nonsense, but I'd be looking at using the navigation mesh/path calculations and feed it the point of the players position. Then after a certain time I'd change the target of the path to a fixed point rather than the player?
Use my example code but change targetPosition to agent.destination