Incorrect text on screen - unity3d

Hi I'm new to this unity and I'm making a 2d game the problem.I'm facing is displaying the right text in the screen , e.g I have a score count for keeping track of score and then I'm displaying this text through count.text , HOWEVER the problem is that when the game starts the text on screen displays "0", score is 0 as well, then I shoot an apple and the score becomes 1 as well as the count.text also becomes 1 however the text is still 0 on the screen, when I shoot another arrow the score and count.text shows value of 2 however on the screen it shows 1 and so on. I followed unity tutorial of roll the ball. here is my code
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class arrowcounttutorial : MonoBehaviour {
public GameObject Arrow;
public GameObject apple;
public int score = 0;
public Text count;
// Use this for initialization
void Start () {
this.gameObject.GetComponent<Rigidbody2D> ().AddForce (transform.right*1500.0f);
//score = 0;
//showcounttext ();
count.text = score.ToString ();
}
// Update is called once per frame
void Update () {
Vector3 diff = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
diff.Normalize();
float rot_z = Mathf.Atan2(diff.y, diff.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0f, 0f, rot_z - 0);
if (Input.GetMouseButtonUp (0)) {
GameObject bullet_new;
bullet_new = Instantiate (Arrow,new Vector2 (-0.23f, -3.78f), Quaternion.identity) as GameObject;
RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition),Vector2.zero);
if (hit.collider!= null ) {
LeanTween.move(bullet_new, hit.collider.transform.localPosition, 1);
if(hit.collider.tag == "fruit")
{
score++;
//showcounttext();
count.text = score.ToString ();
print(count.text);
Destroy(hit.collider.gameObject,1);
Destroy(bullet_new,1);
}
}
}
}
/*
void showcounttext(){
count.text = score.ToString ();
}
*/
}
Also if I initialize the score in void start the text remains 0 through out the level even if the score and count.text are 1,2,3,4,5 so on. What can I do?
UPDATE
I don't know how it worked but I called an invoke function Invoke ("showcounttext",1); and it worked. I won't delete the question in case someone else have this same problem :)

I see your answer, good that it is fixed but it is not the best solution.
Prior to Unity3D version 5.3.1p3 this engine had problems with updating canvases, and sometimes the UI content was disapearing. You didnt tell version you use, but I am almost sure in this case it would help calling
Canvas.ForceUpdateCanvases ();
In your code it should look like that:
if(hit.collider.tag == "fruit")
{
score++;
//showcounttext();
count.text = score.ToString ();
print(count.text);
Destroy(hit.collider.gameObject,1);
Destroy(bullet_new,1);
Canvas.ForceUpdateCanvases ();
}
Try this, or upgrade Unity3D.

Related

"Screen position out of view frustum" errors followed by "Assertion failed on expression: 'std::abs(det) > FLT_MIN'" - Unity 3d

So in my game you are a sphere rolling down ramps, but if you go too fast and crash into a ledge the game freezes and the console gets spammed with the first error in the title followed by the second one. I managed to find what line of code caused this problem, here's that script:
public class FöljaBoll : MonoBehaviour
{
public GameObject player;
public float yOffset;
public float zOffset;
Transform playerPosition;
Transform cameraPosition;
// Start is called before the first frame update
void Start()
{
playerPosition = player.GetComponent<Transform>();
cameraPosition = gameObject.GetComponent<Transform>();
}
// Update is called once per frame
void Update()
{
if (playerPosition == null)
{
return;
}
cameraPosition.position = playerPosition.position + new Vector3(0, +yOffset, -zOffset);
}
private void FixedUpdate()
{
if (player == null)
{
return;
}
else
{
float speed = player.GetComponent<Rigidbody>().velocity.z + 6;
float targetFOV = (float)Math.Log(speed, 1.1) + 34;
GetComponent<Camera>().fieldOfView = Mathf.Lerp(GetComponent<Camera>().fieldOfView, targetFOV, (float)0.1);
}
}
}
So what it does is it sets the FOV based on the player speed through a logarithmic function in order for it to not get out of control at high speeds, but for some reason this part (I commented it out and wasn't able to recreate the errors):
GetComponent<Camera>().fieldOfView = Mathf.Lerp(GetComponent<Camera>().fieldOfView, targetFOV, (float)0.1);
triggers the error messages. If anyone could help me out here that would be awesome, thanks in advance! :)
I solved it myself by setting the bounciness of the Physics Material attached to both the ramps and the sphere to 0. This post: https://answers.unity.com/questions/9985/limiting-rigidbody-velocity.html said that bounciness combined with high velocities can cause problems and that seems to have been the problem.

