- Home /
RTS Style Selection system (How to control one unit and not the others)
Okay, so far I have it so that when I click somewhere, an object(MouseMarker) is created there, the unit(a simple cube) looks at the object and moves towards it. When the cube hits the MouseMarker the marker is destroyed, and so the cube stops. Now, I want it so that if I have 2 (or more) cubes, that set of script is only executed if the cube is selected. Being new to unity, I dont really understand how to make scipts only apply to one instance of an object, not the entire object as a whole. Any explanations or links to tutorials would be great, thanks (:
You have a 'controller' script, which has a reference to a single instance of your pathfinding script- it distributes the messages according to your symbolic selection.
Like I said to the other answer, Im very new, could you explain more? Or at least in more simpler language?
It's the same thing as having a manager, which would keep a reference to the selected object. So you'd always make a selection towards a static variable which keeps the GameObject and that static variable is inside the manager.
$$anonymous$$anager Script named "manager" -> Static variable named "unit" -> GameObject
which in UnityScript is:
manager.unit
Given that unit is set like this:
static var unit : GameObject; //unit is a static variable (reachable from wherever) declared for a GameObject
Answer by save · Oct 25, 2011 at 03:00 PM
The answer is a static variable where you assign the current selected GameObject. Setup a manager (empty GameObject with a script named "manager") which contains these kind of global variables:
static var unit : GameObject;
On the object set the variable (which is done by a raycast):
function OnMouseDown () {
manager.unit = this.gameObject;
}
OnMouseDown/OnMouseUp is short for raycasting towards a specific object. You'll have an advantage in setting up a global raycast by yourself and by checking the objects tag though. It depends a bit on how your world looks like.
Then you'll be able to steer the specific object by referencing to its transform:
manager.unit.transform
Don't have the steering for each object on their GameObject, that would result in plenty of if-statements or workarounds, think global and manage the objects from outside. Although if it's easier for the implementation, you can attach a steering script for each selected object and then destroy it when it's no longer needed.
var steerScript : SteerScript;
function OnMouseDown () {
manager.unit = this.gameObject;
manager.unit.AddComponent(SteerScript)
}
function Unselect () {
if (manager.unit.GetComponent(SteerScript))
Destroy(manager.unit.GetComponent(SteerScript);
}
If you have several objects to steer at once you'd only need to make an array where you assign everything in a for-loop.
Okay, thanks for the help, but, Im very new to unity and am stuggling to understand that last bit of script properly. Perhaps its just your wording, so maybe you could explain it in simler terms? aha, I apologise for my lack of understanding...
No need to apologize. The example scripts are just for you to get an understanding of what way you can take on this.
manager.unit:
$$anonymous$$anager is the script's name "manager", unit is the variable called "unit" which only takes a GameObject.
function Unselect ():
Is a function you can call whenever needed by scripting Unselect();
. There you could also set the manager.unit = null
. You can create any type of functions you want.
AddComponent(theCompoent):
Adds a defined component to a GameObject. There are some components predefined by Unity already, for instance Collider and Rigidbody.
GetComponent(theComponent):
Fetches the named component on the object.
Destroy();:
Destroys a GameObject or a component on a GameObject.
Array:
A list of items.
For-loop:
A loop with a specific condition:
for (this < that) {
//Loop until this = that
}
for (var i=0; i < 10; i++) {
//Loop until i = 10
}
for (var child : Transform in transform) {
//Grab every child in this transform
}
Okay, now I think I understand most of it apart for the SteerScript part. Is that meant to be substituted for the script that makes my units move?
Yes it would be. But if you only have a few of them, then you could also encapsulate their steer function on each object with if (manager.unit == this.gameObject)
. It's although not preferred as that would have to run inside Update ()
. Attaching scripts at runtime is blazingly fast, or having the steering done by a singleton which only reference to manager.unit
. If that is null
then don't execute further - or you could also make a boolean from start which sets to true when something selects:
static var selected : boolean = false;
Then do this:
if (selected) {
manager.unit.transform.position = ..
}
You also have the ability to make a selected boolean variable private for each object if you want to steer several of them at the same time. Play around a little bit and you'll get the hang of it! ;-)
Answer by Panik.Studios · Sep 12, 2012 at 09:51 PM
you can find all the simple source and really good general knowledge here. But do the guy a favor and SUBSCRIBE him. Theres links to his sourc codes tutorials projects all that. Also you'll need the A star pathfinding that he provides a link to in us second RTS tutorial... Like I said.. Subscribe him.. This dudes awesome to the community.
Your answer
Follow this Question
Related Questions
Easily cleaning up \ deleting unused variables? 2 Answers
Changing static variables from another script? 1 Answer
Explanation on how to use functions, variables from other files 1 Answer
Character selection system help script 2 Answers
EditorWindow saves private variables after assembly reload 0 Answers