-1
\$\begingroup\$

I have two scripts the first one is class not monobehaviour:

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

public class LightsEffects
{
    private Renderer[] renderers;
    private float lastChangeTime;
    private int greenIndex = 0;
    private bool shouldChangeDirection = false;

    public void LightsEffect(List<GameObject> objects, Color instantiateColor, Color colorEffect)
    {
        renderers = new Renderer[objects.Count];
        for (int i = 0; i < renderers.Length; i++)
        {
            renderers[i] = objects[i].GetComponent<Renderer>();
            renderers[i].material.color = Color.red;
        }

        // Set green color to the first one
        greenIndex = 0;
        renderers[greenIndex].material.color = Color.green;
    }

    /// <summary>
    /// Running the effect
    /// </summary>
    /// <param name="isReversed">Changing the lights movement directions - false = forward, true = backward.</param>
    public void LightsEffectCore(float delay, bool isReversed)
    {
        // Change color each `delay` seconds
        if (Time.time > lastChangeTime + delay)
        {
            lastChangeTime = Time.time;

            // Set color of the last renderer to red
            // and the color of the current one to green
            renderers[greenIndex].material.color = Color.red;

            if (shouldChangeDirection)
            {
                Array.Reverse(renderers);
                isReversed = !isReversed;
            }

            greenIndex = (greenIndex + 1) % renderers.Length;
            renderers[greenIndex].material.color = Color.green;
        }
    }
}

And in this script the part i'm trying to set what direction is:

if (shouldChangeDirection)
                {
                    Array.Reverse(renderers);
                    isReversed = !isReversed;
                }

The problem is that i'm using this class in another monobehaviour script:

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

public class Waypoints : MonoBehaviour
{
    public Transform traveller;
    public GameObject[] waypoints;
    public Transform nextWaypoint;
    public float moveSpeed = 10f;
    public float slowDownSpeed = 3f;
    public float rotationSpeed = 1f;
    public float distancetoRotate = 3f;
    public bool random = false;
    public bool reverse = false;
    public int howmanylight = 5;
    public Generatenumbers gn;
    public LightsEffects lightseffect;
    public bool changeLightsDirection = false;

    private int targetsIndex = 0;
    private Vector3 originalPosition;
    private List<GameObject> objects = new List<GameObject>();


    private bool rotateNumber = false;
    private int currentIndex = 0;

    // Use this for initialization
    void Start()
    {
        waypoints = GameObject.FindGameObjectsWithTag("Waypoint").OrderBy(go => go.name).ToArray();
        if (random == false)
        {
            targetsIndex = 0;
        }
        else
        {
            targetsIndex = UnityEngine.Random.Range(0, waypoints.Length);
        }
        originalPosition = traveller.position;

        GameObject go1 = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        duplicateObject(go1, howmanylight);

        lightseffect = new LightsEffects();
        lightseffect.LightsEffect(objects, Color.red, Color.green);
    }

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

        if (rotateNumber == true)
        {
            gn.newTexts[currentIndex].transform.Rotate(Vector3.up, 10 * 50 * Time.deltaTime);
        }

        lightseffect.LightsEffectCore(0.1f, changeLightsDirection);
    }

    private void WayPointsAI()
    {
        if (targetsIndex == waypoints.Length)
            targetsIndex = 0;

        nextWaypoint = waypoints[targetsIndex].transform;
        float distance = Vector3.Distance(traveller.transform.position, nextWaypoint.transform.position);
        traveller.transform.rotation = Quaternion.Slerp(traveller.transform.rotation, Quaternion.LookRotation(nextWaypoint.position - traveller.transform.position), rotationSpeed * Time.deltaTime);

        if (reverse == true)
        {
            var targetAngles = traveller.transform.eulerAngles + 180f * Vector3.up;
            traveller.transform.eulerAngles = Vector3.Lerp(traveller.transform.eulerAngles, targetAngles, rotationSpeed * Time.deltaTime);
            var lastWaypoint = waypoints[currentIndex];
            Array.Reverse(waypoints);
            reverse = false;
        }

        if (distance < distancetoRotate)
        {
            traveller.transform.position += traveller.transform.forward * slowDownSpeed * Time.deltaTime;
        }
        else
        {
            traveller.transform.position += traveller.transform.forward * moveSpeed * Time.deltaTime;
        }
        if (distance < nextWaypoint.transform.localScale.magnitude)
        {
            rotateNumber = true;
            currentIndex = targetsIndex;

            if (random == false)
            {
                targetsIndex++;
            }
            else
            {
                targetsIndex = UnityEngine.Random.Range(0, waypoints.Length);
            }
        }
    }

    public void duplicateObject(GameObject original, int howmany)
    {
        howmany++;
        for (int i = 0; i < waypoints.Length - 1; i++)
        {
            for (int j = 1; j < howmany; j++)
            {
                Vector3 position = waypoints[i].transform.position + j * (waypoints[i + 1].transform.position - waypoints[i].transform.position) / howmany;
                GameObject go = Instantiate(original, new Vector3(position.x, 0, position.z), Quaternion.identity);
                go.transform.localScale = new Vector3(0.3f, 0.1f, 0.3f);
                objects.Add(go);
            }
        }
    }
}

