Search Unity

Disappearing/Reappearing spikes

Discussion in '2D' started by oguzhanes98, Jul 25, 2019.

  1. oguzhanes98

    oguzhanes98

    Joined:
    Feb 20, 2018
    Posts:
    4
    So I have this script that randomly enables/disables random spikes on 4 square shaped boxes with spikes on each side, every 2 seconds.

    Code (CSharp):
    1.  
    2.     GameObject[] spikes;
    3.     bool randomBool;
    4.     void Start()
    5.     {
    6.         spikes = GameObject.FindGameObjectsWithTag("Spikes");
    7.         StartCoroutine("Spikes");
    8.     }
    9.  
    10.  
    11.     IEnumerator Spikes()
    12.     {
    13.         randomBool = (Random.value > 0.5f);
    14.         for (int i = 0; i < spikes.Length; i++)
    15.         {
    16.             spikes[Random.Range(0,spikes.Length)].SetActive(randomBool);
    17.         }
    18.         yield return new WaitForSeconds(2f);
    19.         StartCoroutine("Spikes");
    20.     }
    What i want to do is, however, to have a pattern of spikes disappearing/reappearing (not random). For example, when i would jump on the first box 2 times, the spikes on the top side of the next box would disappear but at the same time, the spikes on the top side of the 3rd box would reappear. And to be able to jump on the 3rd box, I would have to jump on the 2nd box twice and go back and jump on the first box once.
    I thought about having a master script with a method that manipulates the active states of the spikes, and seperate scripts for each box that would call this method in the master script when i collide with them.
    Any thoughts on how to achieve this?
     
  2. Rafarel

    Rafarel

    Joined:
    Jul 21, 2017
    Posts:
    199
    Would be easier with a picture to understand your needs :)
     
  3. oguzhanes98

    oguzhanes98

    Joined:
    Feb 20, 2018
    Posts:
    4
    This is what the current script does: http://bit.ly/32SqRUg
    However, what i want to achieve is to enable/disable certain spikes on certain boxes when i collide with a certain box.



    In the image, the numbers represent the spikes. Now for example, when i jump on the first box, the spikes 6,8, 11, 12 will disappear. Then when i jump on the first box again, the spikes 5 and 1 will disappear and 6,8,11,12 will reappear. After that, in order to make the spike 9 disappear, I would have to jump on the second box twice, and on the first box once. I hope this helps.
     
  4. Rafarel

    Rafarel

    Joined:
    Jul 21, 2017
    Posts:
    199
    I guess that if you jump on the first box, it is because spikes one aren't there.

    I do not understand, spikes one were visible when I jumped on it the first time ?

    Seems that two pictures are missing in your post ?
     
  5. oguzhanes98

    oguzhanes98

    Joined:
    Feb 20, 2018
    Posts:
    4

    I think I'm not expressing myself well enough. Those are what I'm trying to accomplish, not some error i want to solve.
    I want to make it so when i collide with a certain box, certain spikes on certain boxes will disappear/reappear. The numbers i gave are just an example. Now, say, If i jump on the second box, I want to make it so the spikes 1, 10, 11 will disappear, and if i jump on it again i want to make it so the same spikes will reappear but at the same time some other spikes will disappear.
     
  6. MisterSkitz

    MisterSkitz

    Joined:
    Sep 2, 2015
    Posts:
    833
    Well, you want to create your spikes. The most basic way (not efficient, I don't feel like designing an array and loops and S*** right now) is to do this

    Code (CSharp):
    1. public GameObject spike1;
    2. public GameObject spike2;
    3. //Make one declaration for each spike
    4.  
    5. void Update()
    6. {
    7. if(player.transform.position == spike1.transform.position)
    8. {
    9. // Set the code here to enable or SetActive your spikes
    10. }
    11. else if(player.transform.position == spike2.transform.position)
    12. {
    13. // Make one logic check for each spike
    14. }
    15. }
    I don't know your set up, but if you can use colliders and OnCollisionEnter2D instead, that would be much better. Also, in my example, I believe Switch/case would be more efficient than else if statements. I can draw you up some better code tomorrow, if I have time. I'm just tired right now.

    Best,

    Tim
     
    oguzhanes98 and Rafarel like this.
  7. hlw

    hlw

    Joined:
    Aug 12, 2017
    Posts:
    250
    There is two versions of the spike platform, the second one is a bit more elaborate but both will basically do the same thing. You have to add the logic for the function to activate, because i don't know if you prefere raycasts, colliders, positions checks etc...

    Beware, there is 3 classes inside this one page, you'll need only two of these, and they must be placed each in a different file.


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5.  
    6. /// <summary>
    7. /// NEEDS A REFERENCE TO SPIKEMASTER GAMEOBJECT
    8. ///
    9. /// in this one, you create arrays of bools in the right order of spikes, the first bool will active the first spike (or deactivate if set to false) and so one.
    10. /// Everytime the player jumps on the platform, it changes to the next array, in this example, once the player jumps three times, the fourth time will start again to the first array.
    11. /// As long as the number of values in the arrays represent the number you put in the brackeys, there wont be any error if there is at least one array.(unless spikemaster isn't referenced or it's spike list is null)
    12. ///
    13. /// If there isn't enough bools in the array used, (example only 8 while there is 12 platforms), the function will control only the first 8 platforms.
    14. /// If there is too much bools, the last bools will be ignored.
    15. ///
    16. /// You can seralize these arrays in the inspector.
    17. /// ___________________________________________________________________________________________________________
    18. /// You have to decide by yourself how/when you want the function to be activated, and write the logic for that yourself.
    19. /// </summary>
    20. public class SpikePlatform : MonoBehaviour
    21. {
    22.     public SpikeMaster master;
    23.  
    24.     public int JumpCount = 0;
    25.  
    26.     public bool[][] SpikesPattern = new bool[3][]
    27.     {      
    28.         new bool[12]{ false, false, false, true, false, true, false, false, true, false, true, false},
    29.         new bool[12]{true, false, true, false, true, false, true, false, true,true, false, true},
    30.         new bool[12]{true, false, false, false, false, false, false, true, false, false, false, true}
    31.  
    32.  
    33.     };
    34.     public void Call_This_Function_When_Player_Gets_On_The_Platform()
    35.     {
    36.         for (int i = 0; i < SpikesPattern[JumpCount].Length; i++)
    37.         {
    38.             if (i >= master.spikes.Count) break;
    39.             master.spikes[i].gameObject.SetActive(SpikesPattern[JumpCount][i]);
    40.         }
    41.         JumpCount++;
    42.         if (JumpCount >= SpikesPattern.Length) JumpCount = 0;
    43.     }
    44. }
    45.  
    46.  
    47.  
    48.  
    49.  
    50.  
    51.  
    52.  
    53.  
    54. /// <summary>
    55. /// NEEDS A REFERENCE TO SPIKEMASTER GAMEOBJECT
    56. ///
    57. /// in this one, a list containing lists of integer, each integer represents one spike, the first spike is equal to 1.
    58. /// If a spike number is in the list, it will be set to active, if it doesn't exist in the list, it will be set inactive.
    59. /// Everytime the player jumps on the platform, it changes to the next list, in this example, once the player jumps five times, the sixth time will start again to the first list.
    60. /// As long as spikemaster is referenced and that its list conaining the spikes isn't null, there shouldn't be any error ever using this code.
    61. ///
    62. /// If a number is referenced in the list but that spike doesn't exist, the number will just be ignored.
    63. ///
    64. /// You can seralize those arrays in the inspector.
    65. /// ___________________________________________________________________________________________________________
    66. /// You have to decide by yourself how/when you want the function to be activated, and write the logic for that yourself.
    67. /// </summary>
    68. public class SpikePlatform2 : MonoBehaviour
    69. {
    70.     public SpikeMaster master;
    71.  
    72.     public int JumpCount = 0;
    73.  
    74.     public List<List<int>> SpikesPattern = new List<List<int>>()
    75.     {
    76.         new List<int>(){4,6,9,11},
    77.         new List<int>(){1,3,5,7,9,10,12},
    78.         new List<int>(){1,8,12},
    79.         new List<int>(){2,7,1,5},
    80.         new List<int>(){175,1550,-19,32167},
    81.  
    82.  
    83.  
    84.     };
    85.  
    86.     public void Call_This_Function_When_Player_Gets_On_The_Platform()
    87.     {
    88.         for (int i = 0; i < master.spikes.Count; i++)
    89.             if ((!master.spikes[i].activeSelf && SpikesPattern[JumpCount].Contains(i - 1)) || (master.spikes[i].activeSelf && !SpikesPattern[JumpCount].Contains(i - 1)))
    90.                 master.spikes[i].SetActive(!master.spikes[i].activeSelf);
    91.  
    92. JumpCount++;
    93.         if (JumpCount >= SpikesPattern.Count) JumpCount = 0;
    94.     }
    95. }
    96.  
    97.  
    98.  
    99.  
    100.  
    101.  
    102.  
    103. public class SpikeMaster : MonoBehaviour
    104. {
    105.     public List<GameObject> spikes;//Put all the 12 (or more) platforms references in this list (you can use the inspector). The list can be empty, but it shouldn't be null !
    106. }


    (Edit : Modified the first for loop, i did put a "return" instead of a break here, it would have broke the spike machine if one too big array of bools was used)

    (Second edit : After reading your posts, i'm figuring out you might need to add a way to synchronize the jump count between each platform, or being able to reset it. You'll maybe even need ternary operations or something if there is a need for you to activate some spikes based on the state of other spikes. )

    I kind of made somehow complex scripts on purpose to make you learn some useful stuffs. (and because i'm mean)
    If you need a step by step explanation of each line, just ask.
     
    Last edited: Jul 28, 2019
    oguzhanes98 likes this.
  8. hlw

    hlw

    Joined:
    Aug 12, 2017
    Posts:
    250
    Well... i did read again your question and it appears you actually want to rotate actually opened spikes, so here is another code. Well, i guess the other one below will be of use one day.

    This time there is no masterSpike.
    You have to add the spikes contained by this platform to its own spike list, the order where you put those spikes in it will determine the rotation of the spikes (clockwise, anticlockwise, unordered).

    Then you desactive the spikes you want to be desactived at the beginning.

    Then you add to the ControledPlatforms the other platforms that should be modified when you jump on this one.


    Code (CSharp):
    1. public class TrueSpikePlatform : MonoBehaviour
    2. {
    3.     public GameObject[] Spikes;
    4.     List<int> StartingOpenedSpikes = new List<int>();
    5.     public TrueSpikePlatform[] ControledPlatforms;
    6.  
    7.     private void Start()
    8.     {
    9.         for (int i = 0; i < Spikes.Length; i++)
    10.         {
    11.             if (Spikes[i].activeSelf) StartingOpenedSpikes.Add(i);
    12.         }
    13.     }
    14.  
    15.  
    16.     public void Call_This_Function_When_Player_Gets_On_The_Platform()
    17.     {
    18.         foreach (var item in ControledPlatforms)
    19.         {
    20.             for (int i = 0; i < StartingOpenedSpikes.Count; i++)
    21.             {
    22.                var intToIncrement = StartingOpenedSpikes[i];
    23.  
    24.                 intToIncrement++;
    25.                 if (intToIncrement >= Spikes.Length) intToIncrement = 0;
    26.  
    27.                 StartingOpenedSpikes[i] = intToIncrement;
    28.             }
    29.  
    30.             for (int i = 0; i < item.Spikes.Length; i++)
    31.             {
    32.                 item.Spikes[i].SetActive(StartingOpenedSpikes.Exists(a => a == i));
    33.  
    34.                
    35.             }
    36.         }
    37.  
    38.        
    39.     }
    40.  
    41. }
    42.  
     
    oguzhanes98 likes this.