How do I get my terrain to self-delete? - unity3d

I set up this code in the deletion script, first off:
var terrain = GetComponent(Rigidbody2D);
function Update ()
{
if (terrain.position.x <= Camera.main.transform.position.x - 5)
{
Destroy(this.GameObject);
}
}
Here is a picture of the screen:
And my prefab stuff:
What I want is for, when the camera is in front of the prefab, I want it to delete itself. However, this is the error I get:
NullReferenceException: Object reference not set to an instance of an object
UnityEngine.Component.GetComponent (System.Type type)
Deletion..ctor () (at Assets/Scripts/Deletion.js:3)
UnityEngine.Object:Instantiate(Object, Vector3, Quaternion)
Repeating Terrain:SpawnTerrain(Object) (at Assets/Scripts/Repeating Terrain.js:60)
Repeating Terrain:Update() (at Assets/Scripts/Repeating Terrain.js:52)

So, it turns out, I just needed to replace this.GameObject with this.gameObject. I capitalized it, that was all.

Try it with a timer and use console/debug to make sure you have the right object
Destroy (this.GameObject, 5);
or
GameObject.Destroy(gameObject)

Related

Unity 2D - how to check if my gameobject/sprite is below ceratin Y lvl?

I've been trying to get a script working to check if my player is below a certain Y lvl, for a platformer. so it can be respawned to the beginning, But how do I put the y lvl inside a variable to check it? i cant figure it out lol
In the Update() run something like:
if(player.transform.position.y < 1)
{
//do something
}
where 'player' is the GameObject in question.
I am assuming you want to just want to compare (==, <=, >=, all that jazz is what I mean by comparing just in case you were not aware) the Y value to something like 10 for example. This is easy and you don't even need a variable necessarily for this.
//For the object position relative to the world
if(transform.position.y == 10) //"transform" gives you acces to the transform component
{ //of the object the script is attached to
Debug.Log("MILK GANG");
}
//For the object position relative to its Parent Object
if(transform.localPosition.y == 10)
{
Debug.Log("MILK GANG");
}
If you want to change the value of the position of your object then
transform.position = new Vector2(6, 9)//Nice
//BTW new Vector2 can be used if you dont
//want to assign a completely new variable
However, if you want to get a reference (Basically a variable that tells the code your talking about this component) to it.
private Transform Trans;
void Awake() //Awake is called/being executed before the first frame so its
{ //better than void Start in this case
Trans = GetComponent<Transform>();
Trans.position = new Vector2(69, 420); //Nice
}
This is the code way of doing it but there's another way that uses Unity
[SerializeField] private Transform Trans;
//[SerializeField] makes the variable changeable in Unity even if it is private so you
//can just drag and drop on to this and you good to go
Hope this help
if it doesn't
then welp I tried lel
You can use a script added to gameobject to check transform.position of the object.
if(transform.position.y < ylvl)
{
//do something
}
where ylvl is the integer of the height you want to check

If Statement doesn't work when I build my game on Unity

I am trying to learn how to develop a 2D game in Unity. I would like to level up the scene when the user completes the scoring task. For example, in the first scene, the user must shoot 5 balls to skip to the second level. I have a score counter which counts down scores.
Here is the related function which I called it in the Update() body:
void GetScore()
{
if (KickTheBall.timeLeft <= 0 ) {
SceneManager.LoadScene ("GameOver");
}
else if (ScoreTask <= 0)
{
Debug.Log (nextScene.name);
LevelUp ();
}
}
LevelUp() function:
void LevelUp()
{
SceneManager.LoadScene (nextScene.name);
}
On iMac Pro everything works properly, however, when I build it on Xcode, the value of the scoreboard falls below zero instead of skipping to the next level.
These are the log outputs from Xcode:
NullReferenceException: A null value was found where an object instance was required.
at Ball.GetScore () [0x00000] in <filename unknown>:0
(Filename: currently not available on il2cpp Line: -1)
-> applicationDidEnterBackground()
I think I set all scenes properly:
You can see the scoreboard on the left corner:
How can I fix this problem? Why it happens only on mobile?

Endless Runner Infinite track generation - Unity3D C#

