Search Unity

Affecting velocity on certain axes

Discussion in 'Scripting' started by Halon_Keiser, Jan 12, 2018.

  1. Halon_Keiser

    Halon_Keiser

    Joined:
    Mar 2, 2017
    Posts:
    7
    I'm trying to write a script for a character to run around from WASD, but I've been running into problems. First, I was using transform.Translate, but the character would clip through objects, especially at high speeds.
    So I tried editing the velocity directly, which worked better for physics interactions, but then it totally killed the jump. The velocity for jumping didn't include forward velocity for any motion that was already there, and if you tried to jump while walking you would lose all upward velocity right away.
    Is there anyway to edit just one axis of velocity, while leaving the rest of them up to the computer?
    Here is my complete script:
     

    Attached Files:

  2. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,498
  3. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    If you don't have any special "air control", you can alter the velocity when you jump to be the current x and z values plus the new added y velocity. Then, in the air, you do not accept/alter movement values (unless you are adding some extra gravity, which is a bit different).
    Hopefully that makes sense.

    Note, as mentioned, please post your code on the forums with code tags.
    I did not download/see your code :)
     
  4. Halon_Keiser

    Halon_Keiser

    Joined:
    Mar 2, 2017
    Posts:
    7
    Ah, that makes sense.
    And sorry about the code, I didn't know about that.
    (What? You didn't download an unknown file from an unknown internet user with no profile photo? how dare you! :p)

    Thanks!
     
  5. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    :) It's that, but not just that. It's much faster to browse code in the thread :)
     
  6. Halon_Keiser

    Halon_Keiser

    Joined:
    Mar 2, 2017
    Posts:
    7
    Actually, I have no idea how you would go about that. How would that work?
    Maybe a better way to ask this is whether there's a way to assign one velocity axis to whatever physics wants it to be.

    Thanks!
     
  7. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Ya, this is often confusing for new comers. If you mean editing 1 part of the property (struct)?
    Code (csharp):
    1.  
    2. // check for jump
    3. rb.velocity = new Vector3(rb.velocity.x, JumpVelocityHere, rb.velocity.z);
    4.  
    is that what you meant?

    Then, if that's what you were after, remember to not alter the velocity (as I mentioned above), while they're in the air. Like don't set x & z to zero because they're not moving, if they let go of the move controls, for example.
     
  8. Halon_Keiser

    Halon_Keiser

    Joined:
    Mar 2, 2017
    Posts:
    7
    Oh, no, I got that far. I don't know how to check whether or not the character is in the air.
    Here's my full code (properly inserted this time).

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. [RequireComponent(typeof(Rigidbody))]
    5.  
    6. public class Walk_script : MonoBehaviour {
    7.  
    8.  
    9.     Animator anim;
    10.     public Vector3 motion;
    11.     public float jumpForce = 0.0f;
    12.  
    13.     public bool isGrounded;
    14.     Rigidbody rb;
    15.    
    16.  
    17.     void Start()
    18.     {
    19.         anim = GetComponent<Animator>();
    20.         rb = GetComponent<Rigidbody>();
    21.         motion = new Vector3(0.0f, jumpForce, 0.0f);
    22.     }
    23.     public float movementSpeed = 10;
    24.     public float Speed = 30;
    25.     public float sprintSpeed = 20;
    26.     private float forward;
    27.     private float jumpforce;
    28.    
    29.     void OnCollisionStay()
    30.     {
    31.         isGrounded = true;
    32.     }
    33.  
    34.  
    35.     void Update()
    36.     {
    37.         jumpForce = rb.velocity.y + Physics.gravity.y * Time.deltaTime;
    38.         if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
    39.         {
    40.  
    41.             jumpForce = 600f;
    42.             isGrounded = false;
    43.         }
    44.         else
    45.         {
    46.             jumpForce = 0f;
    47.  
    48.         }
    49.                 if (Input.GetKey(KeyCode.W))
    50.         {
    51.             //if (Input.GetKeyDown(KeyCode.LeftShift)) anim.SetTrigger("Sprint");
    52.             //if (Input.GetKeyUp(KeyCode.LeftShift)) anim.SetTrigger("Sprint");
    53.             if (Input.GetKey(KeyCode.LeftShift))
    54.             {
    55.                 anim.SetBool("Sprinting", true);
    56.                 //this.transform.Translate(Vector3.left * (sprintSpeed) * Time.deltaTime);
    57.                 motion = new Vector3(-10, jumpForce, 0);
    58.                 rb.velocity = transform.TransformDirection(motion);
    59.  
    60.             }
    61.             else
    62.             {
    63.                 //this.transform.Translate(Vector3.left * (movementSpeed) * Time.deltaTime);
    64.                 rb.velocity = transform.TransformDirection(-20, jumpForce, 0);
    65.                 anim.SetBool("Sprinting", false);
    66.                 anim.SetBool("Walk", true);
    67.             }
    68.             //
    69.         }
    70.         else
    71.         {
    72.             anim.SetBool("Sprinting", false);
    73.             anim.SetBool("Walk", false);
    74.         }
    75.         if(Input.GetKeyDown(KeyCode.Space))
    76.         {
    77.             anim.SetTrigger("Jump");
    78.         }
    79.  
    80.        
    81.              if (Input.GetKey(KeyCode.S))
    82.              {
    83.                 // this.transform.Translate(Vector3.right * (movementSpeed) * Time.deltaTime);
    84.                   anim.SetBool("Back Walk", true);
    85.                  rb.velocity = transform.TransformDirection(10, 0, 0);
    86.               }
    87.                else
    88.               {
    89.                    anim.SetBool("Back Walk", false);
    90.               }
    91.    
    92.        
    93.  
    94.              if (Input.GetKey(KeyCode.D))
    95.               {
    96.                   transform.Rotate(Vector3.up * Speed * Time.deltaTime);
    97.  
    98.              }
    99.  
    100.             if (Input.GetKey(KeyCode.A))
    101.             {
    102.                 transform.Rotate(Vector3.down * Speed * Time.deltaTime);
    103.  
    104.            
    105.         }
    106.     }
    107.  
    108. }
    109.  
     
  9. Halon_Keiser

    Halon_Keiser

    Joined:
    Mar 2, 2017
    Posts:
    7
    The problem with using rigidbody.AddForce is that the character will keep accelerating.
     
  10. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I would recommend that you use a raycast down a small bit to determine if you're grounded.
    You can also explicitly set grounded to false when you jump, which will just turn back in the next FixedUpdate() loop to false whenever you land. Well, I see you're using Update..Anyhow.

    I prefer, after some testing of my own, to use the raycast compared to OnStay calls. I suppose OnStay works in many situations, as well, but technically you could be having a collision with something in the air, that isn't below you, too lol
    You could create a counter for enter/exit of collision, and when you're at 0, you assume you're not grounded, but again, I would suggest trying the raycast ;)
     
  11. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I use modified code from the standard assets in my current character controller. I believe this portion of code is unmodified, though:
    Code (csharp):
    1.  
    2.  if (Physics.Raycast(transform.position + (Vector3.up * 0.1f), Vector3.down, out hitInfo, m_GroundCheckDistance + .1f))
    3.         {
    4.             m_GroundNormal = hitInfo.normal;
    5.             m_IsGrounded = true;
    6.         }
    7.         else
    8.         {
    9.             m_IsGrounded = false;
    10.             m_GroundNormal = Vector3.up;
    11.         }
    12.  
     
  12. Halon_Keiser

    Halon_Keiser

    Joined:
    Mar 2, 2017
    Posts:
    7
    So... That would go inside Update, and then everything else would go inside an if(m_isGrounded) ?
     
  13. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Well, in the code I use (like the standard assets), yes it's run in Update (well, FIxedUpdate), but some parts of code are split into methods, for instance that snippet I posted is in a method.. but that method is called from the FixedUpdate.

    And yes, then there is,
    if grounded, certain code
    else this other code (in the air) .. which is basically not much. In mine it is some extra gravity , for example (don't want to complicate your question) :)
     
  14. Halon_Keiser

    Halon_Keiser

    Joined:
    Mar 2, 2017
    Posts:
    7
    Worked like a charm, thanks a million!
    Only thing that confused me was that for the code snippet you posted, I had to change the it to m_GroundCheckDistance + .7f
     
  15. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Ya, I think in the code I use the original/ground check is: .1 and when you're in the air, going up it changes to .01 and then velocity .y < 0 goes back to '.1' lol
    So maybe you didn't have any value, or it was zero.. but I'm glad it's working for you.