/// <summary> /// Initializes a new instance of the <see cref="DynamicWaterMesh"/> class. /// </summary> /// <param name="resolution"> /// The number of grid nodes along the bigger side of the mesh. /// </param> /// <param name="size">The width and length of the mesh</param> /// <param name="settings"> /// DynamicWaterSettings instance representing the public settings properties of <see cref="DynamicWater"/> class. /// </param> /// <param name="fieldObstruction"> /// The array of <c>byte</c> indicating whether the water is obstructed by an object. \n /// <c>0</c> means the grid node is obstructed by an object, so the simulation is not updated; /// <c>255</c> means the grid node is not obstructed, and the simulation can proceed freely. /// Intermediate values represent the additional dampening value in that node. /// </param> public DynamicWaterMesh(int resolution, Vector2 size, IDynamicWaterSettings settings, byte[] fieldObstruction = null) { IsReady = false; _settings = settings; _size = size; GridMath.CalculateGrid(resolution, size, out _grid, out _nodeSize); // Some failsafe if (_size.x < Vector3.kEpsilon || _size.y < Vector3.kEpsilon) { _grid = new Vector2Int(1, 1); } _mesh = new Mesh(); _mesh.name = "DynamicWaterMesh"; #if !UNITY_3_5 _mesh.MarkDynamic(); #endif AllocateMeshArrays(); CreateMeshGrid(fieldObstruction); AssignMesh(); _mesh.RecalculateBounds(); IsReady = true; }
/// <summary> /// Called when BuoyantObject enters the water. /// </summary> /// <param name="eventWater"> /// The FluidVolume which the object has entered. /// </param> public void OnFluidVolumeEnter(IDynamicWaterFluidVolume eventWater) { _water = eventWater as IDynamicWaterSettings; if (_water == null) { return; } if (_water.PlaneCollider != null) { SpawnSplash(SplashPrefab, _water.PlaneCollider.ClosestPointOnBounds(transform.position)); } }
protected void FixedUpdate() { // Checking for WaterDetector if (_waterDetector == null) { _waterDetector = GetComponent <WaterDetector>() ?? gameObject.AddComponent <WaterDetector>(); } // If we are in the water if (_waterDetector.Water != null) { IDynamicWaterSettings water = _waterDetector.Water as IDynamicWaterSettings; if (water == null) { return; } _controller = GetComponent <CharacterController>(); // If we are actually submerged to a some extent float waterLevel = water.GetWaterLevel(transform.position); float min = _controller.bounds.center.y - _controller.height / 2f; float max = _controller.bounds.center.y + _controller.height / 2f; _isSubmerged = min <waterLevel && max> waterLevel; // Do not make ripples while standing if (_controller.velocity.sqrMagnitude > 0.5f && _isSubmerged) { water.CreateSplash(transform.position, SplashRadius, SplashForce * Time.deltaTime); } // Checking if we must make a splash if (_splashAllowed && _isSubmerged && _isSubmerged != _isSubmergedPrev && !_controller.isGrounded && _controller.velocity.y < -SplashThreshold) { SpawnSplash(JumpSplashPrefab, water.PlaneCollider.ClosestPointOnBounds(transform.position)); water.CreateSplash(transform.position, JumpSplashRadius, JumpSplashForce); // To make sure we are not making splashes too often _splashAllowed = false; StartCoroutine(AllowSplash()); } _isSubmergedPrev = _isSubmerged; } }