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 ToeBeanGames · Jul 20, 2014 at 08:24 PM · rigidbodycontroller

Problems with custom controller

I'm having a few issues with my character controller. While I do have movement and jumping working, as well as aiming the weapon, the problems are with character states.

So what's going on is I added a force in Update that just adds gravity so the character will fall down when they walk off the edge of a platform. I also have the CharacterState set up with Idle, Walk, Jump, and Fall. The problem with this is, with the gravity being added in Update, if I jump and hold down the jump key long enough then my character will be stuck in Fall, unable to do anything but look up and down. Another thing that happens is if I let go of Jump at the right moment, I will hit the ceiling in Fall and switch to Idle, and I'll slowly float down.

Additionally, I'm using velocity to move the character and it isn't really working as I'd want. First off, even with gravity being added at the beginning, I can't walk off of platforms and I instead just fly over the gaps. Also, since I'm moving the player along forward, I don't know how to rotate the character so forward is in the opposite direction when Left is being pressed.

Here is my code so far:

 using UnityEngine;
 using System.Collections;
 public class PlayerController : MonoBehaviour {
 
     #region Animations
     public AnimationClip[] IdleAnimations;
     public AnimationClip[] WalkAnimations;
     public AnimationClip[] JumpAnimations;
     public AnimationClip[] FallAnimations;
     #endregion
 
     #region Variables
     public float WalkSpeed;
     public float Gravity;
     public float JumpForce;
     bool IsGrounded;
     bool HasJumped;
     bool HasHitCeiling;
     Vector3 Forward;
     CharacterController controller;
     //Object LevelMesh;
     //Object Player;
     RaycastHit hit;
     #endregion
 
     #region Enums
     enum PlayerDirection
     {
         Forward = 0,
         Up = 1,
         Down = 2
     }
     enum PlayerState
     {
         Idle = 0,
         Walking = 1,
         Jumping = 2,
         Falling = 3,
         Dead = 4
     }
     PlayerDirection playerDirection;
     PlayerState playerState;
     #endregion
 
     // Use this for initialization
     void Start () {
         Forward = transform.forward;
         playerState = PlayerState.Idle;
         IsGrounded = true;
         //LevelMesh = GameObject.FindGameObjectWithTag ("Level");
         //Player = gameObject;
     }
     
     // Update is called once per frame
     void Update () {
         rigidbody.AddForce (Vector3.down * Gravity);
         ChangeAnimation ();
         AimGun ();
         print ("State: " + playerState + "; Direction: " + playerDirection);
         //MOVE THE PLAYER IN FORWARD AT WALKSPEED
 
         float h = Input.GetAxis ("Horizontal");
         if (h != 0)
         {
             if (IsGrounded)
             {
                 playerState = PlayerState.Walking;
             }
             rigidbody.velocity = Forward * WalkSpeed;
             //rigidbody.AddForce(Forward * WalkSpeed);
         }
         else if (h == 0)
         {
             if (IsGrounded)
             {
                 playerState = PlayerState.Idle;
                 rigidbody.AddForce (new Vector3(0,0,0));
             }
         }
 
         //JUMP
         if (Input.GetButtonDown ("Jump") && playerState != PlayerState.Jumping && playerState != PlayerState.Falling)
         {
             rigidbody.AddForce (new Vector3(0, JumpForce, 0));
             //print ("You are jumping.");
             playerState = PlayerState.Jumping;
             IsGrounded = false;
         }
         if (Input.GetButtonUp ("Jump") && playerState == PlayerState.Jumping)
         {
             playerState = PlayerState.Falling;
         }
         switch (playerState)
         {
         case PlayerState.Falling:
             //rigidbody.AddForce (new Vector3(0,-Gravity,0));
             IsGrounded = false;
             break;
         }
         //FALL WHEN CEILING IS HIT
         //ALSO BE ABLE TO LOOK UP WHILE GROUNDED
         //AND LOOK UP & DOWN WHILE IN AIR
     }
     void OnCollisionEnter (Collision col)
     {
         if (col.gameObject.tag == "LevelMesh")
         {
             if (playerState == PlayerState.Falling)
             {
                 IsGrounded = true;
                 playerState = PlayerState.Idle;
             }
             if (playerState == PlayerState.Jumping && !IsGrounded || playerState == PlayerState.Falling && !IsGrounded)
             {
                 playerState = PlayerState.Falling;
             }
         }
     }
     void ChangeAnimation()
     {
         switch (playerState)
         {
             case PlayerState.Idle:
                 if (playerDirection == PlayerDirection.Forward)
                 {
                     animation.Play (IdleAnimations[0].name);
                 }
                 if (playerDirection == PlayerDirection.Up)
                 {
                     animation.Play (IdleAnimations[1].name);
                 }
             break;
         case PlayerState.Walking:
             if (playerDirection == PlayerDirection.Forward)
             {
                 animation.Play (WalkAnimations[0].name);
             }
             if (playerDirection == PlayerDirection.Up)
             {
                 animation.Play (WalkAnimations[1].name);
             }
             break;
         case PlayerState.Jumping:
             if (playerDirection == PlayerDirection.Forward)
             {
                 animation.Play (JumpAnimations[0].name);
             }
             if (playerDirection == PlayerDirection.Up)
             {
                 animation.Play (JumpAnimations[1].name);
             }
             if (playerDirection == PlayerDirection.Down)
             {
                 animation.Play (JumpAnimations[2].name);
             }
             break;
         case PlayerState.Falling:
             if (playerDirection == PlayerDirection.Forward)
             {
                 animation.Play (FallAnimations[0].name);
             }
             if (playerDirection == PlayerDirection.Up)
             {
                 animation.Play (FallAnimations[1].name);
             }
             if (playerDirection == PlayerDirection.Down)
             {
                 animation.Play (FallAnimations[2].name);
             }
             break;
         }
     }
     void AimGun()
     {
         if (Input.GetButton ("AimUp"))
         {
             playerDirection = PlayerDirection.Up;
         }
         if (Input.GetButton ("AimDown") && playerState == PlayerState.Jumping || Input.GetButton ("AimDown") && playerState == PlayerState.Falling)
         {
             playerDirection = PlayerDirection.Down;
         }
         if (!Input.GetButton ("AimUp") && !Input.GetButton ("AimDown"))
         {
             playerDirection = PlayerDirection.Forward;
         }
     }
 }



