RayCast StandartProjectAssets Ethan prefab problem.
Good day everyone. I try to learn ThirdPersonCharacter from standard Unity assets. When I loading Ethan prefab seems that everything works as it should be, But if I try to create a new project, than import new model ( or using same Ethan model ) adding all needed scripts to it. I can't achieve the same behavior. My player always is onAir state. After debugging little bit, i found that in CheckGroundStatus() method
 if (Physics.Raycast(transform.position + (Vector3.up * 0.1f), Vector3.down, out hitInfo, m_GroundCheckDistance))
, return false every time, so my player is hanging every time. Seem that this happens because m_GroundCheckDistance after I starting the script setting to 0.01f in HandleAirborneMovement method by this line code
 m_GroundCheckDistance = m_Rigidbody.velocity.y < 0 ? m_OrigGroundCheckDistance : 0.01f;
I can't understand that, seems that after running the game , script check raycast to ground every fixedUpdate iteration, getting false, setting m_GroundCheckDistance to 0.01f and that's happening continiusly. Maybe this happens because I have some RigidBody issues, and there is no gravity, that's why player don't' fall, but I have the same rigid body as in working example, and if I added scripts rigid body adding by its self, so I think there is some other problem. Does anyone know such behavior or can tell me what I was missing, or just can show me in what direction I should watch. I try to resolve it more that two days without results, hoping for your help. Thank you With Regards Andrey.
UPDATE:
Seems that I just find out, the issue was in Collider height. I mean that, I don't know why, but collider height should be not more and not less some value. For example, if collider height 1.9 that looks like everything works, but if collider 2 then player hanging, same result with 1.8 height. I think that value depends on model height's, my model a little bit taller than Ethan default model. Another strange thing is that, why collider wich is adding with scripts , don't configuration himself right even with a default model Ethan. So now we seem that raycasting ground depends on collider heights, Can someone answer this? Why it is so, I browse all scripts that I use (ThirdPersonUserControl, ThirdPersonCharacter) and can't find any clue with that values, more of that I can't even find any code that uses collider height Thank you.
UPDATE 2: Adding scripts that i use;
It user input script just for case
 using System;
 using UnityEngine;
 using UnityStandardAssets.CrossPlatformInput;
 
 namespace UnityStandardAssets.Characters.ThirdPerson
 {
     [RequireComponent(typeof (ThirdPersonCharacter))]
     public class ThirdPersonUserControl : MonoBehaviour
     {
         private ThirdPersonCharacter m_Character; // A reference to the ThirdPersonCharacter on the object
         private Transform m_Cam;                  // A reference to the main camera in the scenes transform
         private Vector3 m_CamForward;             // The current forward direction of the camera
         private Vector3 m_Move;
         private bool m_Jump;                      // the world-relative desired move direction, calculated from the camForward and user input.
 
         
         private void Start()
         {
             // get the transform of the main camera
             if (Camera.main != null)
             {
                 m_Cam = Camera.main.transform;
             }
             else
             {
                 Debug.LogWarning(
                     "Warning: no main camera found. Third person character needs a Camera tagged \"MainCamera\", for camera-relative controls.");
                 // we use self-relative controls in this case, which probably isn't what the user wants, but hey, we warned them!
             }
 
             // get the third person character ( this should never be null due to require component )
             m_Character = GetComponent<ThirdPersonCharacter>();
         }
 
 
         private void Update()
         {
             if (!m_Jump)
             {
                 m_Jump = CrossPlatformInputManager.GetButtonDown("Jump");
             }
         }
 
 
         // Fixed update is called in sync with physics
         private void FixedUpdate()
         {
             // read inputs
             float h = CrossPlatformInputManager.GetAxis("Horizontal");
             float v = CrossPlatformInputManager.GetAxis("Vertical");
             bool crouch = Input.GetKey(KeyCode.C);
 
             // calculate move direction to pass to character
             if (m_Cam != null)
             {
                 // calculate camera relative direction to move:
                 m_CamForward = Vector3.Scale(m_Cam.forward, new Vector3(1, 0, 1)).normalized;
                 m_Move = v*m_CamForward + h*m_Cam.right;
             }
             else
             {
                 // we use world-relative directions in the case of no main camera
                 m_Move = v*Vector3.forward + h*Vector3.right;
             }
 #if !MOBILE_INPUT
             // walk speed multiplier
             if (Input.GetKey(KeyCode.LeftShift)) m_Move *= 0.5f;
 #endif
 
             // pass all parameters to the character control script
             m_Character.Move(m_Move, crouch, m_Jump);
             m_Jump = false;
         }
     }
 }
 
