Unable to delete clones made with instantiation function - unity3d

I have made a game where I spawn in several circles which shrink over time until they are supposed to vanish. The problem is, I make all of the circles with the instantiation function. This creates "Ball(clone)" and whenever I try to use Destroy(GameObject) to get rid of one of them i get the following error.
Can't destroy Transform component of 'Ball(Clone)'. If you want to destroy the game object, please call 'Destroy' on the game object instead. Destroying the transform component is not allowed.
To be clear, the creation of the balls is handled by one script attached to an empty child, and the destruction is another script attached to the ball. They are as follows.
var Xpos : float;
var Ypos : float;
var Ball : Transform;
//Place ball
function Update ()
{
if (Input.GetMouseButtonDown(0))
{
//debugging
Xpos = Input.mousePosition.x;
Ypos = Input.mousePosition.y;
//Get mouse input and convert screen position to Unity World position
var position : Vector3 = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Instantiate(Ball,Vector3(position.x,position.y,1),Quaternion.identity);
}
}
//delete ball
#pragma strict
var Ball : Transform;
function Update ()
{
Ball.animation.Play("Shrink");
}
function Despawn ()
{
Destroy(Ball);
}

The error message says it all; you can't Destroy() a Transform. You'll have to apply that to the GameObject instead.
Changing to Destroy(Ball.gameObject); should achieve just that.

Related

Collision not detected by OnTriggerEnter

So I'm trying to make a game about soccer. In this program, I'd created 2 objects called (in Hierarchy): Ball and goal_line_1. In this code, I'm trying to check if the ball collides with the goal line or not, and if it does collide, I will return (Lerp) the ball to the point in the middle (0,0.3,0). But somehow when I drag the ball to the position that the ball collides with the goal line and then press play, the ball just stay there and don't return to the middle point.
public var smooth : float;
private var newPosition : Vector3;
function Awake ()
{
newPosition = transform.position;
}
function OnTriggerEnter (ball : Collider)
{
var positionA : Vector3 = new Vector3(0, 0.3, 0);
newPosition = positionA;
ball.transform.position = Vector3.Lerp(ball.transform.position, newPosition, smooth * Time.deltaTime);
}
That is because you used OnTriggerEnter() function. This function is called when a collider enters a collision with another collider. What you do by dragging the ball into the line and then pressing play is actually skipping the 'Trigger Enter' event. There are three main events when it comes to collisions: TriggerEnter, TriggerStay and TriggerExit.
Although I'm not sure, if you change your function to OnTriggerStay(), you might get your function work. However for a safer testing method, I suggest you add a script to the ball so you can manually move it with your keyboard and see if the OnTriggerEnter() function works because by doing that, you will be simulating a more realistic situation (ball being kicked/moving towards the line rather than "suddenly existing" on the line).
If you are using 2D, you need to change your OnTriggerEnter function to OnTriggerEnter2D.

Unity box to Mouse issue

I am having an issue with my code, i'm trying to move a 3D box to the variable of the position of the mouse, I need to know how to change the box's x,y,z with my mouse position script.
All im asking really, is how do I change my boxes x,y,z with a variable in another script. Thanks!
Code:
#pragma strict
public var distance : float = 4.5;
var box = Transform;
private var firstObject : cube;
function Start () {
}
function Update () {
CastRayToWorld();
}
function CastRayToWorld() {
var ray : Ray = Camera.main.ScreenPointToRay(Input.mousePosition);
var point : Vector3 = ray.origin + (ray.direction * distance);
Debug.Log( "World point " + point );
firstObject = GameObject.Find("pos").GetComponent("cube").pos = point;
firstObject.pos = point;
}
Make sure that the other object is aware of your box gameObject (lets say under the name 'adjustable'), then its simply a case of:
adjustable.transform.position = new Vector3(x, y, z)
To make sure that the object is aware of the boxes gameObject, you could make adjustable a public variable, and then manual drag the box from your scene into the field that would be created in the component on the object in question.

Only select the first sprite in a pile of sprites (Unity3D 2D-game)

I have a number of sprites on top of each-other on the game board. When i use the mouse and select the sprite on top, all sprites under the mouse position is selected. My question is how to only select the sprite that I click on and not catch the ones below?
Here is the code i am using for my tests, attached to the sprites:
function Update () {
if(Input.GetMouseButtonDown(0)) {
var theActualMousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
// print("ALL MousePosition: " + theActualMousePosition);
if(collider2D.OverlapPoint(theActualMousePosition)) {
// print("HIT theActualMousePosition: " + theActualMousePosition);
print(collider2D.gameObject.tag);
}
}
}
The results you are getting are completely expected as your code is placed on the GameObjects, what you should do is to push your script out of those objects or use another function than OverlapPoint (because overlap point does not check for collision it simply checks if you are in the bounds of an object, which means it is valid for all object)
Some ideas :
Using OnMouseDown should provide you with an event only for the first collider encountered
Using A raycast from the camera : Camera.ScreenPointToRay should be able to be used for a raycast and then to check only the first collider encountered
Using Layers depending on layer collision Order.
EDIT :
Or you could also cast the ray the other way around :
function Update () {
if(Input.GetMouseButtonDown(0)) {
var theActualMousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
Vector3 direction = (transform.Position-theActualMousePosition).normalized;
Ray ray = Ray(transform.Position,direction)
if(Physics.Raycast(ray) == null) {
//Then there is nothing between the object and the camera then the object is the first one
print(collider2D.gameObject.tag);
}
}
}

