How to link scripts

I am creating a traffic system where the pedestrians would respond to the traffic lights via collider trigger. The message “STOP” would be displayed with the green light, otherwise the “GO” message would be displayed.

However, the codes I used to perform the above showed that no matter what color the lights are, the message “STOP” is always displayed.

I believe that the issue is the absence of the linkage of my traffic light control script and the trigger script. I would require help in linking them. Thanks in advance.

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

public class TrafficLights : MonoBehaviour
{
   
    [SerializeField] EMode mode = EMode.Red;
    public EMode Mode => mode;
 
    public enum EMode : byte { Red=0, Yellow=1, Green=2 }

  
}

Above is the trigger script.

using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TrafficLightControl : MonoBehaviour {
//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------

    public bool direction1 = true;

    public Renderer objRenderer;
    public int mode;
    float delay;
    
//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------
private void Start()
{
    objRenderer = GetComponent<Renderer>();
        
    mode = 0;
    objRenderer.materials[1].SetTextureOffset("_MainTex", new Vector2(0.0f, 0.0f));
    if(direction1)
    {
        mode = 2;
        objRenderer.materials[1].SetTextureOffset("_MainTex", new Vector2(0.0625f * 2.0f, 0.0f));
    }
    delay = 10.0f;
}
//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------
void Update()
{
    if(mode == 0)
    {    
        delay -= Time.deltaTime;
        if(delay < 0.0f)
        {
            delay = 3.0f;
            objRenderer.materials[1].SetTextureOffset("_MainTex", new Vector2(0.0625f * 1.0f, 0.0f));                
            mode = 1;
                
        }
    }
    else if(mode == 1)
    {    
        delay -= Time.deltaTime;
        if(delay < 0.0f)
        {
            delay = 13.0f;
            objRenderer.materials[1].SetTextureOffset("_MainTex", new Vector2(0.0625f * 2.0f, 0.0f));                
            mode = 2;
        }
    }
    else if(mode == 2)
    {    
        delay -= Time.deltaTime;
        if(delay < 0.0f)
        {
            delay = 1.0f;
            objRenderer.materials[1].SetTextureOffset("_MainTex", new Vector2(0.0625f * 3.0f, 0.0f));                
            mode = 3;
        }
    }
    else if(mode == 3)
    {    
        delay -= Time.deltaTime;
        if(delay < 0.0f)
        {
            delay = 15.0f;
            objRenderer.materials[1].SetTextureOffset("_MainTex", new Vector2(0.0625f * 0.0f, 0.0f));                
            mode = 0;
                
                          
            }
    }
            
}
//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------
}

Above is the traffic lights control script.

You can use

public TrafficLights trafficLightRef;

To link the two scripts and drag the game object containing the TrafficLight script into the inspector

Then you can access public variables like this:

Debug.Log( trafficLightRef.Mode )

Thanks, however I wish to make the collider capable to know the phases of my traffic lighting while it is running? Is the above code able to perform that? Thanks.

Sorry but I don’t really understand though, so maybe someone else would be able to help you

But to the best of my understanding, you want to sync int mode from TrafficLightControl with enum EMode from traffic lights.

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

public class TrafficLights : MonoBehaviour
{
   public TrafficLightControl modeRef;
    [SerializeField] EMode mode = EMode.Red;
    public EMode Mode => mode;
 
    public enum EMode : byte { Red=0, Yellow=1, Green=2 }
    string LightMode;

  void Update() {
         int state = modeRef.mode;
         LightMode = (EMode)state.ToString();
         Debug.Log(LightMode);
   }

}

I haven’t tested it though and I don’t really know much about enum but as I said maybe someone else would be able to help you

When I tested the code, there seems to be an error with this code. May I know how to correct it? Thanks.

LightMode = (EMode)state.ToString()

I am not with my laptop right now so I can’t test the code. Please can u tell me the error so I can try to solve it

This line of code states

cannot convert type ‘string’ to TrafficLights.EMode

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

public class TrafficLights : MonoBehaviour
{
public TrafficLightControl modeRef;
[SerializeField] EMode mode = EMode.Red;
public EMode Mode => mode;

public enum EMode : byte { Red=0, Yellow=1, Green=2 }
string LightMode;
void Update() {
	int state = modeRef.mode;
	switch (state)
	{
		case 0:
			Debug.Log("Traffic Light is Red");
			break;

		case 1:
			Debug.Log("Traffic Light is Yellow");
			break;

		case 2:
			Debug.Log("Traffic Light is Green");
			break;
	}
}

}

So from here, when my collider is triggered, do I write the trigger script like so? As I am trying to prompt the pedestrian to stop if the light is red. Am I am writing it right? Thanks.

void OnTriggerEnter(Collider other)
{
    if ( other.TryGetComponent<TrafficLights>( out var trafficLights) )
    if (trafficLights.Mode != TrafficLights.EMode.Green)        
    {
        print("STOP");
    }
}

The answer to this should be easy.

But I just want to clarify, do u have a traffic light game Object, a traffic controller gameObject and a gameObject with a collider component

All separately?

I do have a traffic light game object with the traffic light control script attached to it and a collider game object.

So sorry, but I seem to have an issue with the collider trigger code I send you.
I tried running the code, however, the word stop was always printed regardless of the light color.

I’m assuming the traffic light script is attached to the collider.
You can add this to the traffic light script

void OnTriggerEnter() { if(state != 2) { Debug.Log("Stop"); } }

And remove the switch statement

