unity3d 物体漂浮

2017-08-05 16:27:00 weixin_33719619 阅读数 1159
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

在官方论坛看到一个关于怎么使物体漂浮在水面上的讨论:https://forum.unity3d.com/threads/floating-a-object-on-water.31671/

 

水动力系统 插件:

另外关于船只移动产生的尾部水波纹,使用粒子特效,可以参考Bootcamp插件。

 

最简单最低成本的办法:

在Update中检测物体高度(y轴),大于水面高度就启用重力,否则禁用重力。

void Update ()
{
    if(transform.position.y <= 0.5f)
    {
        gameObject.GetComponent.<Rigidbody> ().useGravity = false;
    }
    else
    {
        gameObject.GetComponent.<Rigidbody> ().useGravity = true;
    }

    if(transform.position.y <= 0.4f)
    { 
        transform.position.y = 0.5f;
    }
}

 

2015-08-26 10:30:20 sinat_20559947 阅读数 30469
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

using UnityEngine;
using System.Collections;
// 主界面的开始按钮使用该脚本,控制上下来回浮动
public class Floating : MonoBehaviour {
	float radian = 0; // 弧度
	float perRadian = 0.03f; // 每次变化的弧度
	float radius = 0.8f; // 半径
	Vector3 oldPos; // 开始时候的坐标
	// Use this for initialization
	void Start () {
		oldPos = transform.position; // 将最初的位置保存到oldPos
	}
	
	// Update is called once per frame
	void Update () {
		radian += perRadian; // 弧度每次加0.03
		float dy = Mathf.Cos(radian) * radius; // dy定义的是针对y轴的变量,也可以使用sin,找到一个适合的值就可以
		transform.position = oldPos + new Vector3 (0, dy, 0);
	}
}

2017-08-17 14:30:11 dark00800 阅读数 2102
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

之前左右游戏的时候有需要实现模拟物体漂浮的功能的,所以写了一个简单的物体漂浮的算法,使用正弦函数和余弦函数去控制物体的偏移量,这样就能实现物体绕着原点漂浮的感觉。

首先我们需要设置一个最大偏移量offset和振动频率frequency。

public Vector3 offset;
public float frequency;

然后我们还需要记录物体的原始坐标即原点originPosition,用于计算当前时间量的tick值(可以理解成函数坐标轴的x值),物体的振幅(根据我们设定的frequency计算)和用于控制物体漂浮动画的animate值。

private Vector3 originPosition;
private float tick;
private float amplitude;
private bool animate;

在Awake方法中对各个属性进行赋值,然后在FixedUpdate方法中进行计算:

void Awake()
{
    // 如果没有设置频率或者设置的频率为0则自动记录成1
    if (Mathf.Approximately(frequency, 0))
        frequency = 1f;

    originPosition = transform.localPosition;
    tick = Random.Range(0f, 2f * Mathf.PI);
    // 计算振幅
    amplitude = 2 * Mathf.PI / frequency;
    animate = false;
}

void FixedUpdate()
{
    if (animate)
    {
        // 计算下一个时间量
        tick = tick + Time.fixedDeltaTime * amplitude;
        // 计算下一个偏移量
        var amp = new Vector3(Mathf.Cos(tick) * offset.x, Mathf.Sin(tick) * offset.y, 0);
        // 更新坐标
        transform.localPosition = originPosition + amp;
    }
}

由于需求是针对UI的,所以Z轴上不需要做位移,这里可以根据需求进行修改。我们还可以设置一个是否自动播放的变量,并在Awake方法中将其赋值给animate:

public bool playAwake;

void Awake()
{
    animate = playAwake;
}

最后写两个简单的播放和停止的方法:

public void Play()
{
    transform.localPosition = originPosition;
    animate = true;
}

public void Stop()
{
    transform.localPosition = originPosition;
    animate = false;
}

这里直接在停止时将物体移动到原点,如果需要更顺畅的动画的话,我们可以在停止时在停止的位置点和原点之间做一个插值动画来让物体慢慢飘回原点。

将脚本挂载到物体上后进行编辑:
脚本编辑
设置不同的合适的偏移量和频率还可以达到远近景的效果。

运行效果:
运行效果

