Delen via


Overzicht van Oplosser — MRTK2

Oplosser Main

Oplossers zijn onderdelen die het berekenen van de positie en stand van een object vergemakkelijken volgens een vooraf gedefinieerd algoritme. Een voorbeeld hiervan is het plaatsen van een object op het oppervlak waarop de raycast van de gebruiker momenteel wordt weergegeven.

Bovendien definieert het Oplosser-systeem deterministisch een volgorde van bewerkingen voor deze transformatieberekeningen, omdat er geen betrouwbare manier is om op te geven aan Unity de updatevolgorde voor onderdelen.

Oplossers bieden een reeks gedragingen om objecten aan andere objecten of systemen te koppelen. Een ander voorbeeld is een tag-along-object dat voor de gebruiker beweegt (op basis van de camera). Een oplosser kan ook worden gekoppeld aan een controller en een object om de objecttag-langs de controller te maken. Alle oplossers kunnen veilig worden gestapeld, bijvoorbeeld een tag-along gedrag + oppervlakte magnetisme + momentum.

Een oplosser gebruiken

Het Oplosser-systeem bestaat uit drie categorieën scripts:

  • Solver: De abstracte basisklasse waaruit alle oplossers zijn afgeleid. Het biedt statustracking, vloeiende parameters en implementatie, automatische oplossersysteemintegratie en updatevolgorde.
  • SolverHandler: Stelt het referentieobject in om tegen te houden (bijvoorbeeld de hoofdcameratransformatie, handstraal, enzovoort), verwerkt het verzamelen van oplosseronderdelen en voert het bijwerken ervan in de juiste volgorde uit.

De derde categorie is de oplosser zelf. De volgende oplossers bieden de bouwstenen voor basisgedrag:

  • Orbital: vergrendelt op een opgegeven positie en verschuiving van het object waarnaar wordt verwezen.
  • ConstantViewSize: Schaalt om een constante grootte te behouden ten opzichte van de weergave van het object waarnaar wordt verwezen.
  • RadialView: Houdt het object in een weergaveconus cast door het object waarnaar wordt verwezen.
  • Follow: Houdt het object binnen een set door de gebruiker gedefinieerde grenzen van het object waarnaar wordt verwezen.
  • InBetween: Houdt een object tussen twee bijgehouden objecten bij.
  • SurfaceMagnetism: giet stralen naar oppervlakken in de wereld en lijn het object uit op dat oppervlak.
  • DirectionalIndicator: Bepaalt de positie en stand van een object als een richtingsindicator. Vanaf het referentiepunt van het OplosserHandler Tracked Target zal deze indicator zich richten op de opgegeven DirectionalTarget.
  • Momentum: Hiermee past u versnelling/snelheid/wrijving toe om het momentum en de lente te simuleren voor een object dat wordt verplaatst door andere oplossers/onderdelen.
  • HandConstraint: Beperkt object om handen te volgen in een regio die het GameObject niet met de handen kruist. Handig voor handbeperkte interactieve inhoud, zoals menu's, enzovoort. Deze oplosser is bedoeld om te werken met IMixedRealityHand , maar werkt ook met IMixedRealityController.
  • HandConstraintPalmUp: Is afgeleid van HandConstraint, maar bevat logica om te testen of de handpalm de gebruiker voordat deze wordt geactiveerd. Deze oplosser werkt alleen met IMixedRealityHand-controllers , met andere controllertypen werkt deze oplosser net als de basisklasse.

Als u het Oplosser-systeem wilt gebruiken, voegt u een van de bovenstaande onderdelen toe aan een GameObject. Omdat alle Oplossers een SolverHandlervereisen, wordt er automatisch een gemaakt door Unity.

Notitie

Voorbeelden van het gebruik van het Systeem Oplossers vindt u in het bestand OplosserExamples.scene .

Naslaginformatie voor het bijhouden van wijzigingen

