Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question How to throw something using sin/cos 2D

Discussion in 'Scripting' started by Tiny_Tree, Feb 18, 2023.

  1. Tiny_Tree

    Tiny_Tree

    Joined:
    Oct 20, 2021
    Posts:
    3
    Script:
    Xv = Mathf.Sin(arrow.transform.eulerAngles.z)(player.GetComponent<PlayerScript().power/5)*Mathf.Rad2Deg;
    Yv = Mathf.Cos(arrow.transform.eulerAngles.z(player.GetComponent<PlayerScript().power/5)*Mathf.Rad2Deg;

    Im using this script to set an x velocity and y velocity. But the object just moves rlly fast in the wrong deriction. Can someone show me the correct way of doing this?
    Notes:
    arrow.transform.eulerAngles.z is the deriction I want it to move.
    player.GetComponent<PlayerScript().power/5 is how fast I want it to move.
    I also want it to use the xv and yv not rigid-boy velocity.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,762
    You can do it with sin/cos oldskool, but it seems easier to just use Quaternion and Vector multiplication to me.

    So lets say you have an angle:

    Code (csharp):
    1. private float angle;    // in degrees, NOT radians!
    And you agree that zero means "go right directly horizontal" (
    Vector3.right
    )

    Then the actual direction vector you want can be expressed as:

    Code (csharp):
    1. Quaternion rotation = Quaternion.Euler( 0, 0, angle);   //degrees rotated around +Z axis
    2.  
    3. Vector3 LaunchVector = rotation * Vector3.right;
    That's it!

    If you want to do sin/cos you will need to supply the arguments as radians NOT as degrees:

    https://docs.unity3d.com/ScriptReference/Mathf.Sin.html

    You may convert with constants such as
    Mathf.Rad2Deg
    and
    Mathf.Deg2Rad
     
    Last edited: Feb 18, 2023
    chemicalcrux likes this.
  3. Tiny_Tree

    Tiny_Tree

    Joined:
    Oct 20, 2021
    Posts:
    3
    I wish I could use Quaternion and Vector multiplication but for certain reasons to do with the game objects movement I need to use the Xv and Yv variables which means I need to use sin and cos.

    I treid this
    Code (CSharp):
    1. Xv = Mathf.Sin(Mathf.Deg2Rad*arrow.transform.eulerAngles.z)*(player.GetComponent<PlayerScript>().power/5);
    2.                 Yv = Mathf.Cos(Mathf.Deg2Rad*arrow.transform.eulerAngles.z)*(player.GetComponent<PlayerScript>().power/5);
    And its no longer moving a 1000mph in the complete wrong direction. Its still going in the wrong direction just not as fast. I assume this is not the correct implementation of Mathf.Deg2Rad then.
     
  4. chemicalcrux

    chemicalcrux

    Joined:
    Mar 16, 2017
    Posts:
    717
    Why is that? You can just grab the X and Y components from the resulting vector.
     
    Kurt-Dekker likes this.
  5. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,134
    ChatGPT is suggesting that you have Sin and Cos backwards (ie X should be Cos and Y should be Sin).

    It seems like you are on the right track, but there might be a problem with the signs of your trigonometric functions.

    In Unity, the Transform.eulerAngles property returns the rotation of the object as a vector of Euler angles in degrees. However, when using trigonometric functions like Mathf.Sin and Mathf.Cos, the input angle must be in radians. Therefore, you need to convert the degrees to radians using Mathf.Deg2Rad before passing the angle to Mathf.Sin and Mathf.Cos.

    Based on the code you provided, it seems that you are correctly using Mathf.Deg2Rad to convert the angle from degrees to radians. However, the order in which you use Sin and Cos might be incorrect.

    Assuming that you want to calculate the horizontal (X) and vertical (Y) velocities of a projectile, you should use Sin for the vertical velocity and Cos for the horizontal velocity, like this:

    Code (csharp):
    1. Xv = Mathf.Cos(Mathf.Deg2Rad * arrow.transform.eulerAngles.z) * (player.GetComponent<PlayerScript>().power / 5);
    2. Yv = Mathf.Sin(Mathf.Deg2Rad * arrow.transform.eulerAngles.z) * (player.GetComponent<PlayerScript>().power / 5);
    Note that the horizontal velocity is calculated using Cos because it is the component of the velocity in the x-axis, which is represented by the cosine function. The vertical velocity is calculated using Sin because it is the component of the velocity in the y-axis, which is represented by the sine function.

    Also, make sure that the angle returned by arrow.transform.eulerAngles.z is what you expect. If the angle is not what you expect, it might be necessary to use arrow.transform.rotation.eulerAngles.z instead.

    I hope this helps!
     
  6. chemicalcrux

    chemicalcrux

    Joined:
    Mar 16, 2017
    Posts:
    717
    This is correct, yes: the cosine of an angle is the X component of the point on the unit circle at that angle (and the sine is the Y component).
     
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,762
    Trust me, no line of code with that many dots in it is a "correct implementation!"

    If you have more than one or two dots (.) in a single statement, you're just being mean to yourself.

    How to break down hairy lines of code:

    http://plbm.com/?p=248

    Break it up, practice social distancing in your code, one thing per line please.

    "Programming is hard enough without making it harder for ourselves." - angrypenguin on Unity3D forums

    "Combining a bunch of stuff into one line always feels satisfying, but it's always a PITA to debug." - StarManta on the Unity3D forums
     
    Ryiah likes this.
  8. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,134
    You can also hand it to the chatbot and ask it to improve the readability.

    Code (csharp):
    1. // Get the z rotation angle of the arrow in degrees
    2. float arrowRotation = arrow.transform.eulerAngles.z;
    3.  
    4. // Convert the angle from degrees to radians
    5. float arrowRotationRadians = Mathf.Deg2Rad * arrowRotation;
    6.  
    7. // Get the power of the player and scale it down by a factor of 5
    8. float playerPower = player.GetComponent<PlayerScript>().power;
    9. float scaledPower = playerPower / 5;
    10.  
    11. // Calculate the x and y velocity components using trigonometry
    12. float xVelocity = Mathf.Cos(arrowRotationRadians) * scaledPower;
    13. float yVelocity = Mathf.Sin(arrowRotationRadians) * scaledPower;