Jump to content

Recommended Posts

Hoooooooooola a todos

Vengo con algo entre manos y con muchísima ilusión... espero que no me acabe pasando como siempre y el interés decaiga, jejeje. Bueno, el caso es que estoy haciendo un juego, y necesito hacer enemigos, animales y npc's Y no se ni como empezar.... necesito que el movimiento de estos sea el siguiente 

IEnumerator Movimiento()
{
  while (true)
  {
    transform.position += new Vector3(1,0,0); 
    yield return new WaitForSeconds(0.30f);
  }
}

 

y no se como aplicar esto a una IA... no se como hacer que se muevan así. Y ese es mi principal problema ahora.... no se como hacer que te sigan ni que huyan cuando te acercas. A medida que avance con la IA, y mis dudas se ensanchen, publicare mas en este post .

 

Gracias de antemano

Share this post


Link to post
Share on other sites

Supongo por el Vector que utilizas en tu pseudocódigo que te refieres a 3D.

En ese caso, utiliza un sistema de pathfinding. Para ello Unity tiene su sistema llamado Navmesh, con el cual tus entidades pueden moverse sin colisionar con los objetos del mapa.

Aquí un vídeo del brackeys

 

Edited by leocub58
  • Like 1

Share this post


Link to post
Share on other sites

MADRE MIA, que bien que funciona! Muchas gracias a los dos (zelleGames y leocub58) pero ahora me surgen dos dudas....

Es posible substituir el cilindro por un cuadrado?

Como puedo aplicar a este, la clase de movimiento que busco? (que avanza de 1 en uno, mas que moverse parece que se tele transporte un metro mas hacia adelante... para que nos entendamos)

Share this post


Link to post
Share on other sites

Además, mi consejo es que mires como realizar el movimiento de cuerpos con RigidBody en los que no se emplea el componente transform.

Si quieres mover por transform (como tienes en el ejemplo)  lo normal es que utilices el transform.forward de los GameObjects para que se muevan hacia adelante, multiplicando por la velocidad y TIme.deltaTime de la forma:
 

transform.position += transform.forward* velocidad * Time.deltaTime;

o bien con transform.Translate. Tienes en este enlace para qué es necesario Time.deltaTIme.

Si quieres dirigirlos hacia un destino, necesitas lo que yo llamo 'vector dirección', y creo que se llama así. Puedes comprobar como funciona en este enlace.

El componente NavMesh de Unity está genial para darle 'inteligencia' a los enemigos ya que puedes hacer que se dirijan hacia un punto (normalmente contra el jugador) esquivando los obstáculos que haya por el medio.

  • Like 1

Share this post


Link to post
Share on other sites

  Pistaxo21

He estado mirando, y ay opciones muy, pero que muy interesantes... pero no veo ninguna que me pueda ayudar a lograr lo que busco (el movimiento en cuadricula)....

Y AngelFG, cierto, tendría que cambiarlo y usar transform.forward, de echo, así lo aplique cuando intente hacer por mi cuenta los NPC, de momento no es necesario para el jugador. En todo caso, gracias por el consejo

Share this post


Link to post
Share on other sites

Lo que sucede es que para movimiento en cuadrícula deberias de resolver la ruta mediante algún algoritmo y omitir las diagonales, te recomiendo BFS.

Una vez tengas la ruta creada por bloques sera mas facil implementar la mecánica que estas buscando.

Share this post


Link to post
Share on other sites

Jejejeje, encontré una solución bastante "cutre";  he pasado la posición de el objeto con la IA a enteros, y ala, ya esta el movimiento en cuadricula...

 

Ahora estoy tratando de hacer la visión de la ia, 

 

 

Sin título.png

El rojo es el campo de visión y en negro el jugador

Para lograr esto supongo que necesito usar raycast... pero ya no se mas

 

Una vez tenga la visión el script seria algo así como 

if ("player dentro de el campo de vision"){"move to player" }

 

Share this post


Link to post
Share on other sites

Para ello debes saber si el target está dentro del rango de ángulos. Yo me desarrollé un sensor de visión. La clave es:

public float angleCone(Transform child, Transform target) {
  Vector3 heading = (target.transform.position - child.transform.position).normalized;
  // 1 = inFront, -1 = Behind, 0 = sideByside
  float dot = Vector3.Dot(heading, child.transform.forward);
  float angleCone = Mathf.Acos(dot) * Mathf.Rad2Deg;

  return (angleCone);
}

Esto te retorna el ángulo de visión. Si luego verificas que este ángulo esté dentro del cono de visión, ya está.

  • Like 1

Share this post


Link to post
Share on other sites

Ahora doy paso a el siguiente nivel de desarrollo: IA enemigas y sistema de combate

 

Para ello e desarrollado un pequeño script, que básicamente lo que hace es que, si el jugador esta a 1 de distancia, pues atacar

El problema es que ataca en direccion forward... no se si me explico, y necesito hacer que los enemigos miren hacia el jugador, de modo que cuando ataquen, ataquen en su dirección.

Dicho esto, necesito hacer que apunten hacia el player, pero siguiendo la misma logica de la cuadricula, de forma que su rotación sera siempre: 0, 90, 180,  270 o 360 grados....

