Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Hordaland · Jan 13, 2012 at 10:23 PM · colliderclippingcrouchisgrounded

Keeping speed while crouching in midair and remove clipping while returning to standing

I've been working on making a good crouching script now for a while but no matter how I try I can't put the last pieces together.

One thing I want is that if you jump while running (standing) and then start to crouch in midair you should not slow down except for when landing on the ground. I've been trying some IsGrounded-functions but when I do the script just ignore the slowdown altogether and makes the player move around with normal standingspeed while crouching.

The other (and most important - I even dare to say gamebreaking) missing component is the fact that the player should not be able to stand up if standing up will result in the player clipping through objects. At the moment I can stand up straight from crouching anywhere which isn't how it normally works in games. I've tried to create a collider with the same size as the First Person Controller collider and used some collider scripts to make the game realize that while anything is touching this collider the player should not be able to stand.

The code so far looks like this (it's a modified version of a crouching script I found here a while ago):

var forWalkSpeed: float = 7; // regular speed forward var sideWalkSpeed: float = 7; // regular speed sidestep var backWalkSpeed: float = 7; // regular speed backward var forCrchSpeed: float = 3; // crouching speed forward var sideCrchSpeed: float = 3; // crouching speed sidestep var backCrchSpeed: float = 3; // crouching speed backward

internal var forSpeed: float; // the current speed state internal var sideSpeed: float; internal var backSpeed: float;

internal var crouchHeight : float; // variables for character height while crouching internal var crouchingHeight : float;
internal var standingHeight: float; // height of character while standing internal var crouching = false; // boolean is crouching? //internal var running = false; // boolean is running?

internal var characterMotor: CharacterMotor; //direct variable to the characterMotor internal var mainCamera: GameObject; // direct variable to the mainCamera

//var distToGround: float;

function Start() { //initialize characterMotor = GetComponent(CharacterMotor); mainCamera = gameObject.FindWithTag ("MainCamera"); standingHeight = mainCamera.transform.localPosition.y; crouchingHeight = (standingHeight - 0.9); crouchHeight = (standingHeight - crouchingHeight); distToGround = collider.bounds.extents.y; // get the distance to ground }

function Update() { //simple machine for setting the current speed of the character if(crouching) { forSpeed = forCrchSpeed; // slow down when crouching sideSpeed = sideCrchSpeed; backSpeed = backCrchSpeed; } //else if( running ) //{ // speed = runSpeed; //} else { forSpeed = forWalkSpeed; backSpeed = backWalkSpeed; sideSpeed = sideWalkSpeed; } /* //If the sprint button is clicked, and not crouching .. SPRINT!

 if (Input.GetKey("left ctrl") || Input.GetKey("right ctrl")){
     if(!crouching){
         running = true;
         //cameraZoom.sprint = true;  //sets sprint true so the camera knows to pan out
     }
 } else {
     //cameraZoom.sprint = false;
     running = false;
 } */

 // if crouch button has been pressed, put FPS into crouch
 if (Input.GetButtonDown ("Crouch")){
     if(crouching){
         stopCrouching();
         return;
     }
     if(!crouching)
          crouch();
 }
 // crouch with smoothing
 if(crouching)
 {
     if(mainCamera.transform.localPosition.y > crouchingHeight){
         if(mainCamera.transform.localPosition.y - (crouchHeight*Time.deltaTime*4) < crouchingHeight){
             mainCamera.transform.localPosition.y = crouchingHeight;
         }
         else 
         {
             mainCamera.transform.localPosition.y -= crouchHeight*Time.deltaTime*4;
         }
     }
 }
 else 
 {
     if(mainCamera.transform.localPosition.y < standingHeight){
         if(mainCamera.transform.localPosition.y + (crouchHeight*Time.deltaTime*4) > standingHeight){
             mainCamera.transform.localPosition.y = standingHeight;
         }
         else
         {
             mainCamera.transform.localPosition.y += crouchHeight*Time.deltaTime*4;
         }
     }
 }
 //set the max speed in the char motor;
 characterMotor.movement.maxForwardSpeed = forSpeed; // set max forward speed
 characterMotor.movement.maxSidewaysSpeed = sideSpeed; // max sideway speed
 characterMotor.movement.maxBackwardsSpeed = backSpeed; //max backwards speed

}

// sets the size of the collider to crouch size

function crouch() { this.GetComponent(CharacterController).height -= crouchHeight; this.GetComponent(CharacterController).center -= Vector3(0,crouchHeight/2, 0); crouching = true; }

// resets the size of the collider to standing size
function stopCrouching() { crouching = false; this.GetComponent(CharacterController).height += crouchHeight; this.GetComponent(CharacterController).center += Vector3(0,crouchHeight/2, 0); }

/ function IsGrounded(): boolean { return Physics.Raycast(transform.position, -Vector3.up, distToGround + 0.1); }/

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by aldonaletto · Jan 13, 2012 at 11:30 PM

I would do the following changes:
1- cache the CharacterController at Start to save time:

... internal var character: CharacterController;

function Start(){ character = GetComponent(CharacterController); ... You can use it to know when the character is grounded with character.isGrounded

2- Use characterMotor.jumping.jumping to know when the character is jumping, and block the crouch speed:

    ...
    if(crouching && !characterMotor.jumping.jumping)
    {
        forSpeed = forCrchSpeed; // slow down when crouching
        sideSpeed = sideCrchSpeed;
        backSpeed = backCrchSpeed;
    }
    ...
You may also try to use character.isGrounded instead:
     if (crouching && character.isGrounded){


3- Before standing up, do a raycast upwards to check if there's enough room (set the float distUp variable to a suitable value):

    ...
    if (Input.GetButtonDown ("Crouch")){
        if(crouching && !Physics.RaycastHit(transform.position, Vector3.up, distUp)){
            stopCrouching();
            return;
        }
        if(!crouching)
            ...
I hope this can solve your problems - or at least help you to find the solutions.
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Hordaland · Jan 14, 2012 at 02:09 AM

Thanks alot! The speed is now the same even while I crouch midair. I also disabled the ability to jump while crouched since it's not appropriate behaviour to do so in the kind of slowpaced game I'm making.

The raycast worked after a light tweak I had to make since Unity gave me an error. Now it looks like this:

function Update(){

var hit : RaycastHit; ...

// if crouch button has been pressed, put FPS into crouch
if (Input.GetButtonDown ("Crouch")){
    if(crouching && !Physics.Raycast(transform.position, Vector3.up, hit, distUp)){
        stopCrouching();
        return;
    }
    if(!crouching)
         crouch();
}

The only issue I have is that if I don't stand directly below the object the rays won't hit. Is there any possibility to shoot out more rays and in different directions so that my whole character can enjoy this feeling of not being able to stand straight?

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image aldonaletto · Jan 14, 2012 at 05:27 AM 1
Share

You could use Physics.SphereCast ins$$anonymous$$d:

    if(crouching && !Physics.SphereCast(transform.position, character.radius, Vector3.up, hit, distUp)){
SphereCast is a kind of "thick" Raycast, with the specified radius.
avatar image Hordaland · Jan 14, 2012 at 02:37 PM 0
Share

Great! Thanks, you saved me alot of time.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

5 People are following this question.

avatar image avatar image avatar image avatar image avatar image

Related Questions

Player detecting collision when crouching 1 Answer

Internal collisions 1 Answer

Is moving a collider without rigidbody bad? 1 Answer

How to change box collider size without falling through the ground 1 Answer

Third person tank game: Rotating barrel clips through wall when tank isn't moving, even if I add a collider to it. 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges