PUN suddenly demanding I attach a "look source" out of nowhere.

wizard

New member
I believe that this is fixed in the version being released shortly. At least it was for one project that I tested. This related to the script execution order - the SpawnManagerBase should execute before the KinematicObjectManager.

Still presented for me in 2.2.3.
This is how I reproduce it now during cutscenes playing.

When a cutscene is started I run this code:
C#:
            Opsive.Shared.Events.EventHandler.ExecuteEvent(m_Character, "OnEnableGameplayInput", false);
            var CharacterLocomotion = m_Character.GetCachedComponent<UltimateCharacterLocomotion>();
            m_LookSource = CharacterLocomotion.LookSource;
            print("Look source: " + m_LookSource);
            var m_localLookSource = m_Character.GetComponent<Opsive.UltimateCharacterController.Character.LocalLookSource>();
            m_localLookSource.enabled = true;

So the character cannot be controlled and its look source is fixed.
The print log is
Look source: Main Camera (Opsive.UltimateCharacterController.Camera.CameraController)


Once a cutscene is finished I run this code:
C#:
            Opsive.Shared.Events.EventHandler.ExecuteEvent(m_Character, "OnEnableGameplayInput", true);
            var m_localLookSource = m_Character.GetComponent<Opsive.UltimateCharacterController.Character.LocalLookSource>();
            m_localLookSource.enabled = false;

            var CharacterLocomotion = m_Character.GetCachedComponent<UltimateCharacterLocomotion>();
            m_LookSource = CharacterLocomotion.LookSource;
            print("Look source after: " + m_LookSource);

The print log is with the empty look source
Look source after:

and so the error appears.

Am I doing it wrong?
 

Justin

Administrator
Staff member
You should not be enabling or disabling the local look source. Are you able to reproduce the error within the demo scene?
 

wizard

New member
You should not be enabling or disabling the local look source. Are you able to reproduce the error within the demo scene?

There are two things:

1. As I said above, I use it to convert Third person characters from playable to AI and vice versa.
The purpose is the creating of a gameplay just like in VtM: Redemption where you control a single character at a time and others are following as AIs:
Using of this code still gives that error with 2.2.3 when trying to restore a character as a playable once again:

2. I try to use the same method for a playable character during a cutscene so the look wouldn't be following camera during a cutscene play.
As far as I understand I can use ILookSource for a playable character, however, it won't work if that character is supposed to become an AI dynamically and I have to add the local look source component anyway.

Please advise.
 
Last edited:

Justin

Administrator
Staff member
Ahh, ok, I see now.

You should not disable the LocalLookSource. The character should always have a look source. When you do the swap you should always be swapping it with a valid, non-null look source. In this case you should switch between the local look source and the camera controller.
 

wizard

New member
Ahh, ok, I see now.

You should not disable the LocalLookSource. The character should always have a look source. When you do the swap you should always be swapping it with a valid, non-null look source. In this case you should switch between the local look source and the camera controller.
Since I am not an experienced UCC/TCP user yet I took that code from the aforementioned thread.
Could you please provide a code snippet on how to switch between the local look source and the camera controller properly?
 

Justin

Administrator
Staff member
Actually enabling or disabling the local look source is correct. I haven't tested this but you should just be able to do something like to enable the local look source:

Code:
CameraController.Character = null;
LocalLookSource.enabled = true;
[code]
And to enable the camera:
[code]
LocalLookSource.enabled = false;
CameraController.Character = character;

This will ensure the character always has a look source.
 

wizard

New member
Actually enabling or disabling the local look source is correct. I haven't tested this but you should just be able to do something like to enable the local look source:

Code:
CameraController.Character = null;
LocalLookSource.enabled = true;
[code]
And to enable the camera:
[code]
LocalLookSource.enabled = false;
CameraController.Character = character;

This will ensure the character always has a look source.
Thanks, it works for a single character well. Another way is disabling/enabling of the RestrictRotation ability, however, you have to adjust its values.
So this option is preferred.

However, the switching between characters is still spamming these errors. The first switching (from 1st char to 2nd one) works well, however, the further switching to the first character back starts them. Meanwhile, the gameplay is working properly.

Error: There is no look source attached to the character. Ensure the character has a look source attached. For player characters the look source is the Camera Controller, and AI agents use the Local Look Source.
UnityEngine.Debug:LogError (object)
Opsive.UltimateCharacterController.ThirdPersonController.Character.MovementTypes.Combat:GetDeltaYawRotation (single,single,single,single) (at Assets/Opsive/UltimateCharacterController/Scripts/ThirdPersonController/Character/MovementTypes/Combat.cs:32)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotionHandler:GetDeltaYawRotation () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotionHandler.cs:196)
Opsive.UltimateCharacterController.Game.KinematicObjectManager/KinematicCharacter:Move (bool) (at Assets/Opsive/UltimateCharacterController/Scripts/Game/KinematicObjectManager.cs:224)

Opsive.UltimateCharacterController.Game.KinematicObjectManager:Update () (at Assets/Opsive/UltimateCharacterController/Scripts/Game/KinematicObjectManager.cs:805)

Could you please check this code?

