Search Unity

efficient sequencer

Discussion in 'Scripting' started by smetzzz, Apr 23, 2015.

  1. smetzzz

    smetzzz

    Joined:
    Mar 24, 2014
    Posts:
    145
    Hi I'm trying to find a better way to sequence functions in script.
    essentially I have my mainCharacter going across the screen when he triggers the scene end the scene is de-activated and the next scene becomes active. (also the mainCharacter resets to the beginning) It requires me to have a list of if statements. How would I do this in a better way? Arrays? enums maybe? Or should I use events? Thanks for your input.

    if (mainCharacter.transform.position.x > scene.end) {sceneNum = sceneNum +1;}

    if (sceneNum == 1) scene.one.SetActive(true); else scene.one.SetActive(false);
    if (sceneNum == 2) scene.two.SetActive(true); else scene.two.SetActive(false);
    if (sceneNum == 3) scene.three.SetActive(true); else scene.three.SetActive(false);
    if (sceneNum == 4) scene.four.SetActive(true); else scene.four.SetActive(false);
    if (sceneNum == 5) scene.five.SetActive(true); else scene.five.SetActive(false);
     
    Last edited: Apr 23, 2015
  2. DChristy87

    DChristy87

    Joined:
    Jan 23, 2014
    Posts:
    19
  3. mholub

    mholub

    Joined:
    Oct 3, 2012
    Posts:
    123
    Or just put your scenes into array and use code like this:

    Code (csharp):
    1.  
    2. for (int i = 0; i < scenes.Length; i++) {
    3.   scenes[i].SetActive(i == sceneNum);
    4. }
    5.  
     
    Ryiah and smetzzz like this.
  4. smetzzz

    smetzzz

    Joined:
    Mar 24, 2014
    Posts:
    145
    Ah, I got it to work. Thats the pro solution I was looking for. Thanks mholub!
     
  5. smetzzz

    smetzzz

    Joined:
    Mar 24, 2014
    Posts:
    145
    I wonder if there is a way to sequence like this for functions too?
     
  6. mholub

    mholub

    Joined:
    Oct 3, 2012
    Posts:
    123
    What do you mean? To call a function stored inside collection?

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections.Generic;
    4. using System;
    5.  
    6. public class SequencedFunctionCaller : MonoBehaviour {
    7.     private List<Action> actions = new List<Action>(); // Action is a callable type without arguments
    8.     // Use this for initialization
    9.     void Start () {
    10.         actions.Add(() => Debug.Log("hello world")); // lambda function
    11.         actions.Add(someFunction);
    12.  
    13.         actions[1](); // calls someFunction
    14.         call (1); // same
    15.     }
    16.  
    17.     void someFunction() {
    18.         Debug.Log("some function");
    19.     }
    20.  
    21.     void call(int i) {
    22.         actions[i]();
    23.     }
    24.  
    25.     // Update is called once per frame
    26.     void Update () {
    27.  
    28.     }
    29. }
    30.  
    31.  
    https://msdn.microsoft.com/en-us/library/system.action(v=vs.110).aspx

    And please look at UnityEvent:
    http://docs.unity3d.com/ScriptReference/Events.UnityEvent.html

    It can be added as public field into MonoBehaviour and it has nice GUI. You can store UnityEvents into List too. And invoke them with event.Invoke() call;
     
    JoeStrout and smetzzz like this.
  7. smetzzz

    smetzzz

    Joined:
    Mar 24, 2014
    Posts:
    145
    A switch may be the better choice here as I need to add custom functions everytime the scene changes. I want to figure out how events work but I'm using js and the docs and examples are fairly confusing or just broken.
    Perhaps next project I'll switch to C#. I'm still just a 6 months noob at scripting.
     
  8. mholub

    mholub

    Joined:
    Oct 3, 2012
    Posts:
    123
    It's same in UnityScript.

    Code (csharp):
    1.  
    2. #pragma strict
    3.  
    4. import UnityEngine.Events;
    5.  
    6. var events : UnityEvent[];
    7.  
    8. // this code will invoke all events on Start which you can specify by Inspector
    9. // just put the component on some gameobject and add some events
    10. function Start () {
    11.     for (var i = 0; i < events.Length; i++) {
    12.         events[i].Invoke();
    13.     }
    14. }
    15.  
    16.  
     
    smetzzz likes this.
  9. smetzzz

    smetzzz

    Joined:
    Mar 24, 2014
    Posts:
    145
    Oh wow, this is amazing! Thank You. This would have saved me so much trouble if I knew of it months ago.
     
  10. smetzzz

    smetzzz

    Joined:
    Mar 24, 2014
    Posts:
    145
    One last thing, Let say the main character.position.x is greater than scene.position.x. When its true i invoke an event. I check for this in an if statement in update. When it becomes true it sends and event just once until it resets. Whats the best way to do this? I keep reading to use co-routine but haven't found an example of how it would work.
     
  11. mholub

    mholub

    Joined:
    Oct 3, 2012
    Posts:
    123
    I usually use just simple boolean flag for such task.

    Code (csharp):
    1.  
    2. #pragma strict
    3.  
    4. import UnityEngine.Events;
    5.  
    6. var Character : Transform;
    7. var Scene : Transform;
    8.  
    9. var OnPositionEvent : UnityEvent;
    10.  
    11. private var eventFired : boolean;
    12.  
    13. function Start () {
    14. }
    15.  
    16. function Update () {
    17.     if (!eventFired && Character.position.x > Scene.position.x) {
    18.         OnPositionEvent.Invoke();
    19.         eventFired = true;
    20.     }
    21. }
    22.  
    23. function Reset() {
    24.     eventFired = false;
    25. }
    26.  
    27. function OnGUI() {
    28.   if (GUILayout.Button("Reset")) {
    29.     Reset();
    30.   }
    31. }
    32.  
    I don't know how to use coroutine for this. If you can point me into some link you read about it I will be thankful.
     
    smetzzz likes this.
  12. smetzzz

    smetzzz

    Joined:
    Mar 24, 2014
    Posts:
    145
    I just googled "call function once from update" there are a lot of postings but a boolean flag seems to be the only way. Others keep saying to use co-routine without giving an example. There must be a simpler and more elegant way to do this. I guess this isn't terrible.
     
    Last edited: Apr 23, 2015
  13. smetzzz

    smetzzz

    Joined:
    Mar 24, 2014
    Posts:
    145
    I would love to know anymore useful programming tricks mholub. Thanks!