No se si me explico...

Y alguien tiene alguna idea?

Share this post


Link to post
Share on other sites
4 hours ago, nomoregames said:

Ahora doy paso a el siguiente nivel de desarrollo: IA enemigas y sistema de combate

 

Para ello e desarrollado un pequeño script, que básicamente lo que hace es que, si el jugador esta a 1 de distancia, pues atacar

El problema es que ataca en direccion forward... no se si me explico, y necesito hacer que los enemigos miren hacia el jugador, de modo que cuando ataquen, ataquen en su dirección.

Dicho esto, necesito hacer que apunten hacia el player, pero siguiendo la misma logica de la cuadricula, de forma que su rotación sera siempre: 0, 90, 180,  270 o 360 grados....

No se si me explico...

Y alguien tiene alguna idea?

Hola,

Puedes usar un transform.lookAt(*target*) cuando te haga falta. Por lo que comentas, justo cuando va atacar para que mire hacia donde quieres. Te dejo el link de la documentación de Unity:

https://docs.unity3d.com/ScriptReference/Transform.LookAt.html

En mi caso adapté un pequeño Script para que hiciera la rotación hacia el objetivo de forma algo más suave:

using UnityEngine;
using System.Collections;

public class SmoothLookAt : MonoBehaviour {
    public Transform target;        //an Object to lock on to
    public float damping = 6.0f;    //to control the rotation 
    public bool smooth = true;

    private Transform _myTransform;

    void Awake() {
        _myTransform = transform;
    }

    void LateUpdate() {
        if (target) {
            if (smooth) {

                //Look at and dampen the rotation
                Quaternion rotation = Quaternion.LookRotation(new Vector3(target.position.x, transform.position.y, target.transform.position.z) - _myTransform.position);
                _myTransform.rotation = Quaternion.Slerp(_myTransform.rotation, rotation, Time.deltaTime * damping);
            } else { //Just look at
                _myTransform.rotation = Quaternion.FromToRotation(-Vector3.forward, (new Vector3(target.position.x, transform.position.y, target.position.z) - _myTransform.position).normalized);

            }
        }
    }
}

 

Un saludo.

Edited by AxelJG

Share this post


Link to post
Share on other sites

Buenas tardes, haber si me podéis ayudar con este encuentra a Wally.

 

Tengo el siguiente script 

  RaycastHit hitInfo;
        if (Physics.Raycast(NPC.transform.position, NPC.transform.forward,out hitInfo, 1))
            {
                if (hitInfo.transform.tag == "Player")
                {
                    if (IsInAtack == false)	// aqui esta el error.... esto lo uso para que, mientras este atacando, no se pueda ejecutar lo de dentro de el if, que lo que hace es instanciar el arma y ponerla en su sitio... el error es que en ocasiones se ejecuta mas de una bez
                    {
                        sword = Instantiate<GameObject>(Espada);
                        sword.transform.position = NPC.transform.position;
                        sword.transform.SetParent(NPC.transform);
                        sword.transform.localPosition += new Vector3(0, 3, 0.45f);
                        sword.transform.eulerAngles = NPC.transform.eulerAngles;
                        IsInAtack = true;
                      
                        
                        StartCoroutine(Atack());
                    }
                }
            }
        
        
        
        
        }
    IEnumerator Atack()
    {
        float c = 0;         // el contador de la cantidad de tiempo que se ejecutara la corrutina
        
        bool a = true; // lo utilizo para que cuando el contador llegue a cierto numero, pase a ser false
        bool b = false; // solo puede ser true una bez... no se si me explico

        yield return new WaitForSecondsRealtime(0.4f);
        while (IsInAtack == true)
        {
            
          if (b == true)
            {
                b = false;
            }
            
          
            c += 1 * Time.deltaTime;

            if (c >= 0.01f && a == true)
            {
                Destroy(GameObject.Find("Daga(Clone)")); // esto es un arreglillo, en un principio havia echo que destrullera el GameObject Sword, asignado mas arriba... pero ay casos en los que por algun motivo... se instancian mas de una espada, por eso este arreglillo
                
                a = false;
                b = true;
                print(1);
            }

            if (b == true)
            {
                MoveController.transform.position += -MoveController.transform.forward; // esto se ejecuta solo una bez, hace retroceder a el NPC hacia atras, para que sea mas dificil darle... esta esquibando despues de destruir la "Daga"
              
            }
            
            if (c >= 0.5f) // el contador sigue a pesar de que la daga ya fue destruida para darle un tiempo antes de realizar otro ataque... sino estaria atacando todo el rato
            {
                c = 0;
                IsInAtack = false;								// en teoria, al llegar el contador "c" a cierto numero, IsInAtack se buelve false, para permitir bolver a realizar un ataque
                StopCoroutine(Atack());

            }


            
            
            yield return new WaitForSecondsRealtime(0.1f);
        }

No se si me he explicado bien... el caso es que no encuentro el porque se ejecuta en ocasiones (concreta-mente después de haberse ejecutado dos veces ).... alguien sabría encontrar el puñetero error?

Share this post


Link to post
Share on other sites

×
×
  • Create New...