Getting errors after Instantiate player character & camera

bluebird

Member
Hi,

I want to instantiate player character in the scene. (see my code snippet)
After instantiating player character, I also assigned player character gameobject into character property of CameraController through code.
but I'm getting errors. (see attached screenshot)

Guide me in correct direction. where I went wrong.

Do I need to assign player character gameobject into all monitors gameobject & VirtualControlsManager?

Note that
* Target platform is set to Android
* InitCharacterOnAwake property of CameraController is set to false
* ForceInput property of UnityInput is set to Virtual


Code:
public class GameManager : MonoBehaviour
{
    public GameObject obj_Character; // prefab of player character
    public GameObject obj_Camera; // prefab of camera

    [HideInInspector]
    public GameObject m_Character;
    [HideInInspector]
    public GameObject m_Camera;
    [HideInInspector]
    public CameraController m_CameraController;

    public static GameManager instance;
    
    public void Start()
    {
        instance = this;

        m_Character = Instantiate(obj_Character) as GameObject;
        m_Camera = Instantiate(obj_Camera) as GameObject;

        m_CameraController = m_Camera.GetComponent<CameraController>();
        m_CameraController.Character = m_Character;

        m_CameraController.SetPerspective(true);
        .
        .
        .
    }
}
 

Attachments

  • err.PNG
    err.PNG
    239.2 KB · Views: 14
  • 1.PNG
    1.PNG
    36.5 KB · Views: 14
It looks like you are getting UI errors and not character/camera instantiation errors. When you create the camera you'll also want to create the UI since the UI is looking for the camera as soon as it starts but there isn't a camera.
 
Thanks for the response, Justin.

yes, there were UI errors. so, to solve that I also instatiated UI canvas along with character & camera. (see attached screenshot)
errors are gone.

But Inside UICanvas, VirtualControls are disabled when I play the scene. Note that monitors gameobject is visible and ForceInput is set to Virtual as per previous snippet.

I don't know, where I did wrong to set up Virtual Controls.

Aside from this, I want to ask, Can we manage 2 types of canvas & camera where one canvas will responsible to show UIScreen like Home screen, Level Selection, Character Selection screen, Shop screen, etc. This canvas will be rendered by new camera.

And other canvas and camera is came with UCC package which contains UI components for In-game view as you already provided with asset.

Would it be easy to manage? Right? What do you think
 

Attachments

  • 3.PNG
    3.PNG
    25.8 KB · Views: 3
You will need to point the virtual controls to the character that you spawned. Having multiple canvases is no problem.

Code:
        var virtualControls = m_VirtualControls.GetComponent<VirtualControlsManager>();
        if (virtualControls != null) {
            virtualControls.Character = character;
        }
 
Hi,

I assigned a character reference to virtual controls through code as per above snippet.
but didn't get success.

I provided my custom code for GameManager, which instantiate things run time.
I played the scene, and noticed that player character is already assigned but VirtualControls gameobject is disabled. (you can see in screenshot attached) and public variable m_VirtualControls stays null (see attached screenshot)

C#:
public class GameManager : MonoBehaviour
{
    public GameObject obj_Character; // prefab to be instantiated
    public GameObject obj_Camera; // prefab to be instantiated
    public GameObject UI_Canvas; // prefab to be instantiated
 
    public ItemType[] arr_ItemType;   

    [HideInInspector]
    public GameObject m_Character;
    [HideInInspector]
    public GameObject m_Camera;
    [HideInInspector]
    public GameObject m_UICanvas;
    [HideInInspector]
    public CameraController m_CameraController;
    
    public VirtualControlsManager m_VirtualControls;

    public static GameManager instance;

    public void Start()
    {
        instance = this;

        m_Character = Instantiate(obj_Character) as GameObject;
        m_Camera = Instantiate(obj_Camera) as GameObject;
        m_UICanvas = Instantiate(UI_Canvas) as GameObject;
      
        m_CameraController = m_Camera.GetComponent<CameraController>();
        m_CameraController.Character = m_Character;

        m_CameraController.SetPerspective(true); // 3rd person character
      
          // save VirtualControlsManager component & assign a character
        m_VirtualControls = m_UICanvas.GetComponentInChildren<VirtualControlsManager>();
        if (m_VirtualControls != null)
        {
            m_VirtualControls.Character = m_Character;
        }
    }

}
 

Attachments

  • 5.PNG
    5.PNG
    54.3 KB · Views: 7
  • 6.PNG
    6.PNG
    66.4 KB · Views: 7
I can't see anything wrong but for my test case I use the following and it works:

