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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Launching an object in a players front arc

Discussion in 'Scripting' started by taskmagee, May 17, 2021.

  1. taskmagee

    taskmagee

    Joined:
    Sep 16, 2018
    Posts:
    31
    Hello all. I'm having a problem that I've been trying to solve for 2 days. I've tried scouring google to find information that might point me in the right direction but nothing has clicked.

    I'm trying to have it where a player chops down a tree and once the tree is destroyed it instantiates logs outward in front of the player and lands somewhere in front of the player within a 45 degree arc.

    I have it instantiating fine and I can get them to all travel out in the arc but they only move straight on the x or z axis. My problem is, I don't know and can't find the math required if the player is facing an angle and making the logs move out at that angle. An explanation of the logic would be great or if you could point to a resource I could study that would be good to. I've attached the code that works fine and launches the logs along the y axis so you can see how I have it working currently.

    Code (CSharp):
    1. void Start()
    2.     {
    3.         Rigidbody rigidBody = GetComponent<Rigidbody>();
    4.        
    5.         Vector3 direction = new Vector3(Random.Range(-2.0f, 2.0f), 1, 1);
    6.  
    7.         rigidBody.AddForce(direction * 2f, ForceMode.Impulse);
    8.     }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,947
    I'll assume some things:

    playerTransform.forward
    is the direction your player is facing, and he is standing upright

    float ArcWidth
    is the width in degrees on either side of your gaze/regard (so 22.5f would be 45 degrees total arc)

    To pick a lob-out velocity:

    Code (csharp):
    1. // choose launch forward angle: directly forward on Z, and up on Y (45 degree up angle):
    2. Vector3 velocity = playerTransform.forward * 1.0f + playerTransform.up * 1.0f;
    3.  
    4. // choose an angle left /right
    5. float angleLeftRight = Random.Range( -ArcWidth, ArcWidth);
    6.  
    7. // create a rotation around the Y axis based on the angle we chose
    8. Quaternion rotation = Quaternion.Euler( 0, angleLeftRight, 0);
    9.  
    10. // rotate the proposed straight-ahead velocity around the Y axis:
    11. Vector3 actualVelocity = rotation * velocity;
    12.  
    13. // scale the toss velocity up and down randomly (80% to 120% of base)
    14. actualVelocity *= Random.Range( 0.8f, 1.2f);
    15.  
    16. // TODO: perhaps scale the velocity up even more?
    17. actualVelocity *= 10.0f;  // depending on gravity
    18.  
    19. // you don't really need forces: just set the velocity!
    20. rigidbody.velocity = actualVelocity;
    Warning: you might need to move the logs forward a little along their velocity vectors or else they might collide with the terrain or other things where they were spawned.

    If you want to spread the logs evenly out, then you need to compute the angle from a for() loop, something like this:

    Assuming:
    Count
    is the number of items

    Code (csharp):
    1. for (int i = 0; i < Count; i++)
    2. {
    3.    float fraction = 0;
    4.    if (i > 0)
    5.    {
    6.       fraction = (float)i / (Count - 1) - 0.5f;
    7.    }
    8.  
    9. // compute evenly-spaced angles in an arc
    10.    float angleLeftRight = fraction * ArcWidth * 2;
    // TODO: use angleLeftRight for each subsequent log, or put the values in a table first, then loop, whatever suits you
    }
     
    Last edited: May 17, 2021
  3. taskmagee

    taskmagee

    Joined:
    Sep 16, 2018
    Posts:
    31
    That worked perfectly. Thank you so much for the explanation. I'll be studying it to make sure i truly understand what's happening. Quick question if you don't mind. If I wanted to lower the launch angle, would i change the playerTransform.up float to a value lower than 1?
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,947
    Yes, exactly! Line 2 choose "1.0 x forward plus 1.0 x upwards," so you could choose 1.0 forward and 0.5 upwards, or whatever you like.

    If you have a launch trajectory angle in mind, you could always create the "forward" and "up" terms from the trig functions Mathf.Cos() and Mathf.Sin() being fed that trajectory angle, which take angles in radians (not degrees). You can convert from degrees to radians by multiplying by Mathf.Deg2Rad (and back with Mathf.Rad2Deg).

    Don't confuse the trajectory angle with the heading angle above. They would obviously be orthogonal to each other.

    Some stuff in Unity wants degrees (0 to 360), some stuff wants radians (0 to 2pi)