Comment
Add comment · Show 1
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 ToeBeanGames · Jul 20, 2014 at 08:59 PM 0
Share

I switched out rigidbody.velocity for rigidbody.AddForce. But this doesn't completely solve the problem.

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by 0tacun · Jul 20, 2014 at 09:25 PM

First you would like to call AddForce in FixedUpdate() and handling Input in Update(). Because FixedUpdate() uses the fixedtimestep used for physic behaivour.

Second I would cast a Raycast from the player towards the ground to check if there is ground beneth us. This would kill the problem with touching the ceiling and go into idle/walk state. Also Lerp your player position to the impact to prevent that the player flys away and sticks to the ground:

     if( Physics.Raycast( myTransform.position, -Vector3.up, 0.5, hit ) ) {
      isGrounded = true;
      myTransform.position = Vector3.Lerp( myTransform.position, hit.point, Time.deltaTime * frictionAmount );
     } else {
      isGrounded = false;
     }
 

Third, if you want that the player rotates into the direction you want to move like in an action adventure (Uncharted etc.) there are already solutions: http://answers.unity3d.com/questions/8444/moving-player-relative-to-camera.html

Comment
Add comment · Show 4 · 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 ToeBeanGames · Jul 20, 2014 at 09:48 PM 0
Share

With the raycast, I'm getting a couple errors:

"The best overloaded method match for UnityEngine.Vector3.Lerp(UnityEngine.Vector3, UnityEngine.Vector3, float)' has some invalid arguments" "Argument #2' cannot convert UnityEngine.RaycastHit' expression to type UnityEngine.Vector3'"

Commenting out the line with the errors, I am able to jump once before I get stuck on the ground in the Falling state.

avatar image ToeBeanGames · Jul 20, 2014 at 10:01 PM 0
Share

Also getting this error on the first line of the raycast:

"Argument #4' cannot convert UnityEngine.RaycastHit' expression to type `int'"

avatar image 0tacun · Jul 20, 2014 at 10:15 PM 0
Share

you have to declare the hit variable as a RaycastHit type:

     RaycastHit hit;
     if (Physics.Raycast(transform.position, -Vector3.up, out hit))

sorry I just wrote something of the top of my head, check the documents for the right overload function and variables. http://docs.unity3d.com/ScriptReference/Physics.Raycast.html

avatar image 0tacun · Jul 25, 2014 at 01:48 PM 0
Share

If my answer was sufficient please click "accept 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

23 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 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 use character controller to push down hinge joint properly 1 Answer

Step Offset for Rigidbody Character 1 Answer

Need Help in FPS controller based on Rigidbody 0 Answers

RigidbodyFirstPersonController and external forces... 0 Answers

Rigidbody movement in direction of camera? 1 Answer


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