Unity text on cube prefab - c#

I want to make a cube in Unity3D which can move and jump etc.... and I want to generate a random number (1-99). I want the number to be on the cube's every side. I don't want to make 99 texture I want to add the number with script. I read that I should add Text Mesh but i cant because I have Mesh Renderer.
Can somebody help
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerThings : MonoBehaviour {
public static int player_name;
void Start () {
player_name = Random.Range (10, 99);
name = player_name.ToString();
}
// Update is called once per frame
void Update () {
}
}

If nothing is in your Update function, get rid of it. It's still being called every fraction of a second to check there is nothing in it. If this is persistent in your code a lot, it will eventually unnecessarily slow it down.
Next - A solution is to add an empty GameObject, whose children are the sides of your cube which require a Text Mesh.
Place each of the children in an array, and then do a foreach:
foreach(textarray as GameObject ta){
ta.getComponent<TextMesh>().text = name;
}

Related

Hide 3D object at start of scene until certain condition met

Developing a 3D VR application on Unity using OpenXR (2021.3.11f1).
I'm trying to make it so that a Canvas is hidden until a certain condition is met. That condition is that another 3D object's x position is under 45. Here is my script right now:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class OptionsBox : MonoBehaviour
{
public GameObject canvas;
public GameObject playerObj;
void Start()
{
canvas.SetActive(false);
}
void Update()
{
if (playerObj.transform.position.x < 45){
canvas.SetActive(true);
}
}
}
I then made an empty GameObject and inputted the script into there:
However, when I run my scene, the canvas is still displayed. What have I done wrong?
No problem with the script. Problem was the other object started at a x value less than 45, so it was always set to True.
You can add a CanvasGroup to the Canvas and play with the opacity property called Alpha

How can I make a destroyer that destroys all the overtaken platforms in unity?

I'm doing a unity project for an exam I'm attending, so I'm not really good at unity, hope you can help.
I'm doing this 2d endless runner game and I created an empty object to set inactive all the platforms that the player has overtaken. The object moves forward and when its position is > than the platform position, it sets it inactive (since destroying them also removes them from the list so it wouldnt work for others platforms of the same kind). My problem is that I've created a list in which I put all the types of my prefabs but the way I did it, it only sets inactive the first prefab of a kind and then stops working.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DistruttoreLivelli : MonoBehaviour
{
public List<GameObject> objs;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
for (int i = 0; i < objs.Count; i++)
{
if (objs[i].transform.position.x < transform.position.x)
{
objs[i].SetActive(false);
}
}
}
}
How can I manage to make it go forever? I tried to use a while but it makes unity crash. :/
Ty for the help!
The easiest way to make it endless is to move the objects to the furthest position instead of deactivating them. Instead of objs[i].SetActive(false); it should be something like:
Vector3 endOfTheLinePos = objs[i].transform.position;
endOfTheLinePos .x = maxX;
objs[i].transform.position = endOfTheLinePos;
With maxX being a float parameter of the highest value of x that you are using on the objects.
Also, as already pointed out, on the for you should use i < objs.Count instead.

Spawn Enemy GameObject only infornt of the Camera view while camera moves with the Player GameObject

