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 Kaskorian · Aug 29, 2017 at 08:46 PM · movementdirectionmathtop-downsine

Top down wasd movement dependent on rotation of the character - Mathematical problem!!!

Hey there,

I'm programming a top down view game with with wasd movement controlls. I want my character to move by 3.741f * Time.deltaTime in the direction in which he Looks. (Maybe incorrect grammar ^^ )

To achieve this I want to use the law of sine. First of all the Code:

 using UnityEngine;
 
 public class PlayerMovement : MonoBehaviour
 { 
     private Animator anim;
     private bool left, right, forward, backward;
     private float angle_to_rotate = 90, movementInput = 0.0f;
 
     //movement
     private int switchValue, xBehavior, zBehavior;
     private float deltaX, deltaZ;
     private float alpha, beta, gamma = 90;
 
     public Input_m EventSystem;
 
     void Awake () {
         anim = GetComponent<Animator> ();
     }
     
     // Update is called once per frame
     void Update () {
         left = EventSystem.Pressed("Left");
         right = EventSystem.Pressed("Right");
         forward = EventSystem.Pressed("Forward");
         backward = EventSystem.Pressed("Backward");
 
         SetAnimationStats();
         Rotate();
     }
 
     private void FixedUpdate()
     {
         Move();
     }
 
     void CalculateAngle () {
         if (left && !right && !forward && !backward)
             angle_to_rotate = 225;
         else if (left && !right && forward && !backward)
             angle_to_rotate = 270;
         else if (!left && !right && forward && !backward)
             angle_to_rotate = 315;
         else if (!left && right && forward && !backward)
             angle_to_rotate = 360;
         else if (!left && right && !forward && !backward)
             angle_to_rotate = 45;
         else if (!left && right && !forward && backward)
             angle_to_rotate = 90;
         else if (!left && !right && !forward && backward)
             angle_to_rotate = 135;
         else if (left && !right && !forward && backward)
             angle_to_rotate = 180;
     }
 
     private void Rotate()
     {
         CalculateAngle();
         transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.Euler(transform.rotation.eulerAngles.x, angle_to_rotate, transform.rotation.eulerAngles.z), 0.125f);
     }
 
     private void SetAnimationStats()
     {        
         if ((left && !right && (!backward || !forward)) || (!left && ((!right && ((!forward && backward) || (forward && !backward))) || (right && (!backward || !forward)))))
         { 
             movementInput += Time.deltaTime * 3;
             movementInput = Mathf.Min(movementInput, 1.0f);
         }
         else
         {
             movementInput -= Time.deltaTime * 3;
             movementInput = Mathf.Max(movementInput, 0.0f);
         }
 
         anim.SetFloat("movementInput", movementInput);
     }
 
     private void Move()
     {
         if ((left && !right && (!backward || !forward)) || (!left && ((!right && ((!forward && backward) || (forward && !backward))) || (right && (!backward || !forward)))))
         {
             alpha = transform.rotation.eulerAngles.y % 90;
             beta = 180 - alpha - gamma;
             switchValue = (int)(transform.rotation.eulerAngles.y / 90);
 
             switch (switchValue)
             {
                 case 0:
                     xBehavior = 1;
                     zBehavior = 1;
                     break;
                 case 1:
                     xBehavior = 1;
                     zBehavior = -1;
                     break;
                 case 2:
                     xBehavior = -1;
                     zBehavior = -1;
                     break;
                 case 3:
                     xBehavior = -1;
                     zBehavior = 1;
                     break;
                 case 4:
                     xBehavior = 1;
                     zBehavior = 1;
                     break;
                 default:
                     break;
             }
 
             deltaX = 1.0f * Mathf.Sin(beta) / Mathf.Sin(gamma);
             deltaZ = 1.0f * Mathf.Sin(alpha) / Mathf.Sin(gamma);
 
             Debug.Log(deltaX.ToString() + " ; " + deltaZ.ToString());
 
             transform.position = new Vector3(transform.position.x + 3.741f * Time.deltaTime * deltaX * xBehavior, transform.position.y, transform.position.z + 3.741f * Time.deltaTime * deltaZ * zBehavior);
         }
     }
 }

First of all the strategy. Because I move on the X and the Z axis I divide the rotations into 4 parts. 0 - 89.9999, 90 - 179.9999, 180 - 269.9999 and 270 - 359.9999 degrees.

I use the modulus to find out in which quadrant the values ​​are located so that I negate the X or Z values ​​if necessary.

The rest of the division is then always an angle between 0 and 90 degrees.

Then I use the law of sinus to calculate the X and Z values ​​for the movement so that the length of the third side of the triangle is exactly 1.

the final values ​​are then multiplied by these calculated values.

But this does not work. the character is not moving in the direction but rather wildly zapped

Looking Forward for a Reply :)

P.S. Don't care about the if Statements with all the left - right - Forward - backward. These are transformed using the Boolean algebra and correct.

Comment
Add comment · Show 2
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 hexagonius · Aug 30, 2017 at 03:05 AM 0
Share

You're not rotating towards a final angle but by the angle all the time.
If I were you, I'd create the final look direction and Slerp towards it. Rotating a global Vector3.forward by your degree ships give you that.

avatar image Kaskorian · Aug 30, 2017 at 08:52 AM 0
Share

But the Problem is not that the character is not rotating correctly but that the character moves unpredictable

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by Bunny83 · Aug 30, 2017 at 09:21 AM

There are a lot things wrong and / or confusing.

Lets start with the obvious ones: All trigonometric functions inside Mathf that expect or return angles use radians and not degree. However you pass angles in degree. So the result is pretty non-sense.

You read back transform.rotation.eulerAngles.y and turn it into an integer for logical lookup- This seems extremly strange as you initially already have pretty much the same logic in reverse to determine the angle based in the different inputs. Unity reads back the euler angles from the quaternion representation, so it might even return a negative angles. Instead why don't you use your "angle_to_rotate"?

Finally if you have a direction vector and you want to make sure it's length is "1" you usually just normalize it.

However if you just want to move "forward", why not just using "transform.forward"? It's a world space direction vector of length 1 which represents the "blue" axis of the object in Unity (positive z).

All in all it seems way to complicated what you're doing there.

edit
I forgot to mention that read-modify-write operations on eulerAngles are not recommended. The Quaternion to eulerAngles conversion is not unique. So at certain rotations your angles may suddenly flip. However since you always pass a fix / given y angle the result might not be what you want.

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 Kaskorian · Aug 30, 2017 at 09:52 AM

Ok i have now changed everything to one line of code

 transform.Translate(Vector3.forward * 3.741f * Time.deltaTime, Space.Self);

I did not use vector3. Forward previously because the character was always moving in the worldspace, however, I did not notice that I can change the space to Space.self in the translate function, which causes him to move automatically with the rotation. Therefore all the complicated calculations.

Sry :)

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

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

102 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

Related Questions

Enemy strafing AI Top Down 0 Answers

How to make an object go the direction it is facing? 6 Answers

Unity2D, How do i check which way a sprite is facing? 1 Answer

Making a bubble level (not a game but work tool) 1 Answer

How to calculate xSpeed and ySpeed according to float value of rotation? 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