Hello! I am creating a game where you are on a raft and have to manage your health, hunger, thirst, and exposure as well as other things while looking for an island to settle on. Currently, I am trying to implement a water system. Basically, I already have a system for walking and jumping, but I want to add swimming when in the water, as well as objects floating if possible. I’d also like to add breath. I am a beginner, and I’ve done research but what I’ve found is too outdated or wasn’t what I was looking for. I am using pixels for everything as well. If it will help, this is the script for my character. If you decide to help it’s very much appreciated, thanks ^^.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour {
public KeyCode jumpKey = KeyCode.Space;
public KeyCode walkRightKey = KeyCode.D;
public KeyCode walkLeftKey = KeyCode.A;
public Sprite walkSprite1;
public Sprite walkSprite2;
public Sprite walkSprite3;
public Sprite walkSprite4;
public Sprite walkSprite5;
public Sprite walkSprite6;
public Sprite walkSprite7;
public Sprite walkSprite8;
public Sprite walkSprite9;
public Sprite walkSprite10;
public Sprite walkSprite11;
public Sprite walkSprite12;
public Sprite walkSprite13;
public Sprite walkSprite14;
public Sprite idleSprite1;
public Sprite jumpSprite1;
public Sprite jumpSprite2;
public Sprite jumpSprite3;
public Sprite jumpSprite4;
public Sprite jumpSprite5;
public Sprite jumpSprite6;
public float speed;
public float jumpSpeed;
bool isWalking;
bool isGrounded;
bool facingRight;
RaycastHit2D hit;
void Start () {
}
void Update () {
//flips the sprite
Rigidbody2D r = GetComponent<Rigidbody2D>();
r.velocity = new Vector2(Input.GetAxis("Horizontal") * speed, r.velocity.y);
if (Input.GetAxis("Horizontal") > 0)
{
facingRight = true;
}
if (Input.GetAxis("Horizontal") < 0)
{
facingRight = false;
}
if (!facingRight)
{
GetComponent<SpriteRenderer>().flipX = true;
}
else
{
GetComponent<SpriteRenderer>().flipX = false;
}
//End of flipping sprite
hit = Physics2D.Raycast(new Vector2(transform.position.x, transform.position.y), Vector2.down);
Debug.Log(Vector2.Distance(new Vector2(transform.position.x, transform.position.y), hit.collider.transform.position));
//Does the walking and jumping animations
if (Input.GetKeyDown(walkLeftKey))
{
StartCoroutine(Walk());
isWalking = true;
}
else if (Input.GetKeyDown(walkRightKey))
{
StartCoroutine(Walk());
isWalking = true;
}
else if (Input.GetKeyDown(jumpKey))
{
r.velocity = new Vector2(r.velocity.x, jumpSpeed);
StartCoroutine(Jump());
isWalking = true;
}
if (!isWalking)
{
GetComponent<SpriteRenderer>().sprite = idleSprite1;
}
//End of animation runner
//Just for debugging
if (hit.distance < 1.9f)
{
isGrounded = true;
Debug.Log("On ground.");
}
else
{
isGrounded = false;
Debug.Log("Off ground.");
}
//End of debugging
}
//Walk animation
IEnumerator Walk()
{
isWalking = true;
GetComponent<SpriteRenderer>().sprite = walkSprite1;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite2;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite3;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite4;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite5;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite6;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite7;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite8;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite9;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite10;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite11;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite12;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite13;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite14;
yield return new WaitForSeconds(0.05f);
isWalking = false;
}
//Jump animation
IEnumerator Jump()
{
GetComponent<SpriteRenderer>().sprite = jumpSprite1;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = jumpSprite2;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = jumpSprite3;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = jumpSprite4;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = jumpSprite5;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = jumpSprite6;
yield return new WaitForSeconds(0.05f);
}
} [CODE]
I can offer a couple of pretty helpful tips for your code, though unrelated to your question.
Cache the sprite render in Awake() and use the variable throughout your code, instead of calling GetComponent all of the time.
Use arrays for walking and jumping sprites, instead of each one being its own variable. Use the index in the array when you need them.
As for your actual question: What are you looking for exactly? Floating, like in the water, they might bob a little but otherwise not ‘fall’ (ie: not affected by gravity).
Swimming… Is that to say you just want a different animation while moving in the water or something else?
This is the current code I have, and I’ve noticed that it seems that when the player passes through the “water” (it has a box collider with isTrigger checked) nothing happens. Am I doing something wrong? Sorry, I’m new to this.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour {
public KeyCode jumpKey = KeyCode.Space;
public KeyCode walkRightKey = KeyCode.D;
public KeyCode walkLeftKey = KeyCode.A;
public KeyCode walkUpKey = KeyCode.W;
public KeyCode walkDownKey = KeyCode.S;
public float speed = 6.0F;
public float jumpSpeed = 8.0F;
public float gravity = 20.0F;
private Vector3 moveDirection = Vector3.zero;
public Sprite walkSprite1;
public Sprite walkSprite2;
public Sprite walkSprite3;
public Sprite walkSprite4;
public Sprite walkSprite5;
public Sprite walkSprite6;
public Sprite walkSprite7;
public Sprite walkSprite8;
public Sprite walkSprite9;
public Sprite walkSprite10;
public Sprite walkSprite11;
public Sprite walkSprite12;
public Sprite walkSprite13;
public Sprite walkSprite14;
public Sprite idleSprite1;
public Sprite jumpSprite1;
public Sprite jumpSprite2;
public Sprite jumpSprite3;
public Sprite jumpSprite4;
public Sprite jumpSprite5;
public Sprite jumpSprite6;
//public float speed;
private bool conroller;
//public float jumpSpeed;
public float swimUpSpeed;
public float swimDownSpeed;
bool isWalking;
bool isGrounded;
bool facingRight;
bool isSwimming;
RaycastHit2D hit;
void Start () {
}
void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("Water") == true)
{
isSwimming = true;
gravity= 5;
Debug.Log("In Water");
}
}
void OnTriggerExit(Collider other)
{
if (other.gameObject.CompareTag("Water") == true)
{
isSwimming = true;
gravity = -10;
}
}
void Update () {
CharacterController controller = GetComponent<CharacterController>();
//flips the sprite
Rigidbody2D r = GetComponent<Rigidbody2D>();
r.velocity = new Vector2(Input.GetAxis("Horizontal") * speed, r.velocity.y);
if (Input.GetAxis("Horizontal") > 0)
{
facingRight = true;
}
if (Input.GetAxis("Horizontal") < 0)
{
facingRight = false;
}
if (!facingRight)
{
GetComponent<SpriteRenderer>().flipX = true;
}
else
{
GetComponent<SpriteRenderer>().flipX = false;
}
//End of flipping sprite
hit = Physics2D.Raycast(new Vector2(transform.position.x, transform.position.y), Vector2.down);
Debug.Log(Vector2.Distance(new Vector2(transform.position.x, transform.position.y), hit.collider.transform.position));
//Does the walking and jumping animations
if (Input.GetKeyDown(walkLeftKey))
{
StartCoroutine(Walk());
isWalking = true;
}
else if (Input.GetKeyDown(walkRightKey))
{
StartCoroutine(Walk());
isWalking = true;
}
else if (Input.GetKeyDown(walkUpKey))
{
if (isSwimming == true)
{
r.velocity = new Vector2(r.velocity.x, swimUpSpeed);
StartCoroutine(Walk());
}
}
else if (Input.GetKeyDown(walkDownKey))
{
if (isSwimming == true) {
r.velocity = new Vector2(r.velocity.x, swimDownSpeed);
StartCoroutine(Walk());
}
}
else if (Input.GetKeyDown(jumpKey))
{
r.velocity = new Vector2(r.velocity.x, jumpSpeed);
StartCoroutine(Jump());
isWalking = true;
}
if (!isWalking)
{
GetComponent<SpriteRenderer>().sprite = idleSprite1;
}
//End of animation runner
// is the controller on the ground?
if (controller.isGrounded)
{
//Feed moveDirection with input.
moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
//Multiply it by speed.
moveDirection *= speed;
//Jumping
if (Input.GetButton("jumpKey"))
moveDirection.y *= jumpSpeed;
}
//Applying gravity to the controller
moveDirection.y -= gravity * Time.deltaTime;
//Making the character move
controller.Move(moveDirection * Time.deltaTime);
//Just for debugging
if (hit.distance < 1.9f)
{
isGrounded = true;
Debug.Log("On ground.");
}
else
{
isGrounded = false;
Debug.Log("Off ground.");
}
//End of debugging
}
//Walk animation
IEnumerator Walk()
{
isWalking = true;
GetComponent<SpriteRenderer>().sprite = walkSprite1;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite2;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite3;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite4;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite5;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite6;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite7;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite8;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite9;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite10;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite11;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite12;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite13;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = walkSprite14;
yield return new WaitForSeconds(0.05f);
isWalking = false;
}
//Jump animation
IEnumerator Jump()
{
GetComponent<SpriteRenderer>().sprite = jumpSprite1;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = jumpSprite2;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = jumpSprite3;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = jumpSprite4;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = jumpSprite5;
yield return new WaitForSeconds(0.05f);
GetComponent<SpriteRenderer>().sprite = jumpSprite6;
yield return new WaitForSeconds(0.05f);
}
}
[CODE]
In addition to checking that the debug is working, you have set “isSwimming” to true in both enter and exit statements. Also, I believe you have gravity backwards (though I’m not sure if you just want it off while swimming to begin with).
I made sure it was tagged correctly, yet still nothing happens. And I fixed the on ground debugging. I’m using a rigidbody 2d and box collider for the player, and a box collider for the water.
If you’re still stuck after my last response, if you can create a small unity package and post it in this thread, I can take a look at it for you, if you’d like.
If you start seeing “In Trigger” but not “In Water”, double check the tag on your water object. Remember that capitalization matters, that is to say, it won’t work if it’s tagged as “water” instead of “Water”. I can’t tell you how many times I’ve seen people (including myself) forget that.
No, unfortunately. Unity scenes don’t contain everything, they need the assets used in them to work. The easiest two ways to send your projects are either to zip up the whole project folder, or, much simple, you can right click on your scene file within unity, and choose “Export Package”. This will make a package file that someone else can import into their project. That’s the easiest way for you to show us your project.
Okay, so you had a few issues I quickly fixed up & 1 “oops” oversight from this thread lol
So, you were trying OnTriggerEnter and OnTriggerExit and I/we should have corrected you that you should be using OnTriggerEnter2D and OnTriggerExit2D
The errors I fixed were related to index out of range. You are writing you code as though indexes begin at ‘1’, but they begin at ‘0’.
As for the actual water floating implementation, I have not worked that out for you. However, if you make these corrections, perhaps you can at least be on track to tackle that next issue. Ok?