0
\$\begingroup\$

hello I have a game prototype in unity about a local multiplayer sandbox game with gamepad.

The game tries to use vehicles and perform an activity x and I want it to be for 2 people.

At this moment I have a car, a limousine, a tank, a fire truck and an ambulance.

I use Rewired for the input of the gamepad, but the problem I have is that what is already programmed is wrong, that is, everything works in its own scene. In CarScene I have my car and when I move the sticks of the gamepad it moves as it should, so in TankScene my tank moves because it inherits from car and a method of shooting is added, and so on, the ambulance only sounds its siren and the firefighter's cabin shoots water with a shader. But when the players in a scene all move at the same time. Because basically I program in the Update () that takes the movement of the left stick and the movement is applied.

What I need and it is not clear to me is how I can make it possible to select only one vehicle, similar to GTA, a character walks through the city, approaches a vehicle, enters it with a button, at this moment all the Vehicle operations, the player presses a button to exit the vehicle and the control now reprocesses the character.

In fact I already have my modified version of ThirdPersonControl using REWIRED.

The first idea that I have is that in the player's component, a reference to which vehicle is being used is added and it is left null when walking, and add the reference when the button is pressed near a vehicle.

The second idea I had was to create a vehicle-level variable, turn it on and off with the same logic that I require

Vehicle {
Update () {
if (IsInUse)
    ProcessInput ()

And the last thing that occurred to me was to add a Player object in each vehicle, leave it in null when the vehicle is not in use and activate it

Vehicle{ //car inherits from here
Update () {
if (player! = null)
    ProcessInput ()

But I feel that with these approaches at some point I am going to have a bug when two vehicles are very close to the command to enter, activate both and cause bad behavior. Or worse, that at some point you lose the reference of which vehicle is active and nothing moves or the character.

I hope you can help me, and that is that I already thought a lot about it in my head, but I feel that I do not have the right solution for the problem

\$\endgroup\$
1
\$\begingroup\$

A common approach to the issue of "taking control" is to treat a controller as it's own entity within the game, and have objects with a Possessable script. The idea is the following:

You query input from a Possessable. For example in your car controller

public Possessable Possessable;

private void Update() {
  if (!Possessable.Possessed) return;
  if (Possessable.GetButton((int)InputEnum.VehicleAccelerate))
  {
    DriveForward();
  }
}

Your Possessable is basically a wrapper around a controller. Your player is also Possessable. To start the game you call

Possessable playerPossessable = playerGameObject.GetComponent<Possessable();
playerPossessable.Possess(Rewired.ReInput.players.GetPlayer(mainPlayerID));

to pass control to another possessable you can use

Possessable vehiclePossesable;
Possessable myPossessable;
myPossessable.PassPossession(vehiclePossesable);

Now to show you what this component actually will look like

public class Possessable : Monobehaviour
{
  private Rewired.Player currentPlayer = null;

  public bool CanPosses { get { return currentPlayer == null; } }
  public bool Possessed { get { return currentPlayer != null; } }

  public bool Possess(Rewired.Player player) {
    if (!CanPossess) return false;
    currentPlayer = player;
    return true;
  }

  // Convenience if you want to not be possessing anything.
  public Rewired.Player UnPossess() {
    Rewired.Player toRet = currentPlayer;
    currentPlayer = null;
    return toRet;
  }

  public bool PassPossession(Possessable other) {
    if (other.Possess(currentPlayer)) {
      currentPlayer = null;
      return true;
    }
    return false;
  }

  public bool GetButton(int rewiredIndex) {
    if (currentPlayer == null) return false;
    return currentPlayer.GetButton(rewiredIndex);
  }

  // Write similar wrapper functions for the other input methods
}

This method has lots of booleans to check to ensure the possession went through. It will ensure only one thing is possessed at a time if you use the PassPossession method. You can in your update loop for a controller, check if you are possessed to avoid needlessly polling input.

In terms of how to choose which vehicle to possess when multiple are close. You should just have a trigger around your player and track whichever possessable objects are currently inside and when the player presses the button, pick 1 from that list. Usually the one closest to you.

\$\endgroup\$
  • \$\begingroup\$ I need to study it more, but I appreciate your support +1 \$\endgroup\$ – naranja herdez Apr 16 at 3:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.