2017-03-07 142 views
1

当我查看某个对象并按下按钮时,我需要做一些事情。当我第一次这样做的时候,它可以工作,但是我不需要再次按下按钮,我只能看物体。但玩家必须看对象并按下按钮,不仅看起来RaycastHit始终返回true

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

我如何使用它:

public OnMousePressCasino onMousePressCasinoBarthender; 
public OnMousePressCasino onMousePressCasinoDoorToStreet; 

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

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

编辑1无视玩家的对撞机。 Video从游戏

enter image description here

+2

它,因为你打自己返回true。 'Ray_ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width/2,Screen.height/2,0));'将'Z'设置得更远,例如, '2'。除此之外,它总是期望自己... ... –

+0

@ m.rogalski我忽略玩家的碰撞在这里:'int layerMask = 1 << 9; layerMask =〜layerMask;'。我可以击中对象。但是当我想第二次击中它时,我不需要按下按钮,我可以看到对象 – dima

回答

1

好了,所以基本上你设置你ActionNumber到(比方说)1,它停留在此值。

要解决这个问题,您需要设置该值的基于时间的重置或者在Update(或LateUpdate)中始终使用Raycast
另一种方法是利用event driven programming principles,只要符合条件就启动事件,并忘记设置一些值。

制作它很简单:

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

现在创建MeEventArgs

public class MeEventArgs : EventArgs 
{ 
    public readonly int Action; 

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

而且在代码中使用:

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

“好的,所以基本上你的设置是ActionNumber(假设)1,它保持在这个值直到你点击另一个对象“。不完全是。我把这个脚本放在每个对象上,我将来会打这个脚本。所以我可以按对象A,然后按对象B,然后我不需要按对象A,只需要看它就可以了,但是,谢谢,我会试试 – dima

+0

@dima是的。我正是这个意思。谢谢你指出我的错误:) –