- Home /
Scripting Help
I made a script that uses Raycasting. When the players raycast hits a door or a drawer tagged "Open" the player is able to press 'E' and an opening or closing animation would play. The problem is that this works for only one door/drawer. Is their anyway to fix this?
{
public float distance;
public GameObject raycastObject;
public GameObject OpenPanel1;
public GameObject OpenPanel2;
private bool Seen;
public Animator animator;
// Use this for initialization
void Start () {
OpenPanel1.SetActive(false);
OpenPanel2.SetActive(false);
}
private bool IsOpenPanel1Active
{
get
{
return OpenPanel1.activeInHierarchy;
}
}
private bool IsOpenPanel2Active
{
get
{
return OpenPanel2.activeInHierarchy;
}
}
// Update is called once per frame
void Update () {
RaycastHit hit;
Vector3 fwd = raycastObject.transform.TransformDirection(Vector3.forward);
Debug.DrawRay(raycastObject.transform.position, fwd * 50, Color.green);
if (Physics.Raycast(raycastObject.transform.position, fwd, out hit, distance))
{
if (hit.collider.gameObject.tag == "Key")
{
Debug.Log("Visible");
}
if (hit.collider.gameObject.tag == "Open")
{
Debug.Log("Door");
OpenPanel1.SetActive(true);
Seen = true;
}
}
if(IsOpenPanel1Active && Seen == true)
{
if (Input.GetKeyDown(KeyCode.E))
{
OpenPanel1.SetActive(false);
animator.SetBool("open", true);
OpenPanel2.SetActive(true);
}
}
if(IsOpenPanel2Active && Seen == true)
{
if (Input.GetKeyDown(KeyCode.E))
{
OpenPanel2.SetActive(false);
animator.SetBool("open", false);
OpenPanel1.SetActive(true);
}
}
}
}
Answer by oStaiko · Apr 21, 2018 at 12:39 AM
Few bits of advice first: Dont store your raycast as a GameObject, but as a Transform. You can just write "public Transform raycastTransform" and instead of writing "raycastGameObject.transform" 4 times, you can just write "raycastTransform". Second, its never recommended to use tags, I'm pretty sure they only exist for prototyping/debugging, but the ideal case is to have scripts on the object you're tagging that you can detect with GetComponent(). If you stick with tags, you wont be able to have an object that is both a key and a door. It may sound weird now, but if you want some objects to be burnable so to say, you wont be able to have doors on fire. Third, c#, you don't need to write (Seen == true), you can just write (Seen) and (!Seen). It is also good practice to follow common naming conventions, where variables start with lowercase, and methods start in uppercase.
As for problems in the logic of your code, starting on line 56, when the if statement passes, you enable panel 1. Skip to line 65, and now no matter what panel 2 was before this, 65 will pass and then disable panel 2, and enable panel 1, though we just disabled it. More importantly, it also sets the animation back to off. So in short, whenever you start the animation, you turn it off the very same frame. To make it work you need else and else if statements.
To fix:
{
[Header("References")]
public Transform raycastTransform;
public GameObject openPanel1;
public GameObject openPanel2;
public Animator animator;
[Header("Values")]
public float distance;
private bool seen;
private bool isOpenPanel1Active
{
get
{
return openPanel1.activeInHierarchy;
}
}
private bool isOpenPanel2Active
{
get
{
return openPanel2.activeInHierarchy;
}
}
void Start ()
{
openPanel1.SetActive(false);
openPanel2.SetActive(false);
}
void Update ()
{
RaycastHit hit;
Vector3 fwd = raycastTransform.TransformDirection(Vector3.forward);
Debug.DrawRay(raycastTransform.position, fwd*distance, Color.green);
if (Physics.Raycast(raycastTransform.position, fwd, out hit, distance))
{
// KeyScript ks = hit.collider.GetComponent<KeyScript>();
// DoorScript ds = hit.collider.GetComponent<DoorScript>();
if (hit.collider.gameObject.tag=="Key") // if (ks) {}
{
Debug.Log("Visible");
}
else if (hit.collider.gameObject.tag=="Open") // else if (ds) {}
{
Debug.Log("Door");
openPanel1.SetActive(true);
seen = true;
}
else
seen = false;
}
else
seen = false;
if (Input.GetKeyDown(KeyCode.E) && seen)
{
if (isOpenPanel1Active)
{
openPanel1.SetActive(false);
animator.SetBool("open", true);
openPanel2.SetActive(true);
}
else if (isOpenPanel2Active)
{
openPanel2.SetActive(false);
animator.SetBool("open", false);
openPanel1.SetActive(true);
}
}
}
}