- Home /
Dynamic Laser Fence Scripting Problem
Hi Everyone,
I have a player that starts out on an empty terrain. He can place turrets one by one that should shoot a laser at the closest turret once in place. This is to create a laser fence. The turrets used to shoot their lasers, but when I didn't have the following script, they all shot at the second turret created. Thus I implemented this script, but now, the turrets won't shoot anything at each other!
Here is my script for the finding of the closest turret:
//..........Finding Closest Turret
var nearestDistanceSqr = Mathf.Infinity;
var taggedGameObjects: GameObject[] = GameObject.FindGameObjectsWithTag("FenceLaserPoint1");
var nearestTrt : Transform = null;
// loop through each tagged object, remembering nearest one found
for (var obj : GameObject in taggedGameObjects) {
var objectPos = obj.transform.position;
var distanceSqr = (objectPos - transform.position).sqrMagnitude;
if (distanceSqr < nearestDistanceSqr) {
nearestTrt = obj.transform;
nearestDistanceSqr = distanceSqr;
}
}
//................................
And here is my laser shooting code:
Laser=Instantiate(laserPrefab) as LineRenderer;
if (Laser!=null)
{
Laser.SetPosition(0,thisLaserPoint.position);
Laser.SetPosition(1,nearestTrt.transform.position);
Destroy(Laser, laserEnergy);
}
I know for sure that the laser shooting code is working well. It's the scanning code to find the closest turret that isn't working. Except, there are no errors so I cannot pinpoint any specific issues. I would greatly appreciate if you help me solve this problem. Thank you,
Hyperion
Are you sure that anything is being found at all? Are there definitely GameObjects in the scene with the tag "FenceLaserPoint1"? What does nearestDistanceSqr read when the loop is done?
I'm not sure anything is being found, but previously the code could find objects with that tag. At the start, there are no objects with that tag (and it is not misspelled, I checked). But the player creates them. So there will be objects after they are created. Do you think that is the problem?
nearestDist... prints out 6.0blablabla, and changes by a millionth every time a new turret is created.
DISCOVERY: I commented out 'nearestDistanceSqr = distanceSqr' and all the turrets started shooting at the last turret created. Here, nearesDistsqr reads "Infinity", always. This is still not what I want, though.
Answer by iwaldrop · Dec 16, 2013 at 04:19 AM
In all honesty I think what you're doing is just a little overly complicated. I'd just do something like this:
public static class Tools
{
public static T FindNearest<T>(Transform reference) where T : MonoBehaviour
{
return FindNearest<T>(reference.position);
}
public static T FindNearest<T>(Vector3 worldPosition) where T : MonoBehaviour
{
List<T> list = GameObject.FindObjectsOfType<T>().ToList();
list.Sort(
(x, y) =>
(x.transform.position - reference).sqrMagnitude
.CompareTo((y.transform.position - reference).sqrMagnitude));
return list.First();
}
}
To use it, you just pass a Type and a Transform, like so:
Turret nearestTurret = Tools.FindNearest<Turret>(transform.position);
Maybe that's one of the advantages of using C#, because I'm not sure if that works in US or not.
Well, I'll try to convert my script into C# and then add this in, and update you asap (in a few days). Thanks for the script. Could you please tell me the logic?
Fundamentally it's just a LINQ query in a method that returns the first object in a sorted list.
What I'm doing in the above is finding all objects of type Turret (so you may have to change that bit in your implementation) then sorting them by the sqr$$anonymous$$agnitude (because it's faster than magnitude).
A couple notes/disclaimers about this. The above code does not discover GameObjects via tags, but by Type ins$$anonymous$$d. Also, something like this is fine to run every now and again, but should not be used every frame.
I'm fine with it being used every once in a while, but what does "Type" mean? Will this be able to differentiate between different instances of one object?