• 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

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
0 głosów
1,010 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ź 718 wizyt
pytanie zadane 10 października 2020 w C# przez PanPrezes Obywatel (1,520 p.)
0 głosów
0 odpowiedzi 530 wizyt
pytanie zadane 1 grudnia 2019 w C# przez Filip Papros Nowicjusz (120 p.)
0 głosów
1 odpowiedź 391 wizyt
pytanie zadane 2 września 2021 w C# przez hydrogeniumoxygenium Nowicjusz (120 p.)

93,164 zapytań

142,176 odpowiedzi

321,938 komentarzy

62,493 pasjonatów

Advent of Code 2024

Top 15 użytkowników

  1. 688p. - dia-Chann
  2. 676p. - CC PL
  3. 675p. - Łukasz Piwowar
  4. 664p. - Marcin Putra
  5. 662p. - Łukasz Eckert
  6. 649p. - Michal Drewniak
  7. 641p. - rucin93
  8. 641p. - rafalszastok
  9. 629p. - Piotr Aleksandrowicz
  10. 629p. - Adrian Wieprzkowicz
  11. 621p. - Dawid128
  12. 611p. - ksalekk
  13. 606p. - Mariusz Fornal
  14. 602p. - Michał Telesz
  15. 597p. - Hubert Chęciński
Szczegóły i pełne wyniki

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

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...