Spawn UCC prefab, switch between AI and playable

bbjones

New member
This script is for simple testing and is the result of resolving multiple issues with Justin's help.

The script demonstrates how you can spawn a playable UCC prefab into a scene and attach it to the UCC camera.
Then swap that character back and forth between being AI or human playable.
It also shows how you can setup multiple inventory loadouts using item pickup prefabs.

This is one way to make a simple test with the script:
  • Either create a new project or use an existing one that has the Opsive UCC demo asset
  • If you have Opsive UCC version 2.1.8 or lower, replace ObjectdFader.cs and ItemSetManager.cs with the attached scripts
    • Justin provided these to fix some issues related to these tests, and suggested the changes will make their way into the upcoming UCC update
  • Create a new empty scene
  • Using the Opsive Manager
    • Create the Setup objects for Scene (Managers, Camera, UI) and Project (Key bindings, Layers)
    • Make a UCC character normally, then make a new prefab of that character. Repeat so you have multiple different characters.
    • Create item pickup objects, as many as you like.
    • You should now have prefabs in your project assets, the scene should still be empty
  • Create a new empty game object named TestManager, attach the script below.
  • Create a new camera, position somewhere useful, this will be the non-Opsive camera that is activated when you switch to AI
  • Select the TestManager in your scene, and setup the script properties, drag in the prefabs you created
    • Note this test can be done with as little as a single UCC character prefab. You don't need inventory pickups.
  • Disable the Opsive camera
  • Add a plane or simple terrain for the character to stand on, bake a nav mesh (Window->AI->Navigation)
  • Play the scene
    • Scene should start with no characters or item pickups, and the non-opsive camera active.
    • Numpad 1 - Spawns the character prefab into the scene as a playable character, attaches and activates the UCC camera
    • Numpad 2 - Swaps the active character from playable to AI Agent, disables Opsive camera, enables non-Opsive camera
    • Numpad 3 - Swaps the AI agent back to playable, swaps cameras again
You can then go through any combinations of those keys swapping and spawning.
If you have multiple character prefabs, change the Character Type To Spawn at runtime to change which character will spawn.
Note the script is setup to only have a single character in the scene.

Example of the TestManager properties and default scene hierarchy
1573312737111.png

Script:

C#:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Opsive.UltimateCharacterController.Inventory;
using Opsive.UltimateCharacterController.Objects.CharacterAssist;
using Opsive.UltimateCharacterController.Utility.Builders;

[System.Serializable]
public class SpawnCharacter : MonoBehaviour
{
    [Tooltip("At run-time, select the type of character you want to spawn. Then call the SpawnACharacter() method, easy way is to wire that up to a UI Button click event.")]
    [Header("Testing")]
    public ECharacterType characterTypeToSpawn;
    //public bool makeAiAgent;
    //public bool doNotDestroyAiAgents;
    [Tooltip("Drag in the Opsive camera you created in your scene with the Opsive Setup Manager.  Be sure to uncheck Init Character On Awake.")]
    public GameObject opsiveCamera;
    public GameObject nonOpsiveCamera;
    //[Tooltip("If false the Opsive camera will not reference the newly spawned UCC character.")]
    //public bool assignSpawnToCamera;

    [Tooltip("One entry for every combination of character type and default loadout")]
    [Header("Default Kits")]
    public CharacterDefaultKits[] characterDefaultKits;

