Shoot object with rotation only work sometime

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class CastBallTutorial : MonoBehaviour
{
    public float BallPositionCameraY = -1f;
    public float BallPositionCameraZ = 0;
    public GameObject prefabToInstantiate;
    public float CastSpeed = 55;
    public float BallCurve = 3;
    public float ScreenHeight;
    private void Awake()
    {
        ScreenHeight = (Screen.height / 2) / (BallCurve);
    }
    // Start is called before the first frame update
    void Start()
    {
       
    }
    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
                if (!EventSystem.current.IsPointerOverGameObject())
                {
                    Ray mouseRay = Camera.main.ScreenPointToRay(new Vector3(Input.mousePosition.x, Input.mousePosition.y + ScreenHeight, 0));
                    GameObject newGameObject = (GameObject)Instantiate(prefabToInstantiate, new Vector3(mouseRay.origin.x, mouseRay.origin.y + BallPositionCameraY, mouseRay.origin.z - BallPositionCameraZ), Quaternion.identity);
                    Rigidbody rb = newGameObject.GetComponent<Rigidbody>();
                    if (rb != null)
                    {
                        Vector3 mouse = Input.mousePosition;
                        Vector3 mouseWorld = Camera.main.ScreenToWorldPoint(new Vector3(mouse.x, mouse.y, newGameObject.transform.position.y));
                        Vector3 forward = mouseWorld - newGameObject.transform.position;
                        newGameObject.transform.rotation = Quaternion.LookRotation(forward, Vector3.up);
                        rb.velocity = mouseRay.direction * CastSpeed;
                    }
                }
           
        }
    }
}

         
        }

So i have this code that shoots an object and give it a litle rotation based on were on screen you click.

So if you have a cube and throw it by clicking on the right side of screen this object will rotate to look like its been thrown from the middle screen to the right, same works with left.

Problem is it doesnt work on low frames per second and on higher frames it also only work sometimes.

Can someone help me make the code beter please so it will work, thx.

How to report your problem productively in the Unity3D forums:

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

This is the bare minimum of information to report:

  • what you want
  • what you tried
  • what you expected to happen
  • what actually happened, log output, variable values, and especially any errors you see
  • links to actual Unity3D documentation you used to cross-check your work (CRITICAL!!!)

The purpose of YOU providing links is to make our job easier, while simultaneously showing us that you actually put effort into the process. If you haven’t put effort into finding the documentation, why should we bother putting effort into replying?

The first thing I would be suspicious about is that event check on line 28. What is the purpose of that?

If you have no idea what your code is doing, FIX THAT FIRST. Here’s how:

Time to start debugging!

By debugging you can find out exactly what your program is doing so you can fix it.

Here is how you can begin your exciting new debugging adventures:

You must find a way to get the information you need in order to reason about what the problem is.

Once you understand what the problem is, you may begin to reason about a solution to the problem.

What is often happening in these cases is one of the following:

  • the code you think is executing is not actually executing at all
  • the code is executing far EARLIER or LATER than you think
  • the code is executing far LESS OFTEN than you think
  • the code is executing far MORE OFTEN than you think
  • the code is executing on another GameObject than you think it is
  • you’re getting an error or warning and you haven’t noticed it in the console window

To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

Doing this should help you answer these types of questions:

  • is this code even running? which parts are running? how often does it run? what order does it run in?
  • what are the names of the GameObjects or Components involved?
  • what are the values of the variables involved? Are they initialized? Are the values reasonable?
  • are you meeting ALL the requirements to receive callbacks such as triggers / colliders (review the documentation)

Knowing this information will help you reason about the behavior you are seeing.

You can also supply a second argument to Debug.Log() and when you click the message, it will highlight the object in scene, such as Debug.Log("Problem!",this);

If your problem would benefit from in-scene or in-game visualization, Debug.DrawRay() or Debug.DrawLine() can help you visualize things like rays (used in raycasting) or distances.