In the top of the waypoints script i have two lines:

public LightsEffects lightseffect;
public bool changeLightsDirection = false;

Then in the Start i'm creating instance for the LightsEffect:

lightseffect = new LightsEffects();

Then in the Update i want to be able to change the direction of the lights false/true states:

lightseffect.LightsEffectCore(0.1f, changeLightsDirection);

The problem is that no matter if changeLightsDirection is false or true since in the Lights Effect class i'm using: shouldChangeDirection and it's true all the time.

Anyway it's not working when the game is running and i change the changeLightsDirection state in the waypoints script it's not effecting the LighsEffect direction it's not reversing the array each time.

In the Lights Effect class/script i'm using:

if (shouldChangeDirection)

Since i want to track the state of the array reversing. What i did before was: is just checking if isReversed false or true but then if it's on true or false state all the time it will keep reversing the array non stop.

I messed up all the flags in both scripts.

\$\endgroup\$
1
\$\begingroup\$

Ok. Let me try to describe what I think of the problem:

you have a flag to keep track if you should change direction in this method call:

private bool shouldChangeDirection = false;

then you are passing it to the method

lightseffect.LightsEffectCore(0.1f, changeLightsDirection);

to base reverse operation on it.


Here is what I think you should do:

Change method definition to this:

public void LightsEffectCore(float delay, ref bool isReversed)

Notice the ref keyword, it will modify the variable passed as the parameter.

Now in LightsEffectCore() method:

if (!isReversed)
{
    Array.Reverse(renderers);
}

isReversed = !isReversed;

And remove

private bool shouldChangeDirection = false;

from LightsEffects class as it's not being used anymore.


UPDATE:

You don't need to reverse the array, alternatively, you can use First and Last elements in the array using Linq:

firstly, add using System.Linq; at the start of the file.

then use this code:

if (isReversed)
{
    renderers.Last().material.color = Color.green;
    greenIndex = renderers.Length-1;
}
else
{
    renderers.First().material.color = Color.green;
    greenIndex = 0;
}

Hope this helps :)

\$\endgroup\$
  • \$\begingroup\$ I tried your solution now. What it does is changing the flag false/true all the time every frame automatic i don't do anything running the game and it's changing the flag false/true nonstop. In the other script the waypoints i did: lightseffect.LightsEffectCore(0.1f, ref changeLightsDirection); and in the LightsEffect i changed the method like you did: public void LightsEffectCore(float delay, ref bool isReversed) and inside i did the if (!isReversed) and the isReversed = !isReversed; \$\endgroup\$ – Daniel Lip Nov 22 '17 at 14:05
  • \$\begingroup\$ I forgot my log in user name before and used a guest now i entered with my user name again if not i can't add comment. Sorry for that. \$\endgroup\$ – Daniel Lip Nov 22 '17 at 14:05
  • 1
    \$\begingroup\$ @DanielLip when do you want to change the flag? \$\endgroup\$ – Umair M Nov 22 '17 at 14:12
  • \$\begingroup\$ When i change in the other script the waypoints script the flag when the game is running and i change the flag to false/true i want it to change the direction in LightsEffect. The line in waypoints: lightseffect.LightsEffectCore(0.1f, ref changeLightsDirection); The flag changeLightsDirection is public when i change it to false or true change the direction in LightsEffect script in the LightsEffectCore method. \$\endgroup\$ – Daniel Lip Nov 22 '17 at 14:34
  • \$\begingroup\$ I have added an update to my answer. let me know if it works. \$\endgroup\$ – Umair M Nov 22 '17 at 14:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.