1
\$\begingroup\$

Apologies in advance for my lack of knowledge, I am very new to 3D

My goal is relatively simple. The player controls an arm and uses the mouse to rotate it around a point. They can hold the mouse button to pick up a ball and then throw it by rotating the arm and letting go of the mouse button. (See GIF below)

I've managed to get everything to work except for the "throw" part. Once I let go of the mouse button, the ball simply drops straight down with no velocity. I realized that none of the other parts have any velocity for the ball to inherit since I am only setting the rotation.

How can I affect the velocity of the ball based on the speed of the arms rotation and direction?

The code to rotate the arm:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ArmController : MonoBehaviour
{

    public float sensX;
    public float sensY;

    private float xRotation;
    private float yRotation;


    void Start()
    {
        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;
    }


    void Update()
    {
        
        float mouseX = Input.GetAxisRaw("Mouse X") * Time.fixedDeltaTime * sensX;
        float mouseY = Input.GetAxisRaw("Mouse Y") * Time.fixedDeltaTime * sensY;
        
        yRotation += mouseX;
        xRotation -= mouseY;

        transform.rotation = Quaternion.Euler(xRotation, yRotation, 0);

    }

}

The code to pickup and drop the ball:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;

public class Pickup : MonoBehaviour
{

    public Rigidbody ballRB;
    public Transform ball;
    public Transform grabPoint;
    public Rigidbody pointRB;


    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Mouse0))
        {
            PickUpBall();
        }
        else if (Input.GetKeyUp(KeyCode.Mouse0))
        {
            DropBall();
        }


    }

    private void PickUpBall()
    {
        ball.transform.SetParent(grabPoint);
        ball.transform.localPosition = transform.localPosition;

        ballRB.isKinematic = true;
    }


    private void DropBall()
    {
        ball.transform.SetParent(null);

        ballRB.isKinematic = false;

        ballRB.velocity = pointRB.velocity;
    }
}

In the code above, pointRB has no velocity. I believe this is because it is a child of the pivot point which is having its rotation set by the first script. I've been trying for hours to figure out a way to calculate the velocity either using rigidbodies or manually with no luck.

The arm is a child of an empty game object which it rotates around. The grab point is a child of the arm to which the ball attaches.

Here's what my issue looks like

Thank you in advance for any help!

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

I'm not sure if this will end up being the best answer, but an option that I see is:

Attach a gameobject to the ball or "hand" end of the throwing arm. On this gameobject, attach a script that is constantly reading the change in global position of its gameobject, and divding that by Time.deltaTime to get a constant velocity. Here is a possible sample of this script:

Vector3 positionLastFrame;
Vector3 velocityPerSecond;

void checkVelocity()
{
   Vector3 newVelocityThisFrame = transform.position - positionLastFrame;
   velocityPerSecond = newVelocity / Time.deltaTime;
   positionLastFrame = transform.position;
}

At time of release, read the velocity value on this script, and apply the force to the ball.

You may find it necessary to "filter" the velocity by averaging its value across multiple frames, so it does not jump around at very high or low frame rates.

I am not an expert on the physics system, but if you need to use it, I think you could put your velocity-per-second value directly into the rigidbody with myRigidbody.AddForce(velocityPerSecond, ForceMode.Impulse). However, I often find that I get snappier movement by moving things via script rather than the physics system.

Note: this method will get you "real" release speeds as if the ball were swinging on a string that was suddenly cut- it will fly in the direction the arm is swinging, not in the direction the arm is pointing. In sports, players throw balls in a complex way that leaves them pointing in the direction they threw, like darts- if you want to mimic this, you will have to decide for yourself how exactly you want the ball to move- following the vector of the arm could be a start.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .