- Home /
Firing projectile in curve
Okay so I am having some trouble with this. I have an object in unity called Catapult arm. This object contains the meshs and colliders for the arm of a catapult which can be controlled using the arrow keys. The catapult arm object also contains a test block that I am trying to launch when the catapult arm reaches a certain angle (normally reached when firing).
By default the projectile block has a rigidbody set to not use gravity and to be kinematic, this is so that it plays nicely when moving the catapult arm object with the arrow keys. This is all fine and I can raise and lower the catapult arm and block.
The problem comes with when the firing angle has been reached. I have a script attached to the projectile called "changeProjectileState". this script is as follows:
gameObject.tag == "projectile"; function Update () { if(rigidbody.isKinematic == true) { if( transform.rotation.eulerAngles.x >= 75 && transform.rotation.eulerAngles.x <= 85) { transform.parent = null; rigidbody.useGravity = true; rigidbody.isKinematic = false; } } }
I then have a script attached to take care of the movement of the projectile when it is no longer attached to the arm object.
This is the problem as currently it just adds a force to the object and doesnt stop. I want it to take advantage of the activated gravity and apply a single initial force and then leave the rest to the engine so that the block slows down and stops.
gameObject.tag = "projectile";
function Update () { if(rigidbody.isKinematic ==false) { if(rigidbody.AddForce.z <= 20) { rigidbody.AddForce (0,0,10); } } }
Any help would be really appreciated. :)
i know the use of rigidbody.iskinematic ==false for the condition of the second script isn't ideal. if anyone has a suggestion for a different way of activating the script when the block is free of its parent, then do tell :)
What I don't understand, is why you are adding forces like this at all! Surely, all you need to do is sample the velocity at the moment of release, and let the physics engine do the rest?
Answer by syclamoth · Feb 01, 2012 at 11:43 AM
How about this-
function Release()
{
yield WaitForFixedUpdate();
var curPos : Vector3 = transform.position;
yield WaitForFixedUpdate();
var deltaPos : Vector3 = transform.position - curPos;
var calculatedVelocity = deltaPos / Time.fixedDeltaTime;
transform.parent = null;
rigidbody.useGravity = true;
rigidbody.isKinematic = false;
// this is the key bit-
rigidbody.velocity = calculatedVelocity;
}
This samples the movement of the arm at the moment just before the ball should be released, and sets its velocity accordingly.
Am I to replace one of my above scripts with your example? Sorry for sounding stupid but I'm unsure as to how to use your script
I've made a few changes according to your answer. I have a script called rotateCatapultArm which allows the player to choose an angle for the arm before firing (which should in turn affect the force on the projectile, raised arm = less swing and less force). I have added your curPos variable to this script as this position is what should be referenced as the 'initial position' before firing. The script is as follows:
var speed : float = 5.0f; // meters per second var curPos : Vector3 = transform.position;
gameObject.tag == "catapult arm";
function Update() { if(Input.Get$$anonymous$$ey ("up") && transform.rotation.eulerAngles.x < 85) { transform.rotation.eulerAngles.x += speed; } if(Input.Get$$anonymous$$ey ("down") && transform.rotation.eulerAngles.x > 10) { transform.rotation.eulerAngles.x -= speed; }
}
I have then used the remainder of your velocity calculation code within the projectile$$anonymous$$ovement script:
var projectile : Rigidbody; var curPos:rotateCatapultArm = GetComponent(rotateCatapultArm);
function Update() {
if(rigidbody.is$$anonymous$$inematic ==false) { curPos.Translate(0,0,0); var deltaPos: Vector3 = transform.position - curPos; var calculatedVelocity = deltaPos / Time.fixedDeltaTime;
rigidbody.velocity = calculatedVelocity;
} }
but this doesnt seem to do anything. For starters, I get an error in the console saying BCE0051: Operator '-' cannot be used with a left hand side of type 'UnityEngine.Vector3' and a right hand side of type 'rotateCatapultArm'.
Could you please assist me with this?
Well, do you have a 'Translate' method for your rotateCatapultArm script? You can't subtract a 'rotateCatapultArm' from a vector, now, can you? I think you should be using 'curPos.transform.position' for that...
In any case, my 'Release' method should be called from inside Update (or whatever) at the moment that you want to release the ball from the catapult. It manages all of the velocity calculation assu$$anonymous$$g that the arm continues to move. I'm not really sure why people keep changing my scripts and then wondering why they don't work any more.
Sorry, I did not mean to make things more problematic. $$anonymous$$y catapult arm does not carry on moving at the moment the projectile is "unchilded". Do you think it would be best if it was?
I've amended my LaunchSequence.js to
var scriptObject : GameObject; function Update () { if(Input.Get$$anonymous$$ey ($$anonymous$$eyCode.Space) && transform.rotation.eulerAngles.x <= 75) { transform.rotation.eulerAngles.x += 10; } if(transform.rotation.eulerAngles.x >=70) { scriptObject.GetComponent(changeProjectileState).Release(); } }
and then put the Release method in to changeProjectileState.js
gameObject.tag == "projectile"; function Release () { if(rigidbody.is$$anonymous$$inematic == true) // yield WaitForFixedUpdate(); var curPos : Vector3 = transform.position; // yield WaitForFixedUpdate(); var deltaPos : Vector3 = transform.position - curPos; var calculatedVelocity = deltaPos / Time.fixedDeltaTime; transform.parent = null; rigidbody.useGravity = true; rigidbody.is$$anonymous$$inematic = false; // this is the key bit- rigidbody.velocity = calculatedVelocity; }
and then tried to point the scriptObject component to my wooden projectile in the inspector so that it knows what to call the Release method for, also removing my awkward if statement of is$$anonymous$$inematic == false
Problem is, it now seems that the block doesn't move at all. I'm not sure if the reference to Release is working or not but the block doesn't even seem to fall due to the gravity that should turn on $$anonymous$$aybe I'm making a few mistakes here but I feel like it is getting close
Your answer
Follow this Question
Related Questions
Setting limits to my trajectory 2 Answers
rigidbody.Velocity stops gravity 2 Answers
Keeping character's movement consistent. 1 Answer
Simulate gravity on rigidbody 1 Answer