Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.8k views
in Technique[技术] by (71.8m points)

c# - Trying to throw an item to my crosshair direction via ray

I am trying with this more than 5 days now... I am trying to make a simple mechanic in third person mode that is allowing me to throw my items at the center of my screen where my reticle (crosshair) is located... I am using cinemachine, and even tried to simplify that mechanic only when my second "aim" camera is activated... But it still does not wanna throw the item exactly on the crosshair.. I tried making raycast hit function but it's not working. The item just flow in the direction that is not the crosshair aim at all... (Maybe it flows in direction of the camera, but not of crosshair direction) Here is my code that i've written until now for raycasting and throwing function:

if (ObjectIwantToPickUp)


        {
            Debug.DrawRay(Camera.main.transform.position, Camera.main.transform.forward * 100, Color.red);
            RaycastHit hit;
            Vector3 hitPos;
            if (Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hit))
            {
                hitPos = hit.point;
            }
            else
            {
                hitPos = Camera.main.transform.position + Camera.main.transform.forward * 99;
            }


         forceDirection = hitPos - ObjectIwantToPickUp.transform.position;
    }

And here is for throwing:

void throwObject()
        {
            if (hasItem == true && Input.GetKeyDown("t"))
            {
                BoxCollider[] bc = ObjectIwantToPickUp.GetComponents<BoxCollider>();
                foreach (BoxCollider b in bc)
                {
                    b.enabled = true;
                }
                ObjectIwantToPickUp.GetComponent<BoxCollider>().enabled = true;
                ObjectIwantToPickUp.GetComponent<Rigidbody>().isKinematic = false; // make the rigidbody work again
                //ObjectIwantToPickUp.GetComponent<Rigidbody>().useGravity = false; // make the rigidbody work again
                hasItem = false;
 
                ObjectIwantToPickUp.transform.parent = null; // make the object no be a child of the hands
                ObjectIwantToPickUp.GetComponent<Rigidbody>().AddForce(forceDirection.normalized * 15, ForceMode.Impulse);
                ObjectIwantToPickUp.GetComponent<Rigidbody>().AddTorque(ObjectIwantToPickUp.transform.TransformDirection(Vector3.right) * 100, ForceMode.Impulse);
             
            }

Here is the full script in case I missed something: https://hatebin.com/uppepjkemf Please, give me a hint, where am I wrong. I am using cinemachine with two cameras and one Main camera with braincomponent in it. Also, I am using a define position script, with simple two Vector3 positions in it. I use that because I needed the picked up item to be parented exactly on pre-defined position in my hand

I have two cameras: Free Look camera and Virtual Camera (for aiming purposes) I change them via this script for changing the priority :

https://hatebin.com/chbofizvuk

Here is a short video what is not working:

https://vimeo.com/499738119

As u see, the "stick" in the scene does not match the crosshair when it's throwed.

Excuse me if I wasn't clear enough and for the messy code :D


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The problem is that Camera.main is giving you the forward and position of the free look camera. You need to get the virtual camera's transform position and forward direction and use those instead.

First, add a field you can assign the aim camera in the inspector:

[SerializeField] Cinemachine.CinemachineVirtualCameraBase aimCam;

Then for the ray:

Vector3 aimOrigin = aimCam.State.FinalPosition; 
Vector3 aimDir = aimCam.State.FinalOrientation * Vector3.forward;

And then you probably want to add some vertical force so it travels a bit before hitting the ground:

AddForce(forceDirection.normalized * 30f + Vector3.up * 10f, ForceMode.Impulse);

...or you could disable gravity on the object's Rigidbody. But then it may never hit the ground, so your mileage may vary with that.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...