I’m trying to make a Door Script and this is what I’ve made up so far.
var toggleGUI : boolean;
var doorOpen : boolean;
var myStyle : GUIStyle;
var door : GameObject;
function Start ()
{
door = GameObject.Find("Cell1_D");
}
function OnTriggerEnter (other : Collider)
{
toggleGUI = true;
}
function OnTriggerExit (other : Collider)
{
toggleGUI = false;
}
function Update ()
{
if(toggleGUI)
{
if(Input.GetButtonDown("Action"))
{
if(!doorOpen)
{
door.animation.Play("DoorOpen");
doorOpen = true;
}
if(doorOpen)
{
door.animation.Play("DoorClose");
doorOpen = false;
}
}
}
}
function OnGUI ()
{
if(doorOpen)
if (toggleGUI)
GUI.Label (Rect (Screen.width/2-50, Screen.height/2-25, 50, 10), "Press Action to Close", myStyle);
if(!doorOpen)
if (toggleGUI)
GUI.Label (Rect (Screen.width/2-50, Screen.height/2-25, 50, 10), "Press Action to Open", myStyle);
}
But when the Door is closed, and pressed Action to open it opens. But as the script when Action is pressed again the door should play the close Animation instead it plays the Open animation again. And the Door Open doesn’t get marked(ticked).
Easy mistake to make there. =)
You need to use ‘if’ and ‘else if’ there, instead of just two if statements. Like this:
var toggleGUI : boolean;
var doorOpen : boolean;
var myStyle : GUIStyle;
var door : GameObject;
function Start ()
{
door = GameObject.Find("Cell1_D");
}
function OnTriggerEnter (other : Collider)
{
toggleGUI = true;
}
function OnTriggerExit (other : Collider)
{
toggleGUI = false;
}
function Update ()
{
if(toggleGUI)
{
if(Input.GetKeyDown("f"))
{
if(!doorOpen)
{
door.animation.Play("DoorOpen");
doorOpen = true;
}
else if(doorOpen)
{
door.animation.Play("DoorClose");
doorOpen = false;
}
}
}
}
function OnGUI ()
{
if(doorOpen)
{
if (toggleGUI)
{
GUI.Label (Rect (Screen.width/2-50, Screen.height/2-25, 50, 10), "Press Action to Close", myStyle);
}
}
if(!doorOpen)
{
if (toggleGUI)
{
GUI.Label (Rect (Screen.width/2-50, Screen.height/2-25, 50, 10), "Press Action to Open", myStyle);
}
}
}
You were missing a few brackets in the OnGui function in the example you posted, but if it compiled I assume it was just an error in copying it over to the forum. I wrote those in as well though.
You can write a script that gets all gameobjects, looks for ones named “door” (for instance) and then adds a script to them. See below for C# example. Put that script on any game object in the scene (just one!) and it will go through and find all objects named lowercase “door” and add your door script to it. Replace “YourDoorScript” with the name of your Javascript class (filename).
Usually I find that is not quite as useful as one might imagine in advance, as you immediately find that there are custom settings needed for each door. But for a simple generic flop-open script like this it might work.
using UnityEngine;
using System.Collections;
public class AddDoorOpenersToEverything : MonoBehaviour
{
void Start ()
{
Transform[] everything = FindObjectsOfType<Transform>();
foreach ( Transform tr in everything)
{
if (tr.name.ToLower() == "door")
{
tr.gameObject.AddComponent<YourDoorScript>();
}
}
}
}
If you really didn’t want a script on your doors and all they ever did was play the open or close animation, you could write a single script on your player that checks the door’s current animation state and changes it that way. So if the door your checking is currently in the open animation, switch it to the closed animation.
Depending on how you handle animations you can achieve an acceptable result this way.
@SteveJ :That’s how I’m currently doing it. I guess it takes up more memory to hold the script for every door (I guess), that’s why I’m looking for some other way.
@Kurt-Dekker : I’m sure I’ll use it if I didn’t find some other way. Btw, instead of name, tag can be used right?
@Barachiel : Yeah I’m thinking of something like that. Using Raycast to detect if facing at a Door. If it is and display the GUI and when pressed Action door opens… But I’m not familiar with Raycast, how can I do it?
You’d want a ray that uses hit info so you can tell if the object you hit has the door tag. The second example in the docs looks like the sort of thing you’d want to do.
As far as scripts on all your doors, so long as they aren’t using Update at all (and you aren’t calling any functions in the script too frequently) the performance hit shouldn’t be noticeable. Just have a function in the script that does the opening and closing, then when you use a ray or trigger to interact with the door, have a script on your player send it a message telling it to run that script.
You could even do something more generic, like this:
function Interact()
{
var hit : RaycastHit;
if(Input.GetKeyDown("f"))
{
if (Physics.Raycast (transform.position, Vector3.forward, hit, 5))
{
hit.transform.gameObject.SendMessage("Interacting", SendMessageOptions.DontRequireReceiver);
}
}
}
This means that if you press ‘f’ then you send out a raycast 5 units forward. It sends the message ‘Interacting’ to whatever it hits. On your door script, just have a function called ‘Interacting’ and put what you want to in there.
If the ray hits the door, the door gets the message and runs ‘Interacting’.
This also means that you could have a button somewhere, and on a script on the button you could have an ‘Interacting’ function and have it do something else. Maybe turn lights on or off or maybe use it to unlock the door or something. If the ray hits the button, the message is sent and you interact with it appropriately.
In this script the Ray only cast when pressed a Button right? How to make the Ray keep casting from beginning so that when player is looking at a Door or other Interactive objects the Gui appears, so no need of Trigger and stuff. Can I do it if this is put under function Update? And add a interact function to all Interactive object so when their function is called they do whatever the object does.
And the Ray cast towards the center of the screen right? So I add a Crosshair in the center of screen.
What about the GUI display thing? I can’t get it right, where should that part go in?
Edit: Another problem. In the first script. How to know what the Player is looking at? Door, switch, etc. ? So the respective GUI can be displayed, if its a Door “Press action to open Door”, if switch “Press action to use Switch” etc.
Edit2 : I tried what you mentioned, and attached this script to Door. But doesnt work. Tried without “gameObject” too.
function Interacting()
{
gameObject.animation.Play("DoorOpen");
}