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 Utman88 · May 21, 2012 at 02:58 AM · character controllerslopeslopes

CharacterController Hops along upward slopes

Facts:

My character controller uses a Capsule Collider

I check the isGrounded bool to see if my character can jump or is falling.

The problem:

My character hops along an upward slope, inhibiting jumping (You can't jump when you fall) and forcing me to use raycasts to see if I'm "on ground" or not (useless expensive check, if you ask me...).

So, given that Character Controllers are spastic, and that It's late in the dev to rip it out and use my own implementation, what can I do to resolve this issue?

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

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by stingman · May 21, 2012 at 05:01 AM

If you post your movement script this might be easier to solve. But in general have you tried working with the angle of movement to control this behavior? You could try using Vector3.Angle (in the docs) and adjust your movement based on the angle associated with your player's direction of movement along the Y axis when he's not jumping. For example apply more gravity if the angle is above a certain degree. The behavior sounds very weird, so seeing a script could help but I'd start there.

Comment
Add comment · Show 6 · 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 Utman88 · May 21, 2012 at 07:09 AM 0
Share

Here's a postup of my PlayerController class with all his movement code. A lot of comments have been removed, but there still is quite a bit of debug code.

 using UnityEngine;

using System.Collections; [RequireComponent(typeof(CharacterController))] public class PlayerController : $$anonymous$$onoBehaviour { public Transform GunPosition = null; public GameObject playerProjectileObject; public GameObject SpriteObject = null; public Sprite$$anonymous$$anager playerSprite$$anonymous$$anager; public float playerSpeed = 6.0f; public float playerJumpSpeed = 8.0f; public float gravity = 20.0f; public float firingInterval = 0.5f;

 public bool facingRight = true;
 
 private bool isAlive = true;
 
 private bool playerFireReadyNow = true;
 
 private Vector3 directionVector = Vector3.zero;

 private PlayerProgress progress = null;

 CharacterController controller;

 public float YApexOffset = 5.0f;
 float YApex = 0.0f;
 bool flagHitApex = false;

 void Awake()
 {   
     controller = GetComponent<CharacterController>();

     GunPosition = transform.FindChild("GunPos");

     GameObject progressObj = GameObject.Find("PlayerProgress");
     progress = progressObj.GetComponent<PlayerProgress>();
 }

 // Use this for initialization
 void Start () 
 {
     if(SpriteObject == null)
     {
         Debug.LogError("There's no sprite! UH-OH!!!!");
     }
     
     InitializePlayerObject();
 }

 void OnDrawGizmosSelected()
 {
     Gizmos.DrawRay(transform.position, transform.forward * 20);
 }

 void Update()
 {
     if (isAlive)
     {
         PlayerActions();
     }
 }
 
 void InitializePlayerObject()
 {
     transform.rotation = Quaternion.LookRotation(Vector3.right);
     facingRight = true;
 }
 
 void PlayerActions()
 {
     Player$$anonymous$$ove();
     PlayerJump();
     PlayerFire();

     Vector3 current$$anonymous$$ovementOffset = new Vector3(directionVector.x, directionVector.y, 0);
     controller.$$anonymous$$ove(current$$anonymous$$ovementOffset * Time.deltaTime);
 }

 void Player$$anonymous$$ove()
 {   
     
     bool is$$anonymous$$ovementInput = Input.GetButtonDown("Horizontal");
     float movementDirection = Input.GetAxis("Horizontal");
     
     
     {
         if($$anonymous$$athf.Abs(movementDirection) > 0.1)
         {
             Debug.Log("Walking...");
             playerSprite$$anonymous$$anager.ChangeAnimation("Walk");
         }
         else 
         {
             Debug.Log("Idle...");
             playerSprite$$anonymous$$anager.ChangeAnimation("Idle");
         }
         directionVector = new Vector3(movementDirection * playerSpeed, 0, 0);
         if($$anonymous$$athf.Abs(movementDirection) > 0.1f)
         {
             transform.rotation = Quaternion.LookRotation(directionVector);
         }
     }
     if (!controller.isGrounded && GroundCheck() == false)
     {
         playerSprite$$anonymous$$anager.ChangeAnimation("Jump");
     }
 }
 float CurJumpSpeed = 0.0f;
 float GroundY = 0.0f;
 void PlayerJump()
 {

     //apply gravity
     directionVector.y = controller.velocity.y - gravity * Time.deltaTime;
     float curY = transform.position.y;
     bool GroundCheckFail = !GroundCheck();
     //are we jumping?
     if ((Input.GetButtonDown("Jump") || Input.GetButtonDown("JumpAxis")) && controller.isGrounded && GroundCheckFail == false)
     {
         directionVector.y = playerJumpSpeed * gravity * Time.deltaTime;
         YApex = curY + YApexOffset;
         flagHitApex = false;
     }
     else if (!flagHitApex && (Input.GetButton("Jump") || Input.GetAxis("JumpAxis") > 0) && !controller.isGrounded && GroundCheckFail == true)
     {
         directionVector.y = playerJumpSpeed * gravity * Time.deltaTime;
         if (curY >= YApex - 0.1f)
             flagHitApex = true;
     }
     else if (!controller.isGrounded && GroundCheckFail == true && (!Input.GetButton("Jump") || Input.GetAxis("JumpAxis") <= 0))
     {
         flagHitApex = true;
     }
     
 }
 public float GroundCheckRayDistance = 1.2f;
 bool GroundCheck()
 {
     RaycastHit hit;
     Debug.DrawRay(transform.position, Vector3.down, Color.green, 16.0f);
     if (Physics.Raycast(transform.position, Vector3.down, out hit, GroundCheckRayDistance) == true)
     {
         Debug.DrawLine(transform.position, hit.point, Color.red);
         Debug.Log("Ground is " + hit.collider.name + ":" + hit.collider.tag);
         return true;
     }

     return false;
 }
 
 void PlayerFire()
 {
     bool isFireInput = Input.GetButton("Fire");
     
     if (isFireInput && playerFireReadyNow)
     {
         StartCoroutine(PlayerFireCoroutine());
     }
 }
 
 IEnumerator PlayerFireCoroutine()
 {    
     playerFireReadyNow = false;

     GameObject playerProjectileClone = (GameObject)Instantiate(playerProjectileObject, GunPosition.position, Quaternion.LookRotation(GunPosition.forward));
     Physics.IgnoreCollision(playerProjectileClone.collider, collider);
     
     yield return new WaitForSeconds(firingInterval);
     
     playerFireReadyNow = true;
 }

 void OnCollisionEnter(Collision collision)
 {
     if (isAlive)
     {
         string tag = collision.gameObject.tag;
         if(tag == "Enemy" || tag == "EnemyProjectile")
         {
             $$anonymous$$ill();
             return;
         }
     }
 }

 public void $$anonymous$$ill()
 {
     //TODO Run subroutine to play death
     Debug.Log("DEAD PLAYER!!!");
     StartCoroutine("PlayDeath");
 }

 IEnumerator PlayDeath()
 {
     isAlive = false;
     
     SpriteObject.renderer.enabled = false;
     yield return new WaitForSeconds(2);
     //If this is the last life, switch to Game Over,
     progress.PlayerLives -= 1;
     if(progress.PlayerLives <= 0)
     {
         Debug.Log("Game Over, man! Game over!");
     }
     //If not, reload the level.
     Application.LoadLevel("PreLevel");
 }

}

avatar image stingman · May 21, 2012 at 03:38 PM 0
Share

ok based on your original post saying the player hops along upward slopes you are saying he hops when running up a hill? this is correct? or did you mean downward slopes? Because after reading your movement section of your script there is technically nothing wrong with it but it could be an issue with changing values of your variables and/or changing the rotation based on your movedirection. Does your character stay facing straight on a slope or does he change his angle to face the direction? Based on what I'm reading it appears he changes his rotation to the face his direction of movement, but this is not restricted to any axis. Am I right? Also, is this a 2D game?

avatar image Utman88 · May 21, 2012 at 04:55 PM 0
Share

This is a 2D game, yes, and he is locked so he is facing straight along the X axis when traversing slopes (So his Up axis, no matter what the slope is, is {0, 1, 0} in the world, not the slopes Up). The problem is only occurring when going up hills - when he goes down, he moves and behaves absolutely fine.

avatar image stingman · May 22, 2012 at 02:13 AM 0
Share

One thing that caught my attention is how you use Raycasting to detect the ground. Since you are stating that the ray is being cast from the player's position directly below him this may produce some odd behavior when going up slopes. I suggest checking out the 2D tutorial to see how they detect collisions. It's very straightforward and works great... Just a thought. Wish I could help more but best of luck to you

avatar image Lukas_GMC · Oct 08, 2012 at 11:23 PM 1
Share

Did you ever manage to fix this? I'm doing something very similar and have been running into this issue ever since I started.

Show more comments

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

6 People are following this question.

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

Related Questions

Rigidbody controller and slopes 1 Answer

NEW CONTROLLER, NO SLOPE 0 Answers

[Character controller] run faster on slopes and jetpack 1 Answer

2D Slope Sliding: how to prevent with transform.translate logic 0 Answers

CharacterController Slope Problems 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