I am trying to spawn enemies on fixed z-axis and between random x-axis points. I am making the Ground a child of the Player so it moves with the Player. The Player can only move on the Horizontal axis. I want to make it look like the Enemies are always spawning in front of the Player. How can I do it so? Right now if I move Ground with Player, the Enemies spawn only at the designated points.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpawnManager : MonoBehaviour
{
[SerializeField] private GameObject _enemy;
// Start is called before the first frame update
void Start()
{
StartCoroutine(SpawnRoutine());
}
// Update is called once per frame
void Update()
{
}
IEnumerator SpawnRoutine()
{
while(true)
{
Vector3 PosToSpawn = new Vector3(Random.Range(-23.6f, 23.6f),1, 16.6f);
Instantiate(_enemy, PosToSpawn, Quaternion.identity);
yield return new WaitForSeconds(1f);
}
}
}
NEW ANSWER
Get a reference to the Ground object using the same approach as your reference to the enemy object.
[SerializeField]
private GameObject _ground;
Replace:
Vector3 PosToSpawn = new Vector3(Random.Range(-23.6f, 23.6f),1, 16.6f);
With:
Vector3 PosToSpawn = new Vector3(Random.Range(_ground.transform.position.x - 23.6f, _ground.transform.position.x + 23.6f), 1, 16.6f);
This will work, provided that you are updating the position of the ground object relative to the player object as you say you are.
OLD ANSWER (changed after the example script was changed):
If I understand your question/problem correctly, your enemies are spawning in the same places every time your run the game even though you're using Random.Range to set their x value.
If that is your actual problem, then it's caused because your game always uses the same seed for its random number generation.
You can generate a new random seed every time you start the game by using an arbitrary value such as the System.DateTime.Now.Ticks. Put the following code into your Start method (not your Update method):
int seed = (int) System.DateTime.Now.Ticks;
Random.InitState(seed);
What the above code does is, get the current system time ticks (which will change every time you run the game) and then initializes the random number generator using that value as the seed. This should result in different spawn locations each time you run the game.
For more info look at:
https://docs.unity3d.com/530/Documentation/ScriptReference/Random-seed.html
https://docs.unity3d.com/ScriptReference/Random.InitState.html

Different sets of the same class variables within the same Monobehaviour class in c# (Unity3d)

I've been pondering about this for some time and I think I might just be missing an essential basic coding approach to resolve this, but I just can't think of it.
Basicly, in my script I'm trying to have different sets for the 'same variables' of the class where I can swap between (switching turrets ingame). If I would sketch the script, it would look something like this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Testturretscript : MonoBehaviour {
int ammo;
int maxAmmo;
float reloadTime;
set1(){
ammo = set1.ammo;
maxAmmo = set1.maxAmmo;
reloadTime = set1.reloadTime;
}
set2()
{
ammo = set2.ammo;
maxAmmo = set2.maxAmmo;
reloadTime = set2.reloadTime;
}
// Use this for initialization
void Start () {
use set1;
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown(KeyCode.Keypad1) || Input.GetKeyDown(KeyCode.Alpha1)){
use set1;
}
if (Input.GetKeyDown(KeyCode.Keypad2) || Input.GetKeyDown(KeyCode.Alpha2)){
use set2;
}
}
...
}
I know this might sound a bit cryptic, but there must be some easy way i'm missing to do this. Because when I swap back and forth, I do want to values to be properly stored instead of overriding the values of the variables.
I'm doing this from memory, so bear with if there are some errors.
From your question, it looks like you are having multiple turret types, that a player can switch between at any time. A similar idea to a player carrying multiple guns that he can switch to at anytime.
So, you create a base class, in this case Turret which contains all the information common to a type of turret. All turrets will have an ammo count, reloadTime etc regardless of what type of turret it is.
Then, in the same script, we have our Player class. These two classes could be in different files, but for easier viewing, I've combined them into one.
The Player has an array of Turrets, or what turrets he can use. We create a currentTurret variable of the same type, so we can track which Turret the player is currently using.
First, we assign the currentTurret variable to the first Turret in our array (or inventory) of Turrets, using a custom index variable. We use this variable as it is easier to modify and look at rather than using numbers everywhere.
Then, in Update, if we press space, we increase the currentTurretIndex by one. We then set our current turret to the second turret in our array. This is basically switching weapons. WARNING! This is just for example, don't always just increase your index, as it will eventually get a null pointer exception. Instead, this should be a function that sets the current turret.
Then, if we press the W key, we tell our currentTurret to Shoot(). Because we have assigned our currentTurret variable to a turret in our array, only that turret will fire! Hooray!
using System;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class Turret
{
public int ammo;
public int maxAmmo;
public float reloadTime;
public void Shoot()
{
// Do some shooting stuff!
}
}
public class Player : MonoBehaviour
{
public Turret[] turretTypes;
public Turret currentTurret;
int currentTurretIndex = 0;
void Start()
{
currentTurret = turretTypes[currentTurretIndex];
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
// Do your turret switching here.
// For now I've just increased the turret index by 1.
currentTurretIndex++;
currentTurret = turretTypes[currentTurretIndex]
}
if (Input.GetKeyDown(KeyCode.W))
{
currentTurret.Shoot();
}
}
}
Hope this helps! :-)