De eigenschap Tracked Target Type van het SolverHandler onderdeel definieert het referentiepunt dat alle oplossers gebruiken om hun algoritmen te berekenen. Een waardetype van Head een eenvoudig SurfaceMagnetism onderdeel resulteert bijvoorbeeld in een raycast van het hoofd en in de richting van de blik van de gebruiker voor het oplossen van het oppervlak. Mogelijke waarden voor de TrackedTargetType eigenschap zijn:

  • Hoofd : Referentiepunt is de transformatie van de hoofdcamera
  • ControllerRay: Verwijzingspunt is de LinePointer transformatie op een controller (de oorsprong van de aanwijzer op een bewegingscontroller of handcontroller) die in de richting van de lijnstraal wijst
    • Gebruik de TrackedHandedness eigenschap om de voorkeur voor de hand te selecteren (bijv. Links, Rechts, Beide)
  • HandJoint: Verwijzingspunt is de transformatie van een specifieke handverbinding
    • Gebruik de TrackedHandedness eigenschap om de voorkeur voor de hand te selecteren (bijv. Links, Rechts, Beide)
    • TrackedHandJoint De eigenschap gebruiken om de gezamenlijke transformatie te bepalen die moet worden gebruikt
  • CustomOverride: Verwijzingspunt van de toegewezen TransformOverride

Notitie

Voor zowel ControllerRay - als HandJoint-typen probeert de handler van de oplosser eerst de linkercontroller/handtransformatie op te geven en vervolgens het recht als de voormalige niet beschikbaar is of tenzij de TrackedHandedness eigenschap anders opgeeft.

Bijgehouden oplosserobjectVoorbeeld van verschillende eigenschappen die zijn gekoppeld aan elk TrackedTargetType

Belangrijk

De meeste oplossers gebruiken de voorwaartse vector van het bijgehouden transformatiedoel dat wordt geleverd door de SolverHandler. Wanneer u een handgewijs getraceerd doeltype gebruikt, kan de voorwaartse vector van het palmgewricht door de vingers wijzen en niet door de palm. Dit hangt af van het platform dat de handgegevens levert. Voor invoersimulatie en Windows Mixed Reality is het de upvector die door de palm wijst (de groene vector is omhoog, blauwe vector vooruit).

Voorwaartse vector

U kunt dit oplossen door de eigenschap Aanvullende draaiing op de SolverHandler eigenschap 90, 0, 0, 0 bij te>< werken. Dit zorgt ervoor dat de doorstuurvector die aan oplossers wordt geleverd, door de palm wijst en naar buiten van de hand wijst.

Extra draaiing

U kunt ook het doeltype Controller Ray gebruiken om vergelijkbaar gedrag te krijgen voor het aanwijzen met handen.

Oplossers koppelen

Het is mogelijk om meerdere Solver onderdelen toe te voegen aan hetzelfde GameObject, waardoor hun algoritmen worden gekoppeld. De SolverHandler onderdelen verwerken het bijwerken van alle oplossers op hetzelfde GameObject. Standaard worden de SolverHandler aanroepen GetComponents<Solver>() op Start geretourneerd, waardoor de Oplossers worden geretourneerd in de volgorde waarin ze in de inspector worden weergegeven.

Bovendien geeft het instellen van de eigenschap Bijgewerkte gekoppelde transformatie op true aan dat Solver de berekende positie, oriëntatie en schaal worden opgeslagen in een tussenliggende variabele die toegankelijk is voor alle Oplossers (dat wil GoalPositiongezegd). Als dit onwaar is, wordt de Solver transformatie van het GameObject rechtstreeks bijgewerkt. Door de transformatie-eigenschappen op te slaan op een tussenliggende locatie, kunnen andere Oplossers hun berekeningen uitvoeren vanaf de tussenliggende variabele. Dit komt doordat Unity geen updates toestaat voor gameObject.transform om te stapelen binnen hetzelfde frame.

Notitie

