- Home /
Split-Screen without Showing Other Player
So I'm working on a game and I'd like to make it competitive by having players race along the same level/scene in a split-screen format. However, ideally I would like the players to not be able to interact or even show up in each other's screens.
What would be the best way to do this?
My naive initial approach would be to load 2 scenes, but I don't know if you can load the same scene twice. I looked around and layers might work, but my wishes are that:
Interactions with the level be limited to each screen. I.E. if one players uses an elevator, the elevator only moves in that player's scene.
There is a potential for a cooperative 2 v 2 element, so some players need to be able to interact, but not others. This seems to point to the fact that using layers wouldn't work without an obtrusive layer naming scheme.
Edit: The players that would interact with each other would be in the same screen. That line was meant to say that I don't think simply masking that Players can't interact with other Players would work as I want two people working together in one screen and two people working together on the other.
"if one players uses an elevator, the elevator only moves in that player's scene." - that requirement is a bit of a killer: no amount of layers/camera culling is going to handle a gameobject that has both moved and not moved.... you're basically describing two independent instances of the scene. But then that gets kicked in the teeth by "some players need to be able to interact, but not others".
I think you're going to need a much clearer and more detailed design to think through the options - it sounds like it will complex and bespoke.
tanoshimi-
You're right. I apologize for my ambiguity. I thought that two independent scenes might be my only answer, but I'm not sure about how to go about that.
Answer by Bunny83 · Dec 05, 2013 at 10:50 PM
You can't really load two scenes at the same time, however you could load the same scene additivly into the current scene so all objects are actually duplicated. While this does work i don't think that's a good approach in the end. You still have to move the two "content packages" so they don't overlap. It's probably easier, if there are only a few of those cooperative elements, to use one scene with layers.
All geometry that doesn't change individually is on a layer that both players can interact with. Each player has it's own extra layer where it is actually placed in. Both player layers can collide with the common layer (you can use the default layer as common layer). You would simply disable collisions between the two player layers and remove the opposite player layer from your cameras culling mask.
So far for the general approach. Now the "splitted objects" where each player needs it's own version. Initially you have the object only once. That simplyfies the level design. Now you just attach a script to those object which will duplicate the object itself, assign the duplicated object to player 1 and the original to player two.
Important: This duplicating should be done in Start and at the end of Start you have to prevent that the script on the cloned object does the same or you end up with getting a new clone each frame.
This can be done by adding a bool which is initially false and get set to true by the original object.
Example:
//C#
public class SplitObject : MonoBehaviour
{
public bool isClone = false;
public SplitObject other = null;
void Start()
{
if(!isClone)
{
SplitObject clone = (SplitObject)Instantiate(this);
clone.isClone = true;
gameObject.layer = LAYER_PLAYER1;
clone.gameObject.layer = LAYER_PLAYER2;
other = clone;
clone.other = this;
}
}
}
This script will duplicate the object it's attached to and assigns itself to player1 and the clone to player2. I've added a cross link reference to the other object in each instance. That way it's easier to link up signals from triggers ect...
Everytime one of those splitted objects want to communicate with a linked object it has to check if itself is a clone (isclone) and then use the "other" reference to "fix" the link.
Example:
A trigger which sends a message to a door might look like this:
// C#
public class SplittedDoorTrigger : MonoBehaviour
{
public GameObject target;
void Start()
{
var SO = GetComponent<SplitObject>(); // get own instance of SplitObject.
if (SO.isClone) // check if we are the cloned object
{
var splittedTarget = target.GetComponent<SplitObject>().other.gameObject;
target = splittedTarget;
}
}
void OnTriggerEnter(Collider aOther)
{
target.SendMessage("Open");
}
}
In this example both the door and the door-trigger have a SplitObject component which will duplicate the trigger and the door and assign it to the corresponding player. The target reference however will still point to the original target. That's why this code will check if it is a clone and if so it grabs the original target, get the SplitObject instance of the target, use the "other" reference to get the cloned object and use this as target.
A bit complicated but should work ;)