Expand/ Modify Capsule Collider at runtime?

forzabo

Member
Is there any way to expand or change the FPC capsule collider at runtime? My use case is the player picks up an object to push around (a lawn mower, in fact) -- I'd like to be able to modify the colllider so the player can't push it thru walls, fences etc that otherwise restrict the players movement.

Things I've tried:

  • add capsule or sphere collider at runtime as a child of the capsule collider. Causes weird sh*t.
  • add capsule or sphere prior to runtime -- works fine but disabling at runtime doesn't work.
  • create duplicate FPS character with prebuilt extra collider to swap in at runtime -- doesn't seem to work b/c something keeps reactivating the original fpc gameobject
 

Justin

Administrator
Staff member
You can add colliders at runtime with:

UltimateCharacterController.AddCollider

And then you can remove with:

UltimateCharacterController.RemoveCollider

Take a look at the ride ability for an example.
 

forzabo

Member
Thanks Justin --

This is getting me closer:

  • "extra" collider added as child to FPC Colliders game object is ignored until AddCollider is called -- so far so good
  • However, after AddCollider is called, the FPC can only turn (mouse look), can't move (but can jump)

1546

1547
Code:
/// <summary>
    /// Interact with the target.
    /// </summary>
    public void Interact(GameObject character)
    {
        canInteract = false;
        LevelManager.instance.state = LevelManager.State.job;
        m_Prop.SetActive(false);
        pushMowerInstance = Instantiate(m_PushMower);

        player = LevelManager.instance.player;

        UltimateCharacterLocomotion loco = player.GetComponent<UltimateCharacterLocomotion>();
        loco.AddCollider(MowerCollider);

        gameObject.GetComponent<BoxCollider>().enabled = false;

        var inventory = player.GetComponent<InventoryBase>();
        if (inventory == null)
        {
            return;
        }

        // Drop the "weapons"
        for (int i = 0; i < inventory.SlotCount; ++i)
        {
            for (int j = 0; j < m_ItemTypes.Count; j++)
            {
                var item = inventory.GetItem(i, m_ItemTypes[j]);
                if (item != null)
                {
                    inventory.RemoveItem(m_ItemTypes[j], i, true);
                }
            }
        }
    }
 

Justin

Administrator
Staff member
My guess is that the collider is causing a collision that you aren't expecting. Can you send me a repro scene and I'll take a closer look at it?
 

forzabo

Member
Justin -- Thanks!

Minimal repro scene attached. You should be able to walk over to the lawn mower and activate it with the F key. At that point the issue appears. There are two colliders besides those in the player rig -- the ground, and the collider for the interactable, which is disabled as soon as the mower is "equipped" ("equipped" is in quotes because I'm not using the UCC system for equipping this particular item for various reasons).


Attached file tested in new project, Unity 2018.3, but Opsive folder is stripped out to keep file size manageable.
 

Attachments

Justin

Administrator
Staff member
Thanks. It looks like you have the mower collider added to the character initially and that is making the locomotion think that the collider is a subcollider. When the collider is then added it gets more confused over what is a valid collider.

I would start by adding the collider to the lawn mower, and then when the ability starts you add it to the locomotion component with AddCollider. This will prevent the character from adding it to the subcollider layer.
 

forzabo

Member
Justin, thank you

So when I try this approach, I'm not having any luck. The collider apparently gets added but then starts throwing errors as soon as I try to turn the character. Here's my stripped down script that is activated when the interactable is triggered:

Code:
public void Interact(GameObject character)
    {
        canInteract = false;

        player = GameObject.FindGameObjectWithTag("Player");
        UltimateCharacterLocomotion loco = player.GetComponent<UltimateCharacterLocomotion>();
        if(loco == null) {
            Debug.LogError("Locomotion Component not found");
            return;
        }


        m_Prop.SetActive(false);
        pushMowerInstance = Instantiate(m_PushMower);

        //position the mower 1 unit forward of the player rig
        Vector3 vec = player.transform.position + player.transform.forward;
        vec.y = 1;
        pushMowerInstance.transform.position = vec;
        pushMowerInstance.transform.rotation = player.transform.rotation * Quaternion.Euler(0, 90, 0);

        //add the collidr to the locomotion component
        MowerCollider = pushMowerInstance.transform.Find("MowerCollider").GetComponent<CapsuleCollider>();
        if (MowerCollider == null)
        {
            Debug.LogError("Mower Collider not found");
            return;
        }

        loco.AddCollider(MowerCollider);

        //disable the interactable collider, so we can move thru it
        gameObject.GetComponent<BoxCollider>().enabled = false;

    }
Error thrown with each frame:
Code:
NullReferenceException: Object reference not set to an instance of an object
Opsive.UltimateCharacterController.Utility.MathUtility.ApplyRotationToChildMatrices (UnityEngine.Transform current, UnityEngine.Transform root, UnityEngine.Quaternion deltaRotation) (at Assets/Opsive/UltimateCharacterController/Scripts/Utility/MathUtility.cs:268)
Opsive.UltimateCharacterController.Utility.MathUtility.ApplyRotationToChildMatrices (UnityEngine.Transform current, UnityEngine.Transform root, UnityEngine.Quaternion deltaRotation) (at Assets/Opsive/UltimateCharacterController/Scripts/Utility/MathUtility.cs:268)
Opsive.UltimateCharacterController.Utility.MathUtility.ApplyRotationToChildMatrices (UnityEngine.Transform current, UnityEngine.Transform root, UnityEngine.Quaternion deltaRotation) (at Assets/Opsive/UltimateCharacterController/Scripts/Utility/MathUtility.cs:268)
Opsive.UltimateCharacterController.Character.CharacterLocomotion.CheckRotation (UnityEngine.Quaternion rotationDelta, System.Boolean forceCheck) (at Assets/Opsive/UltimateCharacterController/Scripts/Character/CharacterLocomotion.cs:675)
Opsive.UltimateCharacterController.Character.CharacterLocomotion.UpdateRotation () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/CharacterLocomotion.cs:629)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotion.UpdateRotation () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotion.cs:876)
Opsive.UltimateCharacterController.Character.CharacterLocomotion.UpdatePositionAndRotation () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/CharacterLocomotion.cs:525)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotion.UpdatePositionAndRotation () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotion.cs:813)
Opsive.UltimateCharacterController.Character.CharacterLocomotion.UpdatePositionAndRotation (System.Boolean fromAnimatorMove) (at Assets/Opsive/UltimateCharacterController/Scripts/Character/CharacterLocomotion.cs:509)
Opsive.UltimateCharacterController.Character.CharacterLocomotion.OnAnimatorMove () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/CharacterLocomotion.cs:1444)
Opsive.UltimateCharacterController.Character.UltimateCharacterLocomotion.OnAnimatorMove () (at Assets/Opsive/UltimateCharacterController/Scripts/Character/UltimateCharacterLocomotion.cs:1738)
modified. stripped out scene attached. I've stripped out the code that was moving the lawn mower, too, just to make sure that wasn't causing problems...
 

Attachments

Justin

Administrator
Staff member
With your MowerCollider make sure you first reparent it to the character. This will allow the child rotations to be applied correctly. You could do something like:

Code:
MowerCollider.transform.parent = m_CollidersTrasform;
Where m_CollidersTransform is a new variable that points to the Character/Colliders Transform.[/code]
 

forzabo

Member
Bingo!

Thank you. I guess I should have thought of that, but I was a bit confused as to what "AddCollider" really does.

Anyway, it works, yay!

I appreciate the help.
 
Top