I have read posts, watched videos but I cannot get my ray casting water code right.
I got the ground check working no problem, but this is smacking me around a bit.
What I am “trying to do is” raycast up and if I hit the water plane, switch to swimming.
Want to do a distance thing that if the player and the near the surface vs underwater.
Creating a point in front of my character and starting from there.
But no matter what I do I hit the player and not the water.
I am using Aquas Water, but this happens even if I use the basic.
The water has both the water Layer assigned and the tag of water.
The player has both the Player Layer assigned, and a tag of player.
I have looked at a number of posts here and on stack but none of the things they are saying seem to work.
I am definitely missing something in my understanding.
thank you for taking the time to clear the dust out of my canteen and help me find water.
void CheckIsSwimming()
{
Color waterRayColor = Color.blue;
//Exclude Player Mask
int layerMaskIndex = LayerMask.NameToLayer(“Player”);
int layerMask = 1 << layerMaskIndex;
int distanceToWater = 30;
Vector3 startPos = transform.position;
if (GameManager.Instance.IsDebugMode)
{
Debug.DrawRay(startPos, -Vector3.down * distanceToWater, waterRayColor);
}
RaycastHit hit;
if (Physics.Raycast(startPos, -Vector3.down, out hit, distanceToWater, layerMaskIndex))
{
Debug.Log(“hit:” + hit.collider.tag);
if (hit.collider.tag == “Water”)
{
Debug.Log(“Swimming.” + hit.collider.tag);
//TODO: when this works determine distance to hit for surface vs underwater swimming.
}
}
else
{ //Debug.Log(“Not Swimming.”);
Make sure your other paramters are correct. First thing I notice is your direction paramter: it should just say Vector3.up, thus changing the line from
Vector3 dir = transform.position + (Vector3.up * maxDistanceToWater);
to
Vector3 dir = Vector3.up;
Also check your other parameters. Maybe your transform.position is offset or maxDistanceToWater is not set properly or something similiar.
I have a box collider on the water, that is a trigger. I am using alot of paid animations for a mechanim root animation system. I’ll have to strip everything out. Going to try a different scene first, with simpler code to isolate the problem first.
I took the code I have , and used it on a new scene. using the basic unity3d standard third person controller.
it works, dump this code on my player object. and custom controller. it does not.
The ground terrain, and water seem to have same settings. So it has to be something else I did. I’ll add my crap back in, once piece at a time.
Maybe it has something to do with the mechanim, root motion stuff I am using (which I am not even sure I like) maybe it is messing with the transform directions.
I would prefer to not use the y coordinates because I might have caves, mountain lakes, rivers etc. at different levels. The box collider is attached to the AQUAS water prefab and set to be a trigger. I also want to use different animations for surface vs underwater Hit.distance.
And I have to figure this out anyway, for slopes, cover, falling short vs long distances etc. diving etc
I’ll look into the LayerMask.GetMask tomorrow.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ColliderCheck : MonoBehaviour
{
public float maxDistanceToWater = 10;
public LayerMask waterLayer;
public bool InWater = false;
public float distanceToGround = .3f;
public bool IsGrounded = false;
public LayerMask groundLayers;
private void LateUpdate()
{
CheckIsSwimming();
CheckIsGrounded();
}
void CheckIsSwimming()
{
Color waterRayColor = Color.blue;
Vector3 startPos = gameObject.transform.position + Vector3.up;
Debug.DrawRay(startPos, Vector3.up * maxDistanceToWater, waterRayColor);
RaycastHit hit;
if (Physics.Raycast(startPos, Vector3.up, out hit, maxDistanceToWater, waterLayer))
{
if (hit.collider.tag == "Water")
{
InWater = true;
//TODO: when this works determine distance to hit for surface vs underwater swimming.
}
else
{
InWater = false;
}
}
else
{
InWater = false;
}
}
void CheckIsGrounded()
{
Color groundRayColor = Color.yellow;
Vector3 startPos = transform.position;
Vector3 dir = transform.position + (Vector3.down * distanceToGround);
Debug.DrawLine(startPos, dir, groundRayColor);
RaycastHit hit;
if (Physics.Raycast(startPos, Vector3.down, out hit, distanceToGround, groundLayers))
{
IsGrounded = true;
}
else
{
IsGrounded = false;
}
}
}
Rebuilding my controller script from scratch seemed to work. Not sure why.
But here are the functions in case anyone is interested. Made some tweeks to the start and end of the ground check, and switched from the capsule collider to the charactercontroller (Unity’s) when I was modifying the working to to include steps.