Ontwikkelaars kunnen de volgorde van de uitvoering van Oplossers wijzigen door de SolverHandler.Solvers eigenschap rechtstreeks in te stellen.

Een nieuwe oplosser maken

Alle oplossers moeten overnemen van de abstracte basisklasse. Solver De primaire vereisten van een Oplosser-extensie omvat het overschrijven van de SolverUpdate methode. In deze methode moeten ontwikkelaars de overgenomen GoalPositionen GoalRotation GoalScale eigenschappen bijwerken naar de gewenste waarden. Bovendien is het over het algemeen waardevol om te gebruiken SolverHandler.TransformTarget als referentiekader dat door de consument wordt gewenst.

De onderstaande code geeft een voorbeeld van een nieuw Oplosser-onderdeel InFront dat het bijgevoegde object 2m voor de SolverHandler.TransformTargetoplosser plaatst. Als het SolverHandler.TrackedTargetType door de consument is ingesteld als Head, wordt de SolverHandler.TransformTarget cameratransformatie en dus plaatst deze Oplosser het bijgevoegde GameObject 2m voor de blik van de gebruikers elk frame.

/// <summary>
/// InFront solver positions an object 2m in front of the tracked transform target
/// </summary>
public class InFront : Solver
{
    ...

    public override void SolverUpdate()
    {
        if (SolverHandler != null && SolverHandler.TransformTarget != null)
        {
            var target = SolverHandler.TransformTarget;
            GoalPosition = target.position + target.forward * 2.0f;
        }
    }
}

Implementatiehandleidingen voor Oplosser

Algemene eigenschappen van oplosser

Elk Oplosser-onderdeel heeft een kernset identieke eigenschappen die het gedrag van de oplosser bepalen.

Als Smoothing is ingeschakeld, werkt de Oplosser de transformatie van het GameObject geleidelijk bij naar de berekende waarden. De snelheid van deze wijziging wordt bepaald door de eigenschap LerpTime van elk transformatieonderdeel. Een hogere MoveLerpTime-waarde resulteert bijvoorbeeld in tragere stappen tussen frames.

Als MaintainScale is ingeschakeld, gebruikt de Oplosser de standaard lokale schaal van GameObject.

Eigenschappen van Core Oplosser
Algemene eigenschappen overgenomen door alle Oplosser-onderdelen

Orbital

De Orbital klasse is een tag-along-component die zich gedraagt als planeten in een zonnestelsel. Deze Oplosser zorgt ervoor dat het gekoppelde GameObject rond de bijgehouden transformatie draait. Dus, als het tracked target type van de SolverHandler is ingesteld op Head, dan zal het GameObject om de hoofd van de gebruiker draaien met een vaste offset toegepast.

Ontwikkelaars kunnen deze vaste offset aanpassen om menu's of andere scèneonderdelen op oogniveau of op tailleniveau etc. rond een gebruiker te houden. Dit wordt gedaan door de eigenschappen Local Offset en World Offset te wijzigen. De eigenschap Oriëntatietype bepaalt de draaiing die op het object wordt toegepast als deze de oorspronkelijke draaiing moet behouden of altijd de camera of het gezicht moet zien, ongeacht de transformatie die de positie van het object aangeeft, enzovoort.

Orbital-voorbeeld
Orbital-voorbeeld

RadialView

Het RadialView is een ander tag-along-onderdeel dat een bepaald gedeelte van een GameObject in het frustum van de weergave van de gebruiker bewaart.

De eigenschappen Min & Max View Degrees bepalen hoe groot een deel van het GameObject altijd in beeld moet zijn.

De eigenschappen Min & Max Distance bepalen hoe ver het GameObject van de gebruiker moet worden bewaard. Als u bijvoorbeeld naar het GameObject loopt met een minimale afstand van 1m, duwt u het GameObject weg om ervoor te zorgen dat het nooit dichter dan 1m bij de gebruiker is.

