- Home /
Can someone help with the logic behind this?
Hi all,
I'm trying to move a character randomly around his starters position, however it doesnt seem to work and I don't understand why it doesnt. Because I believe, it should work?
I have this on him
float xPos = spawnLocation.x + Random.Range(spawnLocation.x - 10, spawnLocation.x + 10);
float zPos = spawnLocation.z + Random.Range(spawnLocation.z - 10, spawnLocation.z + 10);
targetLocation = new Vector3(xPos, gameObject.transform.position.y, zPos);
myAgent.SetDestination(targetLocation);
So in my head, if he spawns on 0,0,0 then his area of 'patrol' should be max 10,0,10 & -10,0,-10 right? But he goes waaay beyond that and always goes to the same direction once it walks. He goes from 0,0,0 to 33,0,54 for example, way behind his bounderies.
The rest of the code shouldnt be importent as this is all what it needs to move him.
Can someone explain the logic behind this? Am I not seeing something?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class EnemyBehaviour : MonoBehaviour
{
Animator myAnim;
CapsuleCollider myCollider;
public GameObject[] regularZombieLooks;
public GameObject[] bigZombieLooks;
public GameObject[] rangedZombieLooks;
public Transform target;
public PlayerShooting playerTarget;
private Transform myTransform;
private Vector3 targetLocation;
private Vector3 spawnLocation;
public NavMeshAgent myAgent;
public Transform mouthPoint;
public GameObject goo;
public bool regular, big, ranged, rangedAttacked = false, meleeAttacked = false, roleChanged = false;
public bool isChasing = true;
public float health = 100;
public int moveSpeed;
public int rotateSpeed;
public float RangedAttackDistance;
public float MeleeAttackDistance;
public float RangedAttackCooldownTimer;
public float MeleeAttackCooldownTimer;
public float PlayerAggroRange;
public float ShootingAggroRange;
private int zombieRole = 1;
private void Awake()
{
myTransform = transform;
spawnLocation = transform.position;
}
void Start()
{
SpawnLooksDependingOnRole();
CheckingRoleIfNotAttacking();
myAnim = GetComponentInChildren<Animator>();
myCollider = GetComponent<CapsuleCollider>();
myAgent = GetComponent<NavMeshAgent>();
GameObject go = GameObject.FindGameObjectWithTag("Player");
target = go.transform;
playerTarget = go.GetComponent<PlayerShooting>();
}
void Update()
{
AnimationBehaviour();
}
private void AnimationBehaviour()
{
Debug.Log(roleChanged);
// Death
if (health <= 0)
{
myAnim.SetTrigger("death");
myCollider.enabled = false;
myAgent.isStopped = true;
isChasing = false;
Destroy(this.gameObject, 1.5f);
return;
}
// Idle
if(!isChasing && zombieRole == 1)
{
if(roleChanged == true)
{
CheckingRoleIfNotAttacking();
roleChanged = false;
}
myAgent.isStopped = true;
myAnim.SetBool("chasing", false);
float distaggro = Vector3.Distance(transform.position, target.transform.position);
if (distaggro <= PlayerAggroRange)
{
// Player is close enough to be chased.
isChasing = true;
}
float distshooting = Vector3.Distance(transform.position, target.transform.position);
if (distshooting <= ShootingAggroRange && playerTarget.playerIsShooting == true)
{
// Player is shooting nearby and will be chased.
isChasing = true;
}
}
// Roaming
if(!isChasing && zombieRole == 2)
{
if(roleChanged == true)
{
CheckingRoleIfNotAttacking();
roleChanged = false;
float xPos = spawnLocation.x + Random.Range(spawnLocation.x - 10, spawnLocation.x + 10);
float zPos = spawnLocation.z + Random.Range(spawnLocation.z - 10, spawnLocation.z + 10);
targetLocation = new Vector3(xPos, gameObject.transform.position.y, zPos);
myAgent.SetDestination(targetLocation);
myAgent.isStopped = false;
myAgent.speed = 1f;
myAnim.SetBool("chasing", true);
}
float distaggro = Vector3.Distance(transform.position, target.transform.position);
if (distaggro <= PlayerAggroRange)
{
// Player is close enough to be chased.
isChasing = true;
}
float distshooting = Vector3.Distance(transform.position, target.transform.position);
if (distshooting <= ShootingAggroRange && playerTarget.playerIsShooting == true)
{
// Player is shooting nearby and will be chased.
isChasing = true;
}
}
// Following the player to attack
if (isChasing)
{
myAgent.destination = target.position;
myAnim.SetBool("chasing", true);
}
// Ranged Attack behaviour
if (ranged && isChasing)
{
myAgent.speed = 3f;
float dist = Vector3.Distance(transform.position, target.transform.position);
if (dist <= RangedAttackDistance)
{
myAgent.isStopped = true;
myAnim.SetBool("chasing", false);
AimingTowardsPlayer();
if (rangedAttacked == false)
{
myAnim.SetTrigger("attack");
rangedAttacked = true; GameObject fireGoo = Instantiate(goo, mouthPoint.position, mouthPoint.rotation);
fireGoo.GetComponent<Rigidbody>().velocity = mouthPoint.up * 10f;
Destroy(fireGoo, 3f);
StartCoroutine(RangedAttackCooldown());
}
return;
}
if(dist > RangedAttackDistance)
{
myAgent.isStopped = false;
myAgent.destination = target.position;
myAnim.SetBool("chasing", true);
}
}
// Regular Attack behaviour
if(regular && isChasing)
{
myAgent.speed = 3.5f;
float dist = Vector3.Distance(transform.position, target.transform.position);
if (dist <= MeleeAttackDistance)
{
myAgent.isStopped = true;
myAnim.SetBool("chasing", false);
AimingTowardsPlayer();
if (meleeAttacked == false)
{
myAnim.SetTrigger("attack");
meleeAttacked = true;
StartCoroutine(MeleeAttackCooldown());
}
return;
}
if (dist > MeleeAttackDistance)
{
myAgent.isStopped = false;
myAgent.destination = target.position;
myAnim.SetBool("chasing", true);
}
}
// Big Attack behaviour
if(big && isChasing)
{
myAgent.speed = 2f;
float dist = Vector3.Distance(transform.position, target.transform.position);
if (dist <= MeleeAttackDistance)
{
myAgent.isStopped = true;
myAnim.SetBool("chasing", false);
AimingTowardsPlayer();
if (meleeAttacked == false)
{
myAnim.SetTrigger("attack");
meleeAttacked = true;
StartCoroutine(MeleeAttackCooldown());
}
return;
}
if (dist > MeleeAttackDistance)
{
myAgent.isStopped = false;
myAgent.destination = target.position;
myAnim.SetBool("chasing", true);
}
}
}
private void AimingTowardsPlayer()
{
// Calculate the direction
var direction = target.position - transform.position;
// Ignore hight difference
direction.y = 0;
// Make the transform look in the direction
transform.forward = direction;
}
private void SpawnLooksDependingOnRole()
{
if (regular)
{
var regularlook = Random.Range(0, regularZombieLooks.Length);
regularZombieLooks[regularlook].SetActive(true);
}
if (big)
{
var biglook = Random.Range(0, bigZombieLooks.Length);
bigZombieLooks[biglook].SetActive(true);
}
if (ranged)
{
var rangedlook = Random.Range(0, rangedZombieLooks.Length);
rangedZombieLooks[rangedlook].SetActive(true);
}
}
private void CheckingRoleIfNotAttacking()
{
StartCoroutine(RoleChangeCooldown());
}
IEnumerator RangedAttackCooldown()
{
yield return new WaitForSeconds(RangedAttackCooldownTimer);
rangedAttacked = false;
}
IEnumerator MeleeAttackCooldown()
{
yield return new WaitForSeconds(MeleeAttackCooldownTimer);
meleeAttacked = false;
}
IEnumerator RoleChangeCooldown()
{
yield return new WaitForSeconds(10);
zombieRole = Random.Range(1, 3);
Debug.Log(zombieRole);
roleChanged = true;
}
private void OnTriggerEnter(Collider collision)
{
if (collision.gameObject.CompareTag("Bullet"))
{
health -= collision.gameObject.GetComponent<BulletDamage>().totalDamage;
Destroy(collision.gameObject);
}
}
}
I think you should add the rest of the code as something else might be changing the values earlier
Answer by rh_galaxy · Mar 16 at 06:49 PM
How often do you run this to set the destination? Because each time you run it it has the chance to move further away, you have no real boundaries. Also you add spawnLocation.x one time more than you want, it only works as you intend when spawnLocation.x == 0
If you want boundaries you can just do
float xPos = Random.Range(-10.0f, 10.0f);
Or if you want it to move more and more perhaps
float xPos = spawnLocation.x + Random.Range(-10.0f, 10.0f);
I agree with your answer. He was taking a Random.Range from spawnLocation.x -/+10 - + 10 instead of taking Random.Range from -10 - +10
Right. Though there's nothing wrong in using Random.Range(spawnLocation.x - 10, spawnLocation.x + 10)
however the result would be the worldspace xPosition. So adding that do the spawnLocation makes no sense. This was the actual issue. So you can do either
float xPos = Random.Range(spawnLocation.x - 10, spawnLocation.x + 10);
float zPos = Random.Range(spawnLocation.z - 10, spawnLocation.z + 10);
or
float xPos = spawnLocation.x + Random.Range( -10f, 10f);
float zPos = spawnLocation.z + Random.Range( -10f, 10f);
which both give the same result.
Thanks guys! That did indeed fix it! A good nights sleep also helps alot! Thanks again.
Your answer
![](https://koobas.hobune.stream/wayback/20220613054249im_/https://answers.unity.com/themes/thub/images/avi.jpg)