Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 spylefkaditis · May 08, 2020 at 09:26 PM · vector3controller

Problem with adjusting vector.

I've been fighting to get my controller to behave as expected.

What I want is to have two different speeds for sideways movement (X axis) and forward and backwards movement (Z Axis).

         // Get keyboard inputs
         float moveZ = Input.GetAxis("Vertical");
         float moveX = Input.GetAxis("Horizontal");
 
         //Handle Movement
         Vector3 horizontalMovement = transform.right * moveX; // Set new vector based on the local coordinates
         Vector3 verticalMovement = transform.forward * moveZ;
         Vector3 movement = horizontalMovement + verticalMovement; 
         movement = movement.normalized; // Normalize final vector
 
         // Apply speed to normalized vector
         movement.x *= _horizontalMoveSpeed * Time.deltaTime;
         movement.z *= _verticalMoveSpeed * Time.deltaTime;
 
         // If the player is moving then rotate his body to face the same direction as the camera.
         if (movement.magnitude > 0)
         {
             Vector3 playerRotation = new Vector3(0, _cameraFollow.transform.eulerAngles.y, 0);
             transform.rotation = Quaternion.Euler(playerRotation);
         }
 
         _characterController.Move(movement);

The issue I'm having seems to originate with these 2 lines.

  // Apply speed to normalized vector
          movement.x *= _horizontalMoveSpeed * Time.deltaTime;
          movement.z *= _verticalMoveSpeed * Time.deltaTime;

My character moves fine along the forward axis at the speed of verticalMoveSpeed. When i strafe left and right he moves slower at the horizontalMoveSpeed. The issue arises when I then rotate my camera 90, so now my "forward" is facing along the x axis (if you get what i mean). Now If i try to run my forward speed seems to be the horizontalMoveSpeed. If I now strafe I seem to be running with the verticalMoveSpeed.

I have no idea whats going on.

If I remove those lines 2 lines and just do _characterController.Move(movement * speed * Time.deltaTime); Then he moves fast in both axis (which isnt what i want)

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

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by darksider2000 · May 08, 2020 at 11:48 PM

Hi @spylefkaditis

Your issue occurs because you're modifying the X and Z components of a world oriented Vector, but you're looking to modify your character's local horizontal vector.


Try instead to do your modifications to horizontalMovement and verticalMovement before normalizing the vector. This will mean that the normalized vector still comes out with a magnitude of 1, so you'll need to apply speed to it. Its direction however will be aligned based on the moveSpeed values, and you'll end up with what you're looking for.

 //Handle Movement
          Vector3 horizontalMovement = transform.right * moveX * _horizontalMoveSpeed; // Set new vector based on the local coordinates
          Vector3 verticalMovement = transform.forward * moveZ * _verticalMoveSpeed;
          Vector3 movement = horizontalMovement + verticalMovement; 
          movement = movement.normalized; // Normalize final vector


Hope this helps!

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 spylefkaditis · May 09, 2020 at 08:32 AM

Thanks for the reply @darksider2000 . Hmmmm I don't think I understand your solution. It was my understanding when I normalise a vector I'm getting rid of its magnitude and just remain with the direction only. Which is why I then multiply it's x and y components by my 2 different speeds.

If I apply your suggested code as above, then the multiplier values _horizontalMoveSpeed and _verticalMoveSpeed are ignored after normalizing the vector. If I apply a speed to it then it works, but that doesn't actually give me the result I want of having 2 different speeds.

Sorry if I'm misunderstanding.

What I "think" is happening is that

         movement.x = movement.x * _horizontalMoveSpeed * Time.deltaTime;
         movement.z = movement.z * _verticalMoveSpeed * Time.deltaTime;

is saying "Modify the movement in regards to the world axis". So whenever I move in global Z it's one speed and global X another speed. That's why when my character rotates it doesn't change. But I don't understand why. I thought

         Vector3 horizontalMovement = transform.right * moveX;
         Vector3 verticalMovement = transform.forward * moveZ;
         Vector3 movement = horizontalMovement + verticalMovement;

would create movement vector based on the object local coordinates so then calling _characterController.Move(movement) would move it based on those local coordinates.

Clearly i dont understand vectors

Comment
Add comment · Show 3 · 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 darksider2000 · May 09, 2020 at 11:37 AM 0
Share