Code:
using UnityEngine;
using Opsive.UltimateCharacterController.Camera;
using Opsive.UltimateCharacterController.Input.VirtualControls;

public class Instantiate : MonoBehaviour {

    public GameObject m_CharacterPrefab;
    public GameObject m_CameraPrefab;
    public GameObject m_VirtualControls;

    void Start () {
        Invoke("Create", 1);
    }
   
    private void Create()
    {
        var character = GameObject.Instantiate(m_CharacterPrefab);
        var camera = GameObject.Instantiate(m_CameraPrefab);

        // The character needs to be assigned to the camera.
        var cameraController = camera.GetComponent<CameraController>();
        cameraController.Character = character;

        // The virtual controls need to be updated.
        var virtualControls = m_VirtualControls.GetComponent<VirtualControlsManager>();
        if (virtualControls != null) {
            virtualControls.Character = character;
        }
    }
}
 
Hi Justin,

I tried your script, but I think you didn't instantiate Canvas along with character & camera.

if the canvas is there in Hierarchy and we instantiate character & camera as per your script.
it throws errors just b'coz you didn't consider Monitors game object.

1128

The children of monitors requires character game object. that's why it throws errors.

So, I disabled Monitors temporarily in hierarchy and play the scene. Still virtual controls didn't appear. Very strange!
 
The UI Monitors don't have a public character property which allows you to set it at runtime but I've just added it to CharacterMonitor.cs:

Code:
        public GameObject Character { get { return m_Character; } set { OnAttachCharacter(value); } }

After you instantiate the character you can now find and loop through all of the CharacterMonitor components and assign the character.
 
Hello Justin, could you please explain further, how one can now change the Health Monitor for e.g. a switched Character through script in runtime. I tried it like that:

Opsive.UltimateCharacterController.UI.CharacterMonitor myAttributeMonitor = globalHealthMonitor.GetComponent<Opsive.UltimateCharacterController.UI.CharacterMonitor>();

myAttributeMonitor.OnAttachCharacter(spawnedCharacter);

but it is said that the access is protected. As I look in the CharacterMonitor Script, it certainly is but with the above written comment of yours you surely showed a way. Unfortunaly I admit that I cannot work with this information because of lack of experience in UCC. Would you please be so kind to explain it a bit further, like what kind of code I have to implement to get it working?
 
Last edited:
I came a step further. I assigned it via:

Opsive.UltimateCharacterController.UI.CharacterMonitor myHealthMonitor = globalHealthMonitor2.GetComponent<Opsive.UltimateCharacterController.UI.CharacterMonitor>();

myHealthMonitor.Character = m_Character2;

I stomped the idea of switching the display of health of the players and just added a second Health Object as part of the UI Monitor Gameobject Folder in the Runtime Hierarchy. As seen in the picture, the Character of Attribute Monitor (Script) switches successfully to the "Chick" Character in the Inspector. What remains is that the Attribute Manager Field stays at Nolan, I changed the field at runtime by drag and drop and now it functions all well and as wished. Note: I need to change it via script because the Chick Character gets instantiated at runtime, so no assigning beforehand possible (as far as I know).
Now my only question left is: How can I change the content of the field Attribute Manager in the Inspector of the Health Monitor GameObject through script?
 

Attachments

  • showcase_AttributeManager_drag__assign.png
    showcase_AttributeManager_drag__assign.png
    48.6 KB · Views: 3
Last edited:
Yeah I solved it by imitating your steps, you took with the Character field.
I wrote this in the UCC AttributeMonitor Script:

public AttributeManager AttributManager { get { return m_AttributeManager; } set { m_AttributeManager = value; } }

In the execution script, I changed my lines to:

Opsive.UltimateCharacterController.UI.AttributeMonitor myHealthCharacterMonitor = globalHealthMonitor2.GetComponent<Opsive.UltimateCharacterController.UI.AttributeMonitor>();

myHealthCharacterMonitor.Character = m_Character2;
myHealthCharacterMonitor.AttributManager = m_Character2.GetComponent<AttributeManager>();

It worked and I could solve the problem.
Just documentating it here so other Devs can find this information.
But now I ask: Is there not a better way as to alter the(your) original UCC scripts? I don't want to get used to it and eventually mess it up by doing so.
 
Glad you figured it out. It's recommended to edit the source UCC scripts as little as possible (and any edits you do need to make to fix UCC bugs will likely be added in a future update anyway). If you do need to edit UCC scripts, I'd recommend wrapping any changes you make in some kind of comment tags, e.g. @startchanges and @endchanges on either side of code changes. That way whenever you update UCC you know exactly what parts of the code to copy over.
 
Top