There are a couple of scripts that I will need to enable the props and the Player to be able to work together in the correct manner. these are the scripts that I will need to make my game work:
Interaction(with the in-scene objects)
Interactive Grabbable Object(for the objects that can be interacted with)
Interactive Object(not to be attached to the objects but triggers an action)
Lever Script(to make the lever work)
Scripts to make the door and key work together
Disabling of Key collider
Interaction:-
This script will be mainly used to help the player pick up items in-game, but it also contains the code that will trigger the script for the lever to run if E is pressed within the range of the lever. It uses a Raycast that senses when it comes into contact with an object's collider when in a specific range of it.

The script also allows the Player to drop items using G, and the items will return to their original state of either floating or being on the ground; my idea behind letting the player interact with other objects is that they will be able to move objects that are in the way of solving the puzzle if they wish to.


I came across one major issue that is inhibiting me from being able to finish the scene correctly. The script won't register that the Key is being picked up with the use of a Bool. The hasKey Bool just wouldn't turn true when I picked up the Key in-game, so I had to figure out what the issue was. I tested this by putting the leverPressed Bool within the code that allows the Key to be picked up. When I picked the Key up in-game the Key was treated as if it was the Lever, everything around the Key fell down to the ground, which is what is meant to happen when you press on the Lever. I did some debugging and found that somewhere the Bool was being told to default back to false, so it was turning true, but only temporarily. This is a big issue because it means that I will not be able to make the Door and Key work together if I can't tell the scripts that the Player has picked up the Key.
I did find a way to make the Bool turn true, but I figured out after some testing that the Bool will only turn true on the Interaction script that is attached to the Key and not globally. I need the Bool to be globally true when the Key is picked up to make it work.

Interactive Grabbable Object:-
This script is attached to all the game objects that can be interacted with and it tells the objects what to do when they are interacted with, when objects that can be picked up are picked up the collider that the object has will be disabled so that the object doesn't collide with anything whilst being held; it will also become kinematic which means that collisions between the held object will be registered but nothing will happen further than that.

When the object has been dropped the states of the collider and kinematics will return back to normal.

Also, when the Lever is pressed everything with this script and a Rigidbody will become affected by gravity again, meaning that they will fall to the ground, the Key included. I have left in some scripting that I demoed to see if it would work so you can see my thought process and testing.

Interactive Object:-
This script contains two methods that are defined as globally accessible and they allow me to use the two methods in other scripts and define what it is they do depending on what the other scripts are needed for. This script will never be attached to anything in-game.

Lever Script:-
I will define this script in greater detail when I explain how the puzzle works, but this script checks to see if there was an interaction with the lever by using the Interaction script and if there was an interaction the animation I made for the lever will play. This script's purpose is solely to make the lever animation trigger. when the Lever is pressed the Debug Log will tell me so that I know the code is doing what it is meant to do.

This script is constantly checking to see if the Lever has been pressed and when the lever has been pressed the handle will move down, that is because this bit of script is telling the lever to play the animation that shows the Lever's handle coming down.

Scripts to make the Door and Key work together:-
The intention of this script was to used the Interaction script to check to see if the player has hold of the key, and then, if the player has the key and presses E on the door with the key in possession they would be able to escape. The only issue is that I came across an issue with the Interaction script that I couldn't figure out how to fix. Within the Interaction script, I made a Public Bool that would turn true if the player pressed E within range of the key; for some reason, this Bool just didn't want to work in the slightest. This failed miserably. I've chosen to leave still talk about this script as I would like to demonstrate my attempt at getting it to work.

Disabling of Key collider:-
In my scene, there is a collider that stops the player from being able to jump and pick up the Key, I did it this way because I wanted to force the player to actually figure out what they have to do- meaning I want them to find the lever and pull it down. This script is attached to the collider which stops the Key from being accessed and is only attached to that.

The script checks to see if the Lever is pressed then if it is, the collider component will be destroyed.
Interaction
public class Interaction : MonoBehaviour
{
/*The objects that have the abilty to be interacted with will have one of Layers attached to them
and depending on what layer they sit in depends on what the script will make the object do when interacted with*/
public LayerMask CarboardBoxmask;
public LayerMask KeyMask;
public LayerMask LeverMask;
public GameObject grabPosition;
public static GameObject grabbedObject = null;
//This is used to check what has been pressed
public bool leverPressed = false;
public bool hasKey;
public LeverScript leverScriptInstance;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
/*If E is press within the range of the objects within the Layer masks e.g the carboard boxes
the script will either move the object to the grabbed position
or will it will trigger another action*/
if (this.gameObject.tag == "Key" && this.transform.IsChildOf(grabPosition.transform))
{
hasKey = true;
}
if (Input.GetKeyDown(KeyCode.E))
{
{
RaycastHit hit;
if (Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hit, 2f, CarboardBoxmask))
{
Debug.Log("picked up");
if (hit.collider.GetComponent<InteractiveObject>() != null)
{
hit.collider.GetComponent<InteractiveObject>().OnStartInteraction();
}
}
if (Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hit, 2f, LeverMask))
{
Debug.Log("Lever pulled");
if (hit.collider.GetComponent<InteractiveObject>() != null)
{
hit.collider.GetComponent<InteractiveObject>().OnStartInteraction();
leverPressed = true; //This bool is used to tell the scipt that the lever has been pressed and it can also be used by other scripts to call functions if it is true.
}
}
if (Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hit, 2f, KeyMask))
{
//Debug.Log("Key Picked up");
if (hit.collider.GetComponent<InteractiveObject>() != null)
{
hit.collider.GetComponent<InteractiveObject>().OnStartInteraction();
}
}
}
}
/*When G is pressed while in posession of an onject the object that is grabbed will drop and go back to it's original state*/
else if (Input.GetKeyDown(KeyCode.G))
{
if (grabbedObject != null)
{
grabbedObject.transform.parent = null;
grabbedObject.GetComponent<InteractiveObject>().OnEndInteraction();
grabbedObject = null;
}
}
/*When the Player drops the item by pressing G this tells the game object that was picked up to leave the grabbed object state.*/
if (grabbedObject != null)
{
grabbedObject.transform.parent = grabPosition.transform;
grabbedObject.transform.position = Vector3.Lerp(grabbedObject.transform.position, grabPosition.transform.position, Time.deltaTime * 10f);
grabbedObject.transform.rotation = Quaternion.Slerp(grabbedObject.transform.rotation, grabPosition.transform.rotation, Time.deltaTime * 10f);
}
}
}
Interactive Grabbable Object
public class InteractiveGrabbableObject : InteractiveObject
{
public GameObject lever;
public Rigidbody rb;
public Collider coll;
public LeverScript leverScriptInstance;
public Interaction interactionInstance;
public override void OnStartInteraction()
{
Debug.Log(gameObject.name);
if (Interaction.grabbedObject == null)
{
Interaction.grabbedObject = gameObject;
GetComponent<Collider>().enabled = false;
GetComponent<Rigidbody>().isKinematic = true;
}
}
public override void OnEndInteraction()
{
GetComponent<Collider>().enabled = true;
GetComponent<Rigidbody>().isKinematic = false;
}
/*check lever script if a bool is true and if true lever is pressed come down*/
public void Update()
{
if (interactionInstance.GetComponent<Interaction>().leverPressed != false)
{
this.rb.useGravity = true;
}
/*if (leverScriptInstance.GetComponent<LeverScript>().isLeverPulled != false) //This just wouldn't work no matter what I tried.
{
//this.rb.useGravity = true;
}*/
}
}
Interactive Object
public class InteractiveObject : MonoBehaviour
{
// Start is called before the first frame update
public virtual void OnStartInteraction()
{
}
// Update is called once per frame
public virtual void OnEndInteraction()
{
}
}
Lever Script
public class LeverScript : InteractiveObject
{
public Animator anim; //Reference to the animator
public Interaction interactionInstance;
public bool isLeverPulled = false;
public override void OnStartInteraction()
{
Debug.Log(gameObject.name);
}
public void Update()
{
if (interactionInstance.GetComponent<Interaction>().leverPressed != false)
{
/*//Debug.Log("The Lever is pressed");
anim.SetBool("isPulled", true);
anim.SetTrigger("pullDown");*/
this.gameObject.GetComponent<Animator>().Play("Lever trigger");
isLeverPulled = true;
}
}
}
Scripts to make the door and key work together
public class InteractiveKey : InteractiveObject
{
public Interaction interactionInstance;
public bool hasKey = true;
public override void OnStartInteraction()
{
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
public class InteractiveDoor : InteractiveObject
{
//public Animator anim;
public LayerMask DoorMask;
public InteractiveKey interactiveKeyInstance;
private void Start()
{
}
public override void OnStartInteraction()
{
if (interactiveKeyInstance.GetComponent<Interaction>().hasKey != false)
{
RaycastHit hit;
if (Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hit, 2f, DoorMask))
{
Debug.Log("Door Open");
}
}
}
}
Disabling of Key collider
public class DisableKeyCollider : MonoBehaviour
{
public Interaction interactionInstance;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (interactionInstance.GetComponent<Interaction>().leverPressed != false)
{
DestroyComponent();
}
}
void DestroyComponent()
{
// Removes the rigidbody from the game object
Destroy(GetComponent<BoxCollider>());
}
}
Comments