So I remove the switch statement and replace it with the code u sent?
My collider trigger code is tagged to the pedestrian controller though

Should work if the traffic light script is attached to the same gameObject as the collider and the character controller component

my current On trigger code is attached to the character component and the collider code is attached to the collider game object

if I take out the switch, the collider code will have an error.
Also, the on trigger code still did not work

I’m sorry for asking this again

But can u list all the gameObjects in question

Like the gameObject with the collider component
And the gameObject with the traffic light control script and so on… So I can have a better understanding

Sending a screenshot of your hierarchy would be really helpful

  1. Traffic Lights game object with a traffic light control script attached.
using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TrafficLightControl : MonoBehaviour {
//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------

    public bool direction1 = true;
    
    public Renderer objRenderer;
    public int mode;
    float delay;
    
//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------
private void Start()
{
    objRenderer = GetComponent<Renderer>();
        
    mode = 0;
    objRenderer.materials[1].SetTextureOffset("_MainTex", new Vector2(0.0f, 0.0f));
    if(direction1)
    {
        mode = 2;
        objRenderer.materials[1].SetTextureOffset("_MainTex", new Vector2(0.0625f * 2.0f, 0.0f));
    }
    delay = 10.0f;
}
//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------
void Update()
{
    if(mode == 0)
    {    
        delay -= Time.deltaTime;
        if(delay < 0.0f)
        {
            delay = 3.0f;
            objRenderer.materials[1].SetTextureOffset("_MainTex", new Vector2(0.0625f * 1.0f, 0.0f));                
            mode = 1;
                
        }
    }
    else if(mode == 1)
    {    
        delay -= Time.deltaTime;
        if(delay < 0.0f)
        {
            delay = 13.0f;
            objRenderer.materials[1].SetTextureOffset("_MainTex", new Vector2(0.0625f * 2.0f, 0.0f));                
            mode = 2;
        }
    }
    else if(mode == 2)
    {    
        delay -= Time.deltaTime;
        if(delay < 0.0f)
        {
            delay = 1.0f;
            objRenderer.materials[1].SetTextureOffset("_MainTex", new Vector2(0.0625f * 3.0f, 0.0f));                
            mode = 3;
        }
    }
    else if(mode == 3)
    {    
        delay -= Time.deltaTime;
        if(delay < 0.0f)
        {
            delay = 15.0f;
            objRenderer.materials[1].SetTextureOffset("_MainTex", new Vector2(0.0625f * 0.0f, 0.0f));                
            mode = 0;
                
                          
            }
    }

        
       
        
       
}
//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------------------------------------
}


  1. Collider game object with a collider script attached.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TrafficLights : MonoBehaviour
{
    public TrafficLightControl modeRef;
    [SerializeField] EMode mode = EMode.Red;
    public EMode Mode => mode;

    public enum EMode : byte { Red=0, Yellow=1, Green=2 }
    string LightMode;
    void Update()
    {
        int state = modeRef.mode;
        switch (state)
        {
            case 0:
                Debug.Log("Traffic Light is Red");
                break;

            case 1:
                Debug.Log("Traffic Light is Yellow");
                break;

            case 2:
                Debug.Log("Traffic Light is Green");
                break;
        
       }
}
}
  1. Character controller with a controller script plus OnTrigger codes. Once the pedestrian walks into the collider game object, he would be prompted by the message “STOP” if the light is red. This is done by the OnTrigger codes in the character controller script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Experimental.VFX;

public class CharacterNavigationController : MonoBehaviour
{
    public float movementSpeed = 1;
    public float rotationSpeed = 120;
    public float stopDistance = 2f;
    public Vector3 destination;
    public Animator animator;
    public bool reachedDestination;
    public int mode;
    public int state;

    private Vector3 lastPosition;
    Vector3 velocity;
        
    private void Awake()
    {
        movementSpeed = Random.Range(0.5f, 2f);
        animator      = GetComponent<Animator>();
    }

    //Update is called once per frame
    void Update()
    {

        if(transform.position != destination)
        {
            Vector3 destinationDirection = destination - transform.position;
            destinationDirection.y = 0;
            float destinationDestance = destinationDirection.magnitude;
            if (destinationDestance >= stopDistance)
            {
                reachedDestination = false;
                Quaternion targetRotation = Quaternion.LookRotation(destinationDirection);
                transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
                transform.Translate(Vector3.forward * movementSpeed * Time.deltaTime);
            }
            else
            {
                reachedDestination = true;
            }

            velocity = (transform.position - lastPosition) / Time.deltaTime;
            velocity.y = 0;
            var velocityMagnitude = velocity.magnitude;
            velocity = velocity.normalized;
            var fwdDotProduct = Vector3.Dot(transform.forward, velocity);
            var rightDotProduct = Vector3.Dot(transform.right, velocity);

            animator.SetFloat("Horizontal", rightDotProduct);
            animator.SetFloat("Vertical", fwdDotProduct);
           
        }

        lastPosition = transform.position;
    }

    public void SetDestination(Vector3 destination)
    {
        this.destination = destination;
        reachedDestination = false;
    }

    void OnTriggerEnter(Collider other)
    {
        if (state != 2)
        {
            Debug.Log("STOP");
        }
        
    }



}

I haven’t seen anything wrong with the code yet!
But make sure of these according to the unity docs

link to doc

  1. Is the OnTrigger checked for the character and unchecked for the collider

  2. Do they both have rigidbodies

I’ll try to replicate your game with the code u sent to see if that can help me come up with a solution