Witam.
Podobny temat był już poruszany, ale wydaje mi się, że potrzebuję czegoś innego. A mianowicie: stworzyłem grę 3D typu RPG. Mam tam teren, obiekty wrogów i obiekty gracza. Wrogowie pojawiają się w losowych miejscach na planszy i poruszają się w stronę gracza. Wrogowie nie latają, nie skaczą, w zamyśle w ogóle nie powinni odrywać się od ziemi. I tutaj się pojawia problem. W skryptach wrogów zaimplementowałem instrukcję, która metodą raycastingu wykrywa gracza lub innego wroga i jeśli takowego wykryje - wróg dalej się nie porusza. Jednak to nie rozwiązuje do końca problemu: jeśli pojawia się dużo wrogów i wszystkie idą do gracza - pierwszy ładnie się zatrzymuje przed graczem, drugi czasem też, ale częściej jednak korzystając z pędu przesuwa stojącego przed nim wroga minimalnie w stronę gracza i zatrzymuje się i tak dalej. Jeśli w pierwszego wroga uderzy trzech czy czterech następnych ten prawie wchodzi w gracza (w zamyśle zatrzymuje się w odległości 3 jednostki od gracza). I to właściwie nie jest jakieś strasznie złe. Prawdziwym problemem jest to, że jeśli wróg jest dosyć niski, czasem tak jest "wpychany" w gracza, że gracz wchodzi na niego. To psuje efekt. Podobnie dzieje się z samymi wrogami. Jeśli jest cała gromada krasnali, tworzą się z nich małe wieżyczki. Próbowałem już wielu rzeczy żeby to wyeliminować, nic nie działało dostatecznie dobrze. No i wpadł mi do głowy kolejny pomysł, ale nie wiem jak go zrealizować. Chciałbym żeby obiekt gracza i obiekty wrogów były jakby przyczepione do terenu. Chciałbym stworzyc tak silne przyciąganie obiektów przez teraz, żeby mogły poruszać się po terenie (teren jest górzysty, wiele wzniesień, czyli obiekty przesuwają się we wszystkich trzech osiach), ale żadna siła nie jest w stanie ich od tego terenu oderwać w górę. Czy można zrobić coś takiego? Lub może macie inne pomysły które rozwiążą ten problem. Dołączam elementy skryptu, wybaczcie, ale piszę strasznie "brudne" skrypty. Dziękuję za pomoc.
using UnityEngine;
using System.Collections;
public class EnemyAIv5 : MonoBehaviour {
public float walkSpeed = 5.0f;
public float runSpeed = 10.0f;
public float attackDistance = 3.0f;
private Transform mojObiekt;
private Transform gracz;
private bool patrzNaGracza = false;
private Vector3 pozycjaGraczaXYZ;
public float zasiegWzroku = 30f;
public float zasiegPrzygotowaniaAtaku = 10f;
private bool gladkiObrot = true;
private float predkoscObrotu = 6.0f;
RaycastHit hit;
public bool cosFront=false;
public enum stan{s_idzie, s_biegnie, s_walczy, s_nic, s_spawn};
void Start () {
mojObiekt = transform;
GetComponent<Rigidbody> ().freezeRotation = true;
if(GameObject.FindWithTag ("Player"))gracz = GameObject.FindWithTag ("Player").transform;
}
void Update () {
if(gracz)pozycjaGraczaXYZ = new Vector3 (gracz.position.x, mojObiekt.position.y, gracz.position.z);
float dist = Vector3.Distance (mojObiekt.position, gracz.position);
if (dist >= 100) {
Destroy (gameObject);
}
if (HP > 0) {
if (aktualnyStan != stan.s_spawn) {
cosFront = false;
if (Physics.Raycast (transform.position, transform.forward, out hit, (float)(gameObject.GetComponent<BoxCollider>().size.z))) {
if (hit.collider.tag == "Enemy") {
cosFront = true;
}
}
if (dist <= zasiegWzroku && dist > zasiegPrzygotowaniaAtaku) {
if (!atakuje) {
float predkoscRuchu = walkSpeed;
if (!cosFront) {
mojObiekt.position = Vector3.MoveTowards (mojObiekt.position, pozycjaGraczaXYZ, predkoscRuchu * Time.deltaTime);
gameObject.GetComponent<Rigidbody> ().constraints = RigidbodyConstraints.None;
GetComponent<Rigidbody> ().freezeRotation = true;
} else {
gameObject.GetComponent<Rigidbody> ().constraints = RigidbodyConstraints.FreezePosition;
}
}
} else if (dist <= zasiegPrzygotowaniaAtaku && dist > attackDistance) {
if (!atakuje) {
float predkoscRuchu = runSpeed;
if (!cosFront) {
mojObiekt.position = Vector3.MoveTowards (mojObiekt.position, pozycjaGraczaXYZ, predkoscRuchu * Time.deltaTime);
gameObject.GetComponent<Rigidbody> ().constraints = RigidbodyConstraints.None;
GetComponent<Rigidbody> ().freezeRotation = true;
} else {
gameObject.GetComponent<Rigidbody> ().constraints = RigidbodyConstraints.FreezeAll;
}
}
}
}
}
}
Z kodu usunąłem niepotrzebne elementy, zakładamy, że nie brakuje żadnych nawiasów czy czegoś takiego.