- Home /
Private and public variables
Hey guys,
I have script that checks if you are near a door and if you are within a certain range, the script returns the variable 'InRange' true. This variable is a public variable in this script. Then I have another script that opens the door when you pressed E and 'InRange is true'. Now the problem is, if I have multiple doors in my scene and I am near door 1, InRange is returned true, but because I use this variable for every door, also door 2 and 3 think that I am near them while this is not true. So when I press 'E', all the doors open at once. How can I make it so that only the door I am really InRange of opens. So like how can I make a variable that has one name, but has a different values on the different doors (with each assigned an individual script to them) Thank you so so much!
This is the code for checking if you are near the door:
//INSPECTOR SETTINGS
public float Range = 5; // Within this radius the player is able to open/close the door.
public bool InRange;
//DEBUGGING
public Color DebugRayColor = Color.red;
//START
void Start()
{
}
//UPDATE
void Update()
{
InRange = false;
Ray ray = Camera.main.ViewportPointToRay (new Vector3 (0.5F, 0.5F, 0F)); // Set origin of ray to center of screen and direction of ray to cameraview.
RaycastHit hit; // Variable reading information about the hit.
if(Physics.Raycast (ray, out hit, Range)) // Casts a ray from the center of screen towards where the player is looking.
{
if(hit.collider.tag == "Door") // Change the tag you use for your doors here.
{
InRange = true;
}
}
this is the code for rotating the door:
//UPDATE
void Update ()
{
//Access InRange variable from raycasting script
GameObject Player = GameObject.Find("Player");
RayCasting raycasting = Player.GetComponent<RayCasting>();
if (raycasting.InRange == true) {
InRange = true;
}
else InRange = false;
//DEBUGGING
//print (InRange);
if (Input.GetKey(KeyCode.E) && InRange == true) {
Openable = true;
}
if (Openable)
{
//Rotate();
}
}
}
Please, provide some code. It will be much easier to help you and tell you what's wrong.
Answer by Hellium · Jun 26, 2015 at 01:22 PM
Your code seems to be a very big mess ...
A big part of the logic should be in the player, and only in the player :
void Update()
{
if (Input.GetKeyUp(KeyCode.E) )
{
Ray ray = Camera.main.ViewportPointToRay (new Vector3 (0.5F, 0.5F, 0F)); // Set origin of ray to center of screen and direction of ray to cameraview.
RaycastHit hit; // Variable reading information about the hit.
if(Physics.Raycast (ray, out hit, Range) && hit.collider.tag == "Door") // Casts a ray from the center of screen towards where the player is looking.
{
Door door = hit.GameObject.GetComponent<Door>().Open() ;
}
}
}
Then, in the script attached to your doors, define a function called Open() to rotate the door.
+1
- I find this as the best approach. Even better than $$anonymous$$e.
Cool I'll take a look at it when I have some more time, thank you both!!
I didn't test this yet, but if I have $$anonymous$$ultiple doors in the game level and they all have the tag door, won't this open all of the doors? Or does it only count for the door that is hit because of this line of code:
Door door = hit.GameObject.GetComponent<Door>().Open() ;
@alexanderameye it works. But remember, you have to have a script on all of your doors named Door
and a public void Open() {//Rotate function}
inside of it.
Yes, the fonction I wrote you in the player script and an Open() function in the script attached to each individual door.
If the open function is defined in another script, just call the function of that script in the Open function of the Door script
Answer by Wolfdog · Jun 26, 2015 at 01:33 PM
This is how I would do it. I wouldn't use rays, but trigger colliders.
// Assuming this is the player script
//UPDATE
void Update()
{
// nothing needs to be done here.
// just remember to have a trigger collider on your player with a radius of 5
// and also have a rigidbody either on the player or on all of the doors
}
void OnTriggerEnter (Collider c) {
if (c.transform.tag == "Door") {
c.transform.GetComponent <YourDoorScriptHere> ().inRange ();
}
}
void OnTriggerExit (Collider c) {
if (c.transform.tag == "Door") {
c.transform.GetComponent <YourDoorScriptHere> ().outOfRange ();
}
}
// Assuming this is the door script
//UPDATE
private bool Openable = false;
void Update ()
{
if (Input.GetKey(KeyCode.E) && Openable) {
Rotate(); // open door script
}
}
public void inRange () {
Openable = true;
}
public void outOfRange () {
Openable = false;
}
(this is untested. Leave a comment if any problems arise)
This approach is better than using rays, because it isn't as CPU intensive as casting rays every frame.
It's even less CPU intensive to draw a ray only when the player has pressed the action key.
Your answer
Follow this Question
Related Questions
Static Variable Problem 1 Answer
Sharing booleans between 2 scripts 1 Answer
Starting point for leaving each scene? 1 Answer
Open and close doors by pressing 'E' 2 Answers