point and click z wykorzystaniem Mecanim 7439 15

O temacie

Autor Sculler

Zaczęty 21.09.2015 roku

Wyświetleń 7439

Odpowiedzi 15

Sculler

Sculler

Użytkownicy
posty339
Propsy273
ProfesjaProducent
  • Użytkownicy
Siemka
Próbowałem stworzyć sterowanie z widoku izometrycznego coś na wzór Diablo, ale nie mam zielonego pojęcia jak połączyć animacje Mecanim w animatorze z owym sterowaniem. Chodzi mi o to żeby przy kliknięciu myszą na mapie postać zaczynała się przemieszczać we wskazane miejsce.
Są tutoriale jak podłączyć przyciski klawiatury pod konkretne animacje, ale nie znalazłem nic z wykorzystaniem myszy.
To jest testowy skrypt zrobiony na podstawie tutoriali analogicznie zmodyfikowany, ale nie działa :)
Spoiler
public class NewBehaviourScript : MonoBehaviour
{
private Animator animator;
private float chod;
void Start ()
{
animator = GetComponent<Animator>();
}
void Update()
{
chod = Input.GetAxis("Fire1");
}
void FixedUpdate()
{
animator.SetFloat ("chod", chod);
}
}

A tutaj jest skrypt przemieszczania się po mapie( tam gdzie kliknę tam wędruje postać)
Spoiler
public class NewBehaviourScript : MonoBehaviour
{
Vector3 newPosition;
void Start () {
newPosition = transform.position;
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
newPosition = hit.point;
transform.position = newPosition;
}
}
}
}

Wiecie jak można to zrobić?

 
some things are meant to be

Mark56

Mark56

Moderator
som veľký magič
posty1632
Propsy1846
ProfesjaAnimator
  • Moderator
  • som veľký magič
To raczej wymaga:
1.  znalezienie punktu na który sie w świecie klika.
2. pathfinding który ustali ścieżkę do wybranego punktu
3. zaprogramowane AI dla postaci która sama będzie naśladować ta ścieżkę

Nie mam pojęcia jak to zaprogramować. Z mojej strony to tylko teoria. Może jest już gdzieś gotowy "asset" tego stylu ?
 


mgr Fartuess

mgr Fartuess

Użytkownicy
Kiedyś to były czasy!
posty1485
Propsy890
ProfesjaProgramista
  • Użytkownicy
  • Kiedyś to były czasy!
@Mark56
Na UE4 jest już gotowe. Na Unity to głównie tego czy jest już gotowy system do generowania navmesha. Bo z tego co Mark56 napisał, to punkt pierwszy to banał. Do drugiego potrzebujesz navmesha. Jak masz gotowy system od navmesha to on już powinien też mieć gotowe wyszukiwanie ścieżki. Trzeci punkt znów powinien być nie aż tak trudne.

@Sculler
Jutro rzucę okiem i spróbuję coś podpowiedzieć.
 
Popisuje się ciągle menda jedna...

oskardon

oskardon

Użytkownicy
posty91
Propsy38
ProfesjaGracz
  • Użytkownicy
Przecież on się pyta o animację postaci, nie o pathfinding.

Na Unity jest gotowy generator navmesha, ale jeśli Sculler nie potrzebuje pathfindingu (nie był bym pewien czy w ogóle wie co to jest i jak działa) to i navmesh jest zbędny.
@Sculler - wystarczy ci żeby postać po prostu szła do kursura i ewentualnie blokowała się jeśli będzie przed nią przeszkoda? Mnóstwo gier point and click tak działa.
@Mark56  0b1100100 lat ;)
 
Life is brutal and full of zasadzkas.

mgr Fartuess

mgr Fartuess

Użytkownicy
Kiedyś to były czasy!
posty1485
Propsy890
ProfesjaProgramista
  • Użytkownicy
  • Kiedyś to były czasy!
@oskadron Niby o animacje, ale daje kod poruszania, który teleportuje postać a nie ją przemieszcza :P.

Poza tym gra którą chce zrobić to nie jest point&click?
 
Popisuje się ciągle menda jedna...

oskardon

oskardon

Użytkownicy
posty91
Propsy38
ProfesjaGracz
  • Użytkownicy
Nie potrzeba pathfindingu żeby przemieścić postać - zerknij jeszcze raz na mojego posta. Wystarczy zwykła interpolacja między dwoma pozycjami (w przypadku fizyki w Unity, controler.Move).
@Sculler - wystarczy ci żeby postać po prostu szła do kursura i ewentualnie blokowała się jeśli będzie przed nią przeszkoda? Mnóstwo gier point and click tak działa.
 
Life is brutal and full of zasadzkas.

mgr Fartuess

mgr Fartuess