Over het algemeen wordt het RadialView gebruikt in combinatie met Het bijgehouden doeltype ingesteld op Head , zodat het onderdeel de blik van de gebruiker volgt. Dit onderdeel kan echter worden gebruikt om te worden bewaard in de weergave van elk bijgehouden doeltype.

RadialView-voorbeeld
RadialView-voorbeeld

Volgen

De Follow klasse plaatst een element vóór het bijgehouden doel ten opzichte van de lokale voorwaartse as. Het element kan losjes worden beperkt (a.k.a. tag-along), zodat het niet wordt gevolgd totdat het bijgehouden doel buiten door de gebruiker gedefinieerde grenzen wordt verplaatst.

Het werkt op dezelfde manier als de RadialView-oplosser, met extra besturingselementen voor het beheren van Max Horizontal & Vertical View Degrees en mechanismen om de afdrukstand van het object te wijzigen.

Eigenschappen volgen
Eigenschappen volgen

Voorbeeldscène volgen
Volg voorbeeldscène (assets/MRTK/Examples/Demos/Solvers/Scenes/FollowSolverExample.unity)

InBetween

De InBetween klasse behoudt het gekoppelde GameObject tussen twee transformaties. Deze twee transformatie-eindpunten worden gedefinieerd door het eigen SolverHandler bijgehouden doeltype van het GameObject en de eigenschap Second Tracked Target Type van het InBetween onderdeel. Over het algemeen worden beide typen ingesteld op CustomOverride en de resulterende SolverHandler.TransformOverride en InBetween.SecondTransformOverride waarden ingesteld op de twee bijgehouden eindpunten.

Tijdens runtime maakt het InBetween onderdeel een ander SolverHandler onderdeel op basis van de eigenschappen Second Tracked Target Type en Second Transform Override .

De PartwayOffset definieert waar het object langs de lijn tussen twee transformaties moet worden geplaatst met 0,5 als halverwege, 1,0 bij de eerste transformatie en 0,0 bij de tweede transformatie.

Voorbeeld van inbetween
Voorbeeld van het gebruik van InBetween oplosser om het object tussen twee transformaties te behouden

SurfaceMagnetisme

Het SurfaceMagnetism werkt door een raycast uit te voeren tegen een set LayerMask van oppervlakken en het GameObject op dat contactpunt te plaatsen.

De Surface Normal Offset plaatst het GameObject een ingestelde afstand in meters van het oppervlak in de richting van het normale op het hitpunt op het oppervlak.

Omgekeerd plaatst de Surface Ray Offset de GameObject een vaste afstand in meters van het oppervlak, maar in de tegenovergestelde richting van de raycast uitgevoerd. Dus als de raycast de blik van de gebruiker is, gaat het GameObject dichter langs de lijn van het hitpunt op het oppervlak naar de camera.

De standmodus bepaalt het type draaiing dat moet worden toegepast ten opzichte van het normale oppervlak.

  • Geen - Geen draaiing toegepast
  • TrackedTarget - Object zal de bijgehouden transformatie onder ogen zien die de raycast aansturen
  • SurfaceNormal - Object wordt uitgelijnd op basis van normaal op hitpunt op oppervlak
  • Gemengd - Object wordt uitgelijnd op basis van normaal op het trefferpunt op het oppervlak EN op basis van de richting van de bijgehouden transformatie.

Als u wilt afdwingen dat het gekoppelde GameObject verticaal blijft in een andere modus dan Geen, schakelt u Afdrukstand verticaal in.

Notitie

Gebruik de eigenschap Orientation Blend om de balans tussen rotatiefactoren te bepalen wanneer de afdrukstand is ingesteld op Blended. Een waarde van 0,0 heeft de richting volledig aangestuurd door de TrackedTarget-modus en een waarde van 1,0 heeft de oriëntatie volledig aangestuurd door SurfaceNormal.

SurfaceMagnetism-voorbeeld

Bepalen welke oppervlakken kunnen worden bereikt

