- Home /
How to shoot a bullet based on another object's position?
I'm new to code, so bear with me. I've searched everywhere through google and haven't found an explanation for this particular implementation.
So I have a character. That character has a disk parented to it. That disk rotates based on the position of the mouse, independent of character movement. There is a "Gun" parented to one point of the target disk, so that the "gun" is always pointing its Z axis directly at the mouse position. On that "Gun" I have a script set to shoot a bullet, which will be any of a number of prefab objects. Each prefab will behave differently (they'll be different spells), and right now I'm trying to get one to be a fireball-like thing.
It works, it spawns in the correct place but it will only shoot based on its own transform information. If I tell it to travel along Z, it will travel along what is basically world Z. I need it to travel along the Z axis of the "Gun" object, based on wherever that is at the time of instantiation. How do I call up the gun's z axis information within the fireball prefab? I'm coding in Java, for the record.
Showing us your code would help us give you a focused answer. Typically you would use the 'transform.forward' or the rotation of the gun in whatever movement code you use. You can also use the transform.rotation of the gun in the Instantiate() so that the forward of your prefab will be facing the correct way.
I honestly don't know what code to show. The target disk doesn't seem relevant as I'm only wanting to pull its vector3.forward or something similar. The shoot code doesn't seem relevant, it's shooting just fine. The problem lies in the prefab for the bullet, and it's doing what I want it to do, which is transfor$$anonymous$$g forward. I've gone through several iteration of this "forward" command, and they all function as the computer thinks is intended. Here's what I'm currently using:
transform.position += transform.TransformDirection (target * fireballSpeed);
And it is, indeed, transfor$$anonymous$$g the position as I want it to. It's just transfor$$anonymous$$g based on its own axis, when I need it to pull from the gun's vector3.
edit: "target" is currently where I'm trying to plug in my target disc's vector3.
var AimDisk = GameObject.Find("TargetDisk");
var target:Vector3 = AimDisk.transform.position;
and I know this is wrong. I may or may not even be in the right ballpark. What matters is the question: How ARE you supposed to do this?
The problem is that there is no one right way, and I'm not sure from your question whether you are having an issue with ai$$anonymous$$g your projectile or if it is just movement. Say your ai$$anonymous$$g is working correctly...that you instantiate the object facing the correct direction. Then you can just do:
transform.Translate(0,0,fireballSpeed * Time.deltaTime);
Alternate solution that does the same thing:
transform.position += transform.forward * Time.deltaTime * fireballSpeed;
But these two solutions depend on the object facing the correct direction. If you are getting that wrong, you will need to take a look at your Instantiate() code.
var SimpleBullet : Transform;
if (Input.GetButton ("Cast1")) {
var instanceBullet = Instantiate(SimpleBullet, transform.position, Quaternion.identity);
That's my instantiate script, which is on the "Gun" object. I don't want every spell to inherit any value as I want each "spell" to behave differently. So once the object is instantiated, the prefab is intended to define its own behavior, which is the code I posted in that last post, which is similar to what you posted.
Answer by robertbu · Mar 04, 2014 at 09:10 PM
There are two ways to approach your problem if you are aiming your projectile. You either have your objects cast in the direction the 'gun' is facing, or you have your object cast in the direction of some object in the scene. If you are going to do the former, then change your Instantiate() to:
var instanceBullet = Instantiate(SimpleBullet, transform.position, transform.rotation);
If what you are going to do is use a target object, then you can do:
var instanceBullet = Instantiate(SimpleBullet, transform.position, Quaternion.identity);
instanceBullet.rotation = Quaternion.LookRotation(target.position - transform.position);
There is one other choice. That is to have your cast object not face the target (or decide on their own how to face). If so, you are going to have to somehow communicate to the projectile either 1) a direction or 2) a world position of the target (or even a reference to the target itself). Communicating the actual target to the projectile is the most versatile solution. Then the projectile can figure out its own movements based on either of these two values. The specifics of that movement will depend on the nature of the projectile. For example a homing missile will behave differently than an arrow.
Dear God, so that whole time I was focusing on the wrong part of the script as the problem.... And now that I think about what it was doing, I feel like an idiot for not realizing it...
Alright, swapping out the Quaternion for basic rotation made it work, and I'll keep that target position alternative in $$anonymous$$d for future functions.
Thanks for working through this with me, sorry if I was a pain in the butt with my total lack of knowledge! XD
Seeing the code is always best in solving these problems. A lot less guessing. But you did one thing very right. You gave a detail description of your setup...how the object related to each other and how you were dealing with the 'forward' of the objects...better than 99% of similar questions I see on this list. Usually the issue deals with the native rotation of the mesh, but I could see right away your issues were different.