Unity 2D - How to place obstacle in Running game?

I finish making running game. But I placed obstacle like this :
This way makes phone frozen often. So I make a prefeb is made of obstacle object like this :
I want to use function SetActive(bool) to appear/disappear obstacle. Finally, How it works is My runner is at a standstill and background, obstacle, coin, juwel is moved. But My creator script has a big problem.
My Prolem :
As you see, This code create blank(red box) between two obstacle prefebs. I can't find problem. Plz help me...
Creator Script :
using UnityEngine;
using System.Collections;
public class CsPartCreator : MonoBehaviour {
int count = 1;
float timer = 0.0f;
// Use this for initialization
void Start () {
for (int i = 1; i < 26; i++)//set Deactive all object excluding first object (Because This object is watched at first.)
transform.GetChild(i).gameObject.SetActive(false);
}
// Update is called once per frame
void Update () {
timer += Time.deltaTime;
if (timer > 5f && count < 23)//every 5 seconds and count is smaller than the number of prefeb
{
transform.GetChild(count).gameObject.SetActive(true);//
count++;
timer = 0;
}
}
}
This is my Hierarchy :
I think , That missing prefab's Z value is more negative than background , Or you have used a sorting layer which is set to be behind background.
And Check if all obstacle gameobjects correctly orderered in Hirachy Part0, Part1, Part2, Part3 like that. Let me know if those are in correct order
Please check that :)
using UnityEngine;
using System.Collections;
using System.Linq;
using System.Collections.Generic;
public class CsPartCreator : MonoBehaviour
{
private GameObject player;
float timer = 0.0f;
private List<GameObject> obstacles;
void Awake()
{
player = GameObject.FindWithTag("Player");
obstacles = new List<GameObject>();
}
// Use this for initialization
void Start()
{
for (int i = 0; i < 26; i++)//set Deactive all object excluding first object (Because This object is watched at first.)
{
obstacles.Add(transform.GetChild(i).gameObject);
transform.GetChild(i).gameObject.SetActive(false);
}
}
// Update is called once per frame
void Update()
{
if (obstacles == null || obstacles.Count() == 0)
return;
var toActivate = obstacles.Where(x => x.transform.position.x > transform.position.x && x.transform.position.x < transform.position.x + 10).ToList(); // +10 is the range
foreach (GameObject go in toActivate)
{
go.SetActive(true);
obstacles.Remove(go);
}
}
}
Set player gameobject to "Player" tag as in image below

Raycast can't find tagged gameobject

My Raycastrotates around the player and scans the 2D-Area. It should recognize another Gameobject, which is tagged as Pick Up, but found is always false.
using UnityEngine;
using System.Collections;
public class Findway : MonoBehaviour {
public GameObject Player;
// Use this for initialization
void Start () {
transform.position = Player.transform.position;
}
RaycastHit hit;
float[] distance = new float[360];
int moveAngle = 0;
bool found = false;
// Update is called once per frame
void Update () {
transform.position = Player.transform.position;
for (int iii = 0; iii < 360; iii++)
{
Vector3 rayway = new Vector3 (Mathf.Cos(180 * iii / Mathf.PI), 0, Mathf.Sin(180 * iii / Mathf.PI));
if (Physics.Raycast (transform.position, rayway, out hit, 100f))
{
distance [iii] = hit.distance;
//Debug.Log(hit.collider.gameObject);
//Debug.DrawRay(transform.position, transform.forward, Color.green);
if (hit.collider.CompareTag ("Pick Up"))
{
moveAngle = iii;
found = true;
}
}
}
}
}
Use your ray cast out of the for loop , a good cpu will not take long to run the iteration till 360 and using it in update will cause it to run infinite times causing more problems, always use divide and conquer , minimize the code , remove everything and just run the ray to check if its working without any rotation , then apply rotation ,do tell if it worked .Double Check if there is a object tagged as "Pick Up" . Also never use a for loop in update without an explicit condition to stop it like a bool otherwise it keeps on running .