You can also call Debug.Break() to pause the Editor when certain interesting pieces of code run, and then study the scene manually, looking for all the parts, where they are, what scripts are on them, etc.

You can also call GameObject.CreatePrimitive() to emplace debug-marker-ish objects in the scene at runtime.

You could also just display various important quantities in UI Text elements to watch them change as you play the game.

Visit Google for how to see console output from builds. If you are running a mobile device you can also view the console output. Google for how on your particular mobile target, such as this answer for iOS: https://discussions.unity.com/t/700551 or this answer for Android: https://discussions.unity.com/t/699654

If you are working in VR, it might be useful to make your on onscreen log output, or integrate one from the asset store, so you can see what is happening as you operate your software.

Another useful approach is to temporarily strip out everything besides what is necessary to prove your issue. This can simplify and isolate compounding effects of other items in your scene or prefab.

If your problem is with OnCollision-type functions, print the name of what is passed in!

Here’s an example of putting in a laser-focused Debug.Log() and how that can save you a TON of time wallowing around speculating what might be going wrong:

https://discussions.unity.com/t/839300/3

If you are looking for how to attach an actual debugger to Unity: https://docs.unity3d.com/2021.1/Documentation/Manual/ManagedCodeDebugging.html

“When in doubt, print it out!™” - Kurt Dekker (and many others)

Note: the print() function is an alias for Debug.Log() provided by the MonoBehaviour class.

1 Like

I dont understand why quote and take me out of context, my whole sentence was:

Problem is it doesnt work on low frames per second and on higher frames it also only work sometimes.

It works most of the time on high frames, so could possible wrote that better.

So clearly some code strugles to run for some reason, and struggles more the lower the frames are.

if i dont have this the click will go thru buttons like pause button, so if im clicking pause i shoot a ball to pause wich is a waste of a ball.
well actualy the touch version i think will go thru without it, this script is for editor only.

So what i want is for someone to help me understand why this happens, and i tried rearange the code and cant get it to work.

Did you investigate what I suggested above?

Specifically, I suggested this:

If you are unable to explain the PURPOSE of that code and to verify it is functioning correctly then go back to where you got the code from and work on Step #2 below.

OR, put another way: I don’t know why line 28 is there. Either remove it, or at least test if it is your problem, or understand WHY it is there.

Remember: we cannot run your code. That’s NOT a thing! We don’t have your project. It’s your project.

Tutorials and example code are great, but keep this in mind to maximize your success and minimize your frustration:

How to do tutorials properly, two (2) simple steps to success:

Step 1. Follow the tutorial and do every single step of the tutorial 100% precisely the way it is shown. Even the slightest deviation (even a single character!) generally ends in disaster. That’s how software engineering works. Every step must be taken, every single letter must be spelled, capitalized, punctuated and spaced (or not spaced) properly, literally NOTHING can be omitted or skipped.
Fortunately this is the easiest part to get right: Be a robot. Don’t make any mistakes.
BE PERFECT IN EVERYTHING YOU DO HERE!!

If you get any errors, learn how to read the error code and fix your error. Google is your friend here. Do NOT continue until you fix your error. Your error will probably be somewhere near the parenthesis numbers (line and character position) in the file. It is almost CERTAINLY your typo causing the error, so look again and fix it.

Step 2. Go back and work through every part of the tutorial again, and this time explain it to your doggie. See how I am doing that in my avatar picture? If you have no dog, explain it to your house plant. If you are unable to explain any part of it, STOP. DO NOT PROCEED. Now go learn how that part works. Read the documentation on the functions involved. Go back to the tutorial and try to figure out WHY they did that. This is the part that takes a LOT of time when you are new. It might take days or weeks to work through a single 5-minute tutorial. Stick with it. You will learn.

Step 2 is the part everybody seems to miss. Without Step 2 you are simply a code-typing monkey and outside of the specific tutorial you did, you will be completely lost. If you want to learn, you MUST do Step 2.

