2
\$\begingroup\$

I am creating my first game in Unity and now I have a problem.

I created a waterpool (a blue quad) and I want to simulate the floating of the player, so when the player is in the water, its Y position would be equal to that of water.

I think a picture is clearer: the water is blue, the player is blue.

enter image description here

I tried to do it this way but it does not work:

public float myYpos;

void OnTriggerEnter(Collider other) {
   if(other.tag == "Water") {
      walkSpeed = walkSpeed - deltaWaterSpeed;
      jumpHeight = jumpHeight - deltaWaterJump;

      // DOESN'T WORK
      //myYpos = transform.position.y;
      //myYpos = myYpos + 1;
      //transform.position = new Vector3(transform.position.x, myYpos, transform.position.z);
   }
}

This is a gif of my game: enter image description here

I also do not know why sometimes the player is hidden in the water (I see only water), why?

Thanks to anyone who wants to help me.


Thanks for the answers. It is a 2D game but I stupidly followed a tutorial for 3D and so now I go ahead with 3D.

I dont' have a rigidBody on the Player. I added the OnTriggerStay as recommended but the result is this: enter image description here

   void OnTriggerStay(Collider other) {
      if(transform.position.y < other.transform.position.y) {
         transform.position = new Vector3(transform.position.x, other.transform.position.y, transform.position.z);
      }
   }

I deleted the OnTriggerEnter() and OnTriggerExit() methods.

Why the player jumps up and down? Why it doesn't float (a few mm below the surface), but quite a bit below?


Ok, now actually it does what it should have done, but I realized that was not what I wanted.

It behaves in this way:

enter image description here

The water quad has Y position = 8 and when the player is inside water its Y position is rightly 8. However, this generates this first effect while I prefer the second: the player is on the surface or nearly so, regardless of the height of the water.

enter image description here

How can I get this?

I know I have asked one thing and I got the correct answer but only now I realized that I didn't know what I wanted. Sorry...

In any case, why the player does not jump in the water? It jumps only if it is attached to a gray wall. If it is in the water it doesn't jump but parameters for the jump are setup...

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

Your code doesn't work because you use OnTriggerEnter, which is only called once. If you want to call a function for as long as the collider is in the trigger zone you should use OnTriggerStay

PS: You should not change the position of the blue box directly but manipulate Rigidbody.velocity or use Rigidbody.AddForce to move it, otherwise the box may "teleport" inside other objects and cause odd behaviour.

PS2: You seem to be creating a 2D game. Are you using the 2D or the 3D physics components? If you are using the 2D components, you should use OnTriggerStay2D.

EDIT: I don't quite understand the third part of your question, but your second problem is exactly why you should not modify the transform directly. The problem you have now is that your box moves down and is "teleported" back up, but it keeps it downwards velocity. It's downwards velocity is also increasing due to gravity, which causes this odd behaviour. To fix this, you should use Rigidbody.AddForce (or manipulate Rigidbody.velocity) instead.

eg:

void OnTriggerStay(Collider col){
    // 'rigid' is the Rigidbody component.
    rigid.AddForce(Vector3.up);
}

or

void OnTriggerStay(Collider col){
    rigid.velocity = Vector3.up;
}
\$\endgroup\$
  • \$\begingroup\$ Thanks for the reply, I have modified the main message to answer your questions. \$\endgroup\$ – beth Apr 19 '17 at 15:30
  • \$\begingroup\$ Have you made any progress? \$\endgroup\$ – Demindiro Apr 22 '17 at 19:32
  • \$\begingroup\$ No, I don't understand what I have to do and I feel a little stupid... \$\endgroup\$ – beth Apr 22 '17 at 19:37
  • \$\begingroup\$ I added two examples. Tell me if it works and/or if you understand how it works. \$\endgroup\$ – Demindiro Apr 22 '17 at 19:59
  • \$\begingroup\$ Hi, thanks. I added the rigidbody to the player and the code you wrote but when I walk into the water nothing happens, the player's behavior doesn't change \$\endgroup\$ – beth Apr 24 '17 at 9:46
0
\$\begingroup\$

Simply variant if you have RigidBody2D on player

this variant also can modify for RigidBody

private void OnTriggerStay2D(Collider2D collision)
{
    if(other.tag == "Water") {
        if (transform.position.y < collision.transform.position.y)
        {
            GetComponent<Rigidbody2D>()
                .AddForce(new Vector2(0, collision.transform.position.y - 
                transform.position.y - Physics2D.gravity.y));
        }       
    }
}

You can replace

collision.transform.position.y - transform.position.y

On

(collision.transform.position.y - transform.position.y)*floatspeed;

and change speed of floating (floatspeed)

if you don't usee RigidBody for fixation y in OnTriggerStay2D:

if (transform.position.y < collision.transform.position.y){
    transform.position(new Vector3(transform.position.x, collision.transform.position.y));
}

Also you can modify this script to floating player.


For fix twitching: Use bool for check if player and water and run this script in LateUpdate if player in water:

Declaration

bool inWater;
float waterSurface;//y coordinate of water surface

OnTriggerEnter()

if(other.tag == "Water") {
    inWater = true;//player in water
    waterSurface = other.transform.position.y;//set y coord of water surface as center of water
    //you also can get Rect rect of the water sprite for find y coord of water surface
}

OnTriggerExit()

if(other.tag == "Water") {
    inWater = false;
}

LateUpdate()

if(inWater){
    //script for change position in water
}

script for change position in water may be different:

so when the player is in the water, its Y position would be equal to that of water.

if (transform.position.y < waterSurface){
    transform.position(new Vector3(transform.position.x,waterSurface));
}
\$\endgroup\$
  • \$\begingroup\$ Thanks for the reply, I have modified the main message to answer your questions. \$\endgroup\$ – beth Apr 19 '17 at 15:30
  • \$\begingroup\$ I'm add info in answer \$\endgroup\$ – Leonid Apr 19 '17 at 15:53
  • \$\begingroup\$ Perfect, now it does what should have done, but I still have a problem, or rather two. I edited my main question. Thanks again. \$\endgroup\$ – beth Apr 19 '17 at 16:37
  • \$\begingroup\$ Simply way create empty Water object and attach water sprite. Modify sprite y coordinate (move sprite object down) \$\endgroup\$ – Leonid Apr 19 '17 at 16:56
  • \$\begingroup\$ Sorry, I dont' understand what you mean. Now I have a quad called Water and its material. What I have to do? \$\endgroup\$ – beth Apr 20 '17 at 15:46

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.