    private GameObject spawnedCharacter;
    private bool spawnIsAi;

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Keypad1))
        {
            print("Spawn Character...");
            SpawnACharacter();
        }
        if (Input.GetKeyDown(KeyCode.Keypad2))
        {
            print("Convert To AI...");
            ConvertPlaybleToAiAgent();
        }
        if (Input.GetKeyDown(KeyCode.Keypad3))
        {
            print("Convert To Playable...");
            ConvertAiAgentToPlayable();
        }
    }

    public void ConvertPlaybleToAiAgent()
    {
        Opsive.UltimateCharacterController.Camera.CameraController uccCam = opsiveCamera.GetComponent<Opsive.UltimateCharacterController.Camera.CameraController>();
        opsiveCamera.SetActive(false);
        nonOpsiveCamera.SetActive(true);
        uccCam.Character = null;

        var playerInput = this.spawnedCharacter.GetComponent<Opsive.UltimateCharacterController.Input.PlayerInput>();
        playerInput.enabled = false;
        var handler = this.spawnedCharacter.GetComponent<Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotionHandler>();
        handler.enabled = false;
        var localLookSource = this.spawnedCharacter.GetComponent<Opsive.UltimateCharacterController.Character.LocalLookSource>();
        localLookSource.enabled = true;
    }

    public void ConvertAiAgentToPlayable()
    {
        var localLookSource = this.spawnedCharacter.GetComponent<Opsive.UltimateCharacterController.Character.LocalLookSource>();
        localLookSource.enabled = false;
        var playerInput = this.spawnedCharacter.GetComponent<Opsive.UltimateCharacterController.Input.PlayerInput>();
        playerInput.enabled = true;
        var handler = this.spawnedCharacter.GetComponent<Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotionHandler>();
        handler.enabled = true;

        Opsive.UltimateCharacterController.Camera.CameraController uccCam = opsiveCamera.GetComponent<Opsive.UltimateCharacterController.Camera.CameraController>();
        opsiveCamera.SetActive(true);
        nonOpsiveCamera.SetActive(false);
        uccCam.Character = this.spawnedCharacter;
    }

    // The code for adding ItemPickups is taken from the UMA Integration asset scripts found here https://opsive.com/downloads/?pid=923
    // Note that I'm not using anything to do with UMA, and does not require the UMA asset to function.
    // Spawns the character with the typical Unity.GameObject.Instantiate() method.
    public void SpawnACharacter()
    {
        print("Attempt to spawn character...");

        // destroy currently spawned character if exists
        //if (spawnedCharacter != null)
        if (spawnedCharacter != null)
        {
            Destroy(spawnedCharacter);
        }

        Opsive.UltimateCharacterController.Camera.CameraController uccCam = opsiveCamera.GetComponent<Opsive.UltimateCharacterController.Camera.CameraController>();

        // loop through character kits to find the type that matches variable characterTypeToSpawn
        for (int c = 0; c < characterDefaultKits.Length; ++c)
        {
            if (characterDefaultKits[c].ECharacterType == characterTypeToSpawn)
            {
                // find the matching default kit by character type
                spawnedCharacter = GameObject.Instantiate(characterDefaultKits[c].CharacterPrefab);
                var localLookSource = spawnedCharacter.AddComponent<Opsive.UltimateCharacterController.Character.LocalLookSource>();
                localLookSource.enabled = false;

                // attach new character to Opsive camera
                opsiveCamera.SetActive(true);
                nonOpsiveCamera.SetActive(false);
                uccCam.Character = spawnedCharacter;


                // get UCC inventory from new character
                var inventory = spawnedCharacter.GetComponent<InventoryBase>();
                if (inventory == null)
                {
                    return;
                }

                // add all ItemPickups for the new character type
                for (int i = 0; i < characterDefaultKits[c].ItemPickups.Length; ++i)
                {
                    if (characterDefaultKits[c].ItemPickups[i] == null)
                    {
                        continue;
                    }

                    characterDefaultKits[c].ItemPickups[i].DoItemPickup(spawnedCharacter, inventory, -1, true, true);
                }
            }
        }
    }
}

// this class represents all the default items for a single character type
[System.Serializable]
public class CharacterDefaultKits
{
    public ECharacterType ECharacterType;
    public GameObject CharacterPrefab;
    public ItemPickup[] ItemPickups;
}

// this class represents the different types of characters
[System.Serializable]
public enum ECharacterType
{
    CharacterType1,
    CharacterType2,
    CharacterType3
}
Related posts:


 

Attachments

Last edited:
Top