- Home /
Script on multiple objects not working properly!
So I am making a 3D tower defense game and I have my node script on multiple nodes but when I click on one node to build the tower it builds the tower on the first node I created and it acts as one object.
Here is the script:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI;
public class Nodes : MonoBehaviour {
private Renderer rend;
private Color startColor;
private float time = 2.5f;
private bool textOnScreen;
private MeshRenderer render;
public TowerPlacement tower;
public GameObject node;
public Text cantbuild;
public Shop shop;
void Start ()
{
rend = node.GetComponent<Renderer>();
startColor =rend.material.color;
textOnScreen = false;
render = node.GetComponent<MeshRenderer>();
}
void Update()
{
if (shop.selected == true) render.enabled = true;
else render.enabled = false;
}
void OnMouseDown()
{
if(tower.canBuild == false)
{
cantbuild.gameObject.SetActive(true);
if (textOnScreen == false)
{
StartCoroutine(cantBuild());
}
}
else
{
if (shop.selected == true)
{
tower.towerBuilding();
shop.selected = false;
}
}
}
void OnMouseEnter()
{
if (tower.canBuild) rend.material.color = Color.green;
else
{
rend.material.color = Color.red;
}
}
void OnMouseExit()
{
rend.material.color = startColor;
}
private IEnumerator cantBuild()
{
textOnScreen = true;
yield return new WaitForSeconds(time);
cantbuild.gameObject.SetActive(false);
textOnScreen = false;
}
}
Can you show the TowerPlacement script? I guess there's a problem here.
Ye sure. Here it is :
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class TowerPlacement : $$anonymous$$onoBehaviour {
public GameObject standardTower;
public bool canBuild = true;
public Vector3 positionOffSet;
public Nodes node;
public void towerBuilding()
{
standardTower = (GameObject)Instantiate(standardTower, node.transform.position + positionOffSet, Quaternion.identity);
canBuild = false;
}
}
I guess you forgot to set up node. Test the code below.The node will be passed in as a parameter.
public class Nodes : $$anonymous$$onoBehaviour
{
private Renderer rend;
private Color startColor;
private float time = 2.5f;
private bool textOnScreen;
private $$anonymous$$eshRenderer render;
public TowerPlacement tower;
public GameObject node;
public Text cantbuild;
public Shop shop;
void Start()
{
rend = node.GetComponent<Renderer>();
startColor = rend.material.color;
textOnScreen = false;
render = node.GetComponent<$$anonymous$$eshRenderer>();
}
void Update()
{
if (shop.selected == true) render.enabled = true;
else render.enabled = false;
}
void On$$anonymous$$ouseDown()
{
if (tower.canBuild == false)
{
cantbuild.gameObject.SetActive(true);
if (textOnScreen == false)
{
StartCoroutine(cantBuild());
}
}
else
{
if (shop.selected == true)
{
tower.towerBuilding(this);
shop.selected = false;
}
}
}
void On$$anonymous$$ouseEnter()
{
if (tower.canBuild) rend.material.color = Color.green;
else
{
rend.material.color = Color.red;
}
}
void On$$anonymous$$ouseExit()
{
rend.material.color = startColor;
}
private IEnumerator cantBuild()
{
textOnScreen = true;
yield return new WaitForSeconds(time);
cantbuild.gameObject.SetActive(false);
textOnScreen = false;
}
public class TowerPlacement : $$anonymous$$onoBehaviour
{
public GameObject standardTower;
public bool canBuild = true;
public Vector3 positionOffSet;
public void towerBuilding(Nodes pNode)
{
standardTower = (GameObject) Instantiate(standardTower, pNode.transform.position + positionOffSet,
Quaternion.identity);
canBuild = false;
}
}
Also here is a video of my problem : https://www.youtube.com/watch?v=B1hjux$$anonymous$$qsRw
Thank you for your help!
Before I saw the video, I mistaken your question. The real reason is that all the nodes are building when the mouse is pressed. Therefore, a judgement is added to build the operation only at the node where the mouse enters.
public class Nodes : $$anonymous$$onoBehaviour
{
private Renderer rend;
private Color startColor;
private float time = 2.5f;
private bool textOnScreen;
private $$anonymous$$eshRenderer render;
public TowerPlacement tower;
public GameObject node;
public Text cantbuild;
public Shop shop;
void Start()
{
rend = node.GetComponent<Renderer>();
startColor = rend.material.color;
textOnScreen = false;
render = node.GetComponent<$$anonymous$$eshRenderer>();
}
void Update()
{
if (shop.selected == true) render.enabled = true;
else render.enabled = false;
}
private bool _$$anonymous$$ouseEnter = false;
void On$$anonymous$$ouseDown()
{
if (tower.canBuild == false)
{
cantbuild.gameObject.SetActive(true);
if (textOnScreen == false)
{
StartCoroutine(cantBuild());
}
}
else
{
if (shop.selected == true && _$$anonymous$$ouseEnter)
{
tower.towerBuilding(this);
shop.selected = false;
}
}
}
void On$$anonymous$$ouseEnter()
{
if (tower.canBuild) rend.material.color = Color.green;
else
{
rend.material.color = Color.red;
}
_$$anonymous$$ouseEnter = true;
}
void On$$anonymous$$ouseExit()
{
rend.material.color = startColor;
_$$anonymous$$ouseEnter = false;
}
private IEnumerator cantBuild()
{
textOnScreen = true;
yield return new WaitForSeconds(time);
cantbuild.gameObject.SetActive(false);
textOnScreen = false;
}
}
public class TowerPlacement : $$anonymous$$onoBehaviour
{
public GameObject standardTower;
public bool canBuild = true;
public Vector3 positionOffSet;
public void towerBuilding(Nodes pNode)
{
standardTower = (GameObject) Instantiate(standardTower, pNode.transform.position + positionOffSet,
Quaternion.identity);
canBuild = false;
}
}
Answer by madks13 · Jul 26, 2018 at 03:15 PM
From the comments and the video, i'd say you use the wrong renderer. have you tried placing the first tower, which should appear at the wrong place, then trying to place a tower at another placement, a 3rd one? If you can, then the towers are properly instanciated, but you have the same node reference. Otherwise something in your tower creation is wrong.
Edit : i thought this was addressed in the comments, but where do you set up TowerPlacement tower variable? I see it used, but it's not set anywhere.
I resolved the part with the tower building but now i have another problem. After i place one tower i cant build on the other nodes cause i have a boolean that verifies if i have something on a node. The problem is that the boolean changes for all nodes not just the one that has a tower on it. Thank you for your comment
What i have understood is that you have only one instance of TowerPlacement. You should either add a TowerPlacement component to each node in the editor or via code like this :
void Start()
{
rend = node.GetComponent<Renderer>();
startColor = rend.material.color;
textOnScreen = false;
render = node.GetComponent<$$anonymous$$eshRenderer>();
//New line, add a TowerPlacement component to the node
tower = node.AddComponent<TowerPlacement>();
}
Sine you use this component to check if you can build, if you only have one instance of it, it's obvious it will return false after only having built one tower. From the way you made your code, i think you should make TowerPlacement a static class and have all the logic of selecting the right mesh, checking if tower can be built on node, etc inside it.
Your answer
Follow this Question
Related Questions
How can i look for collisions of the bulidngs in may array ? how can i use OnTRiggerEnter/exit ? 0 Answers
how to set an object on a path,how to set an object on a track 0 Answers
Refresh panel with prefab contained value from json that created using array 0 Answers
cannot drag script to player.Guitext error,cannot drag player script to the player in hierarchy 2 Answers
Is there a way to dynamically attach a script to a GameObject during runtime? 1 Answer