AddForce Not Working!

Hey guys,

I am working on a puzzle game that involves a cannon. I have tried all known AddForce, AddExplosionForce, etc, modes that I know of. Yet none of them works. Can someone please tell me what I am doing wrong?

Here is the code:

#pragma strict

var rotateSpeed: int = 10;
var cannon: Transform;  // A reference to the cannon in the scene
var projectile: GameObject; // A reference to the projectile prefab
var projectileSpeed: float; // How fast the bullet should shoot
var heightOffGround: float = 1.996635f; // How far from the ground should the projectile spawn
var projectileSpawnPoint: Transform; //Transform variable referencing the spawn point in-game
var projectileSpawnPoint2: Vector3; //Vector3 variable that is updated constantly so that the Instantiate can use it
var lastShotTime: int;
var reloadTime: int = 1;
var power: float = 2f;
var explosionPos: Transform; //Same thing here as the projectileSpawnPoint
var explosionPos2: Vector3;
var radius: float = 2;

function Start () {

}

function Update () {

	projectileSpawnPoint2 = new Vector3(projectileSpawnPoint.position.x, projectileSpawnPoint.position.y, projectileSpawnPoint.position.z);
	explosionPos2 = new Vector3(explosionPos.position.x, explosionPos.position.y, explosionPos.position.z);

	if(Input.GetAxis("Horizontal")) {
	
		if(Input.GetKey("right")) {
		
			this.transform.Rotate(Vector3.forward, (Time.deltaTime * rotateSpeed) * -1);
		
		}
	
		if(Input.GetKey("left")) {
		
			this.transform.Rotate(Vector3.forward, Time.deltaTime * rotateSpeed);
		
		}
		
		}
		
		if(Input.GetKey("space")) {
		
			if(lastShotTime + reloadTime < Time.fixedTime) {
			
			var spawnPoint: Vector3 = new Vector3(cannon.position.x - 1.5f, heightOffGround, cannon.position.z);
			var clone: GameObject = Instantiate(projectile, projectileSpawnPoint2, this.transform.rotation);
			clone.rigidbody.AddForce(clone.transform.forward * projectileSpeed, ForceMode.Impulse);
			lastShotTime = Time.fixedTime;
			
			
			}
		
		}

}

