How do I let the Player take Direct Control/Possess of A.I Units like in Dungeon Keeper?

Hi yes hello I am trying to make an FPS/RTS style Battlezone tank shooter and I wanted to know how I can get the player to take over an A.I unit then when the player doesn’t need to be in control of that A.I unit he can click or pres a key on his keyboard and leave the A.I and the A.I NPC is no longer under the direct control of the Player as in Parkan: Iron Strategy Strategy and Dungeon Keeper

I wish for this because I want to make a level where the player has to take over planets near a star like Venus and Mercury

do you have any code built for any of this already?

I have code for a hovertank and a player and even some very rudimentary A.I but I am currently triying to get the player to get into the hovertank and drive in in it and then for the player to get out and the hovertank to be disabled what I am talking about here though is a little different

how are you handling the “player code” part? is it directly attached to a specific unit/thing in the game (i.e. gta get in vehicle) or is it a “floating presence” (i.e. player is the camera)?

if it’s a floating presence ala DK you can extend that player code to include a new state “controlling unit” and have it disable any AI script component ( https://unity3d.com/learn/tutorials/modules/beginner/scripting/enabling-disabling-components ) when that state is entered and reenable the AI when the state is left. Then in that state you’ll need to handle how the unit responds to direct user input, if you’ve got lots of different types of units it might be worth adding a script to the unit which interfaces (generic sense not technical sense of the word lol) with the player script, i.e. playerscript takes the button press and calls the unit’s directControlScript’s functions etc.

To generalize that, add a virtual controller script.

In this case, the tank can read inputs from the virtual controller to know when to fire, rotate, rocket-jump, etc.

When the tank is AI-controlled, the AI script will set the virtual controller’s inputs.

When the tank is player-controlled, the player input script will set the virtual controller’s inputs.

The lower-level motor scripts (fire, rotate, etc.) won’t care in this case where the actual inputs are coming from (AI or player). It simply reads them all the same from the virtual controller script.

To switch to player control, disable the AI script and enable the player input script. To switch back to AI control, enable the AI script and disable the player input script.

Something like this:
(I shortened the code for clarity; ignore bad practices such as GetComponent every Update.)

public class VirtualController : MonoBehaviour {
    public bool fire;
    public float verticalAxis;
}

//===================================
public class PlayerInput : MonoBehaviour {
    public void Update() {
        var virtualController = GetComponent<VirtualController>();
        virtualController.fire = Input.GetButtonDown("Fire1");
        virtualController.verticalAxis = Input.GetAxis("Vertical");
    }
}

//===================================
public class AIControl : MonoBehaviour {
    public void Update() {
        var virtualController = GetComponent<VirtualController>();
        virtualController.fire = Think_Should_I_Fire();
        virtualController.verticalAxis = Think_Movement();
    }
}

//===================================
public class Cannon : MonoBehaviour {
    public void Update() {
        var virtualController = GetComponent<VirtualController>();
        if (virtualController.fire) Shoot();
    }
}

//===================================
public class Engine : MonoBehaviour {
    public void Update() {
        var virtualController = GetComponent<VirtualController>();
        SetSpeed(virtualController.verticalAxis);
    }
}

The code above is far from robust or full-featured. It’s just meant to demonstrate the virtual controller idea succinctly.

6 Likes

Thanks TonyLi thanks for the example code That virtual controller idea seems to be a very good idea could use that for air/spacecraft as well I think

Well its going to be both as they way I see it is that if the player is fighting on Mars or Phobos or Ganymede or Io or Europa they can get in and out of vehicles and actually have a presence there, but if fighting on the more hotter planets like Mercury and Venus Robots can actually do the fighting on the planet for them with the player getting into the robot and getting into the tank with the robot or just taking control directly over any vehicle thanks I will look more into that enabling /disabling script component

Unity’s component based system is perfect for this. Set up the movement code and the controller code as seperate components. Use an interface or abstract base class between them. Then the controller can be swapped out at will.

OK I will try and do that