- Home /
Detect collision when changing character controller height
I am using the standard first person character controller and wanted to enable crouching. I added the following script to it, based on one I found in another question on this site.
using UnityEngine;
using System.Collections;
public class CrouchController : MonoBehaviour
{
private CharacterController character;
private float initialHeight;
void Awake()
{
character = GetComponent<CharacterController>();
initialHeight = character.height;
}
void Update()
{
float newHeight = Input.GetButton("Crouch") ? 0.5f * initialHeight : initialHeight;
float currentHeight = character.height;
character.height = Mathf.Lerp(currentHeight, newHeight, 5 * Time.deltaTime);
transform.position = transform.position + new Vector3(0, (character.height - currentHeight) / 2, 0);
}
}
This works perfectly except for one small detail. If I crouch and move beneath a collider, then release crouch, I will return to full height and pass through the collider. I would like the player to simply stop when this kind of collision occurs, but I'm having a hard time figuring out how to do this. It doesn't seem like I can place a script directly on the CharacterController component to detect this (nor do I know how I would filter such collisions out from normal ones) and detecting a collision with the character controller component from within this script doesn't appear to be possible. Any thoughts on how I can go about solving this dilemma?
Answer by TomPendergrass · Dec 30, 2012 at 09:19 PM
I just recently added this functionality to my video game (arxcatalyst.weebly.com) Although I'm programming my character control script from scratch and haven't really used the character controller, the same technique applies I'm sure. When my character wants to stand I do a sphere cast upwards. It's distance is up to the height the character would be standing normally. if it collides with something, I don't allow the function to run that makes the character stand. The spherecast has the same radius as the capsule collider on the character.
Answer by whydoidoit · Dec 30, 2012 at 09:22 PM
You could simply have a trigger box/sphere collider attached to a child of the player that doesn't change its position during the crouch and then maintain a boolean when that trigger is entered and reset it when it exits. If the boolean is set, the character should not try to stand up.
I had the same idea and tried doing this initially, but since that script moves the entire object, it would have involved placing the entire character controller GameObject inside an empty for the explicit purpose of tracking crouching. Feels a little hacky to me since the trigger would be detecting collisions even when I'm not crouching (jumping against the ceiling for instance).
Sure - but the performance of a sphere cast is significantly slower than a trigger collision - still as its for your player - it shouldn't be too onerous.
I would be turning that child object off (SetActive(false)) when not crouching BTW
Would you $$anonymous$$d showing me the facts that prove a sphere cast projected only when the Input is Released is slower than a trigger that must adjust it's state through every collision? I do many sphere casts for characters and my own Artificial Pathfinding. The pathfinding script completed about 40 spherecasts in 2 milliseconds last I checked.