- Home /
Giving Instantiated Object Velocity Causes Wrong Position
I'm knocking out a super simple projectile script. I instantiate an object at a position, no problem. I instantiate an object, on the next line give it a velocity, all of a sudden the object starts at the center of the object that instantiated it.
I use the following JS:
var bullet : GameObject;
var muzzleVelocity : float = 10.0;
private var aim : Vector3 = Vector3.right;
function Update()
{
if(Input.GetKeyDown("space"))
{
var b : GameObject = Instantiate(bullet, transform.position + aim * 2, Quaternion.identity);
b.rigidbody.velocity = aim * muzzleVelocity;
}
}
Commenting out the line where the velocity is set results in the bullet getting spawned at the correct location (in this case, 2 units to the right).
EDIT: It looks like the physics engine isn't revving up in time. I've included the following on the bullet:
var colSparks : Transform;
private var last : Vector3 = Vector3.zero;
private var del : boolean = false;
function Start()
{
last = this.transform.position;
}
function Update()
{
if(del)
{
Destroy(this.gameObject);
}else{
var dir : Vector3 = last - this.transform.position;
last = this.transform.position;
Debug.DrawRay(this.transform.position, dir, Color.green);
var hit : RaycastHit;
if(Physics.Raycast(this.transform.position, dir, hit))
{
Debug.Log(hit.collider.name);
Instantiate(colSparks, hit.point, Quaternion.LookRotation(hit.normal));
if(hit.collider.rigidbody)
{
Destroy(this.rigidbody);
}
this.transform.position = hit.point;
del = true;
}
}
}
I'm guessing the instantiation happens, and Start()
runs on the above script and sets last
before the instantiating function continues and sets the new position. When the first update runs and finds the new position, it checks for collisions along that line and finds the original instantiating object.
New question: can anyone think of a good cheap, simple fix for this?
Answer by Doireth · Jan 28, 2013 at 08:49 PM
Instead of altering the velocity (which you should generally never do as the physics engine will perform those calculations) you should use AddForce(). For example:
b.rigidbody.AddForce(aim * muzzleVelocity);
http://docs.unity3d.com/Documentation/ScriptReference/Rigidbody.AddForce.html
I had actually seen someone suggest that in a similar question. It didn't work but I DID mean to use that version of my code. Anyway, I think I've figured out the problem, but I've raised a new, more general question above.
For your edited question (though in future it's best to make a new question) you should use OnCollisionEnter() (see http://docs.unity3d.com/Documentation/ScriptReference/Collider.OnCollisionEnter.html). For example:
function OnCollisionEnter(collisionInfo : Collision)
{
Destroy(gameobject);
}
As the documentation notes, if you are not using the collision parameter you can leave it out as it reduces calculations.
By using OnCollisionEnter
, though, I'm losing the ability to raycast between frames to check for "paper walls", aren't I? Ballistic projectiles aren't going to be very common, so I'm okay taking the time and processing power to make sure they're handled well.
Shall I make a new question, still? Thanks for all of your patience.
Eh, I just added a function jump()
to the second script that updates variables (such as last
) in the case of a sudden jump where collisions shouldn't be checked. It's a little hacky, but it works. Thanks for all the help, selecting your answer now.
A combination of both would work nicely. Since projectiles are not to be very common then the extra processing of both to make sure it's done right would be perfectly fine. Neither have any major performance costs you need to worry about.
Your answer
Follow this Question
Related Questions
Resume movement of instanced object relative to the original after instantiation. 2 Answers
PhysX and multiple instances at same location 1 Answer
Innacurate terrain collision with fast rigidbody 1 Answer
Projectiles, their speed, and collisions 1 Answer
Bullet projectiles with collision info without affecting others 0 Answers