Inimigo andando de forma aleatória (SEM SER TELEPORTANDO) com sensor de collider por tag
2 participantes
Página 1 de 1
Inimigo andando de forma aleatória (SEM SER TELEPORTANDO) com sensor de collider por tag
Tem como fazer isso galera ? Estou perdido tentando fazer essa parada a um tempo e não consigo
gersoneson- Membro
- PONTOS : 1920
REPUTAÇÃO : 6
Respeito as regras :
Re: Inimigo andando de forma aleatória (SEM SER TELEPORTANDO) com sensor de collider por tag
Gera um Vector3 com valores aleatórios em X e Z respeitando os limites do seu mapa, coloca o valor de Y algo como 50;
Dispara um raycast com uns 100 metros pra baixo, partindo dessa posição;
Pega o hit.point, essa posição é o ponto onde o raio colidiu com o terreno ou cenário, e será o destino do Inimigo;
Passa a posição do hit.point como o destino do NavMeshAgent do inimigo;
Seu inimigo agora já deve andar para a posição aleatória, se a distancia entre o transform.position do inimigo e o hit.point for menor que um valor que você escolher, você reinicia o processo, escolhendo uma nova posição.
Dispara um raycast com uns 100 metros pra baixo, partindo dessa posição;
Pega o hit.point, essa posição é o ponto onde o raio colidiu com o terreno ou cenário, e será o destino do Inimigo;
Passa a posição do hit.point como o destino do NavMeshAgent do inimigo;
Seu inimigo agora já deve andar para a posição aleatória, se a distancia entre o transform.position do inimigo e o hit.point for menor que um valor que você escolher, você reinicia o processo, escolhendo uma nova posição.
Fagner- Moderador
- PONTOS : 4443
REPUTAÇÃO : 667
Áreas de atuação : Modelagem 3D, Programação.
Respeito as regras :
Re: Inimigo andando de forma aleatória (SEM SER TELEPORTANDO) com sensor de collider por tag
Obrigado!
gersoneson- Membro
- PONTOS : 1920
REPUTAÇÃO : 6
Respeito as regras :
Re: Inimigo andando de forma aleatória (SEM SER TELEPORTANDO) com sensor de collider por tag
No exemplo que dei, esqueci de uma coisa importante. É preciso checar se o local do Raycast é válido antes de mover o inimigo. Fiz um exemplo que leva isso em conta, você pode baixá-lo AQUI
Ele possui Gizmos pra exibir os limites de onde o Raycast será disparado, e se o destino não for válido ele continua a gerar posições até encontrar uma que o inimigo possa utilizar.
O código ficou assim:
// Edição:
Caso não queira que o inimigo ande de costas se o destino for atrás dele, jogue esse trecho na Update():
Ele possui Gizmos pra exibir os limites de onde o Raycast será disparado, e se o destino não for válido ele continua a gerar posições até encontrar uma que o inimigo possa utilizar.
O código ficou assim:
- Código:
using UnityEngine;
using UnityEngine.AI;
public class SistemaRonda : MonoBehaviour
{
public float larguraZona, comprimentoZona;
private Vector3 limite1, limite2, limite3, limite4;
private bool destinoAlcancado = true;
private Vector3 posicaoDestino;
public NavMeshAgent inimigo;
private void Start()
{
DefinirLimites();
}
private void Update()
{
if(Vector3.Distance(inimigo.transform.position, posicaoDestino) < 1)
{
destinoAlcancado = true;
}
if (destinoAlcancado)
{
EscolherNovoDestino();
destinoAlcancado = false;
inimigo.SetDestination(posicaoDestino);
}
}
private void EscolherNovoDestino()
{
Vector3 posicaoRaycast = new Vector3(Random.Range(-larguraZona/2, larguraZona/2), transform.position.y, Random.Range(-comprimentoZona / 2, comprimentoZona / 2));
Ray ray = new Ray(posicaoRaycast, -Vector3.up);
RaycastHit hit;
if(Physics.Raycast(ray, out hit, 100))
{
if (hit.collider.tag == "Terreno")
posicaoDestino = hit.point;
else
EscolherNovoDestino();
}
else
EscolherNovoDestino();
}
private void DefinirLimites()
{
limite1 = transform.position + transform.forward * comprimentoZona / 2;
limite2 = transform.position + transform.forward * comprimentoZona / 2;
limite3 = transform.position - transform.forward * comprimentoZona / 2;
limite4 = transform.position - transform.forward * comprimentoZona / 2;
limite1 += transform.right * larguraZona / 2;
limite2 -= transform.right * larguraZona / 2;
limite3 += transform.right * larguraZona / 2;
limite4 -= transform.right * larguraZona / 2;
}
private void OnDrawGizmos()
{
DefinirLimites();
Gizmos.color = Color.green;
Gizmos.DrawSphere(limite1, 0.1f);
Gizmos.DrawSphere(limite2, 0.1f);
Gizmos.DrawSphere(limite3, 0.1f);
Gizmos.DrawSphere(limite4, 0.1f);
Gizmos.color = Color.white;
Gizmos.DrawLine(limite1, limite2);
Gizmos.DrawLine(limite2, limite4);
Gizmos.DrawLine(limite3, limite4);
Gizmos.DrawLine(limite3, limite1);
}
}
// Edição:
Caso não queira que o inimigo ande de costas se o destino for atrás dele, jogue esse trecho na Update():
- Código:
if (inimigo.hasPath)
{
Vector3 dir = (inimigo.path.corners[1] - inimigo.transform.position).normalized;
float dotInimigoP1 = Vector3.Dot(inimigo.transform.forward, dir);
if (dotInimigoP1 < 0.5f)
{
inimigo.velocity = Vector3.zero;
}
else
{
inimigo.velocity = inimigo.desiredVelocity;
}
}
Fagner- Moderador
- PONTOS : 4443
REPUTAÇÃO : 667
Áreas de atuação : Modelagem 3D, Programação.
Respeito as regras :
Re: Inimigo andando de forma aleatória (SEM SER TELEPORTANDO) com sensor de collider por tag
Valeu!Fagner escreveu:No exemplo que dei, esqueci de uma coisa importante. É preciso checar se o local do Raycast é válido antes de mover o inimigo. Fiz um exemplo que leva isso em conta, você pode baixá-lo AQUI
Ele possui Gizmos pra exibir os limites de onde o Raycast será disparado, e se o destino não for válido ele continua a gerar posições até encontrar uma que o inimigo possa utilizar.
O código ficou assim:
- Código:
using UnityEngine;
using UnityEngine.AI;
public class SistemaRonda : MonoBehaviour
{
public float larguraZona, comprimentoZona;
private Vector3 limite1, limite2, limite3, limite4;
private bool destinoAlcancado = true;
private Vector3 posicaoDestino;
public NavMeshAgent inimigo;
private void Start()
{
DefinirLimites();
}
private void Update()
{
if(Vector3.Distance(inimigo.transform.position, posicaoDestino) < 1)
{
destinoAlcancado = true;
}
if (destinoAlcancado)
{
EscolherNovoDestino();
destinoAlcancado = false;
inimigo.SetDestination(posicaoDestino);
}
}
private void EscolherNovoDestino()
{
Vector3 posicaoRaycast = new Vector3(Random.Range(-larguraZona/2, larguraZona/2), transform.position.y, Random.Range(-comprimentoZona / 2, comprimentoZona / 2));
Ray ray = new Ray(posicaoRaycast, -Vector3.up);
RaycastHit hit;
if(Physics.Raycast(ray, out hit, 100))
{
if (hit.collider.tag == "Terreno")
posicaoDestino = hit.point;
else
EscolherNovoDestino();
}
else
EscolherNovoDestino();
}
private void DefinirLimites()
{
limite1 = transform.position + transform.forward * comprimentoZona / 2;
limite2 = transform.position + transform.forward * comprimentoZona / 2;
limite3 = transform.position - transform.forward * comprimentoZona / 2;
limite4 = transform.position - transform.forward * comprimentoZona / 2;
limite1 += transform.right * larguraZona / 2;
limite2 -= transform.right * larguraZona / 2;
limite3 += transform.right * larguraZona / 2;
limite4 -= transform.right * larguraZona / 2;
}
private void OnDrawGizmos()
{
DefinirLimites();
Gizmos.color = Color.green;
Gizmos.DrawSphere(limite1, 0.1f);
Gizmos.DrawSphere(limite2, 0.1f);
Gizmos.DrawSphere(limite3, 0.1f);
Gizmos.DrawSphere(limite4, 0.1f);
Gizmos.color = Color.white;
Gizmos.DrawLine(limite1, limite2);
Gizmos.DrawLine(limite2, limite4);
Gizmos.DrawLine(limite3, limite4);
Gizmos.DrawLine(limite3, limite1);
}
}
// Edição:
Caso não queira que o inimigo ande de costas se o destino for atrás dele, jogue esse trecho na Update():
- Código:
if (inimigo.hasPath)
{
Vector3 dir = (inimigo.path.corners[1] - inimigo.transform.position).normalized;
float dotInimigoP1 = Vector3.Dot(inimigo.transform.forward, dir);
if (dotInimigoP1 < 0.5f)
{
inimigo.velocity = Vector3.zero;
}
else
{
inimigo.velocity = inimigo.desiredVelocity;
}
}
gersoneson- Membro
- PONTOS : 1920
REPUTAÇÃO : 6
Respeito as regras :
Tópicos semelhantes
» (Dúvida) Como acessar o sensor de movimento do Android?
» Como fazer o clique não acertar o inimigo atrás de um objeto (hit collider)
» Script de health de inimigo sendo acessado mesmo sem acerta o inimigo
» [RESOLVIDO] Rigidbody2D.AddForce esta teleportando o objeto
» RigidBody com Box Collider Travando na Aresta de um Box Collider.
» Como fazer o clique não acertar o inimigo atrás de um objeto (hit collider)
» Script de health de inimigo sendo acessado mesmo sem acerta o inimigo
» [RESOLVIDO] Rigidbody2D.AddForce esta teleportando o objeto
» RigidBody com Box Collider Travando na Aresta de um Box Collider.
Página 1 de 1
Permissões neste sub-fórum
Não podes responder a tópicos