And this is the main player script
 using UnityEngine;
 
 namespace UnityStandardAssets.Characters.ThirdPerson
 {
     [RequireComponent(typeof(Rigidbody))]
     [RequireComponent(typeof(CapsuleCollider))]
     [RequireComponent(typeof(Animator))]
     public class ThirdPersonCharacter : MonoBehaviour
     {
         [SerializeField] float m_MovingTurnSpeed = 360;
         [SerializeField] float m_StationaryTurnSpeed = 180;
         [SerializeField] float m_JumpPower = 12f;
         [Range(1f, 4f)][SerializeField] float m_GravityMultiplier = 2f;
         [SerializeField] float m_RunCycleLegOffset = 0.2f; //specific to the character in sample assets, will need to be modified to work with others
         [SerializeField] float m_MoveSpeedMultiplier = 1f;
         [SerializeField] float m_AnimSpeedMultiplier = 1f;
         [SerializeField] float m_GroundCheckDistance = 0.1f;
 
         Rigidbody m_Rigidbody;
         Animator m_Animator;
         bool m_IsGrounded;
         float m_OrigGroundCheckDistance;
         const float k_Half = 0.5f;
         float m_TurnAmount;
         float m_ForwardAmount;
         Vector3 m_GroundNormal;
         float m_CapsuleHeight;
         Vector3 m_CapsuleCenter;
         CapsuleCollider m_Capsule;
         bool m_Crouching;
 
 
         void Start()
         {
             m_Animator = GetComponent<Animator>();
             m_Rigidbody = GetComponent<Rigidbody>();
             m_Capsule = GetComponent<CapsuleCollider>();
             m_CapsuleHeight = m_Capsule.height;
             m_CapsuleCenter = m_Capsule.center;
 
             m_Rigidbody.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ;
             m_OrigGroundCheckDistance = m_GroundCheckDistance;
         }
 
 
         public void Move(Vector3 move, bool crouch, bool jump)
         {
 
             // convert the world relative moveInput vector into a local-relative
             // turn amount and forward amount required to head in the desired
             // direction.
             if (move.magnitude > 1f) move.Normalize();
             move = transform.InverseTransformDirection(move);
             CheckGroundStatus();
             move = Vector3.ProjectOnPlane(move, m_GroundNormal);
             m_TurnAmount = Mathf.Atan2(move.x, move.z);
             m_ForwardAmount = move.z;
 
             ApplyExtraTurnRotation();
 
             // control and velocity handling is different when grounded and airborne:
             if (m_IsGrounded)
             {
                 HandleGroundedMovement(crouch, jump);
             }
             else
             {
                 HandleAirborneMovement();
             }
 
             ScaleCapsuleForCrouching(crouch);
             PreventStandingInLowHeadroom();
 
             // send input and other state parameters to the animator
             UpdateAnimator(move);
         }
 
 
         void ScaleCapsuleForCrouching(bool crouch)
         {
             if (m_IsGrounded && crouch)
             {
                 if (m_Crouching) return;
                 m_Capsule.height = m_Capsule.height / 2f;
                 m_Capsule.center = m_Capsule.center / 2f;
                 m_Crouching = true;
             }
             else
             {
                 Ray crouchRay = new Ray(m_Rigidbody.position + Vector3.up * m_Capsule.radius * k_Half, Vector3.up);
                 float crouchRayLength = m_CapsuleHeight - m_Capsule.radius * k_Half;
                 if (Physics.SphereCast(crouchRay, m_Capsule.radius * k_Half, crouchRayLength, ~0, QueryTriggerInteraction.Ignore))
                 {
                     m_Crouching = true;
                     return;
                 }
                 m_Capsule.height = m_CapsuleHeight;
                 m_Capsule.center = m_CapsuleCenter;
                 m_Crouching = false;
             }
         }
 
         void PreventStandingInLowHeadroom()
         {
             // prevent standing up in crouch-only zones
             if (!m_Crouching)
             {
                 Ray crouchRay = new Ray(m_Rigidbody.position + Vector3.up * m_Capsule.radius * k_Half, Vector3.up);
                 float crouchRayLength = m_CapsuleHeight - m_Capsule.radius * k_Half;
                 if (Physics.SphereCast(crouchRay, m_Capsule.radius * k_Half, crouchRayLength, ~0, QueryTriggerInteraction.Ignore))
                 {
                     m_Crouching = true;
                 }
             }
         }
 
 
         void UpdateAnimator(Vector3 move)
         {
             // update the animator parameters
             m_Animator.SetFloat("Forward", m_ForwardAmount, 0.1f, Time.deltaTime);
             m_Animator.SetFloat("Turn", m_TurnAmount, 0.1f, Time.deltaTime);
             m_Animator.SetBool("Crouch", m_Crouching);
             m_Animator.SetBool("OnGround", m_IsGrounded);
             if (!m_IsGrounded)
             {
                 m_Animator.SetFloat("Jump", m_Rigidbody.velocity.y);
             }
 
             // calculate which leg is behind, so as to leave that leg trailing in the jump animation
             // (This code is reliant on the specific run cycle offset in our animations,
             // and assumes one leg passes the other at the normalized clip times of 0.0 and 0.5)
             float runCycle =
                 Mathf.Repeat(
                     m_Animator.GetCurrentAnimatorStateInfo(0).normalizedTime + m_RunCycleLegOffset, 1);
             float jumpLeg = (runCycle < k_Half ? 1 : -1) * m_ForwardAmount;
             if (m_IsGrounded)
             {
                 m_Animator.SetFloat("JumpLeg", jumpLeg);
             }
 
             // the anim speed multiplier allows the overall speed of walking/running to be tweaked in the inspector,
             // which affects the movement speed because of the root motion.
             if (m_IsGrounded && move.magnitude > 0)
             {
                 m_Animator.speed = m_AnimSpeedMultiplier;
             }
             else
             {
                 // don't use that while airborne
                 m_Animator.speed = 1;
             }
         }
 
 
         void HandleAirborneMovement()
         {
             // apply extra gravity from multiplier:
             Vector3 extraGravityForce = (Physics.gravity * m_GravityMultiplier) - Physics.gravity;
             m_Rigidbody.AddForce(extraGravityForce);
 
             m_GroundCheckDistance = m_Rigidbody.velocity.y < 0 ? m_OrigGroundCheckDistance : 0.01f;
         }
 
 
         void HandleGroundedMovement(bool crouch, bool jump)
         {
             // check whether conditions are right to allow a jump:
             if (jump && !crouch && m_Animator.GetCurrentAnimatorStateInfo(0).IsName("Grounded"))
             {
                 // jump!
                 m_Rigidbody.velocity = new Vector3(m_Rigidbody.velocity.x, m_JumpPower, m_Rigidbody.velocity.z);
                 m_IsGrounded = false;
                 m_Animator.applyRootMotion = false;
                 m_GroundCheckDistance = 0.1f;
             }
         }
 
         void ApplyExtraTurnRotation()
         {
             // help the character turn faster (this is in addition to root rotation in the animation)
             float turnSpeed = Mathf.Lerp(m_StationaryTurnSpeed, m_MovingTurnSpeed, m_ForwardAmount);
             transform.Rotate(0, m_TurnAmount * turnSpeed * Time.deltaTime, 0);
         }
 
 
         public void OnAnimatorMove()
         {
             // we implement this function to override the default root motion.
             // this allows us to modify the positional speed before it's applied.
             if (m_IsGrounded && Time.deltaTime > 0)
             {
                 Vector3 v = (m_Animator.deltaPosition * m_MoveSpeedMultiplier) / Time.deltaTime;
 
                 // we preserve the existing y part of the current velocity.
                 v.y = m_Rigidbody.velocity.y;
                 m_Rigidbody.velocity = v;
             }
         }
 
 
         void CheckGroundStatus()
         {
             RaycastHit hitInfo;
 #if UNITY_EDITOR
             // helper to visualise the ground check ray in the scene view
             Debug.DrawLine(transform.position + (Vector3.up * 0.1f), transform.position + (Vector3.up * 0.1f) + (Vector3.down * m_GroundCheckDistance));
 #endif
             // 0.1f is a small offset to start the ray from inside the character
             // it is also good to note that the transform position in the sample assets is at the base of the character
             if (Physics.Raycast(transform.position + (Vector3.up * 0.1f), Vector3.down, out hitInfo, m_GroundCheckDistance))
             {
                 m_GroundNormal = hitInfo.normal;
                 
                 m_IsGrounded = true;
                 m_Animator.applyRootMotion = true;
             }
             else
             {
                 m_IsGrounded = false;
                 m_GroundNormal = Vector3.up;
                 m_Animator.applyRootMotion = false;
             }
         }
     }
 }
 
 
 
 
