x


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 

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 

Any help would be really appreciated. :)

more ▼

asked Feb 01 '12 at 10:25 AM

gilgada gravatar image

gilgada
70 16 22 26

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 :)

Feb 01 '12 at 11:22 AM gilgada

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?

Feb 01 '12 at 11:40 AM syclamoth
(comments are locked)
10|3000 characters needed characters left

1 answer: sort voted first

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.

more ▼

answered Feb 01 '12 at 11:43 AM

syclamoth gravatar image

syclamoth
14.8k 7 15 80

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

Feb 02 '12 at 12:33 PM gilgada

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.GetKey ("up") && transform.rotation.eulerAngles.x < 85)
		{
		transform.rotation.eulerAngles.x += speed;
		}
	if(Input.GetKey ("down") && transform.rotation.eulerAngles.x > 10)
		{
		transform.rotation.eulerAngles.x -= speed;
		}
		
}

I have then used the remainder of your velocity calculation code within the projectileMovement script:


var projectile : Rigidbody;
var curPos:rotateCatapultArm = GetComponent(rotateCatapultArm);


function Update()
{

if(rigidbody.isKinematic ==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?

Feb 02 '12 at 01:37 PM gilgada

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 assuming 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.

Feb 02 '12 at 11:56 PM syclamoth

Sorry, I did not mean to make things more problematic. My catapult arm does not carry on moving at the moment the projectile is "unchilded". Do you think it would be best if it was?

Feb 03 '12 at 12:27 PM gilgada

I've amended my LaunchSequence.js to

var scriptObject : GameObject;
function Update () {
	if(Input.GetKey (KeyCode.Space) 
		&& 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.isKinematic == 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.isKinematic = 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 isKinematic == 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 Maybe I'm making a few mistakes here but I feel like it is getting close

Feb 03 '12 at 12:59 PM gilgada
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x458
x316
x291
x251
x18

asked: Feb 01 '12 at 10:25 AM

Seen: 1300 times

Last Updated: Feb 07 '12 at 04:30 PM