Unity - Infinite sprite spawner stops spawning at a high speed

i wrote a script for my 2D car game for an infinite track. So i got a "killer" behind my car, that destroys all ground objects coming out the screen on the left and on the right i have a spawner that spawns all my blocky sprites in it and it works pretty good.
Here is my update function:
void Update()
{
if(Mathf.Round(this.transform.position.x) == limit)
{
//Debug.Log("Limit reached");
limit += 10;
Spawn();
}
}
I attached the script to my camera and i have a start limit set to 160 (because i already got 15 10x10 sprites as start). Everytime my spawner passes the x-axis-limit it spawns a new sprite at this position and sets the next limit 10 higher. This works good if I don't drive too fast. Because then it stops spawning and the world is cut off. When I drive back to get my spawner back into the already spawned area and drive slowly again to it, it works again. I believe the method is just to inefficient to spawn fast enough so I maybe need another style of doing it.
For the understanding here the rest of the script:
using UnityEngine;
using System.Collections;
public class Spawner : MonoBehaviour
{
public GameObject[] obj;
private int limit = 160;
public int yAxisValue = -1;
public bool isOnlyDirt;
private ArrayList rotationValues = new ArrayList();
void Start()
{
//Spawn ();
int value = 0;
for(int i = 0; i < 4; i++)
{
rotationValues.Add(value);
//Debug.Log(rotationValues[i]);
value += 90;
}
}
void Spawn()
{
Vector3 pos = new Vector3 (Mathf.Round(transform.position.x), yAxisValue, transform.position.z);
Quaternion rotation = new Quaternion (0, 0, 0, 0);
if(isOnlyDirt)
{
int zRot = (int)rotationValues[Random.Range(0, rotationValues.Count - 1)];
//Debug.Log(zRot);
rotation = new Quaternion(0, 0, zRot, 0);
}
var SpawnedGround = Instantiate(obj[Random.Range(0, obj.GetLength(0))], pos, rotation);
(SpawnedGround as GameObject).gameObject.tag = "Gro
I also have a one-liner to move my spawner in front of my car so it can spawn things:
public float yCoord;
void Start ()
{
this.transform.position = new Vector3 (transform.position.x + 160, -yCoord, transform.position.z);
}
I parented it so i just have to write it in the start function.
Any ideas to improve this one?
Thanks
Sorry can't post as comments. You should try
if(Mathf.Round(this.transform.position.x) >= limit)
instead of
if(Mathf.Round(this.transform.position.x) == limit)
I think the floating point precision is skipping the checking.

Counter is not decremented in Unity 3D

Basically this game is a brick breaker in which I will be giving a quick basic background about it. The game will spawn 10 bricks at random locations, and if the all hits the brick
once, the brick is destroyed. If all 10 bricks are destroyed then the user will be taken to the other scene (gamewon).
My main problem is that when I destroy all the bricks, I am not being redirected to the scene. However if I set the numberOfBricks to 1, it will work.. I can't really understand what's happening.
Thanks alot guys!
-HurpaDurpa
using UnityEngine;
using System.Collections;
public class BrickScript : MonoBehaviour {
public int position_x = 0;
public int position_y = 0;
public GameObject Brick;
public int brickDamage = 0;
public int numberOfBricks = 10;
// Use this for initialization
void Start () {
Brick = GameObject.Find ("Brick");
position_x = Random.Range (-6, 6);
position_y = Random.Range(-1, 4);
transform.position = new Vector3 (position_x, position_y, transform.position.z);
}
// Update is called once per frame
void Update () {
if (brickDamage == 1) { //destroy brick on 1 hit
numberOfBricks--;
Object.Destroy (gameObject); //so it will destroy the hit object
}
if (numberOfBricks == 0) {
Application.LoadLevel (1);
numberOfBricks = 10;//Variable resetted
}
}
void OnCollisionEnter(Collision collision)
{
brickDamage++;
}
}
This is happening because you seem to have attached the script above to each brick.
So what is really happening is when any one of your bricks get hit, the numberOfBricks reduces by 1, resulting the value going to 9. This will happen to each brick.
Rather, what you need to do is to keep this numberOfBricks counter in another script. In the OnCollisionEnter portion of your code, you should reduce the numberOfBricks variable in the other script by 1.
Do that and you'll see the result you expect.