Is your character moving on the y axis? if it stays in one position it will check the distance to 0.01 and the raycast will never reach anything.
Thank for help, Please see updates. $$anonymous$$aybe you know right answers.
Answer by JedBeryll · Jan 23, 2016 at 09:27 PM
It's not specifically about collider heights but it is because of distance in general. So basically for a taller model you need to cast a longer ray to reach the ground. example: you have a 1.8 meter tall character and start casting from 1.9 meters then to reach the ground you need to cast a ray at least 1.9m far. So the raycast distance should be: your character height + distance between character and the casting point (you mentioned this: transform.position + (Vector3.up * 0.1f) so it should be 0.1 + character height).
Can you explain that altering collider height value resolve the problem that I described previously ? I don't update any script value just collider height . Thank you.
I'm not sure what you mean... Though it would help a lot if you posted the whole script.
I am trying to say that I don't change my model height for make it works. I just change collider height. That's why I don't quite understand how collider height and model height interrelated with each other. I using standard assets scripts ThirdPersonUserControl, ThirdPersonCharacter. If you want I can post it here. Once again thank you for you help
Answer by dronissimo · Jan 25, 2016 at 10:26 AM
Sorry must be we misunderstood each other, when I say that there is no gravity it was just a purpose about why this scripts don't work. I have graviti with Rigid Body on my player. About that m_GroundCheckDistance = m_Rigidbody.velocity.y < 0 ? m_OrigGroundCheckDistance : 0. This code was made for falling purspose , if I understands right.
Your answer
 
 
             Follow this Question
Related Questions
Raycast Not Detecting Hit 0 Answers
Angled Physics.Raycast not returning true (C# / C sharp) 1 Answer
Raycast can't detect items by player's feet 2 Answers
What is the best way to do a 2D Ground Check? 0 Answers
Third Person Controller Script Turning Randomly Up and Down Hill [PLEASE HELP] 0 Answers
 koobas.hobune.stream
koobas.hobune.stream 
                       
                
                       
			     
			 
                