• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

C#, Unity 2D - AI - poruszanie horyzontalne za graczem, jeżeli jest w zasięgu

Object Storage Arubacloud
0 głosów
661 wizyt
pytanie zadane 13 grudnia 2019 w C# przez Teslum_369 Gaduła (4,190 p.)

Witam,

Na wstępie chciałbym oznajmić, iż jestem bardzo początkującym programistą w C# / Unity 2D.

Tworzę moją pierwszą grę (edukacyjną), gdzie chcę użyć klasyczne elementy platformówki. Opieram się głównie na poradnikach angielsko języcznych i czasami po prostu używam cudzego kodu do wykonania jakiegoś elementu / akcji etc. Zawsze straram się jednak zrozumieć kod i sprawdzajam co dane linie kodu robią.

Chciałbym zapytać, jak sprawić, aby postać ruszała się horyzontalnie (tylko w lewo i prawo) za graczem, jeżeli jest w zasięgu, oraz gdy gracz opuści go, AI wraca na swoje miejsce. Nie ukrywam, iż posłużyłem się kodem z internetu, ponieważ na moim obecnym poziomie raczej nie dałbym napisać tego skryptu własnymi rękoma. Przedstawiam kod: (Podkreślam, nie jest moim własnym skryptem)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Enemy : MonoBehaviour
{
    public Transform player; // changed this to Transform
    public float detectRange = 10; // this gets multiplied by itself to compare to a sqr magnitude check (instead of distance)
    public bool inRange = false;
    public float moveSpeed = 2f; // you can adjust this, of course.
    Rigidbody2D rb;  // cached the reference, so you can avoid GetComponent calls in Update/FixedUpdate.

    void Awake()
    {
        rb = GetComponent<Rigidbody2D>();
        detectRange *= detectRange;
    }

    void Update()
    {
        // a little cheaper than 'distance'.. deleted the code to create a position from the player values.
        float distsqr = (player.position - transform.position).sqrMagnitude;

        if (distsqr <= detectRange)
        {
            inRange = true;
            // get a velocity based on the normalized direction, multiplied by move speed.
            Vector2 velocity = (player.transform.position - transform.position).normalized * moveSpeed;
            rb.velocity = velocity;
        }

    }

}

Zatem jeszcze raz zapytam, jak mógłbym dodać opcję poruszania się tylko w lewo i w prawo oraz po odejściu gracza po za zasięg, AI wraca do swojego "pierwotnego" miejsca?

Naprawdę dziękuję z góry za pomoc smiley.

1 odpowiedź

+2 głosów
odpowiedź 14 grudnia 2019 przez piotrsz109 Stary wyjadacz (13,730 p.)
wybrane 14 grudnia 2019 przez Teslum_369
 
Najlepsza
Aby postac poruszała się tylko w dwóch osiach, dla zmiennej velocity, musisz ustawić dla jednej z współrzędnych wartość 0.

Aby postać wracała, gdy postać nie jest w zasięgu w metodzie Update musisz dodać warunek, czy gracz nie jest w zasięgu. W ciele if'a piszesz kod podobny do zawierającego się w poprzednim warunku - tylko tam zawierasz pozycję początkową, którą np.: zapisujesz w zmiennej w metodzie start.

Pozdrawiam
komentarz 14 grudnia 2019 przez piotrsz109 Stary wyjadacz (13,730 p.)
Plus dołącz proszę cały kod ponownie, ze zmianami
komentarz 14 grudnia 2019 przez Teslum_369 Gaduła (4,190 p.)
Okej, dołącze Ci jeszcze plik, aby zwizualizować całą sytuację. Za kilka chwil udostępnie.
komentarz 14 grudnia 2019 przez Teslum_369 Gaduła (4,190 p.)

Mała dokumentacja: https://imgur.com/a/WFxd7c4

Kod:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Enemy : MonoBehaviour
{
    public Transform player; // changed this to Transform
    public Transform obj; // changed this to Transform
    public float moveSpeed = 2f;
    public float detectRange = 1; // this gets multiplied by itself to compare to a sqr magnitude check (instead of distance)
    public bool inRange = false;
    Rigidbody2D rb;  // cached the reference, so you can avoid GetComponent calls in Update/FixedUpdate.
    Rigidbody2D rb_obj;  // cached the reference, so you can avoid GetComponent calls in Update/FixedUpdate.


    void Awake()
    {
        rb = GetComponent<Rigidbody2D>();
        rb_obj = GetComponent<Rigidbody2D>();

    }

  

    void Update()
    {
        // a little cheaper than 'distance'.. deleted the code to create a position from the player values.
        float distsqr = (player.position - transform.position).sqrMagnitude;

        if (distsqr <= detectRange)
        {
            inRange = true;
            // get a velocity based on the normalized direction, multiplied by move speed.
            Vector2 velocity = (player.transform.position - transform.position).normalized;
            velocity.y = 0;
            rb.velocity = velocity*2;

        }

        if (distsqr <= 1f) rb_obj.velocity = Vector3.zero;
        else if (distsqr > detectRange && inRange == true)
        {
            inRange = true;
            Vector2 velocity = (obj.transform.position - transform.position).normalized;
            velocity.y = 0;
            rb_obj.velocity = velocity * 2;
        }
    }


}

 

komentarz 14 grudnia 2019 przez piotrsz109 Stary wyjadacz (13,730 p.)
 if (distsqr <= 1f) rb_obj.velocity = Vector3.zero;
else  if (distsqr <= detectRange)
        {
            inRange = true;
            // get a velocity based on the normalized direction, multiplied by move speed.
            Vector2 velocity = (player.transform.position - transform.position).normalized;
            velocity.y = 0;
            rb.velocity = velocity*2;
 
        }
        else if (distsqr > detectRange && inRange == true)
        {
            inRange = true;
            Vector2 velocity = (obj.transform.position - transform.position).normalized;
            velocity.y = 0;
            rb_obj.velocity = velocity * 2;
        }

Moim zdaniem, powinno działać

komentarz 14 grudnia 2019 przez Teslum_369 Gaduła (4,190 p.)
Hah, już działa! :D

Dzięki wielkie za pomoc :))))))

Podobne pytania

0 głosów
1 odpowiedź 531 wizyt
pytanie zadane 10 października 2020 w C# przez PanPrezes Obywatel (1,520 p.)
0 głosów
0 odpowiedzi 440 wizyt
pytanie zadane 1 grudnia 2019 w C# przez Filip Papros Nowicjusz (120 p.)
0 głosów
1 odpowiedź 289 wizyt
pytanie zadane 2 września 2021 w C# przez hydrogeniumoxygenium Nowicjusz (120 p.)

92,550 zapytań

141,394 odpowiedzi

319,522 komentarzy

61,935 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...