Search Unity

Scripting Help

Discussion in 'Scripting' started by DustyShinigami, Mar 22, 2018.

  1. DustyShinigami

    DustyShinigami

    Joined:
    Jan 5, 2018
    Posts:
    529
    Hi, I'm new to the forums and a beginner with Unity and scripting, therefore I'm not particularly brilliant with them, so please bear with me. I'm making a Roll a Ball level using everything from the Unity tutorial for a college assignment. However, I'm a bit lost and confused with what I need to add for some features I want to add. Firstly, I've made a flat cube that I want to be a spring or bouncer that takes the ball up onto a sloped platform. I kinda have the bouncer working, but the ball has to bounce slightly on it first in order to get enough force for a bigger bounce. Ideally, I'd like for it to work as one of the springs in the Sonic games where touching it propels you up straight away. What kind of script would I need? Also, I think I'm having a physics issue with the sloped ramp - when the ball comes down onto it, it doesn't land on it and slide down. It looks like it hovers in mid air. I used a cube and an asset from the store to adjust the edges of it. What am I missing here? And finally, I'd like to add some platforms where if the ball rolls onto them and stays there for too long, the platforms collapse. Again, not sure how to script this.

    Thanks.
     
  2. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    Hi,
    You need a collider added to the spring object, set the collider to be a trigger(it's a check box).
    Then create a script, call it SpingPlate add this code to it.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class SpringPlate : MonoBehaviour
    5. {
    6.     public int SpringFource = 100; //adjust thing number for how high you want it to jump
    7.  
    8.     private Rigidbody rb;
    9.  
    10.     void OnTriggerEnter(Collider other) {
    11.         Debug.log(other.transform.name + " hit the trigger " + gameobject.name);
    12.         rb = other.GetComponent<Rigidbody>();
    13.         rb.AddForce(transform.up * SpringFource);  //you may need to use world space not local
    14.     }
    15. }
     
    Last edited: Mar 22, 2018
  3. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    Create a collider trigger for the platform.
    there are many ways to make a platform fall/collapse

    Sorry for any tpyo's, or errors, I free handed the code. didn't test it.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Platform : MonoBehaviour
    5. {
    6.     public float time = 4.0f;  //4 sec timer
    7.     private bool isActive = false;
    8.     private float activeTime = 0;
    9.  
    10.     void OnTriggerEnter(Collider other) {
    11.         Debug.log(other.transform.name + " hit the trigger " + gameobject.name);
    12.         activeTime = time; //reset the time value
    13.         isActive = true;
    14.     }
    15.  
    16.     void OnTriggerStay(Collider other) {
    17.         //Debug.log(other.transform.name + " is staying in the trigger " + gameobject.name);
    18.     }
    19.  
    20.     void OnTriggerExit(Collider other) {
    21.         Debug.log(other.transform.name + " left the trigger " + gameobject.name);
    22.         isActive = false;
    23.     }
    24.  
    25.     void Update()
    26.     {
    27.        if(isActive)
    28.        {
    29.          activeTime -= Time.deltaTime;
    30.          if ( activeTime < 0 )
    31.          {
    32.             StartCoroutine(Fall());
    33.          }
    34.        }
    35.     }
    36.  
    37.  
    38.     IEnumerator Fall()
    39.     {
    40.         while(true)
    41.         {
    42.             transform.position.y -= Time.deltatime;
    43.             yield return null;
    44.         }
    45.     }
    46. }
    you could also add a rigid body to the platform and turn on gravity when you want it to fall.
     
    Last edited: Mar 22, 2018
  4. DustyShinigami

    DustyShinigami

    Joined:
    Jan 5, 2018
    Posts:
    529
    Thanks for replying. The spring script works nicely, thanks. I can't seem to get the other one to work though - the part about IEnumerator Fall comes up with errors for transform.position.y and Time.deltaTime.
     
  5. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    can you post the error.

    i think you need to change
    transform.position.y -= Time.deltatime;
    to
    gameObject.transform.position.y -= Time.deltatime;
     
  6. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    You must use a intermediate variable for the struct property... or add to the entire thing
    Code (csharp):
    1. Vector3 pos = transform.position;
    2. pos.y -= Time.deltaTime;
    3. transform.position = pos;
    4. // or
    5. transform.position -= new Vector3(0,Time.deltaTime,0);
     
  7. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    Thanks @methos5k, you are always on top of things!
     
  8. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    No prob, man :)
     
  9. DustyShinigami

    DustyShinigami

    Joined:
    Jan 5, 2018
    Posts:
    529
    I've tried the code again and combined
    gameObject.transform.position.y -= Time.deltatime; along with
    Vector3 pos = transform.position;
    pos.y -= Time.deltaTime;
    transform.position = pos;
    // or
    transform.position -= new Vector3(0,Time.deltaTime,0);

    ...and still can't get it to work. The script is accepted, but nothing happens when I touch the platform. :-\ Not sure what I've forgotten or haven't added.
     
  10. DustyShinigami

    DustyShinigami

    Joined:
    Jan 5, 2018
    Posts:
    529
    Okay, I did manage to find a script that got it to work. However, the platform falls slowly and doesn't reset after a few seconds. Also, I can't seem to get the ball to stay on my moving platform. I've tried some scripts to make it stick, but nothing is working.
     
  11. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    what do mean by make it stick? is the ball rolling off the sides? when it falls do you want to stop all player input (wasd keys) from controlling the ball? If the platform falls and ball is on top of it, after it resets, where should the ball be placed? Do you have a death action setup in your game?

    You'll need to post the script you used to make it fall. Then we can help with resetting after a few seconds.
     
  12. DustyShinigami

    DustyShinigami

    Joined:
    Jan 5, 2018
    Posts:
    529
    I guess I worded it wrong... But yeah, the ball doesn't stay on the platform. You have to move the ball as the platform is moving in order to stay on. I guess I just need it to stay still if I slow it down onto it, in the same way if you just slowed down to a stop in a Sonic game.
    With the collapsing platforms, if the player falls with them it hits a death action trigger and the scene resets, which is fine. If you keep moving and don't fall the animation of the platforms seems quite slow.

    This is the script I have at the moment:

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class FallingPlatform : MonoBehaviour
    7. {
    8.     private Rigidbody rb;
    9.     int colliders;
    10.  
    11.     void Start()
    12.     {
    13.         rb.isKinematic = true;
    14.     }
    15.  
    16.     void OnTriggerEnter(Collider other)
    17.     {
    18.         if (IsPlayer(other) && colliders++ == 0)
    19.             PlayerEntered();
    20.     }
    21.  
    22.     void OnTriggerExit(Collider other)
    23.     {
    24.         if (IsPlayer(other) && --colliders == 0)
    25.             PlayerExited();
    26.     }
    27.  
    28.     bool IsPlayer(Collider other)
    29.     {
    30.         return other.tag == "Player";
    31.     }
    32.  
    33.     void PlayerEntered()
    34.     {
    35.         print("Enter");
    36.     }
    37.  
    38.     void PlayerExited()
    39.     {
    40.         print("Exit");
    41.         rb.isKinematic = false;
    42.     }
    43. }
    44.  
     
    Last edited by a moderator: Mar 27, 2018
  13. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    we the script doesn't do much, it just turn the rigidbody.isKinematic to false on exiting the platform.
    it sounds like you need to change the ball parent. make the ball a child of the platform with the OnTriggerEnter.

    public float thrust = 50.0f;

    void PlayerExited()
    {
    print("Exit");
    //code to remove the ball as a child.
    rb.isKinematic = false;
    rb.AddForce(-transform.up * thrust); //should make it fall faster
    }
     
  14. DustyShinigami

    DustyShinigami

    Joined:
    Jan 5, 2018
    Posts:
    529
    Odd. Removing that script still causes the platform to fall when it's touched. If I remove the Rigidbody the platform won't fall, but if I add it back and turn off Use Gravity and Is Kinematic, it falls like it should when it's touched. The other platform doesn't do anything if I do the same to it though. o_O
     
  15. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    well that's good to here. glad you got it fixed
     
  16. DustyShinigami

    DustyShinigami

    Joined:
    Jan 5, 2018
    Posts:
    529
    Also, I've just noticed that when the falling platforms touch the Death Trigger it causes the scene to reset.
     
  17. DustyShinigami

    DustyShinigami

    Joined:
    Jan 5, 2018
    Posts:
    529
    I'm not sure if I have. It's just something I've noticed and don't get why. The platforms still aren't resetting though.
     
  18. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    true, you don't have any code that is "resetting" the platform.
    you have two ways of doing that.
    1) you can destroy the current falling platform, and then spawn in a new platform.
    2) you can move the current falling platform back to it's starting position and put all the Rigidbody settings back to their starting setting.
     
  19. DustyShinigami

    DustyShinigami

    Joined:
    Jan 5, 2018
    Posts:
    529
    How do you do this? I've tried a few scripts doing a Google search to try and respawn them, but they haven't worked. :-\
     
  20. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    well, I don't know enough about your game. You need a script that triggers or detects when to respawn. you can use a box collider, or check the position.y value. then call the Destroy()

    void DestroyGameObject()
    {
    Destroy(gameObject);
    }

    or delay it for some reason
    void DestroyObjectDelayed()
    {
    // Kills the game object in 5 seconds after loading the object
    Destroy(gameObject, 5);
    }

    you need a second script to spawn in the new platform.
    public GameObject SpawnObject

    void SpawnPlatform()
    {
    GameObject newPlatform = Instantiate(SpawnObject, transform.position, transform.rotation);
    newPlatform.transform.position = new Vector3(x, y, 0); // this is the position where you want it to spawn at
    }
     
  21. DustyShinigami

    DustyShinigami

    Joined:
    Jan 5, 2018
    Posts:
    529
    My float postions are highlighted with a red squiggle for my x, y and z axis. It says I can't convert from double to float.
     
  22. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    cast your double as a float, like this
    float variable = (float)yourDoubleVariable;

    can you post the line of code that you're having trouble with
     
  23. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    if you wrote something like this...
    Code (csharp):
    1. new Vector3(3.5, 1.25, 0);
    Just change it so they have an 'f' suffix, like this:
    Code (csharp):
    1. new Vector3(3.5f, 1.25f, 0);
     
  24. DustyShinigami

    DustyShinigami

    Joined:
    Jan 5, 2018
    Posts:
    529
    That was accepted. Thanks. :)

    I've tried putting the respawn code in a script for the platforms, with the original instructions I had and without, and in the Death Trigger script for when the platforms touch it, but nothing's working.

    Script for the platform(s):

    Code (CSharp):
    1. public class FallingPlatform : MonoBehaviour
    2. {
    3.     public GameObject SpawnObject;
    4.  
    5.     void SpawnPlatform()
    6.     {
    7.         GameObject newPlatform = Instantiate(SpawnObject, transform.position, transform.rotation);
    8.         newPlatform.transform.position = new Vector3(-5.990288f, -4.070234f, -0.7937498f);
    9.     }
    10. }
    Death Trigger script:

    Code (CSharp):
    1.     public GameObject SpawnPlatform;
    2.  
    3.     void OnTriggerEnter(Collider other)
    4.     {
    5.      
    6.         if (other.gameObject.CompareTag("Player"))
    7.         {
    8.             Destroy(other.gameObject);
    9.             SceneManager.LoadScene("MiniGame");
    10.         }
    11.  
    12.         else other.gameObject.CompareTag("Ledge");
    13.         {
    14.             Destroy(other.gameObject);
    15.         }
    16.  
    17.     void SpawnPlatform()
    18.     {
    19.         GameObject newPlatform = Instantiate(SpawnObject, transform.position, transform.rotation);
    20.         newPlatform.transform.position = new Vector3(-5.990288f, -4.070234f, -0.7937498f);
    21.     }
    22.  
    23. }
    SpawnPlatform isn't recognised in the latter script. It says it's a local function and it's not available.
     
  25. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    You forgot the curly braces to close the method above. Plus you have a variable named the same as the method..
     
  26. DustyShinigami

    DustyShinigami

    Joined:
    Jan 5, 2018
    Posts:
    529
    I don't follow. Looking through it, I can't see any curly braces that I'm missing. Or do you mean the one after the class name? I have that on my end - both opening and closing braces.

    Not sure which variable I've named the same either.
     
  27. DustyShinigami

    DustyShinigami

    Joined:
    Jan 5, 2018
    Posts:
    529
    As an aside - why don't 'if' statements end with a semi colon?
     
  28. johne5

    johne5

    Joined:
    Dec 4, 2011
    Posts:
    1,133
    you can do an if statement 2 ways.
    Code (CSharp):
    1. if(something == true)
    2. {
    3. // multiple lines of codes
    4. // multiple lines of codes
    5. // multiple lines of codes
    6. // multiple lines of codes
    7. }
    8.  
    9. or
    10.  
    11. if(something == true)
    12. //single line will get used
     
  29. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    OnTriggerEnter doesn't end before SpawnPlatform (which is the duplicate name) begins.

    You can end an 'if' statement with a semicolon -- however it doesn't do anything useful, as far as I know ;)
    I only mean that it's not illegal to type that.. *