Użytkownicy
Kiedyś to były czasy!
posty1485
Propsy890
ProfesjaProgramista
  • Użytkownicy
  • Kiedyś to były czasy!
No niezupełnie jest to interpolacja :>. Ale tak wiem o co ci chodzi, ale nie odpowiadałem, bo to jest oczywiste i nie wymaga komentarza.
 
Popisuje się ciągle menda jedna...

Sculler

Sculler

Użytkownicy
posty339
Propsy273
ProfesjaProducent
  • Użytkownicy
Dzięki za odpowiedzi. Już wiem jak uruchomić animację na przycisk myszki(wystarczyło trochę pobawić się animatorem i skryptami). Teraz męczę się ze skryptem płynnej transformacji w wybrane miejsce. Skrypt nie ma błędu, ale postać po kliknięciu ledwo się porusza jakby ruch trwał tylko jedną klatkę. Ustawiłem raycasta, który wysyła promień od gracza do miejsca kliknięcia myszki i funkcję, która przenosi go do tego miejsca. W teorii wszystko powinno działać, więc czego brakuje?
public class sterowanie : MonoBehaviour
{
   private Vector3 klikmyszki;
   void Start()
   {
   }
   void Update()
   {
      if (Input.GetMouseButtonDown(0))
      {
         RaycastHit hit;
         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
         if (Physics.Raycast(transform.position, ray.direction, out hit))
         {
            klikmyszki = hit.point;
         }
         transform.position = Vector3.MoveTowards(transform.position,klikmyszki,Time.deltaTime * 10);
      }
         

   }
}
 
some things are meant to be

oskardon

oskardon

Użytkownicy
posty91
Propsy38
ProfesjaGracz
  • Użytkownicy
Nie używaj Vector3.MoveTowards, to będzie ignorowało kolizje. Używaj CharacterController.Move / SimpleMove: http://docs.unity3d.com/ScriptReference/CharacterController.SimpleMove.html
Będzie brało pod uwagę kolizje (o ile świat będzie miał ustawione collidery) i dodatkowo grawitację. No chyba że masz płaską mapę bez przeszkód, to Vector3.MoveTowards też się nada.
 
Life is brutal and full of zasadzkas.

mgr Fartuess

mgr Fartuess

Użytkownicy
Kiedyś to były czasy!
posty1485
Propsy890
ProfesjaProgramista
  • Użytkownicy
  • Kiedyś to były czasy!
@Sculler
Przerzuć

transform.position = Vector3.MoveTowards(transform.position,klikmyszki,Time.deltaTime * 10);
za if'a sprawdzającego czy myszka została naciśnięta. Wtedy raz klikniesz i postać sama będzie podążała do celu (tylko najlepiej dla bezpieczeństwa jeszcze machnąć, że on sobie idzie chyba, że jest już wystarczająco blisko celu, bo inaczej może zacząć "tańczyć" jak do niego dojdzie :P). Jeśli chcesz, żeby postać szła dopóki trzymasz przycisk myszy to zamiast Input.GetMouseButtonDown(0) powinieneć użyć Input.GetMouseButton(0)

@oskadron
Zgadza się. Puszczanie raycastów trochę ten problem załatwia, ale i tak mogą być sytuacje problematyczne.
 
Popisuje się ciągle menda jedna...

oskardon

oskardon

Użytkownicy
posty91
Propsy38
ProfesjaGracz
  • Użytkownicy
Te raycasty znajdują tylko punkt docelowy. Nie mają nic wspólnego z ruchem postaci.
 
Life is brutal and full of zasadzkas.

Sculler

Sculler

Użytkownicy
posty339
Propsy273
ProfesjaProducent
  • Użytkownicy
Ta sprawa z character controlerem dużo ułatwia, ale teraz gdziekolwiek nie kliknę postać idzie do tyłu , mimo że w Debug.Log(klikmyszki) za każdym razem pokazuje inną wartość. O dziwo postać porusza się nawet jeśli nie klikam na mapę czyli na colider.Chyba coś jest nie tak z tym raycastem.
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(CharacterController))]
public class sterowanie : MonoBehaviour
{
private Vector3 klikmyszki;
   void Update()
   {
      CharacterController controller = GetComponent<CharacterController>();
      if (Input.GetMouseButtonDown(0))
      {
         RaycastHit hit;
         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
         if (Physics.Raycast(transform.position, ray.direction, out hit))
         {
            klikmyszki = hit.point;
            Debug.Log (klikmyszki);
         }
      }
      controller.SimpleMove (klikmyszki* Time.deltaTime);
   }
}
 
some things are meant to be

oskardon

oskardon

Użytkownicy
posty91
Propsy38
ProfesjaGracz
  • Użytkownicy
