Unity 3D液体浮力实现
来源:互联网 发布:知党史,学党史,跟党走 编辑:程序博客网 时间:2024/04/27 12:05
前言
本文以unity的StandardAssets中的water资源为基础,实现物体在水中的漂浮效果。
概述
1. 建立场景并添加水详见https://docs.unity3d.com/Manual/HOWTO-Water.html
2. 给水添加碰撞体组件,编写脚本现实物体出入水的检测。
3. 创建立方体预制体,添加刚体组件,碰撞体组件,编辑脚本处理入水后的浮力计算。
实现细节
1. 给水体添加碰撞体
需要注意的是要勾选 Is Trigger ,y方向的范围要控制好,不然可能会出现物体掉到水面一下太多会触发OnTriggerExit() (见脚本部分)。
2. 创建立方体
我创建了一个长宽高分别为1,质量为0.5的立方体,预期效果是在水中漂浮一半露出水面。之后可以通过脚本改变大小及质量验证效果。
3. 水的脚本
水的脚本主要实现OnTriggerEnter和OnTriggerExit两个方法,当其他碰撞体进入水中,触发OnTriggerEnter,将cube中的isInWater置为ture,OnTriggerExit相反。
4. 立方体脚本
立方体脚本的核心是calFloatage方法,计算立方体下表面与水面高度差,通过公式计算浮力,并通过Rigidbody.AddForce()方法施加浮力。
进入水中后将阻力系数调高。
需要注意的是物体完全进入水中后保持h = 立方体高度
5. 代码
using System.Collections;using System.Collections.Generic;using UnityEngine;public class Floatage : MonoBehaviour {// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {}/// <summary>/// OnTriggerEnter is called when the Collider other enters the trigger./// </summary>/// <param name="other">The other Collider involved in this collision.</param>void OnTriggerEnter(Collider other){if(other.gameObject.GetComponent<Cube>()){other.gameObject.GetComponent<Cube>().setIsInWater(true);}}/// <summary>/// OnTriggerExit is called when the Collider other has stopped touching the trigger./// </summary>/// <param name="other">The other Collider involved in this collision.</param>void OnTriggerExit(Collider other){if(other.gameObject.GetComponent<Cube>()){other.gameObject.GetComponent<Cube>().setIsInWater(false);}}}
using System.Collections;using System.Collections.Generic;using UnityEngine;public class Cube : MonoBehaviour {private bool isInWater;private GameObject water; private float waterY;private const float floatageForce = 0;private const float density = 1;private const float g = 9.8f;private const float waterDrag = 5;public bool getIsInWater(){return isInWater;}public void setIsInWater(bool isInWater){ this.isInWater = isInWater;}// Use this for initializationvoid Start () {isInWater = false;water = GameObject.FindWithTag("water");}// Update is called once per framevoid Update () {}/// <summary>/// This function is called every fixed framerate frame, if the MonoBehaviour is enabled./// </summary>void FixedUpdate(){if(isInWater){//calculate floatagecalFloatage();//change dargGetComponent<Rigidbody>().drag = waterDrag;}}//calculate and add floatage force to the box.private void calFloatage(){waterY = water.transform.position.y;if(waterY>(transform.position.y-transform.localScale.y)){float h = waterY-(transform.position.y-transform.localScale.y/2)>transform.localScale.y? transform.localScale.y:waterY-(transform.position.y-transform.localScale.y/2);float floatageForce = density * g *transform.localScale.x*transform.localScale.z*h;GetComponent<Rigidbody>().AddForce(0,floatageForce,0);}}}
6. 效果
问题
1. 物体出现旋转的话要很久才能停下来,不知道调整什么阻力可以实现更加逼真的效果,或者手动实现。
已经解决。进入水中增大angular drag即可。
小弟第一次写博客,才开始学习unity,望大佬们多多指教!
- Unity 3D液体浮力实现
- [Unity]液体物理
- unity实现3D饼图
- Unity 3D 存档实现
- Unity 3d 实现倒计时
- Unity 3D UV实现小地图
- Unity 3D实现血量增加减少
- Unity 3D 实现背包效果
- Unity中实现3D物体跳跃
- Unity 实现鼠标拖动3D物体
- Unity 3D实现帧同步技术
- Unity 立体3D VR的实现
- Unity 3D碰撞实现方法
- 2D液体物理引擎 -- LiquidFun
- Unity 2d动画实现
- Unity 3D
- unity 3d 注意事项
- Unity 3d 摄像头
- [Java Web]Web请求过程之一:HTTP
- poj 3678 2SAT+挑战板子
- linux中网络的管理
- java OO——static
- 多线程程序设计
- Unity 3D液体浮力实现
- cp: omitting directory”错误的解释和解决办法
- 1006. 换个格式输出整数 (15)
- mint-ui —— tabbar示例
- File类递归(统计文件夹大小)
- VMware vSphere Web Services SDK编程指南(四)- vSphere API 编程模型(一)
- 算法面试题之句子反转
- GamePlay
- 数据结构 二叉树的先序 中序 后序遍历(linux 下c语言实现)