- Home /
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);
Answer by Harinezumi · Jun 29, 2018 at 07:45 AM
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! :)
man! you are a lifesaver! : D works like a charm! Thank you very very much! I went with the middle script because I'm using it for a really simple project with only doors for now. But thanks a lot for all the effort!
Answer by Hellium · Jun 29, 2018 at 07:45 AM
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<Animator>();
if( animator != null )
{
animator.SetBool("IsOpen", true);
}
}
}
}
Your answer
Follow this Question
Related Questions
I'm trying to allow my character to only jump when grounded 1 Answer
Storing gameObjects in an array and essentially printing them? 1 Answer
Problems with Gyroscope VR Car Game 0 Answers
How to shoot with a raycast? 2 Answers
Unity 3D: How to make the gameobject speed increase continuously on tapping quickly? 1 Answer