Wanneer u een SurfaceMagnetism onderdeel toevoegt aan een GameObject, is het belangrijk om rekening te houden met de laag van het GameObject en de onderliggende elementen, indien er botsen. Het onderdeel werkt door verschillende soorten raycasts uit te voeren om te bepalen tegen welk oppervlak "magneet" zelf. Als het oplosser GameObject een collider heeft op een van de lagen die worden vermeld in de MagneticSurfaces eigenschap van SurfaceMagnetism, raakt de raycast waarschijnlijk zichzelf, wat resulteert in het GameObject dat is gekoppeld aan een eigen colliderpunt. Dit vreemde gedrag kan worden vermeden door het belangrijkste GameObject en alle kinderen in te stellen op de laag Raycast negeren of de MagneticSurfaces LayerMask-matrix op de juiste manier te wijzigen.

Omgekeerd zal een SurfaceMagnetism GameObject niet botsen met oppervlakken op een laag die niet wordt vermeld in de MagneticSurfaces eigenschap. Het wordt over het algemeen aanbevolen om alle gewenste oppervlakken op een toegewezen laag (dat wil bijvoorbeeld Surfaces) te plaatsen en de MagneticSurfaces eigenschap in te stellen op alleen deze laag. Het gebruik van standaardinstellingen of alles kan leiden tot ui-onderdelen of cursors die bijdragen aan de oplosser.

Ten slotte worden de oppervlakken verder dan de instelling van de MaxRaycastDistance eigenschap genegeerd door de SurfaceMagnetism raycasts.

DirectionalIndicator

De DirectionalIndicator klasse is een tag-along-component die zich richt op de richting van een gewenst punt in de ruimte.

Meestal gebruikt wanneer het bijgehouden doeltype van de SolverHandler is ingesteld op Head. Op deze manier stuurt een UX-onderdeel met de DirectionalIndicator oplosser een gebruiker om naar het gewenste punt in de ruimte te kijken.

Het gewenste punt in de ruimte wordt bepaald via de eigenschap Directional Target .

Als het directionele doel door de gebruiker kan worden weergegeven of als er een referentiekader is ingesteld in de SolverHandleroplosser, worden alle Renderer onderdelen eronder uitgeschakeld. Als dit niet zichtbaar is, wordt alles ingeschakeld op de indicator.

De grootte van de indicator verkleint des te dichter de gebruiker is het vastleggen van het directionele doel in hun FOV.

  • Minimale indicatorschaal - De minimale schaal voor het indicatorobject

  • Maximale indicatorschaal : de maximale schaal voor het indicatorobject

  • Zichtbaarheidsschaalfactor - Vermenigvuldiger om de FOV te verhogen of te verlagen die bepaalt of het directionele doelpunt kan worden bekeken of niet

  • View Offset - Vanuit het oogpunt van het referentiekader (mogelijk camera), bepaalt deze eigenschap hoe ver in de indicatorrichting het object zich moet bevinden vanuit het midden van de viewport.

Eigenschappen van directionele indicator
Eigenschappen van directionele indicator

Voorbeeldscène directionele indicator
Directional Indicator Example Scene (Assets/MRTK/Examples/Demos/Solvers/Scenes/DirectionalIndicatorSolverExample.unity)

Handmenu met HandConstraint en HandConstraintPalmUp

Handmenu UX-voorbeeld

Het HandConstraint gedrag biedt een oplosser die het bijgehouden object beperkt tot een regio die veilig is voor handbeperkte inhoud (zoals de gebruikersinterface, menu's, enzovoort). Veilige regio's worden beschouwd als gebieden die niet met de hand snijden. Een afgeleide klasse van HandConstraint aangeroepen HandConstraintPalmUp wordt ook opgenomen om een gemeenschappelijk gedrag aan te tonen van het activeren van het bijgehouden object van de oplosser wanneer de palm de gebruiker tegenkomt.

Zie de pagina Handmenu voor de voorbeelden van het gebruik van handbeperking oplosser om handmenu's te maken.

Zie ook