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 munaeem · Nov 15, 2012 at 07:02 PM · collisioncharactermecanimgravitylocomotion

Capsule collider not touching the ground.

Hi,

i have a character, which has functions from mecanim. My problem is that on my character, capsule collider is attached. So whenever I jump the collider rescales while jumping (new feature in Unity4) which is a good thing. However, when my player runs from the stairs to somewhere where it should fall on the ground. So rather than falling on the ground he continues on(does not fall down to the ground). But when i move my character sideways, then he starts moving down slowly, or if i just completely stop he will fall to the ground. I have tried changing the capsule to character Controller but then when i jump the collider does not scale down when i jump which i don't like. i don't know why but I have applied gravity swell. Did not help. This picture will help you understand. Picture is here

Here is the code i am using for the character to move.

 using UnityEngine;
 using System;
 using System.Collections;
   
 [RequireComponent(typeof(Animator))]  
 [RequireComponent(typeof(CapsuleCollider))]  
 [RequireComponent(typeof(Rigidbody))]  
 
 public class BotCtrl : MonoBehaviour {
     
     [System.NonSerializedAttribute]
     public bool gotWrench;
     
     protected Animator animator;
     CapsuleCollider col;
     float h;
     float v;
     AnimatorStateInfo baseCurrentState;
     AnimatorStateInfo baseNextState;
     AnimatorStateInfo otherMovesCurrentState;
     
     public float DirectionDampTime = 0.15f;
     public float AnimSpeed = 1.2f;
     public float MoveSpeed = 1.5f;
     public float rotSpeed = 90.0f;
     public float JumpHeight = 70.0f;
     public bool useCurves;
     Transform grabbableObj;
     public bool ApplyGravity = true; 
 
     
     void Awake(){
         if(gameObject.tag != "Player")
             gameObject.tag="Player";
     }
     
     void Start () {
         animator = GetComponent<Animator>();
         animator.speed=AnimSpeed;
         
         if(animator.layerCount>1){
             animator.SetLayerWeight(1,1.0f);
         }
         col = GetComponent<CapsuleCollider>();
         
         grabbableObj = GameObject.FindWithTag("grabbable").transform;
     }
     
     void FixedUpdate () {
         
         // Grab Input each frame
             h = Input.GetAxis("Horizontal");
             v = Input.GetAxis("Vertical");
         
         if(animator){
             // Set Speed and Direction Parameters to H and V axes
             animator.SetFloat ("Speed", v);
             animator.SetFloat("Direction", h, DirectionDampTime, Time.deltaTime);
             
             // Set variables for info on states
             baseCurrentState = animator.GetCurrentAnimatorStateInfo(0);
             baseNextState = animator.GetNextAnimatorStateInfo(0);
             
             if(animator.layerCount>1){
                 otherMovesCurrentState = animator.GetCurrentAnimatorStateInfo(1);
             }
             
             //Trigger Jump if we are running
             if(baseCurrentState.IsName("Base.Locomotion")){
                 if(Input.GetButtonDown("Jump")){
                     animator.SetBool("Jump", true );     
                 }
             }
             // Are we in idle state in Base Layer? set actions
             else if(baseCurrentState.IsName("Base.Idle")){
                 // allow pivot on spot with Horizontal axis keys
                 transform.Rotate (new Vector3(0,h*Time.deltaTime*rotSpeed,0));
 
                 // make fire button cause a Wave during idle
                 if(Input.GetButtonDown("Jump")){
                     animator.SetBool("Wave", true );
                 }
             }
             else if(baseCurrentState.IsName("Base.idleGrab")){
                 // allow pivot on spot with Horizontal axis keys
                 transform.Rotate (new Vector3(0,h*Time.deltaTime*rotSpeed,0));
                 animator.SetBool("Grab", false );
             }
             else if(baseCurrentState.IsName("Base.Jump") && !animator.IsInTransition(0)){
                 // Reset our parameter to avoid looping
                 animator.SetBool("Jump", false);
                 
                 // allow half as much rotation during jump
                 transform.Rotate (new Vector3(0,h*Time.deltaTime*rotSpeed*0.5f,0));
                 
                 if(useCurves){
                     //set the collider height and Y center during the jumps, based on curves
                     col.center=new Vector3(0, animator.GetFloat("ColliderY"), 0);    
                     col.height=animator.GetFloat("ColliderHeight");
                 
                     //add extra force to main jump
                     rigidbody.AddForce(Vector3.up * animator.GetFloat("Jumper") * JumpHeight);
                 }
             }    
             else if(baseCurrentState.IsName("Base.JumpDownRollRun") && !animator.IsInTransition(0)){
                 if(useCurves){
                     col.center=new Vector3(0,animator.GetFloat("ColliderY"),0);    
                     col.height=animator.GetFloat("ColliderHeight");    
                 }
             }
             else{
                 // fallback to reset collider height & position
                 col.center = new Vector3(0,1,0);
                 col.height=2;
             } 
             
             // Check other moves layer for status
             
         }
     }
 
     void OnAvatarIK(){    
         if(baseCurrentState.IsName("Base.idleGrab") || baseNextState.IsName("Base.idleGrab")){
             float grabCurve = animator.GetFloat ("GrabCurve");
             AvatarIKGoal rightHand = AvatarIKGoal.RightHand;
             
             if(grabbableObj != null && !gotWrench) {
                 if(useCurves){
                     // Use the Curve from grabbing animation to drive smoothing of avatar hand position
                     animator.SetIKPositionWeight(rightHand, grabCurve);
                     animator.SetIKRotationWeight(rightHand, grabCurve);
                 }
                 // Set IK hand position and rotation destination 
                 animator.SetIKPosition(rightHand, grabbableObj.position);
                 animator.SetIKRotation(rightHand, grabbableObj.rotation);    
             }
             else{
                 // Reset Hand to be controlled by animation
                 animator.SetIKPositionWeight(rightHand, 0);
                 animator.SetIKRotationWeight(rightHand, 0);    
             }
         }
     }
 
     void OnAvatarMove(){
         // Set up for a rigidbody - set the RB position equal to the animator deltaPosition and increase by MoveSpeed
         rigidbody.position += animator.deltaPosition * MoveSpeed;
         transform.rotation *= animator.deltaRotation;     
     }
 }

Tell me what should i do in order to make him touché the ground ? Please help here

Comment
Add comment · Show 14
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 sparkzbarca · Nov 15, 2012 at 09:11 PM 0
Share

2 questions

A. are you using a kinematic rigidbody? You appear to be because you don't appear to be moving the animator through addforce but through direct movement of the transform.

please note that gravity doesnt apply to kinematic rigidbodies. the whole point of marking an object kinematic is to avoid physics stuff done to it.

If you'd like to have gravity do a raycast to the ground and whenever the distance between the bottom of the collider and the terrain (or any box or any object really) is greater than epsilon (epsilon if you don't know is a math term, it just means a really small number number, a number greater than zero but close to it, it can be found in mathf.epsilon for a unity representation or you can just pick a small number.

if the difference is greater than epsilon you move it DURING FIXED UPDATE lerping it towards the ground at 9.8 meters per second squared if you want

B. if so are you applying animations during physics?

avatar image munaeem · Nov 15, 2012 at 10:13 PM 0
Share

is kinematic is unchecked but i hv the rigid body component. can you give me some more info on how i should add ray-cast to the ground and player so that they meet ? please :)

avatar image sparkzbarca · Nov 15, 2012 at 10:51 PM 0
Share
 void FixedUpdate(){
 
 //first we set up an empty ray and raycasthit
 Ray myray;
 Raycasthit ObjectHit;
 
 //we assign the ray so it casts from the right spot
 //in the right direction
 myray.origin = player.transform.position;
 //notice the negative sign, it inverses the vector. up == down
 myray.direction = -player.transform.up;
 
 //now we raycast, notice the out, that just means
 //the raycast modifies the value of ObjectHit
 //basically ObjectHit now contains info about what we hit
 
 physics.raycast(ray,out ObjectHit);
 
 //now we'll check to see how far what we hit is
 //from the nearest point to it on the collider
 //if the collider is on the ground 
 //or another object and the ray is 
 //casting down, which it is casting down
 //the distance between what we hit and the collider
 //should basically be zero.
 
 //ClosestPointOnBounds just finds the closet 
 //point on a collider to another point you give it.
 
 //objectHit.point is the point we hit on whatever 
 //object is directly below the player. Since there 
 //should always be terrain or something eventually
 //below the player at some point we'll hit something.
 
 float distance = vector3.distance(player.collider.ClosestPointOnBounds(ObjectHit.point), Hit.point);
 
 //now we have the distance between the collider and the ground/object/etc whatever is below us.
 
 if(distance  > mathf.epsilon)
 {
    //this will only be ran if the distance between the 
    //player and the ground is not zero, basically your
    //airborne
    //you can sub in a small number you chose for epsilon
    //if you want.
    
    //moves the player down at 1meter per second
    player.rigidbody.addforce(-vector3.up);
    
    //moves the player down at 9.8meters per second
    player.rigidbody.addforce (-vector3.up * 9.8);
 
 }
 
 }
 

just to be clear, i didn't actually try this code at all. But thats pretty much it. Think that add force code is right to add force properly. i'm not sure if you add force with time.deltatime or not. You might need to but I don't think so. Unless you do it in Update ins$$anonymous$$d of FixedUpdate. You should just used fixedupdate though.

avatar image munaeem · Nov 15, 2012 at 11:18 PM 0
Share

Yh i tried but sory i did not work. btw thanks.

avatar image sparkzbarca · Nov 16, 2012 at 12:50 AM 1
Share

yea he said he doesnt want one because he cant modify the size of the collider during a jump like he wants.

Show more comments

2 Replies

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

Answer by munaeem · Nov 22, 2012 at 05:28 PM

Hi, i have fixed it and found solution to my own problem. I don't know why I always solve my own problem (unity). Well anyways, there are some changes in the engine or script what ever and if you are getting this problem from BotCtrl.cs script re-place this script and you'll be done with it. and also make sure in the animator window to the base layer 'IK something' is checked. It is the box right under it. Good luck.

 using UnityEngine;
 using System;
 using System.Collections;
 
 [RequireComponent(typeof(Animator))]  
 [RequireComponent(typeof(CapsuleCollider))]  
 [RequireComponent(typeof(Rigidbody))]  
 
 public class BotCtrl : MonoBehaviour {
 
     [System.NonSerializedAttribute]
     public bool gotWrench;
 
     protected Animator animator;
     CapsuleCollider col;
     float h;
     float v;
     AnimatorStateInfo baseCurrentState;
     AnimatorStateInfo baseNextState;
     AnimatorStateInfo otherMovesCurrentState;
 
     public float DirectionDampTime = 0.15f;
     public float AnimSpeed = 1.2f;
     public float MoveSpeed = 1.5f;
     public float rotSpeed = 90.0f;
     public float JumpHeight = 70.0f;
     public bool useCurves;
     Transform grabbableObj;
 
     void Awake(){
        if(gameObject.tag != "Player")
          gameObject.tag="Player";
     }
 
     void Start () {
 
        animator = GetComponent<Animator>();
        animator.speed=AnimSpeed;
 
        if(animator.layerCount>1){
          animator.SetLayerWeight(1,1.0f);
        }
        col = GetComponent<CapsuleCollider>();
 
        grabbableObj = GameObject.FindWithTag("grabbable").transform;
     }
 
     void FixedUpdate () {
 
        // Grab Input each frame
        h = Input.GetAxis("Horizontal");
         v = Input.GetAxis("Vertical");  
 
        if(animator){
          // Set Speed and Direction Parameters to H and V axes
          animator.SetFloat ("Speed", v);
          animator.SetFloat("Direction", h, DirectionDampTime, Time.deltaTime);
 
          // Set variables for info on states
          baseCurrentState = animator.GetCurrentAnimatorStateInfo(0);
          baseNextState = animator.GetNextAnimatorStateInfo(0);
 
          if(animator.layerCount>1){
           otherMovesCurrentState = animator.GetCurrentAnimatorStateInfo(1);
          }
 
          //Trigger Jump if we are running
             if(baseCurrentState.IsName("Base.Locomotion")){
           if(Input.GetButtonDown("Jump")){
               animator.SetBool("Jump", true );   
           }
          }
          // Are we in idle state in Base Layer? set actions
          else if(baseCurrentState.IsName("Base.Idle")){
           // allow pivot on spot with Horizontal axis keys
           transform.Rotate (new Vector3(0,h*Time.deltaTime*rotSpeed,0));
 
           // make fire button cause a Wave during idle
           if(Input.GetButtonDown("Jump")){
               animator.SetBool("Wave", true );
           }
          }
          else if(baseCurrentState.IsName("Base.idleGrab")){
           // allow pivot on spot with Horizontal axis keys
           transform.Rotate (new Vector3(0,h*Time.deltaTime*rotSpeed,0));
           animator.SetBool("Grab", false );
          }
          else if(baseCurrentState.IsName("Base.Jump") && !animator.IsInTransition(0)){
           // Reset our parameter to avoid looping
                 animator.SetBool("Jump", false);
 
           // allow half as much rotation during jump
           transform.Rotate (new Vector3(0,h*Time.deltaTime*rotSpeed*0.5f,0));
 
           if(useCurves){
               //set the collider height and Y center during the jumps, based on curves
               col.center=new Vector3(0, animator.GetFloat("ColliderY"), 0);  
               col.height=animator.GetFloat("ColliderHeight");
 
               //add extra force to main jump
               rigidbody.AddForce(Vector3.up * animator.GetFloat("Jumper") * JumpHeight);
           }
          }    
          else if(baseCurrentState.IsName("Base.JumpDownRollRun") && !animator.IsInTransition(0)){
           if(useCurves){
               col.center=new Vector3(0,animator.GetFloat("ColliderY"),0);    
               col.height=animator.GetFloat("ColliderHeight");    
           }
          }
          else{
           // fallback to reset collider height & position
           col.center = new Vector3(0,1,0);
           col.height=2;
          } 
 
          // Check other moves layer for status
          if(otherMovesCurrentState.IsName("OtherMoves.Wave")){
               animator.SetBool("Wave", false );
          }    
        }     
     }   
 
     void OnAnimatorIK(){   
        if(baseCurrentState.IsName("Base.idleGrab") || baseNextState.IsName("Base.idleGrab")){
          float grabCurve = animator.GetFloat ("GrabCurve");
          AvatarIKGoal rightHand = AvatarIKGoal.RightHand;
 
          if(grabbableObj != null && !gotWrench) {
           if(useCurves){
               // Use the Curve from grabbing animation to drive smoothing of avatar hand position
               animator.SetIKPositionWeight(rightHand, grabCurve);
               animator.SetIKRotationWeight(rightHand, grabCurve);
           }
           // Set IK hand position and rotation destination 
           animator.SetIKPosition(rightHand, grabbableObj.position);
           animator.SetIKRotation(rightHand, grabbableObj.rotation);   
          }
          else{
           // Reset Hand to be controlled by animation
           animator.SetIKPositionWeight(rightHand, 0);
           animator.SetIKRotationWeight(rightHand, 0); 
          }
        }
     }
 
     void OnAnimatorMove(){
        // Set up for a rigidbody - set the RB position equal to the animator deltaPosition and increase by MoveSpeed
        rigidbody.position += animator.deltaPosition * MoveSpeed;
        transform.rotation *= animator.deltaRotation;     
     }
 }
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 ippdev · Nov 16, 2012 at 05:25 PM

Try setting the Y Transform Based on Feet in the Preview clip setup.

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 munaeem · Nov 22, 2012 at 05:24 PM 0
Share

no actually its mecanim and some problem with script i got it fixed

avatar image munaeem · Nov 22, 2012 at 05:26 PM 0
Share

Thank you for the answer

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

12 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to maintain collision while moving the player? 2 Answers

How to change gravity direction on Character Motor 0 Answers

Error when colliding and calling a IEnumerator 1 Answer

gravity or others. i don't get it. what i suppose to coding it 1 Answer

Simple Circular jump along local normal- similar to planetary gravity 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