[BUG] KeyNotFoundException: The given key 'UnityEngine.RaycastHit' was not present in the dictionary

Hi,

I have a lot of testers now and sometimes while they are playing I'm getting this error logged in my Discord (I have realtime error detection discord bot)

[15:55:02] KeyNotFoundException: The given key 'UnityEngine.RaycastHit' was not present in the dictionary.System.Collections.Generic.Dictionary`2[TKey,TValue].get_Item (TKey key) (at <c9d3ffd4b98649ee9989e1908eaca019>:0)Opsive.UltimateCharacterController.Character.CharacterLocomotion.DetectCollisions () (at <5660b73b509d4872b6fa93e3f8e380f1>:0)Opsive.UltimateCharacterController.Character.CharacterLocomotion.UpdateCharacter () (at <5660b73b509d4872b6fa93e3f8e380f1>:0)Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotion.UpdateCharacter () (at <5660b73b509d4872b6fa93e3f8e380f1>:0)Opsive.UltimateCharacterController.Character.CharacterLocomotion.Move (System.Single horizontalMovement, System.Single forwardMovement, System.Single deltaYawRotation) (at <5660b73b509d4872b6fa93e3f8e380f1>:0)Opsive.UltimateCharacterController.SimulationManager+SmoothedCharacter.Move (System.Boolean preMove) (at <5660b73b509d4872b6fa93e3f8e380f1>:0)Opsive.UltimateCharacterController.SimulationManager.MoveCharacters (System.Boolean preMove, System.Single interpAmount) (at <5660b73b509d4872b6fa93e3f8e380f1>:0)Opsive.UltimateCharacterController.SimulationManager.FixedUpdate () (at <5660b73b509d4872b6fa93e3f8e380f1>:0)

I got it a few times myself, the game freezes for a second then its back to normal and I got no idea whats causing it. Its not breaking anything after the error and its usually logged in only once.
 
Are you using the latest version of the controller? If not, can you update to the latest version and see if you can still reproduce it? Also, can you enable the line numbers so I have a better idea of the cause?
 
I will try to upgrade to the newest and see if I can reproduce it. It happens randomly so I will leave it as unsolved and post an update later on.
 
Last edited:
Are you using the latest version of the controller? If not, can you update to the latest version and see if you can still reproduce it? Also, can you enable the line numbers so I have a better idea of the cause?

By the way - something unrelated with the new version after upgrading my character jumps higher (about 30-40%) was this a desired effect and could I somehow convert to my old values as I placed some platforms to be done with precise jumps?
 
Your best bet is to adjust the jump force to be the values that work with your platforms. Since December there have been some delta time improvements which cause the physics to be more consistent at variable framerates.
 
Are you using the latest version of the controller? If not, can you update to the latest version and see if you can still reproduce it? Also, can you enable the line numbers so I have a better idea of the cause?

Hello, I finally got the line number on the new version of the controller. Here's the full log

KeyNotFoundException: The given key 'UnityEngine.RaycastHit' was not present in the dictionary.
System.Collections.Generic.Dictionary`2[TKey,TValue].get_Item (TKey key) (at <c9d3ffd4b98649ee9989e1908eaca019>:0)
Opsive.UltimateCharacterController.Character.CharacterLocomotion.DetectCollisions () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/CharacterLocomotion.cs:958)
Opsive.UltimateCharacterController.Character.CharacterLocomotion.UpdateCharacter () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/CharacterLocomotion.cs:594)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotion.UpdateCharacter () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotion.cs:591)
Opsive.UltimateCharacterController.Character.CharacterLocomotion.Move (System.Single horizontalMovement, System.Single forwardMovement, System.Single deltaYawRotation) (at Assets/Opsive/UltimateCharacterController/Scripts/Character/CharacterLocomotion.cs:564)
Opsive.UltimateCharacterController.SimulationManager+SmoothedCharacter.Move (System.Boolean preMove) (at Assets/Opsive/UltimateCharacterController/Scripts/Game/SimulationManager.cs:169)
Opsive.UltimateCharacterController.SimulationManager.MoveCharacters (System.Boolean preMove, System.Single interpAmount) (at Assets/Opsive/UltimateCharacterController/Scripts/Game/SimulationManager.cs:723)
Opsive.UltimateCharacterController.SimulationManager.FixedUpdate () (at Assets/Opsive/UltimateCharacterController/Scripts/Game/SimulationManager.cs:671)

if it matters, if happens while executing my dash ability on a staircase, but not sure if it has anything to do with it
 
Is line 958 this for you?

Code:
                        var activeCollider = m_ColliderCount > 1 ? m_Colliders[m_ColliderIndexMap[closestRaycastHit]] : m_Colliders[m_ColliderIndex];

If the character has more than one collider this lookup should always succeed. Are you able to send me a small repro scene so I can take a closer look?
 
Does your character have more than one collider? You could wrap that line within an if (m_ColliderIndexMap.Contains(closestRaycastHit)) but I'd like to understand why it is occurring.
 
Does your character have more than one collider? You could wrap that line within an if (m_ColliderIndexMap.Contains(closestRaycastHit)) but I'd like to understand why it is occurring.

my character has the default collider spawned by the character creator, 1 trigger collider and 1 non-trigger collider - I use those extra two to listen for some special OnTriggerEnter events like entering a BuffZone & increasing the stats of the character. All of them are on the same layer - Character and only the default one has the PlayerCollider tag, the extra two are untagged.
 
If there is only one regular collider then that's causing the issue. Can you see why the m_Colliders array is being populated with that second trigger collider? This is done within CharacterLocomotion.AwakeInternal. I just added a trigger to the character as a test and it didn't get added. The code below should skip the trigger:

Code:
                if (!colliders[i].enabled || colliders[i].isTrigger) {
                    continue;
                }

I could see this failing if the trigger collider is set at runtime and the trigger property is set after CharacterLocomotion.AwakeInternal runs. To fix this you'd change the script execution order so the CharacterLocomotion component runs after the setter.
 
If there is only one regular collider then that's causing the issue. Can you see why the m_Colliders array is being populated with that second trigger collider? This is done within CharacterLocomotion.AwakeInternal. I just added a trigger to the character as a test and it didn't get added. The code below should skip the trigger:

Code:
                if (!colliders[i].enabled || colliders[i].isTrigger) {
                    continue;
                }

I could see this failing if the trigger collider is set at runtime and the trigger property is set after CharacterLocomotion.AwakeInternal runs. To fix this you'd change the script execution order so the CharacterLocomotion component runs after the setter.

Sorry, I didn't understand what I need to test. The 2 extra colliders are not assigned anywhere at least by me manually to any of your scripts. They are just children of "Colliders" game object where the CapsuleCollider also is located.

At the bottom of CharacterLocomotion.AwakeInternal I did this

foreach (var collider1 in colliders)
{
Debug.Log("COLLIDERS " + collider1.name);
}

foreach (var collider1 in m_Colliders)
{
Debug.Log("M_COLLIDERS " + collider1.name);
}

foreach (var collider1 in m_IgnoredColliders)
{
Debug.Log("Ignored_COLLIDERS " + collider1.name);
}

and the result is COLLIDERS CapsuleCollider, MyNonTriggerCollider, CapsuleCollider, MyNonTriggerCollider , MyTriggerCollider,

M_COLLIDERS CapsuleCollider, MyNonTriggerCollider, CapsuleCollider, MyNonTriggerCollider

ignored - 0

not sure why it added them twice in that list collection though (except for the trigger which is only inside the colliders and is added once.
 
Last edited:
So it's not assigning the trigger collider to the m_Colliders array? That's good.

What is MyNonTriggerCollider? Should that be used for collision detection?
 
So it's not assigning the trigger collider to the m_Colliders array? That's good.

What is MyNonTriggerCollider? Should that be used for collision detection?

I have a script similar to your damage zone and after the last update of the UCC, if my character dies inside the damage zone and respawns it keeps damaging the player even after respawning, so I put another collider just to be able to properly reset the collission. To be honest I think this exception was prior to the UCC update and prior to me adding that non-trigger collider
 
The exception will only occur if there are more than one colliders used for collision. Since that collider should not be used for collision make sure to mark it with the SubCharacter or IgnoreRaycast layer. This will prevent that collider from being added to the array.
 
Back
Top