I am new to unity and I am creating my first ever endless runner game. I currently have a cube as a player and another cube (prefab) as the track. I have created a script which aims at instantiating the prefab at runtime and moving the track towards the player (instead of moving the player). For some reason, the tracks instantiated at runtime are being generated at the same position and don't seem to move towards the player. Could anyone tell me if I am doing it right please? How do I generate an infinite/endless track? Thanks in advance
public GameObject[] trackPieces;
public float trackLength;
public float trackSpeed;
private GameObject trackObject;
// Update is called once per frame
void Update ()
{
GenerateInfiniteTrack();
}
private void GenerateInfiniteTrack()
{
trackObject = InstantiatePrefab();
trackObject.transform.Translate(-Vector3.forward * Time.deltaTime * trackSpeed);
}
private GameObject InstantiatePrefab()
{
return Instantiate(trackPieces[Random.Range(0, trackPieces.Length)]) as GameObject;
}
trackObject is overwritten every frame
Your track is not moving because the call to move it occurs only once at instantiation and never again. The value of which track to move is overwritten every update(). Here is what happens:
Every update you make a call to:
private void GenerateInfiniteTrack()
When this method is called you instantiate a new prefab (new instance of your object) and tell the object to move via
trackObject.transform.Translate(-Vector3.forward * Time.deltaTime * trackSpeed);
When you call the method the next time you lose the reference to the original object because you are creating another one that replaces the value held in trackObject. So the previously generated object will never move again. Your new object moves once and then is lost, again, and repeat.
Below I have suggested some code that may work. You will still have to decide how you will dispose of the track objects since you are creating them at a very fast rate. If you can think of a way to use InvokeRepeating() to address this problem, then that would be the cleanest. Invoke repeating has some limitations, like not being able to pass parameters to your repeating function so I did not use it here, but it is conceivably an alternative.
Here is my example.
var TrackObjects = new List<GameObject>();
private void MoveInfiniteTrack()
{
foreach(GameObject gO in TrackObjects )
{
gO.transform.Translate(-Vector3.forward * Time.deltaTime * trackSpeed);
}
}
private void GenerateInfiniteTrack()
{
TrackObject = InstantiatePrefab();
TrackObjects.Add(TrackObject);
}
void Update ()
{
GenerateInfiniteTrack();
MoveInfiniteTrack()
}
void Foo()
{
// Delete your track on some kind schedule or you will quickly get infinite objects and massive lag.
}
As a general observation, creating track this much (60x a second) is very inefficient. I would suggest that you either:
A. Create much larger segments of track, for example once every 1 or 10 seconds and move it along. I don't remember exactly how to do this, but it went something like this:
var lastchecked= datetime.now
Update()
{
if((datetime.now - lastchecked).seconds > 1)
{
// put here what you will do every 1 second.
lastchecked= datetime.now
}
}
B. Create a large cylinder and rotate it to use as a track.

Raycasting from one object to another

I am trying to cast a ray from one object to another but it is not working properly.
Result:
Selected object is "EnemyTank" and ray should point to "PlayerTank" but it is not as you can see.
My code:
void FixedUpdate () {
Vector3 dir = player.transform.position - rayOrigin.transform.position;
RaycastHit hitInfo;
dir = dir.normalized;
Debug.DrawRay(rayOrigin.transform.position, dir*maxCheckDistance,Color.red);
}
player variable points to "PlayerTank"
Playertank location:
So there are a few issues that I can see, but straight to the point:
FixedUpdate Runs on a set interval, it isn't every frame. the Method DrawRay() Has a parameter for duration. by default it is set to 0. This means it will only be visible for a single frame. You have 2 choices you can pass in a duration, or you can put this method in update which does run every frame.
void Update () {
Vector3 dir = player.transform.position - rayOrigin.transform.position;
dir = dir.normalized;
Debug.DrawRay(rayOrigin.transform.position, dir*maxCheckDistance,Color.red);
}
However if you are trying to draw a line from one object to another just use Debug.DrawLine()
Debug.DrawLine(rayOrigin.transform.position, player.transform.position, Color.red);
Lastly, avoid using a color for your line that is the same as one of your objects, I am referring to your red cube, and red line. Use a color that will stand out. Say black in this case.
FixedUpdate example:
void FixedUpdate () {
Vector3 dir = player.transform.position - rayOrigin.transform.position;
dir = dir.normalized;
Debug.DrawRay(rayOrigin.transform.position, dir*maxCheckDistance,Color.red, 1.0f);
}
For fun, to have the line change colors using your maxCheckDistance value:
void Update () {
Color lineColor = color.Black;
if(Vector3.Distance(rayOrigin.transform.position, player.transform.position) < maxCheckDistance) {
lineColor = color.White;
}
Debug.DrawLine(rayOrigin.transform.position, player.transform.position, lineColor);
}
EDIT:
It is important to know where your objects actually are, in your question you have a Player object, that you made the parent of 2 cubes. It appears as though you moved those 2 cubes into where you wanted the player to be in the world instead of moving the Player object itself. So your line is drawing correctly, as it is getting the position to the player object, In the future move the parent object instead of the children object.
From your description and screenshot.
You want to draw ray from "EnemyTank" to "PlayerTank".
and in your code "PlayerTank" is player and "EnemyTank" is rayOrigin.
There has draw a small ray from "EnemyTank" to some other direction. So you definitely miss to define your "PlayerTank" in player object.
The direction parameter in DrawRay is a vector in global space.
Thus your ray always points more or less to the origin.
Sorry, my answer is wrong.

destroy gameObject clone if position x and y is the same with my player

I want to destroy the gameObject(clone) when my player position x and y is the same with gameObject(clone) position x and y. The gameObject appear in my scene when I trigger something else and it has rigidbody and box collider.
I use this code to my player, but it doesn't work
function Update () {
if(this.transform.position.x==rigidbody.transform.position.x){
if(this.transform.position.y==rigidbody.transform.position.y){
Destroy(rigidbody.gameObject);
}
}
}
I used the code and like that but it doesn't work too because it didn't find the variable "other"
function Update () {
var other:Collider;
if(this.transform.position.x==other.transform.position.x){
if(this.transform.position.y==other.transform.position.y){
Destroy(other.gameObject);
}
}
}
Can you help me please?
If you know what's spawning your clones you could spawn them with different names like "gameObject(clone) 2" and then call Destroy().
Destroy(gameObject.Find("gameObject(clone) 2"));
In general though as long as you can identify one object from the other this shouldn't be a problem.
If you have reference to the object you do not wan't deleted then you could perform a .Equals to avoid deleting it.
// C#
foreach(GameObject go in clones) {
if(!go.Equals(playerObject) {
Destroy(go);
}
}
I'd favor the initial approach though. You should have reference or indenifiers for any object in your scene so you can manage them.