Trying to calculate distance from multiple of the same objects in the scene

Hey guys, got a situation here that I can’t figure out.
Basically I have lights throughout the scene, if the player moves so far from the light, his sanity decreases, this works with one light.
When i duplicate the lights around the scene, things start to go a bit funny, only working with one light rather than calculating the distance from all of them (only the closest one would be important).
Hope that makes sense, here’s the script I’ve written so far, also I should say, I’ve trying to learn a lot about C# and unity lately, this is still the start of the journey for me so I’m by far not very good, but I’m surprised and happy about where this project is so far, It’s great learning!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DarknessScript : MonoBehaviour{

     GameObject lightSource;
     public float sanity = 100;

    void Awake(){
        lightSource = GameObject.FindGameObjectWithTag("LightSource");
        //Trying to make lightSource contain anything that's tagged as "LightSource", will be multiple light sources in the scene
    }
 
 
    void Update(){

        if(Vector3.Distance(transform.position, lightSource.transform.position) > 6){
            //If I'm 15 units away from any of the light sources, I'm in the dark and losing sanity (Not scripted yet)
            sanity -= Time.deltaTime;
                print(sanity);
                 
                }
        print(Vector3.Distance(transform.position, lightSource.transform.position));

    }
 
}

I know this isn’t going to work by looking at the code, but I’m not entirely sure why or how to get around it.
I’m wondering if I need some sort of array to store ALL of the lights I want to interact with?

Many thanks,
Chris.

EDIT:
More to it.

Even when it’s just the one light being used, (I’m printing the value of sanity to console) the number starts counting down from 100 as expected, when I enter and exit the ‘zone’ (6 meters from the light) the sanity in the console seems to jump all over the place, it could be counting down from 100, I enter the zone and it stops as expected, when I leave the zone and approach the 6m mark, it’ll drop to 13, then bounce back up, and it gets even weirder when more lights are there.

This is your first problem.

This gets one GameObject, the first random light it finds with that tag.

Rather than making a darkness script, why don’t you make a light controller that turns on when the player is close? That way you put one light controller on each light and give each light a reference to the player.

1 Like

Note the “s”. This gives you an array of your lights which you can iterate to find the closest one (smallest distance) in Update. Then do your logic with that.

versus your registration date:
Joined: Feb 11, 2011
Makes me wonder.

1 Like

That’s seems like a good idea!. I’ll have a fiddle with that idea in the morning.

I assumed the issue was with GameObjectWithTag, I also noticed there’s a GameObjectsWithTag, is that to be used with an array?, I had thought before your reply maybe that’s the way I need to do it, but my limited knowledge quickly put that idea to bed.

I appreciate your reply

I used to mess around with Unity a long time ago on and off. Everything I learned back then has long gone, I believe it was Javascript I was using back then too, This is another return to Unity and my first little while with C#. Would be very interesting to see what I was posting back in 2011

Hopefully that settles your curiosity :smile:

Ok it seems that’s the way to go, I’ll have to dig into it tomorrow, thanks for the pointers

Re-reading your original description of what you’re trying to do, let me revise my suggestion above.

The sanity controller should probably be on the player.

The sanity controller should use FindGameObjectsWithTag to find all the light sources.

Only use that at start, UNLESS you intend to add/remove lights.

Each frame the sanity controller should check the distance to all the lights.

You will either be out of range of ALL of them (going insane), or you will be in range of one or more.

That’s the two states you actually care about, correct?

So that means the result of checking all lights should be a single boolean:

bool CloseToALight = false;

Now based on that value, you would set a desired sanity, perhaps just a floating point number.

float desiredSanity = 0.0f;   // insane
if (CloseToALight)
{
  desiredSanity = 1.0f;  // sane
}

In any case, every frame you would move your current sanity slowly towards your desired sanity (either insane or sane).

Smoothing movement between any two particular values:

You have currentQuantity and desiredQuantity.

  • only set desiredQuantity
  • the code always moves currentQuantity towards desiredQuantity
  • read currentQuantity for the smoothed value

Works for floats, Vectors, Colors, Quaternions, anything continuous or lerp-able.

The code: SmoothMovement.cs · GitHub

Wow, Incredibly helpful, I’ll dig into this tomorrow morning, I’m sure that’s exactly what I need.
thank you! I’ll take a lot from this post, much appreciated.

1 Like