Search Unity

Make the object rise up when clicking on the screen?

Discussion in 'Scripting' started by blaster3900, May 16, 2019.

  1. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    I'm making a new mobile game and I have a problem with the code of the object.
    The object is placed on (y 0 ) and I want to make it rise up ( not left and right or forward and backwards), just when I hold the mouse click down and when releasing the mouse click the object stops rising up and stays in place?
    Can someone help me please?
    Thank you!!
     
  2. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    1,927
    Simplest thing would be to check whether the mouse button is currently help in the Update statement, and if so, add a small amount (constant * Time.deltaTime) to the y-position of the object. It's a pretty simple statement. Why don't you try writing it and post what you come up with. You'll probably want to use Input.GetMouseButton (https://docs.unity3d.com/ScriptReference/Input.GetMouseButton.html) to detect the click.
     
  3. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    Thank you for your reply.
    I already use the Input.GetMouseButton in the script, but what happens is that the object rises up and never stops, just when I click the mouse button once.
    and the object needs to destroy other objects when colliding with them but it just does nothing?
    I provided the script below.
     

    Attached Files:

  4. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    1,927
    Please use code tags for showing code. It's easier for everyone.

    It seems that the issue with your code is that on mouse up, you're setting "goingUp" to false, but you never use it anywhere. You probably need to update your GoUp() method to do one thing or another depending on the current value of goingUp.
     
  5. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    I'm not still a newbie and don't know exactly how to do that.
    Can you please edit my code, because that would be a lot helpful and I could understand it better?
     
  6. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    1,927
    Something like this might work:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlayerController : MonoBehaviour
    6. {
    7.     [Header(" Physics ")]
    8.     Rigidbody rig;
    9.  
    10.  
    11.     [Header(" Up Stuff ")]
    12.     public float upSpeed;
    13.     bool goingUp;
    14.  
    15.     // Start is called before the first frame update
    16.     void Start()
    17.     {
    18.         // Store the rigidbody
    19.         rig = GetComponent<Rigidbody>();
    20.     }
    21.  
    22.     // Update is called once per frame
    23.     void Update()
    24.     {
    25.         if (Input.GetMouseButtonDown(0))
    26.         {
    27.             goingUp = true;
    28.             UpdateVelocity();
    29.         }
    30.  
    31.         else if (Input.GetMouseButtonUp(0))
    32.         {
    33.             goingUp = false;
    34.             UpdateVelocity();
    35.         }
    36.     }
    37.  
    38.     private void UpdateVelocity()
    39.     {
    40.         Vector3 vel = rig.velocity;
    41.         vel.y = goingUp ? upSpeed : 0;
    42.         rig.velocity = vel;
    43.     }
    44.    
    45. }
    46.  
     
  7. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    It worked, but just when I check (use gravity) in the Rigidbody. ( when I don't check the use gravity the ball just rises up and does not stop).
    The problem is now that whenever I release the mouse click the object falls down, but I want the object to stay in place.
    How can I do that?
    Thank you for your help. I appreciate it!
     
  8. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    1,927
    If you want an object to not be affected just by gravity, you can set the rigidbody not to use gravity. If you want it to be unaffected by any physics forces at all (such as other objects colliding with it) you can set it to isKinematic = true. It's not clear which behavior you want on this object. Should it ever be affected by physics forces? If not, set isKinematic = true, and then use MovePosition to move it upward each frame.
     
  9. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    It worked!!
    But the object does not destroy the other objects when colliding with them.
    How can I solve?

    Code (CSharp):
    1.  private void OncollistionStay(Collision other)
    2.     {
    3.  
    4.         if (!goingUp)
    5.  
    6.         {
    7.  
    8.             Destroy(other.transform.parent.gameObject);
    9.  
    10.  
    11.         }
    12.  
    13.  
    14.     }


    Thank you for your help. I appreciate it!
     
  10. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    1,927
    You misspelled "OncollistionStay". It's "OnCollisionStay". You've got one lower case letter wrong there, and you've got an extra "t". Make sure the method names are exact.

    Also, do you only want it to destroy the other objects when it's not moving? Right now you're only destroying when goingUp is false. That seems backwards. Also, you're destroying the parent of the other object. Although that should destroy the other object as well, maybe you just want to destroy other.gameObject? If that's still not working, you should check whether the collision is happening at all.
     
  11. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    I tried this code:

    Code (CSharp):
    1. private void OnCollisionEnter(Collision other)
    2.     {
    3.  
    4.         if (!goingUp) ;
    5.    
    6.         {
    7.          
    8.  
    9.              Destroy(other.transform.parent.gameObject);
    10.          
    11.  
    12.         }
    13.  
    14.  
    15.     }

    and what happens is that the object when it collides with the other objects, the other object gets destroyed but the object then stops even if I hold the mouse button down. ( I need to click every time to destroy an object)
    you need to know that I have a lot of objects in a raw and the moving object has not to stop, it needs to go throw the objects and not stop, just when I release the mouse button.
     
  12. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    1,927
    You've got a stray semicolon on line 4, by the way. I assume that's a copy/paste issue, because that code won't compile the way you have it.

    As for the object stopping, it would only do that if it's not set to isKinematic. If this is a moving platform which should not be affected by other forces acting on it, you should set the rigidbody to isKinematic, otherwise other collisions will slow/stop/reverse the movement of the object.
     
  13. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    I checked the (isKinematic) and removed the code in line 4.
    The player then does not respond to the clicks, it does not move at all.
    And I noticed that when the player is rising up, it kinda lag a bit as it wants to drag itself down.
     
    Last edited: May 17, 2019
  14. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    1,927
    Sorry if this has been disjointed. Taking this back up to a higher level, you're going to need to pick which physics path you want to take for your player. You've got two general options:
    • Kinematic: The player can exert physics forces on other objects, but does not receive physics forces. It's unaffected by gravity, and if you want it to move, you'll need to move it manually with methods like MovePosition and MoveRotation. The rigidbody velocity will no longer affect the object, and instead of setting the velocity to go up, you'll want to use MovePosition within FixedUpdate to move the player upward a little bit each FixedUpdate.
    • Non-Kinematic: The player will be subject to the effects of physics. You can either move it with AddForce, or by setting its velocity manually. But if someone bumps into the player, it will slow/stop the player.
    There may be some subtle in-betweens to these approaches, but these are your general choices. Right now, you've got a bit of both, which is going to be a little messy.
     
  15. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    So what do you suggest to do?
     
  16. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    1,927
    It depends on what kind of behavior you want. But a single question should hopefully point you in the right direction: Are there any times where your player should behave like a normal rigidbody, such that other objects in the scene can push it around and exert force on it? If your player doesn't need to behave like a normal rigidbody, then you should probably set it to kinematic, and move it via MovePosition, rather than adjusting its velocity.

    Maybe you can explain the overall functionality you want to get from your player. What other motion will the player have, other than simply moving up and standing still?
     
  17. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    So the player destroys the other objects when colliding with them and there are enemies too, so when the player collides with them you lose the game.
    Do this behavior works with using kinematic?
    and yes the player just rises up and stops when the mouse button is not clicked.
     
  18. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    1,927
    Sounds fine to use isKinematic, then. It's also possible you don't need a rigidbody on the player at all, but that might lead to some cases where collisions between the player and other objects aren't detected. So, I guess you should keep the rigidbody for now and set it to Is Kinematic. Them, you FixedUpdate would use MovePosition instead of setting the velocity. Something like this:

    Code (CSharp):
    1. void FixedUpdate() {
    2.     if (goingUp) {
    3.         rig.MovePosition(transform.position + transform.up * upSpeed * Time.deltaTime);
    4.     }
    5. }
     
  19. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    I inserted this code:

    Code (CSharp):
    1.  
    2.     void FixedUpdate()
    3.     {
    4.         if (Input.GetMouseButtonDown(0))
    5.         {
    6.             rig.MovePosition(transform.position + transform.up * upSpeed * Time.deltaTime);
    7.  
    8.         }
    9.  
    10.  
    11.     }
    what happens is the player moves just a bit a stops even if I hold the mouse button down.
    and the player does not collide with the other objects, he goes throw them.
    to give you a good example of how I want the player to behave in the game,
    it's like the mobile game "Stack Ball", but in my game, the ball is beginning from 0 and rises up.
     
  20. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    1,927
    Change GetMouseButtonDown to GetMouseButton. They're different. The first only fires once, on the exact frame where you first press the button. The second is true the entire time the button is held.

    As for the collision issue, you'll need to understand that Unity has some fairly complex rules about whether any two objects with colliders will actually trigger collision events. If you look at the "Collision action matrix" on this page, you'll see that it depends strongly on the isKinematic state, whether an object is static, etc:

    https://docs.unity3d.com/Manual/CollidersOverview.html

    In your case, it sounds like changing the player to Kinematic means you'll only collider with other objects that have non-kinematic rigidbodies. You'll need to play around with things to get it working the way you want based on the kinds of collision events Unity will raise. Note that Trigger events fire more liberally than Collision events, so it might be necessary to convert some of your colliders into triggers if you can't get them to collide as expected using OnCollisionEnter.
     
  21. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    It finally works, I used this code :

    Code (CSharp):
    1.  
    2.  
    3. public bool enter = true;
    4.     public bool stay = true;
    5.     public bool exit = true;
    6.     public float moveSpeed;
    7.  
    8.  
    9. // Update is called once per frame
    10.     void Update()
    11.     {
    12.  
    13.         // add isTrigger
    14.         var boxCollider = gameObject.AddComponent<BoxCollider>();
    15.         boxCollider.isTrigger = true;
    16.  
    17.  
    18.  
    19.  
    20.         // create a sphere for this cube to interact with
    21.         GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
    22.         sphere.gameObject.transform.position = new Vector3(0, 0, 0);
    23.         sphere.gameObject.AddComponent<Rigidbody>();
    24.         sphere.gameObject.GetComponent<Rigidbody>().isKinematic = true;
    25.         sphere.gameObject.GetComponent<Rigidbody>().useGravity = false;
    26.     }
    27.  
    28.  
    29.  
    30.  
    31.  
    32.     private void OnTriggerEnter(Collider other)
    33.     {
    34.         if (enter)
    35.         {
    36.             Debug.Log("entered");
    37.  
    38.             Destroy(other.transform.parent.gameObject);
    39.         }
    40.     }
    41.  
    42.  
    43. void FixedUpdate()
    44.     {
    45.         if (Input.GetMouseButton(0))
    46.         {
    47.             rig.MovePosition(transform.position + transform.up * upSpeed * Time.deltaTime);
    48.  
    49.  
    50.  
    51.         }
    Everything works, but the problem now is that the player duplicates a lot when starting the game and there are a lot of box colliders showing up and that makes the game very laggy.
    what can I do to solve it?
     
    Last edited: May 19, 2019
  22. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    1,927
    Look carefully at your code on line 9 there: "// Update is called once per frame"

    Probably everything you have there should be placed in Start (so it runs once at the beginning of the game) instead of Update (which runs possibly hundreds of times per seconds).
     
  23. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    Yeah, it worked!

    I have another problem now, whenever I use this code in the player's
    Code (CSharp):
    1. public class PlayerController : MonoBehaviour
    2. {
    3.     [Header(" Physics ")]
    4.     public float explodeForce;
    5.  
    6. private void OnTriggerEnter(Collider other)
    7.     {
    8.         if (enter && !other.transform.CompareTag("Finish"))
    9.         {
    10.             //Debug.Log("entered");
    11.  
    12.             ExplodeParts(other.transform.parent);
    13.             //Destroy(other.transform.parent.gameObject);
    14.         }
    15.         else if (other.transform.CompareTag("Finish"))
    16.         {
    17.  
    18.             Debug.Log("Level Finished");
    19.  
    20.         }
    21.     }
    22.  
    23. public void ExplodeParts(Transform partsParent)
    24.     {
    25.         Destroy(partsParent.gameObject, 2);
    26.  
    27.         for (int i = 0; i < partsParent.childCount; i++)
    28.         {
    29.  
    30.             Transform child = partsParent.GetChild(i);
    31.  
    32.             // Find the center of the mesh collider
    33.             Vector3 mcCenter = child.GetComponent<MeshCollider>().bounds.center;
    34.  
    35.  
    36.             //Remove the Collider
    37.             Destroy(child.GetComponent<MeshCollider>());
    38.  
    39.             //add a rigidbody
    40.             child.gameObject.AddComponent<Rigidbody>();
    41.  
    42.             // Find the velocity direction
    43.             Vector3 dir = mcCenter - partsParent.position;
    44.  
    45.  
    46.             // Make the it fly
    47.             child.GetComponent<Rigidbody>().velocity = Vector3.up * explodeForce;
    48.  
    49.  
    50.  
    51.         }
    52.  
    53.  
    54.  
    55.     }
    56.  
    57.  
    58.  
    script:

    Unity crashes everytime when the player collides with the objects!
    I don't know what to do?
     
  24. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    1,927
    Unity crashes? Like, you see a box with a red "!" in it, and Unity's crash report window pops up? I'm not sure what would cause that. I was thinking some kind of infinite loop issue could occur, like maybe you're increasing the child count within your loop, causing it to run forever, but that doesn't see me to be the case.

    I'd recommend looking at the editor log file, and it should show some details about the crash. You'll need to show the crash information, or I don't know. Otherwise, add more diagnostics to your ExplodeParts method to give you a sense of whether the for loop ever finishes.
     
  25. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    Yes, there is the red "!" when it crashes every time the player collides with the objects.
    I looked at the editor log file:

    [EnlightenBakeManager] m_Clear = false;
    WARNING: Shader Unsupported: 'AR/TangoARRender' - Pass '' has no vertex shader
    WARNING: Shader Unsupported: 'AR/TangoARRender' - Setting to default shader.
    WARNING: Shader Unsupported: 'Hidden/VideoDecodeOSX' - Pass 'Flip_RGBARect_To_RGBA' has no vertex shader
    WARNING: Shader Unsupported: 'Hidden/VideoDecodeOSX' - Setting to default shader.
    WARNING: Shader Unsupported: 'Hidden/VideoDecodeAndroid' - Pass 'RGBAExternal_To_RGBA' has no vertex shader
    WARNING: Shader Unsupported: 'Hidden/VideoDecodeAndroid' - Setting to default shader.
    Initialize mono
    Mono path[0] = 'C:/Program Files/Unity/Editor/Data/Managed'
    Mono path[1] = 'C:/Program Files/Unity/Editor/Data/MonoBleedingEdge/lib/mono/unityjit'
    Mono config path = 'C:/Program Files/Unity/Editor/Data/MonoBleedingEdge/etc'
    Using monoOptions --debugger-agent=transport=dt_socket,embedding=1,server=y,suspend=n,address=127.0.0.1:56372
    Begin MonoManager ReloadAssembly
    Refreshing native plugins compatible for Editor in 0.33 ms, found 3 plugins.
    Initializing Unity.PackageManager (PackageManager) v2018.3.14 for Unity v2018.3.14f1
    Registering precompiled unity dll's ...
    Register platform support module: C:\Program Files\Unity\Editor\Data\PlaybackEngines\AndroidPlayer/UnityEditor.Android.Extensions.dll
    Register platform support module: C:/Program Files/Unity/Editor/Data/PlaybackEngines/iOSSupport/UnityEditor.iOS.Extensions.dll
    Register platform support module: C:\Program Files\Unity\Editor\Data\PlaybackEngines\windowsstandalonesupport/UnityEditor.WindowsStandalone.Extensions.dll
    Registered in 0.003260 seconds.
    Registering platform support modules:
    Registered platform support modules in: 0,0916145s.
    Native extension for Android target not found
    Native extension for iOS target not found
    Native extension for WindowsStandalone target not found
    Refreshing native plugins compatible for Editor in 0.41 ms, found 3 plugins.
    Preloading 1 native plugins for Editor in 1.32 ms.
    Mono: successfully reloaded assembly
    - Completed reload, in 1.414 seconds
    Registering precompiled user dll's ...
    Registered in 0.039497 seconds.
    Platform modules already initialized, skipping
    Begin MonoManager ReloadAssembly
    Initializing Unity.PackageManager (PackageManager) v2018.3.14 for Unity v2018.3.14f1
    Registering platform support modules:
    Registered platform support modules in: 0,0450934s.
    Native extension for Android target not found
    Native extension for iOS target not found
    Native extension for WindowsStandalone target not found
    Refreshing native plugins compatible for Editor in 0.39 ms, found 3 plugins.
    Preloading 1 native plugins for Editor in 0.21 ms.
    Mono: successfully reloaded assembly
    - Completed reload, in 1.280 seconds
    Platform modules already initialized, skipping
    Validating Project structure ... 0.000663 seconds.
    Refresh: detecting if any assets need to be imported or removed ...

    ========== OUTPUTTING STACK TRACE ==================
    0x00000001418579A0 (Unity) PhysicsScene::processTriggerEnterExits
    0x0000000141857380 (Unity) PhysicsScene::processReports
    0x0000000140B3AF5F (Unity) PhysicsManager::Simulate
    0x0000000140B33616 (Unity) `PhysicsManager::InitializeClass'::`2'::FixedUpdatePhysicsFixedUpdateRegistrator::Forward
    0x000000014095B357 (Unity) ExecutePlayerLoop
    0x000000014095B423 (Unity) ExecutePlayerLoop
    0x000000014095E6E1 (Unity) PlayerLoop
    0x000000014133D25F (Unity) PlayerLoopController::UpdateScene
    0x000000014133B810 (Unity) Application::TickTimer
    0x0000000141497C4B (Unity) MainMessageLoop
    0x00000001414998E6 (Unity) WinMain
    0x00000001424846FA (Unity) __scrt_common_main_seh
    0x00007FFFA7677974 (KERNEL32) BaseThreadInitThunk
    0x00007FFFAA3BA271 (ntdll) RtlUserThreadStart


    There is more information about the crash, if you want to I can attach the whole file if this is not enough.

    "add more diagnostics to your ExplodeParts method " what do you suggest to add to the "ExplodeParts method"
     
    Last edited: May 21, 2019
  26. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    1,927
    Hmm. That's puzzling. Maybe attach the "Error" file it places in the crash folder. I'm not saying I can necessarily be much help, but more eyes can't hurt. I think you might need to submit this as a bug though, with your full project, and see what Unity says.

    As for adding more diagnostics, I just meant to add more Debug.Log statements so you can see which lines of your code are getting executed. Maybe an initial Debug.Log in ExplodeParts that says how many child elements there are, and the name of the object you're exploding. Then another Debug.Log in the for loop, showing the value of "i" and what child it's acting on. That would maybe tell you how far it's getting in the exploding before crashing.

    Have you tried your code without adding the rigidbody to the child? I'm not aware of any reason why it shouldn't work, but maybe the physics system is having trouble adding a rigidbody within a collision event?
     
  27. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    I tried, without adding the Rigidbody to the child, but there is an error popping up that says ... want to call the Rigidbody but it is not found...
    So I sent a bug report to unity about this issue and the replied back with:
    "we actually know about this issue and are tracking progress here": https://issuetracker.unity3d.com/product/unity/issues/guid/1155827
    Crash on PhysicsScene:: ProcessTriggerEnterExits when splitting meshes that also exit a Trigger with OnTriggerExit
    that what the issue is about.
     
  28. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    1,927
    Wow. Well, I'm sorry you stumbled upon such a severe issue. Maybe you can think of some other approach that doesn't result in the crash? Is it possible to add the rigidbodies to the child objects at start? I don't know if that would even matter. Anyway, I'd recommend trying out some new approaches rather than waiting for a fix to this, as it might be a while before a fix is released.
     
  29. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    I added a Rigidbody to the object and set it to isKinematic, then I started the game and I was able to make the player move throw the objects, so I destroyed about 7 objects ( and they were exploding ) and then Unity crashed.
    Before that I was not even able to get throw one object, I don't know why it is still crashing.
    Do you have any ideas?
     
  30. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    I figured it out, it doesn't crash anymore!!!
    What I did is that I removed the Rigidbody that I added to the object because I looked again at the code and it is already added to it, then I added a Mesh Collider to the object and checked the "convex" box.
    The game is working really good.
     
    dgoyette likes this.
  31. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    Hey again,

    I'm now working with complex code, I have a problem that the player goes down when I click the mouse button.

    But I want the player to go up when the mouse button is pressed and stop in place when I release the mouse button.

    This code makes
    the player go down, how can I change it to make him go up?

    Code (CSharp):
    1. public class PlayerController : MonoBehaviour
    2. {
    3.     private static PlayerController instance;
    4.  
    5.     [SerializeField]
    6.     private Transform playerTransform;
    7.     [SerializeField]
    8.     private Animator playerAnimator;
    9.     [SerializeField]
    10.     private GameObject playerDestructedModel;
    11.     [SerializeField]
    12.     private ParticleSystem playerTrailParticleSystem;
    13.     [SerializeField]
    14.     private ProjectData projectData;
    15.  
    16.     [Space]
    17.     [SerializeField]
    18.     private float playerOffset = 0.45f;
    19.  
    20.     [Space]
    21.     [SerializeField]
    22.     private LevelController levelController;
    23.  
    24.     [LineSpacer]
    25.     [SerializeField]
    26.     private GameObject comboObject;
    27.     [SerializeField]
    28.     private Image comboFillbarImage;
    29.     [SerializeField]
    30.     private GameObject comboWarningObject;
    31.     [SerializeField]
    32.     private ParticleSystem comboParticleSystem;
    33.  
    34.     private int comboStartColums = 5;
    35.     private int comboRequireColums = 10;
    36.     private float comboActiveTime = 1.0f;
    37.  
    38.     private float comboTimePerDestruct;
    39.  
    40.     private bool isComboEnabled;
    41.     private float comboTimer;
    42.     private bool isComboReached;
    43.  
    44.     private int destructInARow = 0;
    45.  
    46.     private int downParameterHash;
    47.  
    48.     private Coroutine jumpCoroutine;
    49.     private TweenCase movementTween;
    50.  
    51.     private Rigidbody[] destructRigidbodies;
    52.     private Vector3[] desctructPlayerPositions;
    53.  
    54.     public OnPlayerDown onPlayerDown;
    55.     public OnPlayerDestructPlatform onPlayerDestructPlatform;
    56.     public OnGameStarted onGameStarted;
    57.  
    58.     private bool isEnabled = true;
    59.     private bool isGameStarted = false;
    60.  
    61.     private bool mouseDown = false;
    62.  
    63.     private const float PITCH_MIN = 1.0f;
    64.     private const float PITCH_MAX = 2.0f;
    65.  
    66.     private void Awake()
    67.     {
    68.         instance = this;
    69.  
    70.         downParameterHash = Animator.StringToHash("Down");
    71.      
    72.         destructRigidbodies = playerDestructedModel.GetComponentsInChildren<Rigidbody>();
    73.         desctructPlayerPositions = new Vector3[destructRigidbodies.Length];
    74.         for(int i = 0; i < desctructPlayerPositions.Length; i++)
    75.         {
    76.             desctructPlayerPositions[i] = destructRigidbodies[i].transform.localPosition;
    77.         }
    78.      
    79.         comboStartColums = projectData.comboStartColums;
    80.         comboRequireColums = projectData.comboRequireColums;
    81.         comboActiveTime = projectData.comboActiveTime;
    82.  
    83.         comboTimePerDestruct = (float)1 / comboRequireColums;
    84.     }
    85.  
    86.     public void Init()
    87.     {
    88.         Platform platform = levelController.NextPlatform;
    89.         if(platform != null)
    90.             playerTransform.position = playerTransform.position.SetY(platform.transform.position.y + playerOffset);
    91.     }
    92.  
    93.     private void Update()
    94.     {
    95.         if (!isEnabled)
    96.             return;
    97.  
    98.         if(Input.GetMouseButtonDown(0))
    99.         {
    100.             if(!isGameStarted)
    101.             {
    102.                 onGameStarted.Invoke();
    103.  
    104.                 isGameStarted = true;
    105.             }
    106.  
    107.             playerAnimator.SetBool(downParameterHash, true);
    108.  
    109.             jumpCoroutine = StartCoroutine(JumpCoroutine());
    110.  
    111.             onPlayerDown.Invoke(true);
    112.  
    113.             mouseDown = true;
    114.         }
    115.      
    116.         if(Input.GetMouseButtonUp(0))
    117.         {
    118.             MouseUp();
    119.         }
    120.  
    121.         if(isComboEnabled)
    122.         {
    123.             if(!mouseDown)
    124.             {
    125.                 comboTimer -= Time.deltaTime / comboActiveTime;
    126.             }
    127.             else if(isComboReached)
    128.             {
    129.                 comboTimer -= Time.deltaTime / comboActiveTime;
    130.  
    131.                 if(comboTimer <= 0.2f)
    132.                 {
    133.                     comboWarningObject.SetActive(true);
    134.                 }
    135.             }
    136.  
    137.             comboFillbarImage.fillAmount = comboTimer;
    138.  
    139.             if (comboTimer <= 0)
    140.             {
    141.                 playerTrailParticleSystem.Play();
    142.                 comboParticleSystem.Stop();
    143.  
    144.                 isComboReached = false;
    145.                 isComboEnabled = false;
    146.                 comboObject.SetActive(false);
    147.                 comboWarningObject.SetActive(false);
    148.  
    149.                 destructInARow = 0;
    150.             }
    151.         }
    152.     }
    153.  
    154.     private void MouseUp()
    155.     {
    156.         if (isEnabled)
    157.         {
    158.             if (destructInARow > 1)
    159.             {
    160.                 Platform tempPlatform = levelController.NextPlatform;
    161.                 if (tempPlatform != null)
    162.                 {
    163.                     bool isObstacleHitted = false;
    164.                     Collider[] hitColliders = Physics.OverlapSphere(playerTransform.transform.position.SetY(tempPlatform.transform.position.y), 0.1f);
    165.                     for (int i = 0; i < hitColliders.Length; i++)
    166.                     {
    167.                         if (hitColliders[i].CompareTag("Obstacle"))
    168.                         {
    169.                             isObstacleHitted = true;
    170.  
    171.                             break;
    172.                         }
    173.                     }
    174.  
    175.                     if (isObstacleHitted)
    176.                     {
    177.                         tempPlatform.ScalePlatform();
    178.  
    179.                         PlayBounceSound();
    180.                     }
    181.                 }
    182.             }
    183.         }
    184.  
    185.         playerAnimator.SetBool(downParameterHash, false);
    186.  
    187.         onPlayerDown.Invoke(false);
    188.  
    189.         mouseDown = false;
    190.     }
    191.  
    192.     private bool CheckPlatformGround(Platform platform)
    193.     {
    194.         Collider[] hitColliders = Physics.OverlapSphere(playerTransform.transform.position.SetY(platform.transform.position.y), 0.1f);
    195.         for (int i = 0; i < hitColliders.Length; i++)
    196.         {
    197.             if (hitColliders[i].CompareTag("Obstacle"))
    198.             {
    199.                 return true;
    200.             }
    201.         }
    202.  
    203.         return false;
    204.     }
    205.  
    206.     public void Revive()
    207.     {
    208.         for (int i = 0; i < destructRigidbodies.Length; i++)
    209.         {
    210.             destructRigidbodies[i].gameObject.SetActive(false);
    211.         }
    212.      
    213.         playerDestructedModel.SetActive(false);
    214.         playerTransform.gameObject.SetActive(true);
    215.  
    216.         isEnabled = true;
    217.  
    218.         GameController.Revive();
    219.     }
    220.  
    221.     private void DestructPlayer()
    222.     {
    223.         for (int i = 0; i < destructRigidbodies.Length; i++)
    224.         {
    225.             destructRigidbodies[i].transform.localPosition = desctructPlayerPositions[i];
    226.             destructRigidbodies[i].gameObject.SetActive(true);
    227.         }
    228.  
    229.         playerTransform.gameObject.SetActive(false);
    230.  
    231.         playerDestructedModel.transform.position = playerTransform.position;
    232.         playerDestructedModel.SetActive(true);
    233.  
    234.         for (int i = 0; i < destructRigidbodies.Length; i++)
    235.         {
    236.             destructRigidbodies[i].AddExplosionForce(5f, playerDestructedModel.transform.position.SetZ(0), 10, 0, ForceMode.Impulse);
    237.         }
    238.     }
    239.  
    240.     private IEnumerator JumpCoroutine()
    241.     {
    242.         WaitForSeconds waitForSeconds = new WaitForSeconds(0.05f);
    243.  
    244.         destructInARow = 0;
    245.  
    246.         bool jump = true;
    247.         while(jump)
    248.         {
    249.             yield return waitForSeconds;
    250.  
    251.             if (!mouseDown)
    252.                 yield break;
    253.  
    254.             Platform tempPlatform = levelController.NextPlatform;
    255.             if(tempPlatform != null)
    256.             {
    257.                 bool isObstacleHitted = CheckPlatformGround(tempPlatform);
    258.  
    259.                 if (isObstacleHitted && !isComboReached)
    260.                 {
    261.                     if(destructInARow > 0)
    262.                     {
    263.                         float timer = 0.05f;
    264.                         while (timer > 0)
    265.                         {
    266.                             timer -= Time.deltaTime;
    267.  
    268.                             if (!mouseDown)
    269.                                 yield break;
    270.  
    271.                             yield return null;
    272.                         }
    273.                     }
    274.                  
    275.                     tempPlatform.ScalePlatform();
    276.  
    277.                     DestructPlayer();
    278.  
    279.                     AudioController.PlaySound(projectData.playerDeathAudioClip, AudioController.AudioType.Sound, 1);
    280.  
    281.                     isEnabled = false;
    282.  
    283.                     comboObject.SetActive(false);
    284.  
    285.                     MouseUp();
    286.  
    287.                     GameController.GameOver();
    288.  
    289.                     yield break;
    290.                 }
    291.                 else
    292.                 {
    293.                     movementTween = playerTransform.DOMoveY(tempPlatform.transform.position.y - 0.5f + playerOffset, 0.05f).SetEasing(Ease.Type.BounceOut).OnComplete(delegate
    294.                     {
    295.                         GameController.Score++;
    296.  
    297.                         destructInARow++;
    298.  
    299.                         levelController.DestructPlatform(tempPlatform);
    300.  
    301.                         onPlayerDestructPlatform.Invoke(tempPlatform);
    302.  
    303.                         if (levelController.PlatformsQueueCount == 0)
    304.                         {
    305.                             playerTrailParticleSystem.Play();
    306.                             comboParticleSystem.Stop();
    307.  
    308.                             comboObject.SetActive(false);
    309.  
    310.                             GameController.WinGame();
    311.  
    312.                             isEnabled = false;
    313.  
    314.                             MouseUp();
    315.  
    316.                             jump = false;
    317.                         }
    318.                         else
    319.                         {
    320.                             if(!isComboReached && destructInARow > comboStartColums)
    321.                             {
    322.                                 if(!isComboEnabled)
    323.                                 {
    324.                                     comboObject.SetActive(true);
    325.                                     comboFillbarImage.color = Color.white;
    326.  
    327.                                     isComboEnabled = true;
    328.                                 }
    329.  
    330.                                 comboTimer += comboTimePerDestruct;
    331.  
    332.                                 if(comboTimer >= 1)
    333.                                 {
    334.                                     playerTrailParticleSystem.Stop();
    335.                                     comboParticleSystem.Play();
    336.  
    337.                                     isComboReached = true;
    338.                                     comboFillbarImage.color = Color.red;
    339.                                     comboFillbarImage.fillAmount = 1;
    340.                                 }
    341.                             }
    342.  
    343.                             if(destructInARow > 1 && !mouseDown)
    344.                             {
    345.                                 tempPlatform = levelController.NextPlatform;
    346.  
    347.                                 isObstacleHitted = CheckPlatformGround(tempPlatform);
    348.  
    349.                                 if (isObstacleHitted)
    350.                                 {
    351.                                     tempPlatform.ScalePlatform();
    352.  
    353.                                     PlayBounceSound();
    354.                                 }
    355.                             }
    356.                         }
    357.                     });
    358.                 }
    359.             }
    360.         }
    361.     }
    362.  
    363.     public static void PlayDestructSound(float pitch)
    364.     {
    365.         AudioController.PlaySound(instance.projectData.destructAudioClip, AudioController.AudioType.Sound, 1, Mathf.Lerp(PITCH_MAX, PITCH_MIN, pitch));
    366.     }
    367.  
    368.     public static void PlayBounceSound()
    369.     {
    370.         AudioController.PlaySound(instance.projectData.bounceAudioClip, AudioController.AudioType.Sound, 1);
    371.     }
    372.  
    373.     public delegate void OnPlayerDown(bool state);
    374.     public delegate void OnPlayerDestructPlatform(Platform platform);
    375.     public delegate void OnGameStarted();
    376. }
    I sent you all of the code for the PlayerController script.

    Without the jumping or bouncing in the code
    Can you please help me?
     
    Last edited: Jun 13, 2019
  32. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    1,927
    Tough to say. I see the following:

    playerAnimator.SetBool(downParameterHash, true);

    Does that animation move the player at all? You're calling that when the mouse button is pressed down.

    You're also calling onPlayerDown.Invoke(true); at the same time. Is some event wired up that affects the player?

    If not, there's a bit too much going on here for me to easily understand what should happen, or what might be going wrong. Does this happen on mouse down, or mouse up? That should help isolate which half of the code (or so) is causing it.
     
  33. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    That's when the mouse button is down:

    Code (CSharp):
    1.  if(Input.GetMouseButtonDown(0))
    2.         {
    3.             if(!isGameStarted)
    4.             {
    5.                 onGameStarted.Invoke();
    6.  
    7.                 isGameStarted = true;
    8.             }
    9.  
    10.             playerAnimator.SetBool(downParameterHash, true);
    11.  
    12.             jumpCoroutine = StartCoroutine(JumpCoroutine());
    13.  
    14.             onPlayerDown.Invoke(true);
    15.  
    16.             mouseDown = true;
    17.         }

    and that's when the mouse button is up:

    Code (CSharp):
    1.  private void MouseUp()
    2.     {
    3.         if (isEnabled)
    4.         {
    5.             if (destructInARow > 1)
    6.             {
    7.                 Platform tempPlatform = levelController.NextPlatform;
    8.                 if (tempPlatform != null)
    9.                 {
    10.                     bool isObstacleHitted = false;
    11.                     Collider[] hitColliders = Physics.OverlapSphere(playerTransform.transform.position.SetY(tempPlatform.transform.position.y), 0.1f);
    12.                     for (int i = 0; i < hitColliders.Length; i++)
    13.                     {
    14.                         if (hitColliders[i].CompareTag("Obstacle"))
    15.                         {
    16.                             isObstacleHitted = true;
    17.  
    18.                             break;
    19.                         }
    20.                     }
    21.  
    22.                     if (isObstacleHitted)
    23.                     {
    24.                         tempPlatform.ScalePlatform();
    25.  
    26.                         PlayBounceSound();
    27.                     }
    28.                 }
    29.             }
    30.         }
    31.  
    32.         playerAnimator.SetBool(downParameterHash, false);
    33.  
    34.         onPlayerDown.Invoke(false);
    35.  
    36.         mouseDown = false;
    37.     }
    I just want it to make the opposite, instead of going down, to go up.
     
  34. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    1,927
    Sure. I just can't tell from looking at your code what is actually moving the character. It's not obvious to me.

    You're calling position.SetY on your player, which I don't recognize. That could be moving it to the wrong place. You're starting an animation which might be applying root motion, which could move the player. You're making the player jump, where you're calling playerTransform.DOMoveY, which would change the y-position as well. You should figure out which of those (if any) are responsible for the character movement. To figure that out, you could just comment out all but one of those, and see if the bad behavior still occurs, then you'll know which line of code is responsible. Maybe you've got a sign reversed. Maybe you need to include an offset.
     
  35. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    This line code is responsible for the Player movement:

    Code (CSharp):
    1.  else
    2.                 {
    3.                     movementTween = playerTransform.DOMoveY(tempPlatform.transform.position.y - 0.5f + playerOffset, 0.05f).SetEasing(Ease.Type.BounceOut).OnComplete(delegate
    4.                     {
     
  36. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    1,927
    DOMoveY isn't a Unity function, so you must be using some other library for your movement. So that doesn't tell me much, since I don't know what the parameters mean. I'll assume you're setting the player's height to the platform's height, minus half a unit, plus some offset. Have you confirmed that's correct? What if you don't have the 0.5? What if you don't have the offset?

    Anyway, moral of the story here is that you're going to have to figure this out, not just keep reposting your code. You need to learn how to debug your code. By that, I mean that you should see what the values are before and after calling a line of code, and decide whether the line of code changes the values reasonably. Learn to debug either by adding Debug.Log statements, or attach the debugger and set breakpoints.
     
  37. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    Hey,

    I have created 416 levels in my game, I want the first 0 to 90 levels play in a row (not randomly) and the levels from 91 to 416 to play randomly. (the player also starts where he left the game).
    Is that possible to make?
     
  38. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    1,927
    There are a couple of fairly simple ways to handle that, though my concern is what will happen if you add more levels beyond 416.

    Maybe the easiest thing is to create a list of level IDs when a player first starts playing. You'd populate values 0 through 90 into the list in that order, then you'd randomly populate the remaining 300+ levels randomly. (There's plenty of stuff to find on google if you search for how to randomize a c# list). So then you'd end up with some list containing values: [0,1,2,3...88,89,90,303,118,290,etc]. You'd store this list in some persistence storage, and then just keep track of how many levels the player has completed, and use that value to index into this list.

    Another approach, where you don't need to keep track of the list, would be to just keep track of the "seed" you give to the randomization function, so that you can regenerate the same ransom sequence of numbers to order levels 91 through 416. That's probably what I'd do.

    The downside to both is that neither would cleanly handle the case where you add more levels beyond 416 later on. In the first example, you can't just insert level 417 somewhere in the list, because that would mess up the order of the other levels. And in the second case, I expect you'd get a different sequence of values if you sorted a list of 417 things compared to sorting 416 things. So I'm not sure how I'd handle adding more levels later.
     
  39. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    6,511
    It's possible and fairly easy to do (see dgoyette's comment above), but from a game design standpoint: Why would you ever want this?
    There are two possibilities:
    1) A player will not interact with the community of other players of this game, in which case, they will never have any idea that the order >90 is randomized, in which case it may as well just be the same for everyone.
    2) A player WILL interact with the community, and will notice that his level 91 is different from someone else's level 91, and will think your game is buggy.

    As a design decision this is 100% downside as far as I can tell.
     
  40. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    I want to randomize the levels after level 90 because the player plays till level 416 after this level the game starts from level 1.
    When randomizing the levels the player can get to for example level 600 without starting of level 1.
    Do you have another solution to my problem?
    Thank you.
     
  41. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    6,511
    I'm not sure I follow. Randomizing the order in which the levels appear won't magically cause 200 more levels to appear.

    Or are you saying that, the player plays 1-90, and then after that, there's and infinite random selection of the other 300 levels? And the level number can go to any arbitrary amount, but it'll just pull randomly from levels 91-416 forever?

    If so, then the above advice isn't ideal. What you'd really want to do is have two separate lists or collections of levels, with 1-90 in the first and 91-416 in the second. Then you can shuffle the second list however much you want (like after you run through it).

    Design-wise, I'd recommend making it clear to the player after level 90 that they're now on a longterm, more random section of levels - that way if they are comparing to other users they won't raise bug reports after level 91. Unless it's your intent to deceive your customers into thinking there are more levels than there are (which is a valid, if morally problematic, strategy), that is.
     
  42. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    The player will not notice that a few levels are repeating, because in these games the levels are similar to each other like in my case.
    What if I add more levels to the game, can I add them to the list or is it more complicated?
     
  43. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    6,511
    If you're just picking a random level from list #2, then yeah adding new levels is no problem.
     
  44. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    Can you give me an example code for this list, please?
     
  45. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    1,927
    It's just picking a random index in an array/list based on the number of elements in the list. Every time you go to a new level just pick a random number from 90 to 416 (assuming your levels are indexed starting at 0). For example,

    Code (CSharp):
    1.  
    2. // Note: Upper bound is exclusive, when using integers.
    3. var randomLevelIndex = UnityEngine.Random.Range(90,416);
    In reality, you'd want to pick a random number from 90 up to the max number of levels, rather than hard-coding 416 here.
     
  46. blaster3900

    blaster3900

    Joined:
    May 12, 2019
    Posts:
    25
    I have a problem with game, when I export it for android and install it on my device the game crashes instantly when opening it (before the splash screen appears), that never happend before!
    Do you have any solutions for this problem?
    Thank you