I misunderstood what you meant by two speeds. In that case just don't normalize the vector, ins$$anonymous$$d add both vectors together (While multiplying each by their respective moveSpeed), and then divide their product by the square root of 2. (This is because combining two vectors that are perpendicular to each other results in a magnitude bigger than you want)

          // Get keyboard inputs
          float moveZ = Input.GetAxis("Vertical");
          float moveX = Input.GetAxis("Horizontal");
  
          //Handle $$anonymous$$ovement
          Vector3 horizontal$$anonymous$$ovement = transform.right * moveX * _horizontal$$anonymous$$oveSpeed; // This will be the smaller vector
          Vector3 vertical$$anonymous$$ovement = transform.forward * moveZ * _vertical$$anonymous$$oveSpeed;
          Vector3 movement = horizontal$$anonymous$$ovement + vertical$$anonymous$$ovement; 
          movement /= $$anonymous$$athf.Sqrt(2f); // Get real magnitude from perpendicular input
  
  
          // If the player is moving then rotate his body to face the same direction as the camera.
          if (movement.magnitude > 0)
          {
              Vector3 playerRotation = new Vector3(0, _cameraFollow.transform.eulerAngles.y, 0);
              transform.rotation = Quaternion.Euler(playerRotation);
          }
  
          _characterController.$$anonymous$$ove(movement * Time.deltaTime);
avatar image spylefkaditis darksider2000 · May 09, 2020 at 01:10 PM 0
Share

I tried your suggestion and it fixed the initial problem I had. However now whenever I my character ran in a diagonal motion his speed was being affected in a weird way.

I've decided to take a different approach and calculate the dot product of my movement vector and the characters forward vector to find out the direction he is moving relative to his forward. That way I adjust my velocity value based on whether he's moving backwards, forwards sideways etc.

Here is my final solution.

 using System;
 using UnityEngine;
 
 public class Player$$anonymous$$ovement : $$anonymous$$onoBehaviour
 {
     [SerializeField] private GameObject _cameraFollow;
     [SerializeField] private float _moveSpeed = 6;
     private CharacterController _characterController;
     private Animator _anim;
     private float _velocity;
     private Vector3 _movement;
 
     void Start()
     {
         _anim = GetComponent<Animator>();
         _characterController = GetComponent<CharacterController>();
         Cursor.lockState = CursorLock$$anonymous$$ode.Locked;
     }
 
     private void Update()
     {
         CalculatePlayer$$anonymous$$ovement();
         CalculatePlayerRotation();
     }
 
     void LateUpdate()
     {
         $$anonymous$$ovePlayer();
     }
 
     void CalculatePlayer$$anonymous$$ovement()
     {
         // Get keyboard inputs
         float moveZ = Input.GetAxis("Vertical");
         float moveX = Input.GetAxis("Horizontal");
 
         //Animate $$anonymous$$ovement
         _anim.SetFloat("VelocityZ", moveZ);
         _anim.SetFloat("VelocityX", moveX);
 
         //Handle $$anonymous$$ovement
         Vector3 horizontal$$anonymous$$ovement = transform.right * moveX; // Set new vector based on the local coordinates
         Vector3 vertical$$anonymous$$ovement = transform.forward * moveZ;
         _movement = horizontal$$anonymous$$ovement + vertical$$anonymous$$ovement;
 
         float dotProduct = Vector3.Dot(transform.forward, _movement.normalized);
 
         if (dotProduct >= 0.4)
         {
             _velocity = _moveSpeed;
         }
         else if (dotProduct < 0.4 && dotProduct > -0.2)
         {
             _velocity = _moveSpeed / 1.5f;
         }
         else if (dotProduct <= -0.2)
         {
             _velocity = _moveSpeed / 2;
         }
     }
 
     void CalculatePlayerRotation()
     {
         // If the player is moving then rotate his body to face the same direction as the camera.
         if (_movement.magnitude > 0)
         {
             Vector3 playerRotation = new Vector3(0, _cameraFollow.transform.eulerAngles.y, 0);
             transform.rotation = Quaternion.Euler(playerRotation);
         }
     }
 
     void $$anonymous$$ovePlayer()
     {
         _characterController.$$anonymous$$ove(_movement * _velocity * Time.deltaTime);
     }
 }
 
avatar image darksider2000 spylefkaditis · May 09, 2020 at 07:08 PM 0
Share

Well if it works don't fix it! Glad you found a solution

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

161 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 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 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 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 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 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 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 keep going forward while jumping ? 1 Answer

Vector3 Error? 0 Answers

Unity 8-Directional Locked Movement (Super Mario 3D World Style) 3 Answers

How to make object lean in the direction it's going 3 Answers

MMD How to export model and animations to Unity as 3rd person controller? 2 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