Autor Wątek: Character Controler - Skrypt AI  (Przeczytany 2370 razy)

Offline BrunonDEV

  • Użytkownik
    • Construgia -- RPG

# Luty 07, 2015, 15:14:24
Witam. Podczas pisania skryptu AI dla przeciwnika do gry, napotkałem pewien problem; otóż gdy próbuję poruszyć stworka za pomocą CharacterControler, objekt dziwnie się zachowuje; tj. skrypt nie działa jak powinien. Szukałem w dokumentacji, kombinowałem, i skrypt dalej nie działa. :(

Kod:
void Update () {
GameObject Pom = GameObject.FindGameObjectWithTag ("Player");
Transform Cel = Pom.transform;

float Distance = Vector3.Distance (this_Imicreap.position, Cel.position);

if (Distance <= 50) {
this_Imicreap.rotation = Quaternion.Slerp(this_Imicreap.rotation, Quaternion.LookRotation(Cel.position - this_Imicreap.position), rotationSpeed * Time.deltaTime);

kontroler.Move(this_Imicreap.transform.forward);
Debug.Log(Distance);
}

}

Wspomnę również (jak w każdym założonym przeze mnie temacie), że mam 11 lat i mogę nie znać np. jakiś zaawansowanych reguł matematycznych itp. ;)

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Xirdus

  • Redaktor

  • +1
# Luty 07, 2015, 15:40:02
Co dokładnie znaczy nie działa? Co byś chciał żeby robił, a co zamiast tego robi?

Offline BrunonDEV

  • Użytkownik
    • Construgia -- RPG

# Luty 07, 2015, 15:44:17
Ma iść w kierunku gracza. :)

Wiem że da się to (chodzenie w przód) tak zrobić:
cos.position += cos.forward * predkoscRuchu * Time.deltaTime;
ale ja chcę to zrobić za pomocą CharacterControler, żeby nie przenikał przez obiekty. ;)

Offline Xirdus

  • Redaktor

  • +1
# Luty 07, 2015, 16:00:32
OK, powiedziałeś co chciałbyś, ale dalej nie powiedziałeś co się dzieje. Tak czy inaczej, spróbuj zamienić Move() na SimpleMove().

Offline BrunonDEV

  • Użytkownik
    • Construgia -- RPG

# Luty 07, 2015, 16:21:01
No więc po zmianie na SimpleMove gdy podejdę do stworka na (<= 50) to stworek jedynie obraca się w moim kierunku (co też ma robić), ale nie chodzi za mną.

Może pokażę cały kod:
using UnityEngine;
using System.Collections;

[RequireComponent(typeof(CharacterController))]

public class Imicreap : MonoBehaviour {

public Transform this_Imicreap;
public Transform player;
public int runSpeed;
public int rotationSpeed;
int w;
int h;
private int imicreap_healt;
public static int attack;
public Transform explosion;
public CharacterController kontroler;

void Start () {
this_Imicreap = transform;
player = transform;

h = Screen.height / 2;
w = Screen.width  / 2;

kontroler = gameObject.GetComponent<CharacterController> ();
}

void Update () {
GameObject Pom = GameObject.FindGameObjectWithTag ("Player");
Transform Cel = Pom.transform;

float Distance = Vector3.Distance (this_Imicreap.position, Cel.position);

if (Distance <= 50) {
this_Imicreap.rotation = Quaternion.Slerp(this_Imicreap.rotation, Quaternion.LookRotation(Cel.position - this_Imicreap.position), rotationSpeed * Time.deltaTime);


kontroler.SimpleMove(this_Imicreap.forward);

}

}
}


Offline Xirdus

  • Redaktor

  • +1
# Luty 07, 2015, 17:01:03
Wrzuć do loggera "this_Imicreap.forward" i powiedz czy poprawnie pokazuje (tj. jeśli potwór patrzy wzdłuż osi X, to druga i trzecia składowa wektora powinny być bliskie zera, a pierwsza bliska 1 lub -1).

Offline BrunonDEV

  • Użytkownik
    • Construgia -- RPG

# Luty 07, 2015, 17:13:43
Ustawiłem stworka na tej samej wartości X co gracza, i wynik wyszedł taki:

(0.0, -0.5, 0.8)

To chyba niepoprawny. :/ Co mam z tym zrobić?

Offline laggyluk

  • Użytkownik
    • twitter

  • +1
# Luty 07, 2015, 17:31:07
a CharacterController to nie jest czasem komponent przewidziany do poruszania aktorem gracza?
na creepa wystarczy wrzućić rigidbody i capsule collider. btw nie rób tego:
GameObject Pom = GameObject.FindGameObjectWithTag ("Player");
w update tylko wyszukaj i zapisz do zmiennej w start/awake bo to wolna metoda

Offline BrunonDEV

  • Użytkownik
    • Construgia -- RPG

# Luty 07, 2015, 18:07:24
No to jak w takim razie zrobić by Imicreap nie przenikał przez wszystko? Próbowałem dodawać i różnie ustawiać rigidbody, ale to nic nie dawało. :(

Skrypt:

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(CharacterController))]

public class Imicreap : MonoBehaviour {

public Transform this_Imicreap;
public Transform player;
public int runSpeed;
public int rotationSpeed;
int w;
int h;
private int imicreap_healt;
public static int attack;
public Transform explosion;
public CharacterController kontroler;
public Transform Cel;

void Start () {
this_Imicreap = transform;
player = transform;

h = Screen.height / 2;
w = Screen.width  / 2;

kontroler = gameObject.GetComponent<CharacterController> ();

GameObject Pom = GameObject.FindGameObjectWithTag ("Player");
Cel = Pom.transform;
}

void Update () {
float Distance = Vector3.Distance (this_Imicreap.position, Cel.position);

if (Distance <= 50) {
this_Imicreap.rotation = Quaternion.Slerp(this_Imicreap.rotation, Quaternion.LookRotation(Cel.position - this_Imicreap.position), rotationSpeed * Time.deltaTime);

if(Distance >= 3){
this_Imicreap.position += this_Imicreap.forward * runSpeed * Time.deltaTime;
}
}

}
}

Offline koirat

  • Użytkownik

  • +2
# Luty 07, 2015, 18:09:52
A tak poza tym to pisz własny Character Controller większość gotowych skryptów które dostajesz wraz z Unity to badziewie.

Offline BrunonDEV

  • Użytkownik
    • Construgia -- RPG

# Luty 07, 2015, 18:42:02
No i oto rozwiązałem właśnie problem w taki oto sposób:

Vector3 fwd = transform.TransformDirection(Vector3.forward);
RaycastHit hit;

if(Physics.Raycast(transform.position, fwd, out hit)){
float ObjDistance = Vector3.Distance(this_Imicreap.position, hit.collider.gameObject.transform.position);
if(Distance >= 3 && ObjDistance > 1){
this_Imicreap.position += this_Imicreap.forward * runSpeed * Time.deltaTime;
}
}

Problem rozwiązany, dziękuję wszystkim za pomoc. Pozdrawiam. :)

Offline laggyluk

  • Użytkownik
    • twitter

# Luty 07, 2015, 20:03:38
kolizje występują między obiektami które mają jakiś collider. samo rigidbody włącza tylko fizykę bez kolizji.