- Home /
Multiple enemy indicators
Hi guys, I have looked everywhere for a code or a tutorial on this, and I was not able to find one about this, I am able to make a target indicator for one target in my game but I need to make target indicators for all of my enemies using GUI. If anyone can please point me to a tutorial or provide me with a simple script to do this. Thanks in advance guys!
Check out the progress of my game! https://sites.google.com/site/whitegalaxystudiosltd/the-space-wars
Answer by Addyarb · Apr 29, 2015 at 08:56 PM
Hi there! As the other answer said, don't be intimidated by "indicators" or anything like that. There's a really easy way to do it for multiplayer, you just have to know how to script it. My suggestion would be the following:
For this example, the indicator will be a triangle above the target (think SIMS). The color will vary on the hostility of the target. I'm a huge fan of the uGUI system, and I personally would stay away from old GUI/Legacy GUI (stuff that you write in-script) as it's harder to control, and gives no visual representation. This is just my opinion though, many people still love it.
Step 1: Attach a Canvas to the prefab of each enemy. Step 2: Import your triangle picture, and make sure it's white. Step 3: Convert your triangle picture to a Sprite/UI within Unity. (Under import settings when you click it, default setting is "Textrue"). If you have trouble here, post a comment. Step 4: Right-click the canvas on your prefab, and hover over "Create" and then "UI" and then "Image." Step 5: Position the arrow so that it's where you'd like it to be. I'd personally put it 2-3 meters above the target, but that will vary based on what you want to do with it. Step 6: Create a script that turns the triangle off and on, and different colors depending on who is clicking it!
Step 7: The Script
I'm going to write this in English first, then in C#.
There is a Red Team
There is a Blue Team
I have a networkView
If I click something... If I am myself... (will explain in script using NetworkView)
If I click this thing, and my tag isn't the same as this ship, enable the ship's indicator and make it red.
If I click this thing, and my tag is the same as this ship, enable the ship's indicator and make it green.
If I right-click the ship instead of left-clicking, deselect just that ship.
If I click the deselect button on the GUI, deselect ALL of the targets, friend and foe.
C#
Warning: Not Tested. Will try later to make sure..
using UnityEngine;
using System.Collections;
public class ThisScriptName : MonoBehaviour {
NetworkView nView;
public string team1 = "RedTeam";
public string team2 = "BlueTeam";
GameObject playerWhoSelected;
public GameObject myArrow;
public bool iAmOnRedTeam;
public bool iAmOnBlueTeam;
void Start(){
nView = GetComponent<NetworkView> ();
iAmOnRedTeam = true;
}
void OnMouseDown(){
if (!nView.isMine) { //If we are not ourselves (we're someone else)
GameObject[] redPlayers = GameObject.FindGameObjectsWithTag (team1);
GameObject[] bluePlayers = GameObject.FindGameObjectsWithTag (team2);
if (iAmOnRedTeam) {
foreach (GameObject player in redPlayers) { //Find ourselves
if (player.GetComponent<NetworkView> ().isMine) {
SetIndicator (player);
}
}
}
if (iAmOnBlueTeam) {
foreach (GameObject player in bluePlayers) { //Find ourselves
if (player.GetComponent<NetworkView> ().isMine) {
SetIndicator (player);
}
}
}
}
}
void SetIndicator(GameObject playerWhoSelected){
if (playerWhoSelected.tag == team1 && iAmOnRedTeam ||
playerWhoSelected.tag == team2 && iAmOnBlueTeam) {
myArrow.SetActive (true);
myArrow.GetComponent<Material> ().color = color.green;
} else {
myArrow.SetActive (true);
myArrow.GetComponent<Material> ().color = color.green;
}
}
public void DeselectAllPlayers(){ //This can be mapped to a UI Button..
players = GameObject.FindGameObjectsWithTag(playerTag);
foreach (GameObject player in players) {
player.GetComponent<ThisScriptName>().myArrow.SetActive(false);
}
}
}
Thank you very much toddisarockstar :D it works perfectly!
Did you mean Addyarb? :P Either way, mark the answer that helped you as "Answered" by clicking the check mark button underneath the thumbs down button.
Good luck with your game!
Answer by toddisarockstar · Apr 24, 2015 at 07:36 PM
indicators are typically just simple game objects that snap to the desired position when you need them. an example might be a game object that looks like a simple circle. the texture would be a simple red or green, the shader would be one that supports transparency. They seem to look cool when they are half transparent so that you still see a bit of terrain and stuff behind them. when you want them to "appear" or "go away". you simply script the transparency to zero to make them invisible. typically you would make sure it has no colliders attached so they dont trigger any collisions or affect other gameplay. here are code exaples:
//drag and drop your indicator in the inspector
//changing the alpha color only works if shader is a transparent one
var target:GameObject;
//i am invisable;
target.transform.renderer.material.color.a=0;
//now i am half transparent
target.transform.renderer.material.color.a=.4;
// make it follow this object
target.transform.position=transform.position;
//make it follow some other enemy object;
target.transform.position=someotherenemyobject.transform.position;
if you have multiple ships all needing these things i would personally just have the indicators built into the models of your ships so they are always there and simply script transparency on and off.
//attach a script like this to your ship
var target:Transform;
//and find the model part you named "mytarget"
target=transform.Find("mytarget");
target.renderer.material.color.a=.4;
there is nothing fancy about indicators. they are simple gameobjects! by the way, your game looks cool. Good luck!
Thanks a lot but I can't do it like that, it is a multiplayer game, I have tried a similar method, because it is multiplayer, there will be two $$anonymous$$ms, thus if I active the idicators, all player will see them. That is why I try to do it with GUI. Is there any way to do this with the GUI system?
here is a link about converting world position to GUI coordinates if thats what you really need:
but really with your multiplayer project im sure at somepoint before its done it would be very helpfull for each machine's script to know what $$anonymous$$m/player each ship actually belongs to anyhow. in my last project i sent a seperate rpc with $$anonymous$$m/player info at the same time as Network.Instantiate. then simply had the newly spawned object's script immediately look for the RPC call to get it's "real" $$anonymous$$m and player number. im sure there are other ways of doing it but this worked very reliably for me.
after setting that up its really simple for other object and scripts to look and see if the new objects $$anonymous$$m doesent match the player's machine's $$anonymous$$m so you can light up those targets and fire away!!!!
ideally with multiplayer, on every computer, each object's script needs two numbers. one for the $$anonymous$$m it actually is, and one for the $$anonymous$$m of the computer its riding on. if they dont match then your scripts does enemy indicators and stuff.
If you are interested let me know and i can take the time to explain more and post some working code from my last project.
I can already make one indicator that follows the locked on target with the GUI system, but i can not figure out how to do this with mutiple enemies. Here is my script that does not want to work.
var REDTeam : GameObject[]; var TheCam : Camera; var EnIcon : Texture2D; var rect : Rect;
function Start() { REDTeam = GameObject.FindObjectsWithTag("REDTeam"); }
function Update() { for( var go : GameObject in REDTeam) { var AllEnPos =TheCam.WorldToScreenPoint(go.transform.position); rect = new Rect(AllEnPos.x, Screen.width - AllEnPos.y, 30,30); } }
function OnGUI() { for( var i = 0; i < REDTeam.Length; i++) { GUI.DrawTexture( rect, EnIcon); { }
It only draws one texture and i cant figure out why, could you possibly look over my script and help me with this problem?
var REDTeam : GameObject[]; var TheCam : Camera; var EnIcon : Texture2D; var rect : Rect;
function Start() { REDTeam = GameObject.FindObjectsWithTag("REDTeam"); }
function Update() { }
function OnGUI() { for( var i = 0; i < REDTeam.Length; i++) {
var AllEnPos =TheCam.WorldToScreenPoint(REDTeam[i].transform.position);
GUI.DrawTexture(AllEnPos.x, Screen.width - AllEnPos.y, 30,30, EnIcon); }}
Sorry i didn't debug or anything so there might be typos but this is how it should be set up to do what i think you want to do.
i think your loop in function update was just leaving you with only the variable at the end of the loop. moving it to gui like this should fix so GUI recalculates before every button