- Home /
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;
}
}
}
I think the way you are going about this is pretty flaky. You might need to do a little refactoring to get the control stuff working in a more consistent way. Does every object the player can inhabit have the same behaviour, or do they all do different things? I wouldn't be using a boolean for this, I would keep a reference to the currently controlled object in the player script, and manage things from there, so that the player can only ever be controlling one object at a time.
well, the objects do different things.
but what do you mean by "keep a reference to the currently controlled object in the player script"?
I mean, make some kind of interface (however you choose to do so, there are a few ways), and then have something like this in your player-
Inhabitable currentlyInhabited;
void Update()
{
// blah blah blah
currentlyInhabited.Update();
}
Then, when you want to change object,
currentlyInhabited.PlayerLeaves();
// returns it to its original state, plays an animation or something
currentlyInhabited = nextObjectToInhabit;
currentlyInhabited.PlayerEnters();
// does something when the player starts to inhabit it
Basically, treat the whole thing like a finite state machine.
uuum, I'm kind of new to program$$anonymous$$g so I'm not really getting it =/
Want me to elaborate on this stuff in a full answer? I was new to program$$anonymous$$g about a year ago, but I had some very good $$anonymous$$chers.
Answer by syclamoth · Nov 18, 2011 at 11:08 AM
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.
hey, sorry I'm replying late. I have been busy lately =/ I think I see what you mean, but could you give me and example how it could look like (the code that is) in a actual game? you can use my game for an example or another game (take then a popular game...for an example Grand Theft Auto how he jumps into cars and then jumps out of them).
Cuase I really want to learn this, sounds like something that will be useful in the future =)
I solved the problem now, altough not with the reference thing you mentioned. But thanks for trying to help, I should check it out in the future =) gives thumbs up
Your answer
![](https://koobas.hobune.stream/wayback/20220613045534im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Problem with jump bool. Help?! 0 Answers
Get Boolean from another Script, C# 2 Answers
Stop spawning enemies when a bool is enabled 0 Answers
BoolPrefs Problem 2 Answers