Of course, all this presupposes no errors in the tutorial. For certain tutorial makers (like Unity, Brackeys, Imphenzia, Sebastian Lague) this is usually the case. For some other less-well-known content creators, this is less true. Read the comments on the video: did anyone have issues like you did? If there’s an error, you will NEVER be the first guy to find it.

Beyond that, Step 3, 4, 5 and 6 become easy because you already understand!

Do you have litle to do and is just trolling now, i told you what it does.

if i dont have this the click will go thru buttons like pause button, so if im clicking pause i shoot a ball to pause wich is a waste of a ball.
well actualy the touch version i think will go thru without it, this script is for editor only.

And no i didnt follow a tutorail but got help from forum some places.

It doesn’t matter. If you don’t understand what you’re working with, that’s on you, not us.

I have offered you guidance to learn what your code is doing.

You don’t seem interested in that.

I have suggested areas for you to investigate further.

You don’t seem interested in that either.

I wish you the best of luck with this approach.

If you just need to throw or cast stuff there are plenty of examples that work 100%. I even have one in my MakeGeo project:

Terrain damager in MakeGeo:

https://discussions.unity.com/t/681462/7

My script is very different from your throwing it. My camera is not rotating, and i can throw balls in all directions based on where i click screen, everything works exept the rotate of ball dosnt always work.

If you cant understand the code then i try expalin it to you.

Ray mouseRay = Camera.main.ScreenPointToRay(new Vector3(Input.mousePosition.x, Input.mousePosition.y + ScreenHeight, 0));
                    GameObject newGameObject = (GameObject)Instantiate(prefabToInstantiate, new Vector3(mouseRay.origin.x, mouseRay.origin.y + BallPositionCameraY, mouseRay.origin.z - BallPositionCameraZ), Quaternion.identity);
                    Rigidbody rb = newGameObject.GetComponent<Rigidbody>();

This code instantiate the ball and set the direction it will be thrown in.

Vector3 mouse = Input.mousePosition;
                        Vector3 mouseWorld = Camera.main.ScreenToWorldPoint(new Vector3(mouse.x, mouse.y, newGameObject.transform.position.y));
                        Vector3 forward = mouseWorld - newGameObject.transform.position;
                        newGameObject.transform.rotation = Quaternion.LookRotation(forward, Vector3.up);
                        rb.velocity = mouseRay.direction * CastSpeed;

This code should rotate the ball a few degrees based on were you click screen, and here is the proble that it dont always run and i cant understand why.

The object isnt rotating constantly its beeing rotatet to a specific angle to look more realistic.

lets say you have a book and throw it forward, now take the same book and throw it sideways by 45 degrees, then the book will look like its rotated 45 degrees from your front view.

without the code i have here, the book will always be thrown as it was thrown forward even when clicked on the side of the screen, thats why i want to rotate it, it also rotate a litle back and forth depending if you click up or down on the screen.

And to say if i dont understand what im working on its on me, ofc it is but maybe some people that have knowledge in coding could help me understand why, you seem very tempered and i dont understand why.

using UnityEngine;
public class CastBallTutorial : MonoBehaviour
{
    public GameObject prefabToInstantiate;
    public float CastSpeed = 55;

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (!Physics.Raycast(mouseRay,2)) // clear ahead?
            {
                GameObject obj = Instantiate(prefabToInstantiate, mouseRay.origin+Vector3.down, Quaternion.LookRotation(mouseRay.direction));
                Rigidbody rb = obj.GetComponent<Rigidbody>();
                rb.velocity = mouseRay.direction * CastSpeed;
            }
        }
    }
}

Thank you, you did what i was trying to, to instantiate an rotate it in 1 go, and on my script i found out that if i took interpolation and set it to none instead of interpolation on the ball object then my script worked all the time.
Frames didnt matter then, have no idea why that happens but atleast now it works, again thank you.