Booleans problem

I’m using C#

I’m making a game there you can jump into objects and controll them. And I use booleans to make the game to switch controlls between the player and objects (if soulcontroll = true, you can controll the player).
I made it before with another objects, and it works perfectly!
but now when I’m trying to fix it to another objects, it won’t turn soul controll to false =S

here is the code for the trigger that decides if you can jump into the object:

using UnityEngine;
using System.Collections;

public class walltrigger : MonoBehaviour {
	
public Transform player;
public Transform SPwall;
public playersoulscript playersoul;
public bool NexttoWall;


// Use this for initialization
void Start () {

}

// Update is called once per frame
void Update () {
	
	if(NexttoWall == true)
	{
		
	playersoul.soulcontroll = false;
	player.transform.parent = SPwall.transform;
		
		
		if(Input.GetKeyDown("r"))
		{
		
			
			NexttoWall = false;
			playersoul.soulcontroll = true;
			player.transform.parent = null;
			
		}
		
		
		
	}
	
	
	

}


void OnTriggerStay(Collider other)
{
	
print("knock knock");
	
	if(Input.GetKeyDown("e"))
	{
		
		NexttoWall = true;
		
	}
	
	
}

}

and here is the code for the object I will controll:

using UnityEngine;
using System.Collections;

public class wallscript : MonoBehaviour {
	
float wallspeed = 5;
public walltrigger Wtrigg;
public playersoulscript playersoul;

// Use this for initialization
void Start () {

}

// Update is called once per frame
void Update () {
	
	if(Wtrigg.NexttoWall == true)
	{
	
	playersoul.soulcontroll = false;	
	float WmoveV = Input.GetAxis("Vertical") * wallspeed * Time.deltaTime;
	transform.Translate(Vector3.forward * WmoveV);	
		
		
	}
	
	
	if(Wtrigg.NexttoWall == false)
	{
		
	playersoul.soulcontroll = true;	
		
	}
	
	
	

}

}

The way I would do this would be to have all of the objects which can be inhabited share a common interface, so that you can refer to lots of different kinds of behaviour all in the same slot!

As you know, when you declare a ‘Vector3’ in your script, it is equivalent to making a Vector3-shaped imprint in your memory, that the program knows how to manipulate. What actually goes in there has to be a Vector3, but can be any Vector3 you like. The program knows that it can use methods like ‘Scale’, ‘Normalize’, ‘sqrMagnitude’ and so on, because you have told it exactly what kind of object it will be.

Now, the problem with this is- if you want to have lots of different kinds of objects that can fit into the same hole (for example, lots of different objects that the player can manipulate with the same inputs), you can only declare the variable for one type at a time (unless you use dynamic typing like JavaScript does, but let’s not go there, it’s terribly messy).

This is where interfaces come in.

While a class can only inherit directly from one parent class, it can also agree to conform to any number of ‘interfaces’ - simply, the class says that while it may have more than just these, it will definitely have some set of functions which can be called in a way that conforms to the interface.

This allows you to make a ‘hole’ shaped like the interface, and have lots of different classes (as long as they conform to the interface) fit into it!

You declare an interface like this-

public interface Inhabitable {
    void PlayerEnters();
    void PlayerLeaves();
    void UpdateInhabited(float deltaTime);
}

Each line inside the interface defines a method that each class that conforms to it must implement in some way- in this case, anything that implements ‘Inhabitable’ must have at least-

public void PlayerEnters() {

}
public void PlayerLeaves() {

}
public void UpdateInhabited(float deltaTime) {

}

You can do whatever you like inside these methods- as long as the return type and the parameters are the same it’s all fair game.

To use one of these interfaces in a Unity class, it must be declared after the class name-

public class HauntedBox : MonoBehaviour, Inhabitable
{
    // the rest of the class (must contain at least the interface members)
}

To use the interface for what you are doing here, you would have as one of the member variables of your player script

Inhabitable currentlyInhabiting;

This defines a reference which can refer to any class that inherits from Inhabitable.

In your ‘Start’ script, you would set it up so that the ‘default’ body (is it some kind of ghost? I’ll assume it is) gets set as the currentlyInhabiting variable.

currentlyInhabiting = GetComponent<Ghost>();

This is, of course, assuming you have a class called Ghost on the same object as the ‘Player’- you might not, I’m not sure. In any case, it’d look (minimally) something like this-

public class Ghost : MonoBehaviour, Inhabitable
{
    public void UpdateInhabited(float deltaTime)
    {
        // do all your keyboard input/ mouselook or whatever here
    }

    public void PlayerEnters() {
        // spray particles everywhere! Everyone likes particles.
    }

    public void PlayerLeaves() {
        // disable any glitz, since the ghost should be invisible when not inhabited.
    }
}

Then, in your ‘Player’ update method, call the currently inhabited object’s UpdateInhabited-

void Update()
{
    currentlyInhabiting.UpdateInhabited(Time.deltaTime);
}

Set up a simple method for changing inhabited objects, like this-

public void ChangeInhabited(Inhabitable newHabitation)
{
    currentlyInhabiting.PlayerLeaves();
    currentlyInhabiting = newHabitation;
    currentlyInhabiting.PlayerEnters();
}

When you want to change objects (say to a haunted box that’s lying around) (you’re the one haunting it), if you know that a given object will have a certain component on it, and you know that that component is also Inhabitable, you can use this-

ChangeInhabited(boxObject.GetComponent<HauntedBox>());

And that will automatically change what the player is inhabiting, through the magic of interfaces.