I am trying to recreate the first level of Chips Challenge which was an old game that came pre-loaded on my parents Windows 1995 PC back in the day. I am wondering if there is a better way for me to set up my collision than what I have been doing. The code that I have been using and testing is working as expected.
In a nut shell I have four collision boxes around my player and each one has a different script to test for the collision of a wall using the OnCollisionEnter() and OnCollisionExit() methods. Both of these methods returns a public Boolean back to the script that is controlling my players movement which is on the player. Depending on if the Boolean is true or false determines if the player can move in that specific direction (preventing the player from moving through a wall).
Setting up the collision like this ended up leaving me with 4 simple scripts (one for each direction of collision) and a 5th script for the player movement which contained an IF statement with 7 corresponding ELSE IF statements.
This all seemed fine until I realized that I would need to do the exact same thing four more times as there are four colored locked doors in the game as well. This is where I think there has got to be an easier/better way of setting up this type of collision.
If anyone could point my in the right direction on how I might start to set this up I would appreciate it.
You could expand your 4 collider scripts to detect more than just blocking objects. Give them another boolean to set true if there’s a special object. If it’s a door and it’s locked, you can set blocking to true, and isDoor to true. That way the player won’t be able to move through it, but the player can know that it’s a door, and try to unlock it.
I don’t know that I’ve ever played Chip’s Challenge, so I might not understand the concept fully, but I did a quick Google to see what it is… I hope I understand it.
I would think you could just have one collider on your player though, and just set up tags on your doors… ex. BlueDoor, RedDoor (or something). On collision, check if other.tag == “BlueDoor” (that might not be exactly the right code), and if so, see if player has the blue key. If so, then perhaps you’d have a function on your bluedoor called “Open()” that the player’s script could call, and that would open the blue door. Or perhaps your player would call someDoor.Open() regardless of whether he has the key or not, and your door would have the logic to check whether the player has the key.
You could create a class for your doors to derive from that has an Open function (I’d assume they’d all work the same).
Anyways, I hope you get the idea, and hope something like that would work.
Edit: It sounds like your doors don’t actually physically open/close, but the concept would be similar. check the tag on the door… look for the key that matches… if you have it… you can move through. Should only require one collider (or trigger) on the player, and one on the door.
@cstooch the problem I had with only having one collider is that if I press the up arrow to move up and I hit a wall I couldn’t figure out how I would tell the program to check for which direction the player was going and to prevent the player from moving up any further (prevent him from going through the wall). I tried adding the code that checked for a key press in the OnCollisionEnter() method but that code was not being read by the program. I can only assume because you can only check for keyboard input within the various update functions.
@ jeffreyschoch Thanks for the advice. I am not sure why I thought that in order to check my boolean variables from my OnCollisionEnter() method on my collision script that I would have to return them. This has answered part of my question However as I mentioned above in response to cstooch, is there anyway to have just one collider on my player and to have the program knowing what direction the player has collided with and than cut off the movement in that direction? This would elimanate the need to have 4 box colliders surrounding the player. Perhaps using another type of Input check. I am currently using Input.GetKeyDown(KeyCode.key)
If your character is moving through the walls, sounds more like a problem with how you are moving the player. Are you merely translating the player?
Moving through the walls isn’t/wasn’t the problem. I was just wondering if there was a better way to go about programming everything than how I thought to do it.
I personally hate using tags. It’s easy to manage for small projects, but when the project gets bigger, and if you have multiple designers tinkering with the project, lack of communication about what each tag is meant to represent can result in a large number of tags for no reason since each designer is adding their own stuff.
An alternative to using tags would be checking for components unique to the object. I went to see a some gameplay footage and saw a movable block. So maybe the movable block as a script named “Movable”. On collision you can use GetComponent to check if “Movable” exists in the object you collided with. If it does, execute the relevant behaviour. same can be done for doors and keys. and if none of them are detected, it is an uninteractable wall.
void OnCollisionEnter(Collision col){
GameObject colObj = col.gameObject;
if(colObj.GetComponent<Movable>()){
//move object
}
if(colObj.GetComponent<Pickable>()){
//add object data to inventory
}
if(colObj.GetComponent<Unlockable>()){
//check if relevant key exists
//if key exist, remove object
}
}
Even better I feel would be for the collision behavior needed to be on the object itself, so the objects will be the ones checking if they collide with the player instead of the reverse. And if you are using tags you would only need to check for the existing Player tag.