2017-03-07 2 views
1

Wenn ich ein Objekt an und drücke den Knopf, muss ich etwas tun. Wenn ich es zum ersten Mal mache, funktioniert es, aber dann muss ich den Knopf nicht mehr drücken, ich kann nur auf das Objekt schauen. Aber Spieler muss bei Objekt suchen und die Taste drücken, sieht nicht nurRaycastHit Rückkehr die ganze Zeit wahr

private Collider thisCollider; 
public int ActionNumber { get; private set; } 

void Start() 
{ 
    thisCollider = GetComponent<Collider>(); 
} 

void Update() 
{ 
    if (Input.GetButton("Fire1") && DoPlayerLookAtObject()) 
     ActionsList(); 
} 

bool DoPlayerLookAtObject() 
{ 
    int layerMask = 1 << 9; 
    layerMask = ~layerMask; 

    RaycastHit _hit; 
    Ray _ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width/2, Screen.height/2, 0)); 
    bool isHit = Physics.Raycast(_ray, out _hit, 2.0f, layerMask);   
    if (isHit && _hit.collider == thisCollider) 
     return true; // this return true all the time after first interaction with object 
    else 
     return false; 
} 

public bool ActionsList() 
{ 
    if (DoPlayerLookAtObject()) 
     switch (thisCollider.name) 
     { 
      case "barthender": ActionNumber = 1; return true; 
      case "doorToStreet": ActionNumber = 2; return true; 
      default: Debug.Log("Error: Out of range"); break; 
     } 
    return false; 
} 

Wie ich es verwenden:

public OnMousePressCasino onMousePressCasinoBarthender; 
public OnMousePressCasino onMousePressCasinoDoorToStreet; 

if (onMousePressCasinoBarthender.ActionNumber == 1 && 
    onMousePressCasinoBarthender.ActionsList()) 
    // do something 

if (onMousePressCasinoDoorToStreet.ActionNumber == 2 && 
    onMousePressCasinoDoorToStreet.ActionsList()) 
    // do something 

Edit 1 Ignorieren Spieler Collider. Video aus dem Spiel

enter image description here

+2

Es gibt true zurück, weil Sie sich treffen sind. 'Ray _ray = Camera.main.ScreenPointToRay (neuer Vector3 (Screen.width/2, Screen.height/2, 0));' setze das 'Z' weiter entfernt z.B. "2". Außerdem erwartet es immer, sich selbst zu treffen ... –

+0

@ m.rogalski Ich ignoriere den Collider des Spielers hier: 'int layerMask = 1 << 9; layerMask = ~ layerMask; '. Ich kann das Objekt treffen. Aber wenn ich es zum zweiten Mal treffen will, brauche ich nicht auf den Knopf zu drücken, ich kann einfach auf Objekt – dima

Antwort

1

Okay, so im Grunde sind Sie Einstellungen, die Sie ActionNumber auf (sagen wir mal) 1 und es bleibt auf diesem Wert.

Um dies zu beheben, müssten Sie die zeitbasierte Zurücksetzung dieses Werts festlegen oder einfach Raycast die ganze Zeit in Update (oder LateUpdate) verwenden.
Eine andere Möglichkeit wäre, event driven programming principles zu verwenden und das Ereignis nur dann auszulösen, wenn Ihre Bedingungen erfüllt sind, und die Einstellung einiger Werte zu vergessen.

es einfach zu machen genug:

private Collider thisCollider; 

public event EventHandler<MeEventArgs> OnAction; 

void Start() 
{ 
    thisCollider = GetComponent<Collider>(); 
} 

void Update() 
{ 
    if (Input.GetButtonDown("Fire1")) 
    { 
     EventHandler<MeEventArgs> handler = OnAction; 
     int actionIndex = DoPlayerLookAtObject(); 
     if (handler != null && actionIndex >= 0) 
     { 
      handler(this, new MeEventArgs(actionIndex)); 
     } 
    } 
}  

int DoPlayerLookAtObject() 
{ 
    int layerMask = 1 << 9; 
    layerMask = ~layerMask; 

    RaycastHit _hit; 
    Ray _ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width/2, Screen.height/2, 0)); 
    bool isHit = Physics.Raycast(_ray, out _hit, 2.0f, layerMask);   
    //if (isHit && _hit.collider == thisCollider) 
    // return true; // this return true all the time after first interaction with object 
    //else 
    // return false; 
    if (isHit && _hit.collider == thisCollider) 
     return ActionList(); 

    return -1; 
} 

public int ActionsList() 
{ 
    int result = -1; 
    switch (thisCollider.name) 
    { 
     case "barthender": result = 1; break; 
     case "doorToStreet": result = 2; break; 
     default: Debug.Log("Error: Out of range"); break; 
    } 
    return result; 
} 

Jetzt MeEventArgs erstellen:

public class MeEventArgs : EventArgs 
{ 
    public readonly int Action; 

    public MeEventArgs(int actionIndex) : base() 
    { 
     Action = actionIndex; 
    } 
} 

Und dies in Code zu verwenden:

public OnMousePressCasino onMousePressCasinoBarthender; 
public OnMousePressCasino onMousePressCasinoDoorToStreet; 

void Start() 
{ 
    onMousePressCasinoBarthender.OnAction += MeAction; 
    onMousePressCasinoDoorToStreet.OnAction += MeAction; 
} 

void MeAction(object sender, MeEventArgs e) 
{ 
    if(e.Action == 1) 
    { 
     // do something 
    } 
    else if (e.Action == 2) 
    { 
     // do something else. 
    } 
} 
+1

schauen. "Okay, im Grunde genommen hast du Einstellungen an ActionNumber (sagen wir mal) 1 und es bleibt bei diesem Wert bis du auf ein anderes Objekt klickst ". Nicht genau. Ich lege dieses Skript auf jedes Objekt, das ich in Zukunft treffen werde. Also kann ich Objekt A drücken, dann Objekt B drücken, und dann muss ich Objekt A nicht drücken, kann es nur anschauen, wie und B. Aber danke, ich werde es versuchen – dima

+0

@dima Ja. Das ist es was ich meinte. Danke für das Zeigen meines Fehlers :) –

Verwandte Themen