I am writing a quick and easy puzzle game (don’t need to go into details). However, it does involve a cannon, which will (obviously) fire something. I’m not very good with instantiation code, and I need to have it fire with force. Note that this is a 2d game, so it will only be going about the Y and X axes. I need the cannon to fire sideways, so the ball needs to be instantiated next to the cannon, and it also needs to have force, but it needs to be a RigidBody.
None of the Unity Documentations on Instantiate tell me what I need to know. Can someone please help me?
This code assumes you have the cannon able to rotate towards the player, or if it is stationary like Mario then it’ll work aswell.
public Transform cannon; // A reference to the cannon in the scene
public GameObject projectile; // A reference to the projectile prefab
public float projectileSpeed = 750.0f; // How fast the bullet should shoot
public float heightOffGround = 1.5f; // How far from the ground should the projectile spawn
private GameObject clone;
void /***Whatever function you want this in***/() {
// Create a position for the bullet to spawn assuming you dont have a defined gameObject connected
// spawn point child'd to your cannon
Vector3 spawnPoint = new Vector3(cannon.position.x + 1.5f, heightOffGround, cannon.position.z);
// Create the projectile, and get a reference to the created object
// I'd recommend making something to manage the amount of projectiles in the screen
// That way you don't end up with 5000 instantiated clones in the scene
clone = (GameObject)Instantiate(projectile, spawnPoint, Quaternion.identity);
// Make the instantiate projectile move
clone.rigidbody.AddForce(cannon.forward * projectileSpeed);
}
Instantiate is simple. It takes a GameObject, so it has something to spawn, a vector3 position to spawn at and rotation to spawn at.
Thank you very much, I do believe this is what I’m looking for. However, a few small problems are holding me back.
First, you wrote the code in Java, not JavaScript, so I had to translate (mostly it was just translating public GameObject x to var x: GameObject, and etc). However, there is one error I cannot seem to figure out. Here it is:
Assets/Scripts/cannon.js(35,45): UCE0001: ‘;’ expected. Insert a semicolon at the end.
It is obvious what it means, however, I cannot detect any error within the code. Is there something I am missing?
Here is the code I have so far:
#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 = 750.0f; // How fast the bullet should shoot
var heightOffGround: float = 1.996635f; // How far from the ground should the projectile spawn
var clone: GameObject;
function Start () {
}
function Update () {
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("Jump")) {
var spawnPoint: Vector3 = new Vector3(cannon.position.x + 2f, heightOffGround, cannon.position.z);
clone = (GameObject)Instantiate(projectile; spawnPoint; Quaternion.identity);
clone.rigidbody.AddForce(cannon.forward * projectileSpeed);
}
}
function Start(){
clone = GameObject.Find("Projectile");
}
//In your if statement, change the clone code to this:
Instantiate(clone) as GameObject;
If you want to control where the projectile starts at, etc, do that in the Start() function in the Projectile script.
Or, you could change var clone : GameObject to public var clone : GameObject, and then assign the gameobject in the inspector, and then use the same instantiation code I just gave you.
In other words, I don’t believe you can assign an Instantiate statement to a variable. You must assign the variable to the Instantiate statement.
http://docs.unity3d.com/Documentation/ScriptReference/Object.Instantiate.html
Instantiate returns a object which can be type casted to a game object. This means the statement can be assigned to a variable, cause when the statement executes it will returns the created object and that object will be put into the variable.
Alright, I think I’ve found a solution. Here is the updated 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 = 1000f; // How fast the bullet should shoot
var heightOffGround: float = 1.996635f; // How far from the ground should the projectile spawn
function Start () {
}
function Update () {
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")) {
var spawnPoint: Vector3 = new Vector3(cannon.position.x - 1.5f, heightOffGround, cannon.position.z);
var clone: GameObject = Instantiate(projectile, spawnPoint, this.transform.rotation);
clone.rigidbody.AddForce(Vector3.forward * projectileSpeed);
}
}
This works fine, spawning a new bullet next to the cannon. However, there is no force, and the bullet just falls straight down.
Problem #2: I don’t know how to make the position of the bullet as well as the rotation be relative to the rotation of the cannon.
Problem #3: When space is held down, it will continue to spawn the bullets as long as it is held down. I do know how to solve this, however. [SOLVED, but I didn’t want to bump for such a small thing]
Alright, Problem #2 solved. I created a new cube and placed it a bit to the side of the cannon and parented it to the cannon so it would follow its movements. I then made it invisible. I then created a couple new variables. I called the invisible cube Projectile Spawn Point. I created a Transform variable for it and assigned it. However, the Instantiate() code won’t take a transform, it takes a Vector3. So, I added another variable for the PSP’s Vector3 and added this line to the top of the Update() function so it would update itself every time the game had another tick:
projectileSpawnPoint2 = new Vector3(projectileSpawnPoint.position.x, projectileSpawnPoint.position.y, projectileSpawnPoint.position.z);
After that, it was as simple as changing the Instantiate() line to this:
var clone: GameObject = Instantiate(projectile, projectileSpawnPoint2, this.transform.rotation);
to make sure there were no Vector3 related errors.
So that solves problem #2, but I still need Problem #1 solved in order to continue with my game.
remember that ForceMode.Impulse is necessary as a parameter because, in physics terms, the force that a cannon applies to its projectile is an impulse, not a constant force or acceleration or something.