2017-03-07 2 views
1

Lorsque je regarde un objet et appuyez sur le bouton, je dois faire quelque chose. Quand je le fais pour la première fois, cela fonctionne, mais alors je n'ai pas besoin d'appuyer à nouveau sur le bouton, je peux juste regarder l'objet. Mais joueur doit regarder l'objet et appuyez sur le bouton, non seulement regarderRaycastHit retourne vrai tout le temps

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; 
} 

Comment je l'utilise:

public OnMousePressCasino onMousePressCasinoBarthender; 
public OnMousePressCasino onMousePressCasinoDoorToStreet; 

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

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

Modifier 1 Ignorer collisionneur du joueur. Video du jeu

enter image description here

+2

Il retourne vrai parce que vous vous frapper. 'Ray _ray = Camera.main.ScreenPointToRay (nouveau Vector3 (Screen.width/2, Screen.height/2, 0));' mettre le 'Z' plus loin, par ex. '2'. En plus, il s'attend toujours à se toucher ... –

+0

@ m.rogalski J'ignore le collisionneur du joueur ici: 'int layerMask = 1 << 9; layerMask = ~ layerMask; '. Je peux frapper l'objet. Mais quand je veux frapper pour la deuxième fois, je n'ai pas besoin d'appuyer sur le bouton, je peux juste regarder l'objet – dima

Répondre

1

Ok donc en gros vous êtes paramètres ActionNumber à (disons) 1 et il reste à cette valeur.

Pour résoudre ce problème, vous devez régler la réinitialisation basée sur le temps de cette valeur ou simplement utiliser Raycast tout le temps en Update (ou LateUpdate).
Une autre façon serait d'utiliser event driven programming principles et de simplement déclencher l'événement lorsque vos conditions sont remplies et oublier de régler certaines valeurs.

Faire assez simple:

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; 
} 

Maintenant créer MeEventArgs:

public class MeEventArgs : EventArgs 
{ 
    public readonly int Action; 

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

Et pour l'utiliser dans le code:

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

"Ok, donc, fondamentalement, vous êtes paramètres ActionNumber à (disons) 1 et il reste à cette valeur jusqu'à ce que vous cliquez sur un autre objet ". Pas exactement. Je mets ce script sur chaque objet, que je vais frapper dans le futur. Donc, je peux appuyer sur l'objet A, puis appuyer sur l'objet B, puis je n'ai pas besoin d'appuyer sur l'objet A, je peux juste le regarder, comme et B. Mais merci, je vais essayer – dima

+0

@dima Oui. C'est ce que je voulais dire. Merci d'avoir signalé mon erreur :) –