Score Count not working on a prefab

This is semi complicated of a question but I'll do my best to explain it:
I am making this mobile game in which you have to shoot four cubes. I'm trying to make it so when the cubes are shot by a bullet, they're destroyed and a UI text says 1/4, to 4/4 whenever a cube is shot. But it's being really weird and only counts to 1/4 even when all four cubes are shot and destroyed. I put these two scripts on the bullets (I made two separate scripts to see if that would do anything, it didn't)
And to give a better idea of what I'm talking about, here's a screenshot of the game itself.
I've been using Unity for about 6 days, so I apologize for anything I say that's noob-ish.
EDIT
So I combined the two scripts onto an empty gameobject and here's the new script:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class GameManagerScript : MonoBehaviour {
public GameObject cubes;
public Text countText;
public int cubeCount;
public Transform target;
// Use this for initialization
void Start () {
}
void OnTriggerEnter(Collider other)
{
cubes = other.gameObject;
}
// Update is called once per frame
void Update () {
cubes.transform.position = Vector3.MoveTowards(transform.position, target.position, 1f * Time.deltaTime);
if (cubes.gameObject.tag == "BULLET")
{
cubeCount = cubeCount + 1;
countText.text = cubeCount + "/4";
cubes.SetActive(false);
}
}
}
ANOTHER EDIT
I tried everything, so is there a way to detect when all the children in a parent on the Hierarchy are destroyed? Instead of counting up? This can give a better idea:
So I want to be able to detect when Cube, Cube1, Cube2, and Cube3 have all been destroyed.
The answer is pretty simple: Since every individual bullet has that script, each bullet has its own score.
For something like a score you want a single spot to store it, e.g. a script on an empty gameobject that serves as game controller. Just access that in the collision and increase the score (maybe have a look on singletons here).
You can combine those two scripts and actually it might be better to not have this on the bullet, but on the target because there are probably less of them which will save you some performance. (And it does more sense from a logical point of view.)
Edit:
I assume you create the bullets using Instantiate with a prefab. A prefab (= blueprint) is not actually in the game (only objects that are in the scene/hierarchy are in the game). Every use of Instantiate will create a new instance of that prefab with it's own version of components. A singleton is a thing that can only exist once, but also and that is why I mention it here, you can access it without something like Find. It is some sort of static. And an empty gameobject is just an object without visuals. You can easily create one in unity (rightclick > create empty). They are typically used as container and scriptholders.
Edit:
What you want is:
An empty gameobject with a script which holds the score.
A script that detects the collision using OnTriggerEnter and this script will either be on the bullets or on the targets.
Now, this is just a very quick example and can be optimized, but I hope this will give you an idea.
The script for the score, to be placed on an empty gameobject:
public class ScoreManager : MonoBehaviour
{
public Text scoreText; // the text object that displays the score, populate e.g. via inspector
private int score;
public void IncrementScore()
{
score++;
scoreText.text = score.ToString();
}
}
The collision script as bullet version:
public class Bullet : MonoBehaviour
{
private ScoreManager scoreManager;
private void Start()
{
scoreManager = GameObject.FindWithTag("GameManager").GetComponent<ScoreManager>(); // give the score manager empty gameobject that tag
}
private void OnTriggerEnter(Collider other)
{
if(other.CompareTag("Target") == true)
{
// update score
scoreManager.IncrementScore();
// handle target, in this example it's just destroyed
Destroy(other.gameObject);
}
}
}

Categories