Unity - How to instantiate new object with initial properties (like velocity)?

I'm trying to implement a tower defense game in Unity, and I can't figure out how can I assign a velocity or a force to a new instantiated object (in the creator object's script)
I have a tower which is supposed to shoot a bullet towards the enemy which triggered its collider. This is the script of the towers:
function OnTriggerEnter(other:Collider){
if(other.name=="Enemy")
{
ShootBulletTo(other.transform);
}
}
function ShootBulletTo(target:Transform)
{//public var Bullet:Transform
var BulletClone = Instantiate(Bullet,transform.position, Quaternion.identity); // ok
BulletClone.AddForce(target.position); //does not compile since Transform.AddForce() does not exist.
}
I guess the problem is I have to use a Transform variable for instantiate but I need a GameObject variable for velocity, force etc. So how can I instantiate the bullet with initial velocity?
Thanks for help.
You have to acces the rigidbody component of your bullet clone to change the force, not the transform.
Here's how your code should look:
function OnTriggerEnter(other:Collider)
{
if(other.name=="Enemy")
{
ShootBulletTo(other.transform);
}
}
function ShootBulletTo(target:Transform)
{
var Bullet : Rigidbody;
BulletClone = Instantiate(Bullet, transform.position, Quaternion.identity);
BulletClone.AddForce(target.position);
}
There's also a good example in the unity script reference
http://docs.unity3d.com/Documentation/ScriptReference/Object.Instantiate.html
[EDIT] I'm pretty sure, that you don't want to add the enemies position as a force, instead you should add a direction that goes towards the enemies position.
You subtract two positions to gain a direction vector between them, so the ShootBulletTo function should look like this:
function ShootBulletTo(target:Transform)
{
// Calculate shoot direction
var direction : Vector3;
direction = (target.position - transform.position).normalized;
// Instantiate the bullet
var Bullet : Rigidbody;
BulletClone = Instantiate(Bullet, transform.position, Quaternion.identity);
// Add force to our bullet
BulletClone.AddForce(direction);
}

Unity3D: Two objects with the same script

I would like to associate the same script to different empty objects I just use as placeholders in the game. The aim is to exploit their positions so that when the user touch a point in the screen, close to one of these objects, a dedicate GUI appears. The problem is that though the two objects are different their scripts seem to influence each other so that when the game is running and I touch one of these two objects both the gui appears. What am I doing wrong?
....
private var check: boolean;
var topCamera : Camera;
var customSkin : GUISkin;
function Update () {
if (Input.GetMouseButtonDown(0)){
if(Input.mousePosition.x > this.transform.position.x - Screen.width*0.20 && Input.mousePosition.x < this.transform.position.x + Screen.width*20){
if(Input.mousePosition.y > this.transform.position.y - Screen.height*0.2 && Input.mousePosition.y < this.transform.position.y + Screen.height*0.2){
check = true;
}
}
}
if(check){
//the camera zooms forward
}else{
//the camera zooms backward
}
}
function OnGUI () {
if (this.check){
var w = Screen.width;
var h = Screen.height;
var bw = 0.083;
var bws = 0.001 *w;
GUI.skin = customSkin;
GUI.Box(new Rect(w*0.6,h*0.3,w*0.38,h*0.45), "Stuff");
customSkin.box.fontSize = 0.04*h;
customSkin.textField.fontSize = 0.08*h;
customSkin.button.fontSize = 0.04*h;
textFieldString = GUI.TextField (Rect (w*0.62, h*0.39, w*0.34, h*0.1), textFieldString);
if (GUI.Button (Rect (w*0.62,h*0.50, w*bw, h*0.1), "+")) {
if (this.check){
this.check=false;
}else{
this.check = true;
}
//...
}
//...
}
This is probably not working, because you are comparing apples with oranges in your Update() function. Input.mousePosition returns the the position in 2D pixel coordinates and transform.position returns the GameObject's position in 3D world coordinates.
To check if you clicked on an object, you need to attach a Collider to the game object in question and test for collisions using a Raycast in your script. Here is the relavant example from the documentation in JavaScript:
var ray = Camera.main.ScreenPointToRay (Input.mousePosition);
if (Physics.Raycast (ray, 100)) {
print ("Hit something");
}
The cool thing about this approach is that we are checking for collisions between the Collider and the ray. If you only want to see if you clicked near the GameObject, just make the Collider larger than the GameObject. No need for messing around with inequalities!
If your objective is to click somewhere close to the object and not only at the object, then you have some configurations (positions of those objects in space) where there are space that are close enough to both objects for their GUI to appear and therefore you need some script to decide which one is closer.
I suggest you to implement a monobehaviour that is a singleton that would track those clicks and measure the distance of all objects, to get the closest.
Reading again your post, I think you want to get the GUI just when you click at the object, and when you do this you get both GUIs. I think that's happening because wrong calculation of the area that makes check to go true.
Can you give more details? Is there some space where there shouldn't have GUI messages when clicked, or is everything filled by those objects?