Come posso creare un oggetto trascinabile che si agganci agli ostacoli lungo la strada?


8

Porto ancora un'altra domanda con il trascinamento del mouse (sto usando Unity con C #), ma con un dettaglio particolare meno comune: l'esistenza di ostacoli nel mezzo del percorso attraverso il quale si verifica il trascinamento (spazio 3D, non 2D) .

Lasciatemi spiegare. Supponiamo di avere un piano sul quale voglio trascinare un cubo chiamato "obj". È facile. Ecco la mia semplice implementazione per questo:

void Update () {
  Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
  RaycastHit hit;
  if(Physics.Raycast(ray, out hit, 1000000))
  obj.transform.position = new Vector3(hit.point.x,0.25F,hit.point.z);
}

Funziona. Tuttavia, supponiamo che io abbia anche alcuni altri cubi sull'aereo, che sono gli ostacoli. Ovviamente, quando il giocatore muove "obj" sull'aereo, tale movimento dovrebbe essere bloccato dagli ostacoli. E poi, mentre si scontra con gli ostacoli, "obj" dovrebbe spostarsi solo ai lati di quell'ostacolo. Se il mouse viene spostato e "obj" smette di scontrarsi con ostacoli, riprende il movimento libero di trascinamento.

l'oggetto viene trascinato verso un ostacolo e si ferma sul suo bordo, quindi riprende quando la resistenza supera l'ostacolo

Per rendere più difficile la sfida, sto cercando di raggiungerla senza l'uso di componenti RigidBody agli ostacoli (l'oggetto trascinato può averlo). Qualche idea su qual è il modo più efficace per raggiungere questo obiettivo? Grazie molto!

EDIT: I commentatori hanno portato alla mia attenzione che dovrei menzionare che gli oggetti possono ruotare quando scattano.

EDIT 2: Considerando la difficoltà della formulazione originale, ho cambiato la domanda permettendo l'uso di componenti Rigidbody sugli oggetti trascinati. La soluzione non è in grado di utilizzare i componenti Rigidbody per gli ostacoli.


Muovi forme convesse arbitrarie: sono sempre quadrilatere? Sono sempre in 2D?
Steven,

Posso sapere il motivo per cui non userete Rigidbodies? Sono il modo più semplice per fare ciò che vuoi senza dover reimplementare il codice già disponibile in Unity.
EvilTak

@EvilTak Preferisco imparare a gestire la geometria coinvolta nell'attività e, per motivi di prestazioni, non mi piace usare Rigidbodies a meno che non sia davvero inevitabile. In questo caso particolare, avrò molte migliaia di oggetti comportarsi come ostacoli
MAnd

A proposito, grazie a @Anko (oa chiunque l'abbia fatto) per aver incluso quell'immagine animata per illustrare il problema! Stavo ancora pensando al modo migliore per farlo.
Ma

1
@Steven ed EvilTak: l'oggetto può ruotare, gli ostacoli non dovrebbero. I soliti modi di rilevare la collisione sembrano non essere sufficienti: l'oggetto principale continua a entrare all'interno degli oggetti.
MAnd

Risposte:


2

È difficile rilevare la collisione senza che siano coinvolti corpi rigidi, ma poiché stai usando dei cubi potresti essere in grado di usare Bounds.Intersects . Ad ogni aggiornamento, controlla se i limiti dell'oggetto trascinato si intersecano con i limiti degli ostacoli. In tal caso, puoi provare questo:

  1. Disabilita il Rendering mesh per l'oggetto trascinato per renderlo invisibile (ma continua a trascinarlo).
  2. Rilascia un oggetto segnaposto visibile identico a quello trascinato nell'ultima posizione prima dei limiti dell'intersezione (ora sembra che l'oggetto sia fermo, ma in realtà stai ancora trascinando l'originale).
  3. Ad ogni aggiornamento, controlla se i limiti dell'oggetto che stai ancora trascinando si intersecano con i limiti di un ostacolo.
  4. Quando i limiti dell'oggetto trascinato non si intersecano più con quelli di un ostacolo, eliminare / disattivare l'oggetto segnaposto e riattivare Mesh Renderer per l'oggetto trascinato per renderlo nuovamente visibile.

Non smetti mai di trascinare il blocco; sembra semplicemente all'utente che il blocco ha smesso di trascinarsi mentre si interseca con un ostacolo.


Sulla base dei commenti precedenti e della tua risposta, ho modificato la domanda per renderlo più facile da realizzare: ora diciamo che Rigidbody potrebbe essere usato per l'oggetto trascinabile o i suoi segnaposto. Il rigido non poteva proprio essere usato per gli ostacoli.
Ma

1

Senza averlo fatto da solo, ecco cosa proverei:

  1. Decidi quanto in alto deve essere un ostacolo sull'aereo per bloccare l'oggetto trascinato (dove "alto" significa rimosso lungo qualunque asse sia appropriato; suppongo che quello che punta verso la telecamera).
  2. Ad ogni aggiornamento, salva la posizione del tuo colpo raycast.
  3. Ogni aggiornamento, prima di salvare la posizione dell'hit raycast corrente, controlla la posizione dell'hit raycast corrente rispetto alla posizione dell'hit raycast precedente.
  4. Se la differenza> = altezza di blocco, ferma l'oggetto in movimento nella posizione precedente del colpo di raycast.

Mi sembra che se desideri che il tuo oggetto trascini lungo un piano inclinato di un ostacolo, dovresti semplicemente fare in modo che la sua trasformazione continui a seguire la posizione dell'ultimo colpo di raycast.


Grazie per la tua risposta, @Evan. Tuttavia, quella soluzione non sarebbe accurata. Supponiamo che RayCast venga sparato dal centro del riquadro di selezione dell'oggetto trascinabile. Cosa succede se l'ostacolo sulla strada blocca solo una parte dell'oggetto trascinabile che si trova a sinistra o a destra del raggio di lancio? Anche se aumentiamo il numero di raggi proiettati (cosa può diventare esponenzialmente alto se l'oggetto trascinabile può essere trascinato in direzioni 360 ° nelle dimensioni X, Z), a seconda di quanto piccolo sia l'ostacolo rispetto all'oggetto trascinabile, potrebbe comunque essere nel raggio tra i raggi - e quindi non verrebbero rilevati
MA

Va bene, penso di vedere cosa intendi.
Evan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.