/// <summary> /// Swim Logic /// </summary> protected virtual void Swimming(float time) { if (!canSwim) { return; //If it cannot swim do nothing } if (CanGoUnderWater && underwater) { return; //if we are underwater this behavior does not need to be calcultate **Important** } if (Stand) { return; //Skip if where doing nothing } if (!hasSwim) { return; //If doesnt have swimm animation don't do the swimming calculations } if (!pivot_Water) { return; //If there's no water Pivot do nothing } RaycastHit WaterHitCenter; //Front RayWater Cast if (Physics.Raycast(pivot_Water.transform.position, -_transform.up, out WaterHitCenter, scaleFactor * pivot_Water.multiplier, WaterLayer)) { waterlevel = WaterHitCenter.point.y; //Get the water level when find water if (!isInWater) { isInWater = true; //Has found a water layer.. so Set isInWater to true } } else { if (isInWater && !RealAnimatorState(Hash.Tag_SwimJump)) { isInWater = false; } } if (isInWater) //if we hit water { if ((hit_Chest.distance < (_Height * 0.8f) && movementAxis.z > 0 && hit_Chest.transform != null) || //Exit the water walking forward and it has found land (hit_Hip.distance < (_Height * 0.8f) && movementAxis.z < 0 && hit_Hip.transform != null)) //Exit the water walking backward and it has found land { if (CurrentAnimState.tagHash != Hash.Tag_Recover) //Don't come out of the water if you are playing entering water { Swim = false; return; } } if (!swim) { if (Pivot_Chest.Y <= waterlevel) //Enter the water if the water is above chest level { Swim = true; OnSwim.Invoke(); if (_RigidBody) { _RigidBody.constraints = Still_Constraints; } } } } if (swim) { fall = isInAir = fly = false; // Reset all other states float angleWater = Vector3.Angle(_transform.up, WaterHitCenter.normal); //Calculates the angle of the water Quaternion finalRot = Quaternion.FromToRotation(_transform.up, WaterHitCenter.normal) * transform.rotation; //Calculate the rotation forward for the water //lerp rotate until is Aling with the Water if (angleWater > 0.5f) { _transform.rotation = Quaternion.Lerp(_transform.rotation, finalRot, time * 8); } else { _transform.rotation = finalRot; } //Smoothy Aling position with the Water Vector3 NewPos = new Vector3(_transform.position.x, waterlevel - _Height + waterLine, _transform.position.z); if (CurrentAnimState.tagHash != Hash.Tag_SwimJump) //if is not Swim Jumping then aling with the water { _transform.position = Vector3.Lerp(_transform.position, NewPos, time * 5f); } //-------------------Go UnderWater--------------- if (CanGoUnderWater && down && !IsJumping() && !RealAnimatorState(Hash.Tag_SwimJump)) { underwater = true; } } }
/// <summary> /// Swim Logic /// </summary> protected virtual void Swimming(float time) { if (!hasSwim || !canSwim) { return; //If doesnt have swimm animation don't do the swimming calculations } if (underwater) { return; //if we are underwater this behavior does not need to be calcultate **Important** } if (Stand || !pivot_Water) { return; //Skip if where doing nothing | If there's no water Pivot do nothing } if (FrameCounter % WaterRayInterval == 0) { RaycastWater(); //DO the Water Raycast } if (isInWater) //if we hit water { if ((hit_Chest.distance < (_Height * 0.8f) && movementAxis.z > 0 && hit_Chest.transform != null) || //Exit the water walking forward and it has found land (hit_Hip.distance < (_Height * 0.8f) && movementAxis.z < 0 && hit_Hip.transform != null)) //Exit the water walking backward and it has found land { if (AnimState != AnimTag.Recover) //Don't come out of the water if you are playing entering water { Swim = false; return; } } if (!swim) { if (Pivot_Chest.Y <= Waterlevel) //Enter the water if the water is above chest level { Swim = true; currentSpeed = swimSpeed; OnSwim.Invoke(); _RigidBody.constraints = Still_Constraints; } } } if (swim) { fall = isInAir = fly = false; // Reset all other states float angleWater = Vector3.Angle(T_Up, WaterHitCenter.normal); //Calculates the angle of the water Quaternion finalRot = Quaternion.FromToRotation(T_Up, WaterHitCenter.normal) * _transform.rotation; //Calculate the rotation forward for the water Quaternion deltaFixRotation = Quaternion.Inverse(_transform.rotation) * finalRot; if (angleWater > 0.5f) { deltaFixRotation = Quaternion.Slerp(DeltaRotation, DeltaRotation * deltaFixRotation, time * 10f); } DeltaRotation *= deltaFixRotation; //-------------------Go UnderWater--------------- if (CanGoUnderWater && Down && !IsJumping && AnimState != AnimTag.SwimJump) { underwater = true; } } }