C# Closing a Box on Distance Away.

Hi guys,

Trying to make my loot source change state to “close”, if you walk a certain distance. It already removes the GUI from display; just would also like it to close too; however would have to call it from another script… having problem with GetComponent due to the syntax:

The Loot GUI:

	public float Loot_Window_Height = 90;
	public float ButtonWidth = 40;
	public float ButtonHeight = 40;
	
	private List<Item> LootItems;
	private float Offset = 10;
	private const int Loot_Window_ID = 0;
	private Rect Loot_Window_Rect = new Rect(0,0,0,0);
	private Vector2 Loot_Window_Slider = Vector2.zero;
	public bool DisplayLootWindow = false;
	public GameObject LootSource;
	
	void Start()
	{
		LootItems = new List<Item>();
		DisplayLootWindow = false;
	}
	
	public void OnEnable()	
	{
		Messenger<int>.AddListener("PopulateChest", PopulateChest);	
		Messenger.AddListener("Close Loot Source", ClearWindow);
	}
	
		public void OnDisable()	
	{
		Messenger<int>.RemoveListener("PopulateChest", PopulateChest);
		Messenger.RemoveListener("Close Loot Source", ClearWindow);
	}

	void Update()
	{			
		LootAbility CheckScript;
		CheckScript = LootSource.GetComponent<LootAbility>();
		DisplayLootWindow = CheckScript.Check();
	}

	void OnGUI()
	{	
		if (DisplayLootWindow)					// How far from the top of the screen  // Height of the GUI window   // Width of the GUI 
		Loot_Window_Rect = GUI.Window(Loot_Window_ID, new Rect(Offset, Screen.height - (Offset + Loot_Window_Height), 300 - (Offset * 2),
		Loot_Window_Height), LootWindow, "Loot Window");
		// X, Y, Z location of screen co-ords for window	
	}
			
	private void LootWindow(int id)
	{					
		// SLIDER INFO - Space from the left, from the top, how wide etc...
		Loot_Window_Slider = GUI.BeginScrollView(new Rect(Offset *.5f , 15, Loot_Window_Rect.width - 10, 70), Loot_Window_Slider,
			new Rect(0, 0, (LootItems.Count * ButtonWidth) + Offset, ButtonHeight + Offset));
			
						   //this makes it a complete horizontal scroll i.e. decides its navigation type
		
		//Displays The Items	
		for(int cnt = 0; cnt < LootItems.Count; cnt++)
		{	
							   //Buttonsize consistent, Button Distance from Top, Output Number according to the iteration i.e. 1st iteration will name Button1, 2nd Button2 etc 
			GUI.Button(new Rect(5 + (ButtonWidth * cnt), Offset, ButtonWidth, ButtonHeight), cnt.ToString());
		}
		
		GUI.EndScrollView();
	}
	
	private void PopulateChest(int x)
	{	
		ClearWindow();
		for(int cnt = 0; cnt < x; cnt++)
			LootItems.Add(new Item());
		
		DisplayLootWindow = true;
	}
	
	private void ClearWindow()
	{	
		DisplayLootWindow = false;
		LootItems.Clear();
	}
}

The Loot Source:

using UnityEngine;
using System.Collections;

[RequireComponent (typeof(BoxCollider))]	
[RequireComponent (typeof(AudioSource))]	// Remember to add an AUDIO SOURCE to objects requiring audio
public class LootAbility : MonoBehaviour { // Named Loot rather then "chest" so it can be used throughout the entire game and in multiple scenarios.
public bool StateChecker;
	
	public enum State // State Types
	{
		Open,
		Close,
		Inbetween
	}
	public AudioClip OpenSound; // Make Several of these to call different sounds for different 3D objects. i.e. drawers/chests et
	public AudioClip CloseSound;
	
	public GameObject ParticleEmit;
	public State CurrentState; // Current State Referes to State within my Methods.
	public float MaxLootDistance = 3; // Max Distance to Loot from Interacted Objects
	
	public GameObject Player;
	private Transform PlayerTransform;
	
	
	void Start () 
	{	
		PlayerTransform = transform;
		
		CurrentState = LootAbility.State.Close;
		
		ParticleEmit.active = false;
		
		Player = GameObject.FindWithTag("Player");
	}
	
	void Update()
	{
		if (Vector3.Distance(transform.position, Player.transform.position) > MaxLootDistance)
			Messenger.Broadcast("Close Loot Source");
	
		if (Vector3.Distance(transform.position, Player.transform.position) <MaxLootDistance)
		Debug.Log ("Close Enough To Loot!");

		if (Input.GetButton("Cancel Button")) // Custom Action Button Called - Input Manager B, easier this way to convert to Xbox 360 Controller
	
		switch(CurrentState) 
		{
		case State.Open:
			CurrentState = LootAbility.State.Inbetween;
			StartCoroutine("Close");
			StateChecker = false;
			
		break;
		}
		
		if (Input.GetButton("Interact Button"))
			
		switch(CurrentState)
		{
		case State.Close:
			CurrentState = LootAbility.State.Inbetween;
			StartCoroutine("Open");
			StateChecker = true;
			break;
		}
		
		if(CurrentState == LootAbility.State.Close) // == is a comparison not an assignment
			Open();
		else
			Close();
	}
	
	private IEnumerator Open() // Coroutines have to be called by a IEnumerator rather then a standard void method
	{	
		Messenger<int>.Broadcast("PopulateChest", 5, MessengerMode.DONT_REQUIRE_LISTENER);
		
		animation.Play("Open");
		ParticleEmit.active = true;
		audio.PlayOneShot(OpenSound);
		yield return new WaitForSeconds(animation["Open"].length);
		
		CurrentState = LootAbility.State.Open;
	}
	
	private IEnumerator Close()
	{	
		animation.Play("Close");
		ParticleEmit.active = false;
		audio.PlayOneShot(CloseSound);
		yield return new WaitForSeconds(animation["Close"].length);
		
		CurrentState = LootAbility.State.Close;
	}
	
	public bool Check(){
		if(StateChecker)
			return true;
		else
			return false;
	}
}

Bump

I dont quite get what you are saying but wouldnt a sphere trigger be helpful?
Like if you leave the trigger the box closes.

Yeh,

if you can explain how to do this :stuck_out_tongue: then sure.

Put a sphere collider on your box object and check the ‘isTrigger’ on the collider.
And resize it as you want.

In the box script you use

You would most likly want to check if the gameObject that left is is your player.

in LootAbility.check()

use

public bool Check()
{
	if(StateChecker)
	{
		if( Vector3.Distance( PlayerTransform.position, transform.position) > 10 )
		{
			Close();
			return false;
		}
		else
		{

            return true;
		}
	}
    else
	{
       return false;
    }
}

Where 10 would be the distance away you want it to close.