W swojej zmiennej klikmyszki zapisujesz pozycję. Do SimpleMove jako argument przekazujesz właśnie tą pozycję, do tego przemnożoną przez liczbę.
Mnożenie pozycji przez liczbę jest prawie zawsze bez sensu, a przecież SimpleMove nie oczekuje nawet pozycji!
Zamiast tego, oczekuje wektora "speed", co ściśle rzecz biorąc oznacza tutaj zarówno szybkość (długość tego wektora) jak i kierunek (kąt nachylenia tego wektora w przestrzeni).
Spróbuj tak:
controller.SimpleMove ((klikmyszki - transform.position).normalized * Time.deltaTime * wspolczynnikSzybkosciZdefiniowanyWKlasie);Co tutaj robimy:
  • (klikmyszki - transform.position) : liczymy różnicę między pozycją oczekiwaną a obecną
  • (...).normalized - wyciągamy z tej różnicy sam kierunek ("neutralizujemy" wpływ odległości)
  • ... * Time.deltaTime - zapobiegamy wpływowi liczby fps na szybkość ruchu
  • ... * wspolczynnikSzybkosciZdefiniowanyWKlasie - jest bardzo mała szansa że wektor który ci wyjdzie będzie miał akurat odpowiednią długość (a więc zapweni odpowiednią szybkość ruchu), więc przemnóż go przez eksperymenalnie dobraną stałą
BTW, nie wstawiaj tagu code w tag spoiler - nie wytworzy się w prawdzie czarna dziura, ale przez bug w skinie jest to ciężkie do przeczytania.
 
Life is brutal and full of zasadzkas.

Sculler

Sculler

Użytkownicy
posty339
Propsy273
ProfesjaProducent
  • Użytkownicy
Coś jest spieprzone z wykrywaniem kolizji, bo raycast z tego co rozumiem działa na zasadzie wykrywania kolizji, a u mnie nawet jak nie kliknę na mapę to postać zaczyna się przemieszczać i niezależnie od tego gdzie kliknę postać i tak idzie tam gdzie chce :). Na dodatek zauważyłem dziwną zależność, jak dam wartość szybkości na 100 to postać idzie w górne rejony mapy jak na -100 to w dolne.
 
some things are meant to be

oskardon

oskardon

Użytkownicy
posty91
Propsy38
ProfesjaGracz
  • Użytkownicy
Coś jest spieprzone z wykrywaniem kolizji, bo raycast z tego co rozumiem działa na zasadzie wykrywania kolizji
Raycast znajduje punkt przecięcia się danego wektora i colliderów w świecie. Czy twój świat ma ustawiony poprawny collider? Sam renderer to za mało.

u mnie nawet jak nie kliknę na mapę to postać zaczyna się przemieszczać
Jest tak ponieważ umieściłeś polecenie wykonywania ruchu bez względu na to czy jest gdzie iść.
Przed ruszeniem postaci gdziekolwiek wypadałoby właściwie sprawdzić czy jakieś miejsce jest w ogóle kliknięte. Najprościej byłoby to zrobić porównując czy wektor "klikmyszki" (swoją drogą: kiepska nazwa) jest niezerowy i nie zbyt bliski do obecnej pozycji. Przykładowo dodaj nad linijkją "controller.SimpleMove" taki warunek:
if (klikmyszki != Vector3.zero && Vector3.Distance(klikmyszki, transform.position) > minimalnaOdleglosc)Wartość stałej minimalnaOdleglosc podobnie jak współczynnik szybkości zależy od skali twojej mapy, także musisz dobrać ją eksperymentalnie.

niezależnie od tego gdzie kliknę postać i tak idzie tam gdzie chce
To może oznaczać że twój raycast w ogóle nie działa i wektor "klikmyszki" cały czas zawiera zerowe współrzędne. Czy twój "Debug.Log (klikmyszki);" w ogóle się pojawia po kliknięciu?

zauważyłem dziwną zależność, jak dam wartość szybkości na 100 to postać idzie w górne rejony mapy jak na -100 to w dolne.
Nie ma w tym nic dziwnego, to by tylko potwierdzało to co napisałem wyżej - że wektor "klikmyszki" cały czas zawiera same zera.
 
Life is brutal and full of zasadzkas.

Sculler

Sculler

Użytkownicy
posty339
Propsy273
ProfesjaProducent
  • Użytkownicy
Tak, wydaje się, że Debuglog prawidłowo pokazuje wartości. Możesz skopiować kod i sprawdzić to u siebie? Przy klikaniu występuje dziwna zależność pomiędzy miejscem kliknięcia i poruszaniem się modelu gracza, którą trudno opisać. Może wtedy mógłbyś bliżej powiedzieć co zawodzi w kodzie.
 
some things are meant to be


0 użytkowników i 1 Gość przegląda ten wątek.
0 użytkowników
Do góry