C#:
    private void SwitchCharacters(GameObject m_Char1, GameObject m_Char2) {

            var prevCharacter = m_Char1;
            var spawnedCharacter = m_Char2;

            Opsive.Shared.Events.EventHandler.ExecuteEvent(prevCharacter, "OnEnableGameplayInput", false);
            var localLookSource = prevCharacter.GetComponent<Opsive.UltimateCharacterController.Character.LocalLookSource>();
            localLookSource.enabled = true;
       
            localLookSource.Target = spawnedCharacter.transform;

            Opsive.Shared.Events.EventHandler.ExecuteEvent(spawnedCharacter, "OnEnableGameplayInput", true);
            var localLookSource2 = spawnedCharacter.GetComponent<Opsive.UltimateCharacterController.Character.LocalLookSource>();
            localLookSource2.enabled = false;

            cameraController.Character = spawnedCharacter;

    }
 

Justin

Administrator
Staff member
At the end of that code do both characters have a look source? After the character is assigned to the camera controller you can output the look source for both characters and they should be non-null values.
 

wizard

New member
At the end of that code do both characters have a look source? After the character is assigned to the camera controller you can output the look source for both characters and they should be non-null values.
Here is what is going on step by step:

0. Starting with Char1 as the playable one
Char1.LookSource is Main Camera (Opsive.UltimateCharacterController.Camera.CameraController)
Char1.LocalLookSource is disabled
Char2.LookSource is null
Char2.LocalLookSource is enabled
No errors spam here

1. Switching to Char2
Char1.LookSource is null
Char1.LocalLookSource is enabled
Char2.LookSource is Main Camera (Opsive.UltimateCharacterController.Camera.CameraController)
Char2.LocalLookSource is disabled
No errors spam here

2. Switching back to Char1
Char2.LookSource is null
Char2.LocalLookSource is enabled
Char1.LookSource is Main Camera (Opsive.UltimateCharacterController.Camera.CameraController)
Char1.LocalLookSource is disabled
Errors spam is starting
 

Justin

Administrator
Staff member
After step 2 does both Char2 and Char1 have a LookSource? My guess is that you should set the main camera after disabling the Local Look Source, so your steps would be:

2. Switching back to Char1
Char2.LookSource is null
Char2.LocalLookSource is enabled
Char1.LocalLookSource is disabled
Char1.LookSource is Main Camera (Opsive.UltimateCharacterController.Camera.CameraController)
 

wizard

New member
After step 2 does both Char2 and Char1 have a LookSource? My guess is that you should set the main camera after disabling the Local Look Source, so your steps would be:
Thanks! It has worked this way:
C#:
    private void SwitchCharacters(GameObject m_Char1, GameObject m_Char2) {
            var prevCharacter = m_Char1;
            var spawnedCharacter = m_Char2;

            // Enable Char2
            Opsive.Shared.Events.EventHandler.ExecuteEvent(spawnedCharacter, "OnEnableGameplayInput", true);
            var localLookSource2 = spawnedCharacter.GetComponent<Opsive.UltimateCharacterController.Character.LocalLookSource>();
            localLookSource2.enabled = false;
            // Switch camera to Char2
            cameraController.Character = spawnedCharacter;

            // Disable Char1
            Opsive.Shared.Events.EventHandler.ExecuteEvent(prevCharacter, "OnEnableGameplayInput", false);
            var localLookSource = prevCharacter.GetComponent<Opsive.UltimateCharacterController.Character.LocalLookSource>();
            localLookSource.enabled = true;            
            localLookSource.Target = spawnedCharacter.transform;   
    }
 

Jaakk0S

New member
Thanks for this, this saved me. I am making a screen where the game is paused (timeScale=0) but the player needs to be able to move the camera to inspect an object, so the camera needs to detach from the character. Well, doesnt have to, I could also use a separate camera for this, but the player camera is already a composition of several cameras with huge post-processing stacks etc... I'm sure they could all be configured in a smart magic way to jump on the separate camera if I was just better at all of this, but at this point really I'd like to just detach the player camera...

I can confirm that the only thing that worked was to add a LocalLookSource component to my character (disable it by default), then pretty much:

C#:
Opsive.Shared.Events.EventHandler.ExecuteEvent(GameObject.FindGameObjectWithTag("Player"), "OnEnableGameplayInput", false);
myCameraController.Character = null;
this.player.GetComponent<LocalLookSource>().Target = some.transform; // this mustn't be empty
this.player.GetComponent<LocalLookSource>().enabled = true;

This disables the character input and frees the camera, and avoids the runtime exception saying Look Source is missing.

Oh just noticed, pretty much what wizard just said. :) This could benefit from documenting because I read all the docs and tried like 10 other things before finding just this page that solved it :)
 
Last edited:

Jaakk0S

New member
Looks like I got an issue with Combat movement type while doing the above, changing the look source manually. There's some code in Combat.cs that reads m_LookSource which will be null after changing the look source and will throw a manual exception and a nullpointer.

So, looks like those steps aren't enough to update m_LookSource in MovementType base class. In my own case it looks like it doesn't matter because I am making a pause menu and don't need movement while my camera is detached; I just replaced Combat with a modified version that doesn't exception when m_LookSource == null.
 
Top