setting a bool on another object's animator by player's raycast

So I’m really not a programmer… I went through some tutorials to make a door open and close on a playerraycast (interaction). This door object has an animator and should open and close with animations that are made in Blender with a rig and stuff. but I don’t know how to set the bool if the door is open or closed… this is what I got:

public float distanceToSee;
RaycastHit whatIHit;
public GameObject player;

void Start () {
	player = GameObject.FindWithTag ("Player");
}

void Update () 
{
	Debug.DrawRay (this.transform.position, this.transform.forward * distanceToSee, Color.magenta);

	if (Physics.Raycast (this.transform.position, this.transform.forward, out whatIHit, distanceToSee)) 
	{
		if (Input.GetKeyDown (KeyCode.E)) 
		{
			if (whatIHit.collider.tag == "Door")
			{ 
				//this is where the magic should happen
				}
			}
		}
	}
}

and it should have somehing like this?:

animator.SetBool (“IsOpen”, true);

You can get components from other GameObjects or even component like Collider using GetComponent() function. With this you can get the Animator or a specific script that you create for doors (or if you want to be more general, interactable objects).

So the simpler solution is:

Animator animator = whatIHit.collider.GetComponent<Animator>();
if (animator != null) { // if the hit object has an Animator...
    animator.SetBool("name of animator variable", true); // the second parameter tells you what state it should change
}

A somewhat better solution is to create a class for the door, which will store the internal state of the door and handle the use of the Animator. This will also make sure that you use the correct animator variables with the correct object types:

// add this component to the game object that has the door's collider
public class Door : MonoBehaviour {

    private Animator animator;

    private bool isOpen = false;

    private void Awake () {
        animator = GetComponent<Animator>();
        animator.SetBool("name of animator variable to control door", isOpen);
    }

    public void ToggleDoor () {
        isOpen = !isOpen;
        animator.SetBool("name of animator variable to control door", isOpen);
    }

}

And you use it like this:

Door door = whatIHit.collider.GetComponent<Door>();
if (door != null) { door.ToggleDoor(); }

Finally, you can create an interface, a kind of template, for all objects that you will be able to interact. By implementing an interface (which looks the same as sub-classing) you promise that this class has the functions the interface has. This way, you won’t need to know what is the type of object you hit and try to interact with, you just do:

public interface Interactable {
    void Interact();
}

public class Door : MonoBehaviour, Interactable { // you also implement the Interactable interface
// everything the same as before, but you change ToggleDoor() to Interact()

public class Lever : MonoBehaviour, Interactable { // this would be a new class, a lever that you can pull, and it animates it and does stuff...

And you use it like this:

Interactable interactable = whatIHit.collider.GetComponent<Interactable>();
if (interactable != null) { interactable.Interact(); } // you don't need to care anymore what the exact type is, you just know you can interact with it, because it implements the Interactable interface

There are a lot of small other things you could do to make this design as flexible and clean as possible, but I think this is already too much information. Good luck! :slight_smile:

void Update ()
{
Debug.DrawRay (this.transform.position, this.transform.forward * distanceToSee, Color.magenta);
if ( Input.GetKeyDown (KeyCode.E) && Physics.Raycast (this.transform.position, this.transform.forward, out whatIHit, distanceToSee))
{
if ( whatIHit.collider.CompareTag( “Door” ) )
{
Animator animator = whatIHit.collider.GetComponent();
if( animator != null )
{
animator.SetBool(“IsOpen”, true);
}
}
}
}