And here it is with AddExplosionForce() {

#pragma strict

var rotateSpeed: int = 10;
var cannon: Transform;  // A reference to the cannon in the scene
var projectile: GameObject; // A reference to the projectile prefab
var projectileSpeed: float; // How fast the bullet should shoot
var heightOffGround: float = 1.996635f; // How far from the ground should the projectile spawn
var projectileSpawnPoint: Transform; //Transform variable referencing the spawn point in-game
var projectileSpawnPoint2: Vector3; //Vector3 variable that is updated constantly so that the Instantiate can use it
var lastShotTime: int;
var reloadTime: int = 1;
var power: float = 2f;
var explosionPos: Transform; //Same thing here as the projectileSpawnPoint
var explosionPos2: Vector3;
var radius: float = 2;

function Start () {

}

function Update () {

	projectileSpawnPoint2 = new Vector3(projectileSpawnPoint.position.x, projectileSpawnPoint.position.y, projectileSpawnPoint.position.z);
	explosionPos2 = new Vector3(explosionPos.position.x, explosionPos.position.y, explosionPos.position.z);

	if(Input.GetAxis("Horizontal")) {
	
		if(Input.GetKey("right")) {
		
			this.transform.Rotate(Vector3.forward, (Time.deltaTime * rotateSpeed) * -1);
		
		}
	
		if(Input.GetKey("left")) {
		
			this.transform.Rotate(Vector3.forward, Time.deltaTime * rotateSpeed);
		
		}
		
		}
		
		if(Input.GetKey("space")) {
		
			if(lastShotTime + reloadTime < Time.fixedTime) {
			
			var spawnPoint: Vector3 = new Vector3(cannon.position.x - 1.5f, heightOffGround, cannon.position.z);
			var clone: GameObject = Instantiate(projectile, projectileSpawnPoint2, this.transform.rotation);
			clone.rigidbody.AddExplosionForce(power, explosionPos2, radius, 3.0);
			lastShotTime = Time.fixedTime;
			
			
			}
		
		}

}

I can provide screenshots if needed.

I already have another thread that could provide more info on the question:

http://forum.unity3d.com/threads/164497-Instantiation?p=1124665&posted=1#post1124665

Thanks guys. You’ve already been a great help.

-Silent

I’m not sure if this will help, but I’ve heard people say that AddForce should only be used inside a FixedUpdate and not in a regular Update.

Try changing the name of the Update function to FixedUpdate.

Also, what’s happening when you hit play. Anything, or is it not doing anything at all? Is it obvious that it’s trying to do something, or is it not even trying?

The program works fine, but when the ball is Instantiated, all it does is drop to the floor.

I’ll try changing it to FixedUpdate.

EDIT:::::

Nope, still just falls to the floor. I thought that wouldn’t work because I have created other projects that use AddForce and they worked.

I think I may be mis-assigning the AddForce, because like you said, it doesn’t look like it’s trying to do anything, so it might not even be applying force to the right thing, but I’ve quadruple checked everything, so I can’t figure out what’s wrong.

what… is projectileSpeed?

Try making it something like 5000 or maybe 500000.

force needs to be proportional to the mass. If you have high mass, you will require alot of force to move the object.

I would not use Force.Impulse, but it really doesnt matter as all you are going to do is add it once.

You may achieve the same results with something like this:

clone.rigidbody.velocity = this.transform.forward * 100;

Also, instead of doing all this calculation for position and rotation. If you are using a gun, simply put a projectile on the end of it, in the direction it should be firing. Make it inactive, instantiate it, use the projectile’s position and rotation. Then you can use something like this:

var clone: GameObject = Instantiate(projectile, projectile.transform.position, projectile.transform.rotation);
clone.active = true;
clone.rigidbody.velocity = clone.transform.forward * 100;

I am not attempting to get a bullet-like thing. I am attempting to get a small cannonball that does not go very fast and is obviously affected by gravity.

In fact, the mass is very small. It is just 1. I will try what you have said.

EDIT::::

No, there is still no applied force to the ball. Here is the updated code:

			if(lastShotTime + reloadTime < Time.fixedTime) {
			
			var spawnPoint: Vector3 = new Vector3(cannon.position.x - 1.5f, heightOffGround, cannon.position.z);
			var clone: GameObject = Instantiate(projectile, projectileSpawnPoint2, this.transform.rotation);
            //clone.rigidbody.AddForce(clone.transform.forward * projectileSpeed, ForceMode.Impulse);
            clone.rigidbody.velocity = cannon.transform.forward * 100;
			lastShotTime = Time.fixedTime;
			
			
			}

Have you tried setting the velocity, not the force.

What I just did, check my previous edited post.

Is the rigidbody on your cannonball set to kinematic? It will ignore force if so.

you either have a lock on the rigidbody that prevents it from moving. or something strange in code that is stopping it. (maybe like a onCollisionEnter)

Rebuild the ball with nothing but a rigidbody. As a matter of fact, just build one with a new script that sets the velocity on startup, put it in the world someplace and just see if it moves.

Alright, I’ll try that. I don’t have it set on Kinematic, already checked that. I’ll take out the code for force in the cannon script and assign the ball a new script of its own. Hold on.

I’m not sure why it’s not working. It looks right.

I programmed something similar a few weeks ago, but instead of adding the force in the script that creates the projectile, I add the force in the start function of the projectile.

On the projectile prefab, have a script that says:
function Start()
{
rigidbody.AddForce(transform.forward * speed);
}

Also on this script, I would store all the other variables that affect the fire pattern as public. That way, you can have one script for all projectiles which you can attach to multiple prefabs to make multiple projectiles with different fire patterns. In my game, I had several guns. For each gun, I also had a projectile prefab. All the projectile prefabs had the same script attached to them, just different values stored in the public variables.

On the object that creates the projectile, have a script that says:
function Fire() {
GameObject.Instantiate(projectile,transform.position + transform.forward * lengthOfBarrel,transform.rotation);
}

Projectile would just be whatever projectile prefab you have saved for that particular gun. This avoids the possibility of miss assigning things.

I don’t know if that would work with your game, but I’m just throwing out ideas here.

This is a working bullet script that I made for a test I did for someone.

It is meant to be placed on a bullet. All I would do in this case is to instantiate it, then call the Shoot() method.

#pragma strict

var explosionObject:GameObject;
var explosionRadius:float = 20;
var explosionDamage:float = 10;
var speed:float = 100;
private var lastPos:Vector3;

function Start () {
	if(collider) Destroy(collider);
	if(!rigidbody)gameObject.AddComponent(Rigidbody);
	lastPos = transform.position;
}

function Shoot (){
	Start();
	rigidbody.velocity = transform.forward * speed;
}

function Update () {
	var hit:RaycastHit;
	if(Physics.Linecast(lastPos, transform.position, hit)){
		Debug.DrawLine(lastPos, transform.position, Color.green, 3);
		Debug.Log(hit.collider);
		if(explosionObject){
			var obj:GameObject = Instantiate(explosionObject, hit.point, Quaternion.identity);
			obj.transform.up = hit.normal;
			obj.transform.Rotate(0,Random.Range(0,360),0, Space.Self);
		}
		Destroy(gameObject);
		/*
		var objs:Health[] = root.GetComponentsInChildren(Health) as Health[];
		if(objs.Length > 0){
			for(var obj:Health in objs){
				var damage:float = (1 - Vector3.Distance(hit.point, root.transform.position) / explosionRadius) * explosionDamage;
				obj.Damage(damage);
			}
		}
		*/
	}
	lastPos = transform.position;
}

Well tested and it works fine.

Demo

Alright, I tried the method I mentioned earlier, and here are my results.

The ball moves correctly, however, the movement is not what I intended for. I did not intend for the bullet to continue moving forever, I wanted the bullet to be pushed once and then be affected by gravity. However, at least the bullet moves.

I added just this code into the update function of the moveBullet script, which I then attached to the Bullet prefab:

this.rigidbody.velocity = this.transform.right * -10;

I will now try the AddForce method to see if that works. Hold on.

No, that definitely does not produce the results I was looking for.

so reduce the speed. :wink:

Also, if your canon ball goes on forever, and never drops, then you have Use Gravity turned off. :wink:

Sorry, but UseGravity is on, and if I reduce the speed, it still just goes on forever, just slower. :stuck_out_tongue:

Argh! Sorry for the trouble, guys!

it never drops? What is Physics.gravity set to? (Edit, Project Settings Physics) gravity.

I know that gravity works, because if the ball hits one of my cubes in the scene that has a RigidBody on it, the cubes fall fine.

Gravity is set to -9.81 Y.

AHAHAHAHAHAHAHAHAHAHAHA! I FIGURED IT OUT!

I was putting the velocity function in the Update() function, so it was continually repeating the action. However, if I put it in the Start() function, then it does it once, therefore doing it correctly!

I also figured out why it couldn’t do it in the cannon script. The script couldn’t get to the velocity function because the if statement required the space button to be pressed, but the statement required the space button to be held down… or something like that… I think…

I am such an idiot for not noticing this!

HAHA! Thanks a lot, everyone, for your help!