完整代码:
FloatingObj.cs:

using UnityEngine;

public class FloatingObj : MonoBehaviour
{
    public Vector3 offset;
    public float frequency;
    public bool playAwake;

    private Vector3 originPosition;
    private float tick;
    private float amplitude;
    private bool animate;

    void Awake()
    {
        // 如果没有设置频率或者设置的频率为0则自动记录成1
        if (Mathf.Approximately(frequency, 0))
            frequency = 1f;

        originPosition = transform.localPosition;
        tick = Random.Range(0f, 2f * Mathf.PI);
        // 计算振幅
        amplitude = 2 * Mathf.PI / frequency;
        animate = playAwake;
    }

    public void Play()
    {
        transform.localPosition = originPosition;
        animate = true;
    }

    public void Stop()
    {
        transform.localPosition = originPosition;
        animate = false;
    }

    void FixedUpdate()
    {
        if (animate)
        {
            // 计算下一个时间量
            tick = tick + Time.fixedDeltaTime * amplitude;
            // 计算下一个偏移量
            var amp = new Vector3(Mathf.Cos(tick) * offset.x, Mathf.Sin(tick) * offset.y, 0);
            // 更新坐标
            transform.localPosition = originPosition + amp;
        }
    }
}

By: 蒋志杰

2016-10-15 22:06:13 alistair_chow 阅读数 1217
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

效果图:


思路:

1. 首先获取3D物体在屏幕上的坐标点

2. 将2D图像放置于该坐标点的上方

3. 判断物体在屏幕上的坐标是否改变,若改变则更新2D图像位置

代码

<pre name="code" class="csharp">public class UIImageOnObject : MonoBehaviour {
    public Camera m_Camera;
    public GameObject m_Target;
    public float m_Offset = 90f;
    public bool m_IsActive;
    private Vector3 m_Pos;
    private Vector3 m_CurPos;
    private Tweener m_Tween;

	// Update is called once per frame
	void Update () {
        if (m_IsActive)
        {
            m_CurPos = m_Camera.WorldToScreenPoint(m_Target.transform.position);
            //若目标物体在屏幕上的坐标改变,则更新位置及动画
            if(m_Pos != m_CurPos)
            {
                m_Pos = m_CurPos;
                transform.position = new Vector3(m_CurPos.x, m_CurPos.y + m_Offset, m_Pos.z);
                m_Tween.Kill();
                m_Tween = transform.DOMoveY(m_CurPos.y + m_Offset - 10f, 0.8f).SetLoops(-1);
            }
        }
    }

    public void SetActive(bool active)
    {
        m_IsActive = active;
        if (active)
        {
            //获取目标物体在屏幕上的坐标
            m_Pos = m_Camera.WorldToScreenPoint(m_Target.transform.position);
            m_CurPos = m_Pos;
            //将2D物体置与坐标点的上方
            transform.position = new Vector3(m_CurPos.x, m_CurPos.y + m_Offset, m_CurPos.z);
            //动画,2D物体上下漂浮效果
            m_Tween = transform.DOMoveY(m_CurPos.y + m_Offset - 10f, 0.8f).SetLoops(-1);
        }
        if (active == false)
            gameObject.SetActive(false);
    }
}





2019-05-03 23:12:48 qq_39574690 阅读数 698
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 物品浮动效果
/// </summary>
public class TestItemFloat : MonoBehaviour
{
    //漂浮幅度
    public float speed = 1f;
    //漂浮范围X,Y,Z
    public Vector3 offsetXYZ = new Vector3(1, 1, 1);
    //原点
    private Vector3 originalPos;

    void Start()
    {
        if (speed <= 0)
        {
            speed = 1f;
        }
        //获取原点
        originalPos = transform.localPosition;
    }

    void Update()
    {
        //根据三角函数以时间为变化量模拟浮动效果(看个人喜好如何偏移但是乘上的值必须要在[-1,1]合理范围内变化)
        transform.localPosition = originalPos + new Vector3(offsetXYZ.x * Mathf.Sin(Time.time * speed), offsetXYZ.y * Mathf.Cos(Time.time * speed) * Mathf.Sin(Time.time * speed), offsetXYZ.z * Mathf.Cos(Time.time * speed));
    }
}